@holdyapp/sdk 1.5.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/changes.d.ts +16 -2
- package/dist/changes.d.ts.map +1 -1
- package/dist/core.d.ts +1 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/friction.d.ts +2 -1
- package/dist/friction.d.ts.map +1 -1
- package/dist/holdy.js +25 -4
- package/dist/holdy.js.map +4 -4
- package/dist/index.cjs +540 -33
- package/dist/index.cjs.map +4 -4
- package/dist/index.mjs +540 -33
- package/dist/index.mjs.map +4 -4
- package/dist/server.cjs +3 -0
- package/dist/server.cjs.map +2 -2
- package/dist/server.mjs +3 -0
- package/dist/server.mjs.map +2 -2
- package/dist/skeleton.d.ts +52 -0
- package/dist/skeleton.d.ts.map +1 -0
- package/dist/theme.d.ts +43 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/tip-css.d.ts +9 -0
- package/dist/tip-css.d.ts.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/web-context.d.ts +1 -0
- package/dist/web-context.d.ts.map +1 -1
- package/dist/web.d.ts +10 -1
- package/dist/web.d.ts.map +1 -1
- package/dist/web.mjs +540 -33
- package/dist/web.mjs.map +4 -4
- package/package.json +1 -1
- package/src/changes.dom.test.ts +221 -0
- package/src/changes.test.ts +38 -0
- package/src/changes.ts +299 -26
- package/src/core.test.ts +15 -0
- package/src/core.ts +3 -0
- package/src/friction.dom.test.ts +54 -0
- package/src/friction.test.ts +43 -0
- package/src/friction.ts +44 -7
- package/src/skeleton.test.ts +60 -0
- package/src/skeleton.ts +182 -0
- package/src/theme.test.ts +118 -0
- package/src/theme.ts +120 -0
- package/src/tip-css.ts +32 -0
- package/src/types.ts +6 -0
- package/src/web-context.test.ts +18 -0
- package/src/web-context.ts +8 -0
- package/src/web.ts +28 -3
package/README.md
CHANGED
|
@@ -26,18 +26,25 @@ O SDK web observa sozinho os sinais de fricção e emite eventos determinístico
|
|
|
26
26
|
| `$dead_click` | clique em controle desabilitado / `aria-disabled` / âncora sem `href` | `element`, `element_text`, `element_id`, `path` |
|
|
27
27
|
| `$rage_click` | 3 cliques em 1s num raio de 30px | idem |
|
|
28
28
|
| `$form_abandon` | campos de um form tocados e a página sai sem `submit` | `form`, `fields_touched`, `path` |
|
|
29
|
-
| `$js_error` | `window.error` / `unhandledrejection` | `message` (≤200), `source`, `line` |
|
|
29
|
+
| `$js_error` | `window.error` / `unhandledrejection` | `message` (≤200), `source`, `line`, `column`, `stack` (até 8 frames, URL sem query) |
|
|
30
30
|
| `$slow_request` | `fetch`/XHR acima de 3s com resposta ok | `url` (sem query), `method`, `duration_ms`, `status` |
|
|
31
31
|
| `$nav_loop` | A → B → A → B em menos de 60s | `from`, `to`, `path` |
|
|
32
32
|
| `$http_error` | `fetch`/XHR com status ≥ 400 ou sem resposta (cancelado não conta), ou a própria página abrindo com status ≥ 400 | `url` (sem query), `method`, `duration_ms`, `status` ou `failed`; `document: true` quando é a página |
|
|
33
33
|
|
|
34
34
|
Requisição pra URL da Holdy nunca vira `$http_error`; `ignoreUrls` acrescenta outras (prefixo).
|
|
35
|
+
| `$page_skeleton` | esqueleto da página, uma vez por (rota, estrutura) por aba: elementos interativos sem texto livre nem valor de input | `path`, `hash`, `count`, `elements` |
|
|
35
36
|
|
|
36
37
|
```ts
|
|
37
38
|
initHoldy({ apiKey, friction: false }) // desliga
|
|
38
39
|
initHoldy({ apiKey, friction: { slowRequestMs: 5000 } }) // ajusta limiares
|
|
39
40
|
```
|
|
40
41
|
|
|
42
|
+
`release` diz qual versão do produto está no ar (sha do commit, tag ou número do build). Vai em `context.release` de todo evento, e é o que deixa a Holdy dizer em que versão um erro apareceu:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
initHoldy({ apiKey, release: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA })
|
|
46
|
+
```
|
|
47
|
+
|
|
41
48
|
No Holdy esses eventos viram Behaviors de fricção e alimentam o contraste "sessões com fricção convertem X% menos" (ADR-0009).
|
|
42
49
|
|
|
43
50
|
### Mudanças no produto (default ligada)
|
|
@@ -47,6 +54,7 @@ Quando uma ação de texto ou dica é posta no ar na Holdy, o SDK a aplica na p
|
|
|
47
54
|
- Precisa de conta identificada (`group()` ou `accountKey`): sem ela nada é aplicado.
|
|
48
55
|
- Troca de texto só acontece quando o elemento ainda tem o texto esperado; a dica é um cartão em shadow DOM que não volta depois de fechado.
|
|
49
56
|
- Só `textContent`, nunca HTML.
|
|
57
|
+
- Prévia: abrir o produto com `?holdy_preview=<id da mudança>` (o link "Ver no seu produto" na tela da ação) mostra a mudança pra quem abriu, antes ou depois de ir pro ar, fora do sorteio. Vale pela aba, não emite `$change_exposure` nem `$voice`, e qualquer outro valor desliga.
|
|
50
58
|
|
|
51
59
|
| Evento | Quando | Propriedades |
|
|
52
60
|
|---|---|---|
|
package/dist/changes.d.ts
CHANGED
|
@@ -8,16 +8,23 @@ export type ChangeAnchor = {
|
|
|
8
8
|
} | {
|
|
9
9
|
kind: 'page';
|
|
10
10
|
};
|
|
11
|
+
export interface ChecklistItem {
|
|
12
|
+
definition_name: string;
|
|
13
|
+
label: string;
|
|
14
|
+
events: string[];
|
|
15
|
+
}
|
|
11
16
|
export interface ProductChange {
|
|
12
17
|
id: string;
|
|
13
|
-
kind: 'copy' | 'guidance';
|
|
18
|
+
kind: 'copy' | 'guidance' | 'question' | 'checklist';
|
|
14
19
|
path: string;
|
|
15
20
|
anchor: ChangeAnchor;
|
|
16
21
|
expected_text: string | null;
|
|
17
22
|
content: {
|
|
18
23
|
text: string;
|
|
24
|
+
items?: ChecklistItem[];
|
|
19
25
|
};
|
|
20
26
|
holdout_pct: number;
|
|
27
|
+
plan_id?: string;
|
|
21
28
|
}
|
|
22
29
|
export interface ProductChangesOptions {
|
|
23
30
|
baseUrl: string;
|
|
@@ -28,15 +35,22 @@ export interface ProductChangesOptions {
|
|
|
28
35
|
}
|
|
29
36
|
export interface ProductChangesHandle {
|
|
30
37
|
onNavigate(): void;
|
|
38
|
+
/** Evento do produto: marca na hora o passo do checklist que ele satisfaz; o servidor confirma depois. */
|
|
39
|
+
onEvent(name: string): void;
|
|
31
40
|
refresh(): Promise<void>;
|
|
32
41
|
teardown(): void;
|
|
33
42
|
}
|
|
43
|
+
export declare const VOICE_EVENT = "$voice";
|
|
44
|
+
export declare const MAX_ANSWER_CHARS = 1000;
|
|
45
|
+
export declare const PREVIEW_PARAM = "holdy_preview";
|
|
34
46
|
export declare function normalizeText(text: string): string;
|
|
35
47
|
export declare function parseChanges(body: unknown): ProductChange[];
|
|
36
|
-
export declare function changesForPage(changes: readonly ProductChange[], path: string, accountKey: string | null): Array<{
|
|
48
|
+
export declare function changesForPage(changes: readonly ProductChange[], path: string, accountKey: string | null, previewId?: string | null): Array<{
|
|
37
49
|
change: ProductChange;
|
|
38
50
|
arm: ChangeArm;
|
|
51
|
+
preview: boolean;
|
|
39
52
|
}>;
|
|
53
|
+
export declare function resolvePreviewId(search: string, store: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'> | undefined): string | null;
|
|
40
54
|
export declare function findByText(value: string): Element | null;
|
|
41
55
|
export declare function installProductChanges(opts: ProductChangesOptions): ProductChangesHandle;
|
|
42
56
|
//# sourceMappingURL=changes.d.ts.map
|
package/dist/changes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../src/changes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtE,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpB,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAA;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,YAAY,CAAA;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;KAAE,CAAA;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;IAClC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;IAClE,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,IAAI,IAAI,CAAA;IAClB,0GAA0G;IAC1G,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB,QAAQ,IAAI,IAAI,CAAA;CACjB;AAYD,eAAO,MAAM,WAAW,WAAW,CAAA;AACnC,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAEpC,eAAO,MAAM,aAAa,kBAAkB,CAAA;AAK5C,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,EAAE,CAG3D;AAiCD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,aAAa,EAAE,EACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,SAAS,GAAE,MAAM,GAAG,IAAW,GAC9B,KAAK,CAAC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,GAAG,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAUpE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAqBtI;AAuCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAcxD;AAqBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,qBAAqB,GAAG,oBAAoB,CAiavF"}
|
package/dist/core.d.ts
CHANGED
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAkB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEvF,eAAO,MAAM,gBAAgB,8BAA8B,CAAA;AAS3D,qBAAa,SAAS;IACpB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACjC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAkB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEvF,eAAO,MAAM,gBAAgB,8BAA8B,CAAA;AAS3D,qBAAa,SAAS;IACpB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACjC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAE3C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAO;IACtC,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAO;IAC3C,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAO;gBAE9B,MAAM,EAAE,SAAS,GAAG,YAAY,EAAE,IAAI,EAAE,YAAY;IAmBhE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,cAAc,GAAG,IAAI;IAmC9E,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IAMnD,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IAMpD,uFAAuF;IACjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,gFAAgF;IAC1E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B,OAAO,CAAC,UAAU;YAYJ,KAAK;IAenB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,SAAS;YAIH,IAAI;IAqClB,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,QAAQ;IAMhB;;;;OAIG;IACH,SAAS,CAAC,kBAAkB,IAAI,UAAU;IAI1C,oCAAoC;IACpC,IAAI,OAAO,IAAI,MAAM,CAEpB;CACF"}
|
package/dist/friction.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare class NavLoopDetector {
|
|
|
40
40
|
} | null;
|
|
41
41
|
}
|
|
42
42
|
export interface ElementLike {
|
|
43
|
-
tagName
|
|
43
|
+
tagName?: string;
|
|
44
44
|
id?: string;
|
|
45
45
|
disabled?: boolean;
|
|
46
46
|
textContent?: string | null;
|
|
@@ -52,6 +52,7 @@ export declare function isDeadClickTarget(el: ElementLike | null): boolean;
|
|
|
52
52
|
export declare function describeElement(el: ElementLike | null): Record<string, string>;
|
|
53
53
|
export declare function stripRequestUrl(input: string, base?: string): string;
|
|
54
54
|
export declare function errorMessage(reason: unknown): string;
|
|
55
|
+
export declare function sanitizeStack(stack: unknown): string | null;
|
|
55
56
|
export declare function isAbortError(err: unknown): boolean;
|
|
56
57
|
export declare function isIgnoredUrl(url: string, ignore: readonly string[]): boolean;
|
|
57
58
|
/**
|
package/dist/friction.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"friction.d.ts","sourceRoot":"","sources":["../src/friction.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,UAAU,GACV,cAAc,GACd,UAAU,GACV,YAAY,CAAA;AAEhB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAA;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB;AAQD,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAL3B,OAAO,CAAC,MAAM,CAAiD;gBAG5C,SAAS,SAAI,EACb,QAAQ,SAAO,EACf,QAAQ,SAAK;IAGhC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;CAW/C;AAED,qBAAa,eAAe;IAGd,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,MAAM,CAAyC;gBAE1B,QAAQ,SAAS;IAE9C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAUnE;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"friction.d.ts","sourceRoot":"","sources":["../src/friction.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,UAAU,GACV,cAAc,GACd,UAAU,GACV,YAAY,CAAA;AAEhB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAA;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB;AAQD,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAL3B,OAAO,CAAC,MAAM,CAAiD;gBAG5C,SAAS,SAAI,EACb,QAAQ,SAAO,EACf,QAAQ,SAAK;IAGhC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;CAW/C;AAED,qBAAa,eAAe;IAGd,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,MAAM,CAAyC;gBAE1B,QAAQ,SAAS;IAE9C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAUnE;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACzC,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;CAC/C;AAMD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,WAAW,GAAG,IAAI,CAS7E;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAYjE;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa9E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAOpE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAQpD;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAa3D;AAUD,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAElD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAItD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO,CAc/G;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,YAAY,GAAG,cAAc,GAAG,IAAI,CAI7F;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE;IAAE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,EAAE,CAAA;CAAE,GAAG,SAAS,GACnE,MAAM,GAAG,IAAI,CAQf;AAqBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,eAAe,CAqLpF"}
|
package/dist/holdy.js
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
"use strict";var Holdy=(()=>{var N=Object.defineProperty;var ht=Object.getOwnPropertyDescriptor;var ft=Object.getOwnPropertyNames;var gt=Object.prototype.hasOwnProperty;var mt=(e,t)=>{for(var n in t)N(e,n,{get:t[n],enumerable:!0})},yt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ft(t))!gt.call(e,i)&&i!==n&&N(e,i,{get:()=>t[i],enumerable:!(r=ht(t,i))||r.enumerable});return e};var vt=e=>yt(N({},"__esModule",{value:!0}),e);var pe={};mt(pe,{flush:()=>le,getInstance:()=>de,group:()=>se,identify:()=>ie,init:()=>re,page:()=>ae,reset:()=>ue,shutdown:()=>ce,track:()=>oe});var wt="https://holdy.chat/api/v1";var I=class{apiKey;baseUrl;flushAt;debug;source;queue=[];timer=null;flushing=null;retryAt=0;failures=0;warned=new Set;userId=null;anonymousId=null;accountKey=null;constructor(t,n){this.source=t,this.apiKey=n.apiKey,this.accountKey=n.accountKey??null,this.baseUrl=(n.baseUrl??wt).replace(/\/$/,""),this.flushAt=Math.max(1,n.flushAt??20),this.debug=n.debug??!1;let r=n.flushIntervalMs??5e3;r>0&&(this.timer=setInterval(()=>void this.flush(),r),typeof this.timer.unref=="function"&&this.timer.unref())}track(t,n,r){if(!t||typeof t!="string")return;let i=r?.userId??this.userId??void 0,l=r?.accountKey??this.accountKey??void 0,c=r?.occurredAt?new Date(r.occurredAt).toISOString():new Date().toISOString(),p={...this.environmentContext(),...r?.context??{}};l&&(p.account_external_id=l);let f={event:t,occurred_at:c,source:this.source,external_id:xt(),...i?{user_id:i}:{},...this.anonymousId?{anonymous_id:this.anonymousId}:{},properties:n??{},...Object.keys(p).length>0?{context:p}:{}};this.queue.push(f),this.trimQueue(),this.queue.length>=this.flushAt&&this.flush()}identify(t,n){!t||typeof t!="string"||(this.userId=t,this.track("$identify",n??{}))}group(t,n){!t||typeof t!="string"||(this.accountKey=t,this.track("$group",n??{}))}async flush(){return this.startFlush(!1)}async shutdown(){this.timer&&(clearInterval(this.timer),this.timer=null),await this.startFlush(!0)}startFlush(t){return this.flushing?this.flushing:this.queue.length===0||!t&&Date.now()<this.retryAt?Promise.resolve():(this.flushing=this.drain().finally(()=>{this.flushing=null}),this.flushing)}async drain(){for(;this.queue.length>0;){let t=this.queue.splice(0,500),n=await this.send(t);if(n.kind==="retry"){this.queue.unshift(...t),this.trimQueue(),this.scheduleRetry(n.afterMs);return}this.failures=0,this.retryAt=0}}scheduleRetry(t){if(this.failures+=1,t!==null){this.retryAt=Date.now()+t;return}let n=Math.min(6e4,1e3*2**(this.failures-1));this.retryAt=Date.now()+n+Math.floor(Math.random()*n*.2)}trimQueue(){this.queue.length>1e3&&this.queue.splice(0,this.queue.length-1e3)}async send(t){try{let n=await fetch(`${this.baseUrl}/events/bulk`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({events:t}),...this.source==="sdk_web"?{keepalive:!0}:{}});return n.ok?{kind:"sent"}:n.status===429?(this.log("rate limited \xB7 will retry after Retry-After"),{kind:"retry",afterMs:bt(n)}):n.status>=500?(this.log(`bulk failed ${n.status} \xB7 will retry with backoff`),{kind:"retry",afterMs:null}):n.status===401?(this.warnOnce("401","API key inv\xE1lida ou revogada \xB7 eventos descartados. Confira a chave em Configura\xE7\xF5es \u203A SDK."),{kind:"dropped"}):n.status===403?(this.warnOnce("403","Origem n\xE3o permitida ou chave sem escopo events:write \xB7 eventos descartados."),{kind:"dropped"}):(this.log(`bulk rejected ${n.status} \xB7 batch dropped`),{kind:"dropped"})}catch(n){return this.log(`bulk network error: ${n.message} \xB7 will retry with backoff`),{kind:"retry",afterMs:null}}}log(t){this.debug&&console.warn(`[holdy] ${t}`)}warnOnce(t,n){this.warned.has(t)||(this.warned.add(t),console.warn(`[holdy] ${n}`))}environmentContext(){return{}}get pending(){return this.queue.length}};function bt(e){let t=typeof e.headers?.get=="function"?e.headers.get("Retry-After"):null;if(!t)return null;let n=Number(t);return!Number.isFinite(n)||n<0?null:Math.min(6e4,n*1e3)}function xt(){let e=globalThis.crypto;if(typeof e?.randomUUID=="function")return e.randomUUID();let t=()=>Math.random().toString(36).slice(2,12);return`${Date.now().toString(36)}-${t()}-${t()}`}var H="__holdy_autocapture__";function G(e){if(typeof window>"u"||typeof history>"u")return()=>{};let t=window;if(t[H])return()=>{};t[H]=!0;let n=[],r=X(),i=null;function l(m){try{e.onNavigate(m)}catch{}}function c(){i&&clearTimeout(i),i=setTimeout(()=>{i=null;let m=X();m!==r&&(r=m,l("route_change"))},50)}l("initial_load");let p=history.pushState,f=history.replaceState;history.pushState=function(..._){let k=p.apply(this,_);return c(),k},history.replaceState=function(..._){let k=f.apply(this,_);return c(),k},n.push(()=>{history.pushState=p,history.replaceState=f});let b=()=>c();window.addEventListener("popstate",b),n.push(()=>window.removeEventListener("popstate",b));let x=()=>c();return window.addEventListener("hashchange",x),n.push(()=>window.removeEventListener("hashchange",x)),()=>{i&&clearTimeout(i);for(let m of n)m();t[H]=!1}}function X(){return typeof location>"u"?"/":`${location.pathname}${location.search}${location.hash}`}var q="__holdy_friction__",_t='button, a, input, select, textarea, summary, [role="button"], [role="link"], [role="menuitem"], [role="tab"]',Ct=new Set(["button","a","input","select","textarea","summary"]),Et=new Set(["input","select","textarea"]),$=class{constructor(t=3,n=1e3,r=30){this.threshold=t;this.windowMs=n;this.radiusPx=r}clicks=[];push(t,n,r){return this.clicks=this.clicks.filter(i=>r-i.t<=this.windowMs&&Math.hypot(i.x-t,i.y-n)<=this.radiusPx),this.clicks.push({x:t,y:n,t:r}),this.clicks.length>=this.threshold?(this.clicks=[],!0):!1}},K=class{constructor(t=6e4){this.windowMs=t}visits=[];push(t,n){if(this.visits=[...this.visits,{path:t,t:n}].filter(p=>n-p.t<=this.windowMs).slice(-4),this.visits.length<4)return null;let[r,i,l,c]=this.visits.map(p=>p.path);return r===l&&i===c&&r!==i?(this.visits=[],{from:r,to:i}):null}};function J(e){if(!e)return null;let t=e.closest?.(_t)??null;if(t)return t;let n=e.tagName.toLowerCase();if(Ct.has(n))return e;let r=e.getAttribute("role");return r==="button"||r==="link"||r==="menuitem"||r==="tab"?e:null}function kt(e){let t=J(e);if(!t)return!1;if(t.disabled===!0||t.getAttribute("disabled")!==null||t.getAttribute("aria-disabled")==="true")return!0;if(t.tagName.toLowerCase()==="a"){let r=t.getAttribute("href");if(!r||r==="#"||r.startsWith("javascript:"))return!0}return!1}function z(e){let t=J(e)??e;if(!t)return{};let n={element:t.tagName.toLowerCase()};t.id&&(n.element_id=t.id);let r=t.getAttribute("role");r&&(n.element_role=r);let l=(t.getAttribute("aria-label")??t.textContent??"").replace(/\s+/g," ").trim().slice(0,60);l&&(n.element_text=l);let c=t.getAttribute("name")??t.getAttribute("data-testid");return c&&(n.element_name=c),n}function P(e,t){try{let n=new URL(e,t);return`${n.origin}${n.pathname}`}catch{return e.split("?")[0].split("#")[0]}}function At(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function St(e){return typeof e=="object"&&e!==null&&e.name==="AbortError"}function Lt(e,t){return t.some(n=>n.length>0&&e.startsWith(n))}function Y(e){let t=e.toLowerCase().split(".").filter(Boolean);return t.length<=2?t.join("."):t.slice(-2).join(".")}function Mt(e,t,n=[]){let r,i;try{r=new URL(e,t),i=new URL(t)}catch{return!0}if(r.protocol!=="http:"&&r.protocol!=="https:"||r.host===i.host||n.some(c=>c.length>0&&r.origin===c))return!0;let l=Y(r.hostname);return l.length>0&&l===Y(i.hostname)}function Tt(e){return e.aborted?null:!e.opaque&&(e.status===null||e.status>=400)?"http_error":e.durationMs>=e.slowMs?"slow_request":null}function Pt(e){try{let n=e?.getEntriesByType?.("navigation")?.[0]?.responseStatus;return typeof n=="number"&&n>0?n:null}catch{return null}}function Ot(e){return e.id||e.getAttribute("name")||e.getAttribute("data-testid")||P(e.getAttribute("action")??"",location.href).replace(location.origin,"")||"form"}function Rt(){return typeof location>"u"?"/":location.pathname||"/"}function Q(e){let t={onNavigate:()=>{},teardown:()=>{}};if(typeof window>"u"||typeof document>"u")return t;let n=window;if(n[q])return t;n[q]=!0;let r=(o,s)=>{try{e.onFriction({kind:o,properties:{path:Rt(),...s}})}catch{return}},i=[],l=new $(e.rageClicks,e.rageWindowMs,e.rageRadiusPx),c=new K(e.navLoopWindowMs),p=e.slowRequestMs??3e3,f=new Map,b=o=>{let s=o.target instanceof Element?o.target:null;kt(s)&&r("dead_click",z(s)),l.push(o.clientX,o.clientY,o.timeStamp||Date.now())&&r("rage_click",z(s))};document.addEventListener("click",b,!0),i.push(()=>document.removeEventListener("click",b,!0));let x=o=>{r("js_error",{message:String(o.message??"").slice(0,200),...o.filename?{source:P(o.filename,location.href)}:{},...o.lineno?{line:o.lineno}:{}})};window.addEventListener("error",x),i.push(()=>window.removeEventListener("error",x));let m=o=>{r("js_error",{message:At(o.reason).slice(0,200),unhandled_rejection:!0})};window.addEventListener("unhandledrejection",m),i.push(()=>window.removeEventListener("unhandledrejection",m));let _=(e.ignoreUrls??[]).map(o=>P(o,location.href)),k=(e.apiOrigins??[]).map(o=>{try{return new URL(o,location.href).origin}catch{return""}}),A=(o,s,u,a,d={})=>{let h=P(o,location.href);if(Lt(h,_)||!Mt(h,location.href,k))return;let g=performance.now()-u,E=Tt({status:a,durationMs:g,slowMs:p,...d});E&&r(E,{url:h,method:s,duration_ms:Math.round(g),...d.opaque?{}:a!==null?{status:a}:{failed:!0}})},S=window.fetch;if(typeof S=="function"){let o=async(s,u)=>{let a=performance.now(),d=typeof s=="string"?s:s instanceof URL?s.href:s.url,h=(u?.method??(s instanceof Request?s.method:"GET")).toUpperCase();try{let g=await S(s,u);return A(d,h,a,g.status,{opaque:g.type==="opaque"||g.type==="opaqueredirect"}),g}catch(g){throw A(d,h,a,null,{aborted:St(g)}),g}};window.fetch=o,i.push(()=>{window.fetch=S})}let v=typeof XMLHttpRequest=="function"?XMLHttpRequest.prototype:null;if(v){let o=v.open,s=v.send,u=new WeakMap;v.open=function(a,d,...h){return u.set(this,{method:String(a).toUpperCase(),url:String(d)}),o.apply(this,[a,d,...h])},v.send=function(a){let d=u.get(this);if(d){let h=performance.now(),g=!1;this.addEventListener("abort",()=>{g=!0}),this.addEventListener("loadend",()=>{A(d.url,d.method,h,this.status===0?null:this.status,{aborted:g})})}return s.call(this,a)},i.push(()=>{v.open=o,v.send=s})}let C=Pt(typeof performance>"u"?void 0:performance);C!==null&&C>=400&&r("http_error",{document:!0,status:C,url:P(location.href)});let L=o=>{let s=o.target;if(!s||!Et.has(s.tagName.toLowerCase()))return;let u=s.form;if(!u)return;let a=f.get(u)??{form:Ot(u),fields:new Set},d=s.name||s.id||s.tagName.toLowerCase();a.fields.add(d),f.set(u,a)};document.addEventListener("focusin",L,!0),i.push(()=>document.removeEventListener("focusin",L,!0));let M=o=>{o.target instanceof HTMLFormElement&&f.delete(o.target)};document.addEventListener("submit",M,!0),i.push(()=>document.removeEventListener("submit",M,!0));let T=()=>{for(let o of f.values())r("form_abandon",{form:o.form,fields_touched:o.fields.size});f.clear()};return window.addEventListener("pagehide",T),i.push(()=>window.removeEventListener("pagehide",T)),{onNavigate:o=>{T();let s=c.push(o,Date.now());s&&r("nav_loop",{from:s.from,to:s.to})},teardown:()=>{for(let o of i)o();f.clear(),n[q]=!1}}}var It=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],V="holdy_session",Z="holdy_attribution";function tt(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch{return null}}function Ut(e){let t={};try{let n=new URL(e).searchParams;for(let r of It){let i=n.get(r)?.trim();i&&(t[r]=i.toLowerCase().slice(0,120))}}catch{}return t}function Ft(e){if(!e)return{};let t=e.toLowerCase(),n=t.includes("edg/")?"Edge":t.includes("opr/")||t.includes("opera")?"Opera":t.includes("samsungbrowser")?"Samsung Internet":t.includes("firefox")||t.includes("fxios")?"Firefox":t.includes("chrome")||t.includes("crios")?"Chrome":t.includes("safari")?"Safari":void 0,r=t.includes("iphone")||t.includes("ipad")||t.includes("ipod")?"iOS":t.includes("android")?"Android":t.includes("windows")?"Windows":t.includes("mac os")||t.includes("macintosh")?"macOS":t.includes("cros")?"ChromeOS":t.includes("linux")?"Linux":void 0,i=t.includes("ipad")||t.includes("android")&&!t.includes("mobile")?"tablet":t.includes("mobi")||t.includes("iphone")||t.includes("ipod")?"mobile":"desktop";return{...n?{browser:n}:{},...r?{os:r}:{},device:i}}function et(e,t){try{return(e==="session"?sessionStorage:localStorage).getItem(t)}catch{return null}}function nt(e,t,n){try{(e==="session"?sessionStorage:localStorage).setItem(t,n)}catch{}}function Nt(){try{return crypto.randomUUID()}catch{return`hol-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}}function Ht(){let e=et("session",V);if(e)return e;let t=Nt();return nt("session",V,t),t}function qt(e,t,n){let r=et("session",Z);if(r)try{return JSON.parse(r)}catch{}let i={...Ut(e)},l=$t(t);if(l&&l!==n){let c=tt(t);c&&(i.referrer=c),i.referrer_host=l}return nt("session",Z,JSON.stringify(i)),i}function $t(e){try{return new URL(e).hostname.toLowerCase()||null}catch{return null}}function rt(){if(typeof window>"u"||typeof location>"u")return{};let e=location.href,t=typeof document<"u"?document.referrer:"",n=location.hostname.toLowerCase(),r=typeof navigator<"u"?navigator.userAgent:"",{browser:i,os:l,device:c}=Ft(r),p=tt(e);return{...p?{url:p}:{},path:location.pathname||"/",host:n,...i?{browser:i}:{},...l?{os:l}:{},...c?{device:c}:{},...typeof navigator<"u"&&navigator.language?{locale:navigator.language}:{},session_id:Ht(),...qt(e,t,n)}}function Kt(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619)>>>0;return t>>>0}function Dt(e,t){return Kt(`${e}:${t}`)%100}function ot(e,t,n){return Dt(e,t)<n?"holdout":"change"}function it(e,t){let n=e.split(/[?#]/)[0].split("/").filter(Boolean),r=t.split(/[?#]/)[0].split("/").filter(Boolean);return n.length!==r.length?!1:n.every((i,l)=>i.startsWith(":")||i===r[l])}var Wt=300*1e3,Bt=60*1e3,jt=250,st="holdy_changes_seen",at="holdy_changes_dismissed",ut=8,Xt=`:host{all:initial}
|
|
2
|
-
.
|
|
1
|
+
"use strict";var Holdy=(()=>{var se=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var nt=Object.prototype.hasOwnProperty;var rt=(t,e)=>{for(var n in e)se(t,n,{get:e[n],enumerable:!0})},ot=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of tt(e))!nt.call(t,o)&&o!==n&&se(t,o,{get:()=>e[o],enumerable:!(r=et(e,o))||r.enumerable});return t};var it=t=>ot(se({},"__esModule",{value:!0}),t);var Cn={};rt(Cn,{flush:()=>En,getInstance:()=>_n,group:()=>wn,identify:()=>bn,init:()=>yn,page:()=>xn,reset:()=>kn,shutdown:()=>Sn,track:()=>vn});var st="https://holdy.chat/api/v1";var ee=class{apiKey;baseUrl;flushAt;debug;source;release;queue=[];timer=null;flushing=null;retryAt=0;failures=0;warned=new Set;userId=null;anonymousId=null;accountKey=null;constructor(e,n){this.source=e,this.apiKey=n.apiKey,this.accountKey=n.accountKey??null,this.baseUrl=(n.baseUrl??st).replace(/\/$/,""),this.flushAt=Math.max(1,n.flushAt??20),this.debug=n.debug??!1,this.release=typeof n.release=="string"&&n.release.trim()?n.release.trim().slice(0,64):null;let r=n.flushIntervalMs??5e3;r>0&&(this.timer=setInterval(()=>void this.flush(),r),typeof this.timer.unref=="function"&&this.timer.unref())}track(e,n,r){if(!e||typeof e!="string")return;let o=r?.userId??this.userId??void 0,l=r?.accountKey??this.accountKey??void 0,c=r?.occurredAt?new Date(r.occurredAt).toISOString():new Date().toISOString(),f={...this.environmentContext(),...this.release?{release:this.release}:{},...r?.context??{}};l&&(f.account_external_id=l);let m={event:e,occurred_at:c,source:this.source,external_id:lt(),...o?{user_id:o}:{},...this.anonymousId?{anonymous_id:this.anonymousId}:{},properties:n??{},...Object.keys(f).length>0?{context:f}:{}};this.queue.push(m),this.trimQueue(),this.queue.length>=this.flushAt&&this.flush()}identify(e,n){!e||typeof e!="string"||(this.userId=e,this.track("$identify",n??{}))}group(e,n){!e||typeof e!="string"||(this.accountKey=e,this.track("$group",n??{}))}async flush(){return this.startFlush(!1)}async shutdown(){this.timer&&(clearInterval(this.timer),this.timer=null),await this.startFlush(!0)}startFlush(e){return this.flushing?this.flushing:this.queue.length===0||!e&&Date.now()<this.retryAt?Promise.resolve():(this.flushing=this.drain().finally(()=>{this.flushing=null}),this.flushing)}async drain(){for(;this.queue.length>0;){let e=this.queue.splice(0,500),n=await this.send(e);if(n.kind==="retry"){this.queue.unshift(...e),this.trimQueue(),this.scheduleRetry(n.afterMs);return}this.failures=0,this.retryAt=0}}scheduleRetry(e){if(this.failures+=1,e!==null){this.retryAt=Date.now()+e;return}let n=Math.min(6e4,1e3*2**(this.failures-1));this.retryAt=Date.now()+n+Math.floor(Math.random()*n*.2)}trimQueue(){this.queue.length>1e3&&this.queue.splice(0,this.queue.length-1e3)}async send(e){try{let n=await fetch(`${this.baseUrl}/events/bulk`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({events:e}),...this.source==="sdk_web"?{keepalive:!0}:{}});return n.ok?{kind:"sent"}:n.status===429?(this.log("rate limited \xB7 will retry after Retry-After"),{kind:"retry",afterMs:at(n)}):n.status>=500?(this.log(`bulk failed ${n.status} \xB7 will retry with backoff`),{kind:"retry",afterMs:null}):n.status===401?(this.warnOnce("401","API key inv\xE1lida ou revogada \xB7 eventos descartados. Confira a chave em Configura\xE7\xF5es \u203A SDK."),{kind:"dropped"}):n.status===403?(this.warnOnce("403","Origem n\xE3o permitida ou chave sem escopo events:write \xB7 eventos descartados."),{kind:"dropped"}):(this.log(`bulk rejected ${n.status} \xB7 batch dropped`),{kind:"dropped"})}catch(n){return this.log(`bulk network error: ${n.message} \xB7 will retry with backoff`),{kind:"retry",afterMs:null}}}log(e){this.debug&&console.warn(`[holdy] ${e}`)}warnOnce(e,n){this.warned.has(e)||(this.warned.add(e),console.warn(`[holdy] ${n}`))}environmentContext(){return{}}get pending(){return this.queue.length}};function at(t){let e=typeof t.headers?.get=="function"?t.headers.get("Retry-After"):null;if(!e)return null;let n=Number(e);return!Number.isFinite(n)||n<0?null:Math.min(6e4,n*1e3)}function lt(){let t=globalThis.crypto;if(typeof t?.randomUUID=="function")return t.randomUUID();let e=()=>Math.random().toString(36).slice(2,12);return`${Date.now().toString(36)}-${e()}-${e()}`}var ae="__holdy_autocapture__";function xe(t){if(typeof window>"u"||typeof history>"u")return()=>{};let e=window;if(e[ae])return()=>{};e[ae]=!0;let n=[],r=we(),o=null;function l(v){try{t.onNavigate(v)}catch{}}function c(){o&&clearTimeout(o),o=setTimeout(()=>{o=null;let v=we();v!==r&&(r=v,l("route_change"))},50)}l("initial_load");let f=history.pushState,m=history.replaceState;history.pushState=function(...w){let C=f.apply(this,w);return c(),C},history.replaceState=function(...w){let C=m.apply(this,w);return c(),C},n.push(()=>{history.pushState=f,history.replaceState=m});let y=()=>c();window.addEventListener("popstate",y),n.push(()=>window.removeEventListener("popstate",y));let b=()=>c();return window.addEventListener("hashchange",b),n.push(()=>window.removeEventListener("hashchange",b)),()=>{o&&clearTimeout(o);for(let v of n)v();e[ae]=!1}}function we(){return typeof location>"u"?"/":`${location.pathname}${location.search}${location.hash}`}var le="__holdy_friction__",ct='button, a, input, select, textarea, summary, [role="button"], [role="link"], [role="menuitem"], [role="tab"]',ut=new Set(["button","a","input","select","textarea","summary"]),dt=new Set(["input","select","textarea"]),ce=class{constructor(e=3,n=1e3,r=30){this.threshold=e;this.windowMs=n;this.radiusPx=r}clicks=[];push(e,n,r){return this.clicks=this.clicks.filter(o=>r-o.t<=this.windowMs&&Math.hypot(o.x-e,o.y-n)<=this.radiusPx),this.clicks.push({x:e,y:n,t:r}),this.clicks.length>=this.threshold?(this.clicks=[],!0):!1}},ue=class{constructor(e=6e4){this.windowMs=e}visits=[];push(e,n){if(this.visits=[...this.visits,{path:e,t:n}].filter(f=>n-f.t<=this.windowMs).slice(-4),this.visits.length<4)return null;let[r,o,l,c]=this.visits.map(f=>f.path);return r===l&&o===c&&r!==o?(this.visits=[],{from:r,to:o}):null}};function Y(t){return typeof t?.tagName=="string"?t.tagName.toLowerCase():""}function Ce(t){if(!t)return null;let e=t.closest?.(ct)??null;if(e)return e;let n=Y(t);if(ut.has(n))return t;let r=t.getAttribute("role");return r==="button"||r==="link"||r==="menuitem"||r==="tab"?t:null}function ft(t){let e=Ce(t);if(!e)return!1;if(e.disabled===!0||e.getAttribute("disabled")!==null||e.getAttribute("aria-disabled")==="true")return!0;if(Y(e)==="a"){let r=e.getAttribute("href");if(!r||r==="#"||r.startsWith("javascript:"))return!0}return!1}function ke(t){let e=Ce(t)??t;if(!e)return{};let n={element:Y(e)};e.id&&(n.element_id=e.id);let r=e.getAttribute("role");r&&(n.element_role=r);let l=(e.getAttribute("aria-label")??e.textContent??"").replace(/\s+/g," ").trim().slice(0,60);l&&(n.element_text=l);let c=e.getAttribute("name")??e.getAttribute("data-testid");return c&&(n.element_name=c),n}function z(t,e){try{let n=new URL(t,e);return`${n.origin}${n.pathname}`}catch{return t.split("?")[0].split("#")[0]}}function pt(t){if(t instanceof Error)return t.message;if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return String(t)}}var ht=8,gt=200,mt=/^at\s|^\S*@\S+:\d+(?::\d+)?$/;function yt(t){if(typeof t!="string"||!t)return null;let e=t.split(`
|
|
2
|
+
`).map(n=>n.trim()).filter(n=>n.length>0&&mt.test(n)).slice(0,ht).map(n=>n.replace(/(https?:\/\/[^\s)?#]+)[?#][^\s)]*?(?=(?::\d+){0,2}\)?$)/,"$1").slice(0,gt));return e.length>0?e.join(`
|
|
3
|
+
`):null}function Ee(t){return t?{stack:t}:{}}function Se(t){return typeof t=="object"&&t!==null?yt(t.stack):null}function vt(t){return typeof t=="object"&&t!==null&&t.name==="AbortError"}function bt(t,e){return e.some(n=>n.length>0&&t.startsWith(n))}function _e(t){let e=t.toLowerCase().split(".").filter(Boolean);return e.length<=2?e.join("."):e.slice(-2).join(".")}function wt(t,e,n=[]){let r,o;try{r=new URL(t,e),o=new URL(e)}catch{return!0}if(r.protocol!=="http:"&&r.protocol!=="https:"||r.host===o.host||n.some(c=>c.length>0&&r.origin===c))return!0;let l=_e(r.hostname);return l.length>0&&l===_e(o.hostname)}function xt(t){return t.aborted?null:!t.opaque&&(t.status===null||t.status>=400)?"http_error":t.durationMs>=t.slowMs?"slow_request":null}function kt(t){try{let n=t?.getEntriesByType?.("navigation")?.[0]?.responseStatus;return typeof n=="number"&&n>0?n:null}catch{return null}}function Et(t){return t.id||t.getAttribute("name")||t.getAttribute("data-testid")||z(t.getAttribute("action")??"",location.href).replace(location.origin,"")||"form"}function St(){return typeof location>"u"?"/":location.pathname||"/"}function Ae(t){let e={onNavigate:()=>{},teardown:()=>{}};if(typeof window>"u"||typeof document>"u")return e;let n=window;if(n[le])return e;n[le]=!0;let r=(u,h)=>{try{t.onFriction({kind:u,properties:{path:St(),...h}})}catch{return}},o=[],l=new ce(t.rageClicks,t.rageWindowMs,t.rageRadiusPx),c=new ue(t.navLoopWindowMs),f=t.slowRequestMs??3e3,m=new Map,y=u=>{let h=u.target instanceof Element?u.target:null;ft(h)&&r("dead_click",ke(h)),l.push(u.clientX,u.clientY,u.timeStamp||Date.now())&&r("rage_click",ke(h))};document.addEventListener("click",y,!0),o.push(()=>document.removeEventListener("click",y,!0));let b=u=>{r("js_error",{message:String(u.message??"").slice(0,200),...u.filename?{source:z(u.filename,location.href)}:{},...u.lineno?{line:u.lineno}:{},...u.colno?{column:u.colno}:{},...Ee(Se(u.error))})};window.addEventListener("error",b),o.push(()=>window.removeEventListener("error",b));let v=u=>{r("js_error",{message:pt(u.reason).slice(0,200),unhandled_rejection:!0,...Ee(Se(u.reason))})};window.addEventListener("unhandledrejection",v),o.push(()=>window.removeEventListener("unhandledrejection",v));let w=(t.ignoreUrls??[]).map(u=>z(u,location.href)),C=(t.apiOrigins??[]).map(u=>{try{return new URL(u,location.href).origin}catch{return""}}),P=(u,h,_,x,k={})=>{let M=z(u,location.href);if(bt(M,w)||!wt(M,location.href,C))return;let E=performance.now()-_,W=xt({status:x,durationMs:E,slowMs:f,...k});W&&r(W,{url:M,method:h,duration_ms:Math.round(E),...k.opaque?{}:x!==null?{status:x}:{failed:!0}})},K=window.fetch;if(typeof K=="function"){let u=async(h,_)=>{let x=performance.now(),k=typeof h=="string"?h:h instanceof URL?h.href:h.url,M=(_?.method??(h instanceof Request?h.method:"GET")).toUpperCase();try{let E=await K(h,_);return P(k,M,x,E.status,{opaque:E.type==="opaque"||E.type==="opaqueredirect"}),E}catch(E){throw P(k,M,x,null,{aborted:vt(E)}),E}};window.fetch=u,o.push(()=>{window.fetch=K})}let I=typeof XMLHttpRequest=="function"?XMLHttpRequest.prototype:null;if(I){let u=I.open,h=I.send,_=new WeakMap;I.open=function(x,k,...M){return _.set(this,{method:String(x).toUpperCase(),url:String(k)}),u.apply(this,[x,k,...M])},I.send=function(x){let k=_.get(this);if(k){let M=performance.now(),E=!1;this.addEventListener("abort",()=>{E=!0}),this.addEventListener("loadend",()=>{P(k.url,k.method,M,this.status===0?null:this.status,{aborted:E})})}return h.call(this,x)},o.push(()=>{I.open=u,I.send=h})}let D=kt(typeof performance>"u"?void 0:performance);D!==null&&D>=400&&r("http_error",{document:!0,status:D,url:z(location.href)});let j=u=>{let h=u.target;if(!h||!dt.has(Y(h)))return;let _=h.form;if(!_)return;let x=m.get(_)??{form:Et(_),fields:new Set},k=h.name||h.id||Y(h);x.fields.add(k),m.set(_,x)};document.addEventListener("focusin",j,!0),o.push(()=>document.removeEventListener("focusin",j,!0));let V=u=>{u.target instanceof HTMLFormElement&&m.delete(u.target)};document.addEventListener("submit",V,!0),o.push(()=>document.removeEventListener("submit",V,!0));let X=()=>{for(let u of m.values())r("form_abandon",{form:u.form,fields_touched:u.fields.size});m.clear()};return window.addEventListener("pagehide",X),o.push(()=>window.removeEventListener("pagehide",X)),{onNavigate:u=>{X();let h=c.push(u,Date.now());h&&r("nav_loop",{from:h.from,to:h.to})},teardown:()=>{for(let u of o)u();m.clear(),n[le]=!1}}}var _t='button[type="submit"],[data-testid*="primary"],.btn-primary,button,[role="button"],a.button';var Pe=["font","size","fg","bg","accent","accentFg","radius"],Ct=/^(rgba?\([\d.,\s%/]{1,40}\)|#[0-9a-fA-F]{3,8}|(?:color|oklch|oklab|hsla?|lab|lch)\([^()]{1,60}\))$/;var Te=/^rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/;function At(t,e){let n=Te.exec(t),r=e?Te.exec(e):null;return!n||!r?61:Math.abs(+n[1]-+r[1])+Math.abs(+n[2]-+r[2])+Math.abs(+n[3]-+r[3])}var Tt=/^(transparent|rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*0\s*\)|rgba?\(\s*\d+\s+\d+\s+\d+\s*\/\s*0\s*\))$/;function Me(t){return`--holdy-${t.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}`}function G(t){let e=(t??"").trim();return e&&e.length<=80&&!Tt.test(e)&&Ct.test(e)?e:void 0}function Lt(t){let e=(t??"").split(",")[0].trim().replace(/^["']|["']$/g,"").trim();return/^[\w\s-]{1,60}$/.test(e)?e:void 0}function Le(t,e,n){let r=/^(\d+(?:\.\d+)?)px/.exec((t??"").trim()),o=r?Math.round(Number(r[1])):NaN;return o>=e&&o<=n?`${o}px`:void 0}function Pt(t){let e=t.getBoundingClientRect?.();return!e||e.width>0&&e.height>0}function te(t,e,n=null){let r=t.body;if(!r)return null;let o=e(r),l={},c=(v,w)=>{w&&(l[v]=w)};c("font",Lt(o.getPropertyValue("font-family"))),c("size",Le(o.getPropertyValue("font-size"),10,20)),c("fg",G(o.getPropertyValue("color"))),c("bg",G(o.getPropertyValue("background-color"))??G(e(t.documentElement).getPropertyValue("background-color")));let f=t.querySelectorAll(_t),m=null,y=60;for(let v=0;v<f.length&&v<40;v++){let w=f[v];if(!Pt(w))continue;let C=e(w),P=G(C.getPropertyValue("background-color"));if(!P||P===l.bg)continue;let K=At(P,l.bg);K<=y||(y=K,c("accent",P),c("accentFg",G(C.getPropertyValue("color"))),m=w)}let b=n&&n.tagName.toLowerCase()==="button"?n:m;return b&&c("radius",Le(e(b).getPropertyValue("border-top-left-radius"),0,24)),Object.keys(l).length>0?l:null}function Mt(t){let e=[];for(let n of Pe){let r=t?.[n];r&&e.push([Me(n),r])}return e}function Re(t,e){for(let n of Pe)t.style.removeProperty(Me(n));for(let[n,r]of Mt(e))t.style.setProperty(n,r)}var Rt='a[href], button, input, select, textarea, [role="button"], [role="link"], [role="tab"], [role="menuitem"], [role="checkbox"], [role="radio"], [role="switch"], [data-testid]',Nt=80,Ot=1500,Ne="holdy_skeletons",It=200;function Ut(t){let e=2166136261;for(let n=0;n<t.length;n++)e^=t.charCodeAt(n),e=Math.imul(e,16777619)>>>0;return e.toString(16).padStart(8,"0")}function J(t,e,n){let r=t.getAttribute(e);return r&&r.replace(/\s+/g," ").trim().slice(0,n)||void 0}function Ft(t){if(!t.getBoundingClientRect)return!0;let e=t.getBoundingClientRect();return e.width>0&&e.height>0}function $t(t,e){let n=(r,o)=>o>0?Math.max(0,Math.min(100,Math.round(r/o*100))):0;return[n(t.x,e.width),n(t.y+e.scrollY,e.height),n(t.width,e.width),n(t.height,e.height)]}function Ht(t,e){let n={t:t.tagName.toLowerCase()},r=J(t,"role",40);r&&(n.r=r);let o=J(t,"data-testid",80);o&&(n.id=o);let l=J(t,"name",80);l&&(n.n=l);let c=J(t,"aria-label",80);if(c&&(n.l=c),n.t==="input"||n.t==="button"){let f=J(t,"type",20);f&&(n.k=f.toLowerCase())}return e&&t.getBoundingClientRect&&(n.b=$t(t.getBoundingClientRect(),e)),n}function Kt(t,e,n,r=null){let o=t.querySelectorAll(Rt),l=[];for(let m=0;m<o.length;m++){let y=o[m];y.tagName.toLowerCase()==="input"&&(y.getAttribute("type")??"").toLowerCase()==="hidden"||Ft(y)&&l.push(y)}let c=l.slice(0,Nt).map(m=>Ht(m,n)),f=c.map(({b:m,...y})=>y);return{path:e,hash:Ut(JSON.stringify(f)),count:l.length,elements:c,...r?{theme:r}:{}}}function qt(){try{let t=sessionStorage.getItem(Ne),e=t?JSON.parse(t):[];return new Set(Array.isArray(e)?e.filter(n=>typeof n=="string"):[])}catch{return new Set}}function Dt(t){try{sessionStorage.setItem(Ne,JSON.stringify([...t].slice(-It)))}catch{return}}function Oe(t){if(typeof window>"u"||typeof document>"u")return{onNavigate:()=>{},teardown:()=>{}};let e=t.delayMs??Ot,n=qt(),r=null,o=l=>{if(r=null,location.pathname===l)try{let c={width:window.innerWidth,height:Math.max(document.documentElement.scrollHeight,window.innerHeight),scrollY:window.scrollY},f=te(document,b=>window.getComputedStyle(b)),m=Kt(document,l,c,f),y=`${l}:${m.hash}`;if(n.has(y))return;n.add(y),Dt(n),t.onSkeleton(m)}catch{return}};return{onNavigate:l=>{r&&clearTimeout(r),r=setTimeout(()=>o(l),e)},teardown:()=>{r&&clearTimeout(r),r=null}}}var Wt=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],de="holdy_session",Ie="holdy_attribution";function Ue(t){try{let e=new URL(t);return`${e.origin}${e.pathname}`}catch{return null}}function Bt(t){let e={};try{let n=new URL(t).searchParams;for(let r of Wt){let o=n.get(r)?.trim();o&&(e[r]=o.toLowerCase().slice(0,120))}}catch{}return e}function Vt(t){if(!t)return{};let e=t.toLowerCase(),n=e.includes("edg/")?"Edge":e.includes("opr/")||e.includes("opera")?"Opera":e.includes("samsungbrowser")?"Samsung Internet":e.includes("firefox")||e.includes("fxios")?"Firefox":e.includes("chrome")||e.includes("crios")?"Chrome":e.includes("safari")?"Safari":void 0,r=e.includes("iphone")||e.includes("ipad")||e.includes("ipod")?"iOS":e.includes("android")?"Android":e.includes("windows")?"Windows":e.includes("mac os")||e.includes("macintosh")?"macOS":e.includes("cros")?"ChromeOS":e.includes("linux")?"Linux":void 0,o=e.includes("ipad")||e.includes("android")&&!e.includes("mobile")?"tablet":e.includes("mobi")||e.includes("iphone")||e.includes("ipod")?"mobile":"desktop";return{...n?{browser:n}:{},...r?{os:r}:{},device:o}}function Fe(t,e){try{return(t==="session"?sessionStorage:localStorage).getItem(e)}catch{return null}}function $e(t,e,n){try{(t==="session"?sessionStorage:localStorage).setItem(e,n)}catch{}}function Xt(){try{return crypto.randomUUID()}catch{return`hol-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}}function He(){try{sessionStorage.removeItem(de)}catch{}}function jt(){let t=Fe("session",de);if(t)return t;let e=Xt();return $e("session",de,e),e}function zt(t,e,n){let r=Fe("session",Ie);if(r)try{return JSON.parse(r)}catch{}let o={...Bt(t)},l=Yt(e);if(l&&l!==n){let c=Ue(e);c&&(o.referrer=c),o.referrer_host=l}return $e("session",Ie,JSON.stringify(o)),o}function Yt(t){try{return new URL(t).hostname.toLowerCase()||null}catch{return null}}function Ke(){if(typeof window>"u"||typeof location>"u")return{};let t=location.href,e=typeof document<"u"?document.referrer:"",n=location.hostname.toLowerCase(),r=typeof navigator<"u"?navigator.userAgent:"",{browser:o,os:l,device:c}=Vt(r),f=Ue(t);return{...f?{url:f}:{},path:location.pathname||"/",host:n,...o?{browser:o}:{},...l?{os:l}:{},...c?{device:c}:{},...typeof navigator<"u"&&navigator.language?{locale:navigator.language}:{},session_id:jt(),...zt(t,e,n)}}var qe=`:host{all:initial;--h-bg:#111;--h-fg:#fff;--h-accent:#fff;--h-accent-fg:#111;--h-border:transparent}
|
|
4
|
+
@media (prefers-color-scheme:dark){:host{--h-bg:#fff;--h-fg:#111;--h-accent:#111;--h-accent-fg:#fff}}
|
|
5
|
+
.tip{position:fixed;box-sizing:border-box;max-width:280px;padding:10px 12px;border-radius:var(--holdy-radius,8px);background:var(--holdy-bg,var(--h-bg));color:var(--holdy-fg,var(--h-fg));border:1px solid color-mix(in srgb,var(--holdy-fg,var(--h-fg)) 14%,transparent);font:var(--holdy-size,13px)/1.45 var(--holdy-font,system-ui),system-ui,-apple-system,sans-serif;box-shadow:0 8px 24px rgba(0,0,0,.18);pointer-events:auto;display:flex;gap:10px;align-items:flex-start}
|
|
3
6
|
.tip p{margin:0;flex:1}
|
|
4
|
-
.tip button{all:unset;cursor:pointer;opacity:.7;font-size:15px;line-height:1}
|
|
7
|
+
.tip button{all:unset;cursor:pointer;opacity:.7;font-size:15px;line-height:1;color:inherit}
|
|
5
8
|
.tip button:hover,.tip button:focus-visible{opacity:1}
|
|
6
|
-
|
|
9
|
+
.ask{flex-direction:column;width:300px;max-width:calc(100vw - 16px);gap:8px}
|
|
10
|
+
.ask .head{display:flex;gap:10px;align-items:flex-start;width:100%}
|
|
11
|
+
.ask textarea{all:unset;box-sizing:border-box;width:100%;min-height:56px;padding:8px;border-radius:calc(var(--holdy-radius,8px) * .75);background:color-mix(in srgb,var(--holdy-fg,var(--h-fg)) 8%,transparent);color:inherit;font:inherit;white-space:pre-wrap;overflow-wrap:anywhere;cursor:text}
|
|
12
|
+
.ask textarea:focus-visible{outline:2px solid color-mix(in srgb,var(--holdy-fg,var(--h-fg)) 45%,transparent)}
|
|
13
|
+
.ask .send{align-self:flex-end;padding:5px 12px;border-radius:calc(var(--holdy-radius,8px) * .75);background:var(--holdy-accent,var(--h-accent));color:var(--holdy-accent-fg,var(--h-accent-fg));font-size:12.5px;font-weight:500;opacity:1}
|
|
14
|
+
.ask .send[disabled]{opacity:.4;cursor:default}
|
|
15
|
+
.list{flex-direction:column;width:300px;max-width:calc(100vw - 16px);gap:8px}
|
|
16
|
+
.list .head{display:flex;gap:10px;align-items:flex-start;width:100%}
|
|
17
|
+
.list .head p{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
|
|
18
|
+
.list .count{opacity:.7;font-size:12px;white-space:nowrap}
|
|
19
|
+
.list ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;width:100%}
|
|
20
|
+
.list li{display:flex;gap:8px;align-items:flex-start}
|
|
21
|
+
.list li.done{opacity:.55;text-decoration:line-through}
|
|
22
|
+
.list .mark{flex:none;width:16px;height:16px;border-radius:4px;border:1px solid color-mix(in srgb,var(--holdy-fg,var(--h-fg)) 45%,transparent);font-size:11px;line-height:16px;text-align:center}
|
|
23
|
+
.list li.done .mark{background:var(--holdy-accent,var(--h-accent));color:var(--holdy-accent-fg,var(--h-accent-fg));border-color:var(--holdy-accent,var(--h-accent))}
|
|
24
|
+
.list.folded ul{display:none}
|
|
25
|
+
.list.folded{width:auto}
|
|
26
|
+
.preview{flex:none;order:-1;width:100%;font-size:11px;opacity:.7}
|
|
27
|
+
.tip:has(.preview){flex-wrap:wrap;row-gap:4px}`;function Gt(t){let e=2166136261;for(let n=0;n<t.length;n++)e^=t.charCodeAt(n),e=Math.imul(e,16777619)>>>0;return e>>>0}function Jt(t,e){return Gt(`${t}:${e}`)%100}function De(t,e,n){return Jt(t,e)<n?"holdout":"change"}function We(t,e){let n=t.split(/[?#]/)[0].split("/").filter(Boolean),r=e.split(/[?#]/)[0].split("/").filter(Boolean);return n.length!==r.length?!1:n.every((o,l)=>o.startsWith(":")||o===r[l])}var Qt=300*1e3,Zt=60*1e3,en=250,Be="holdy_changes_seen",Ve="holdy_changes_dismissed",Xe=8,je="holdy_questions_answered",fe="holdy_checklist_folded",ze="holdy_checklist_completed",tn=60*1e3,nn="$voice",Ye=1e3,rn=1600,on="holdy_preview",pe="holdy_preview",he=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function H(t){return t.replace(/\s+/g," ").trim()}function sn(t){let e=t?.changes;return Array.isArray(e)?e.filter(cn):[]}function an(t){let e=t;return e?.kind==="page"?!0:(e?.kind==="selector"||e?.kind==="text")&&typeof e.value=="string"&&e.value.length>0}function ln(t){let e=t;return typeof e?.definition_name=="string"&&typeof e.label=="string"&&Array.isArray(e.events)&&e.events.every(n=>typeof n=="string")}function cn(t){let e=t;return typeof e?.id=="string"&&(e.kind==="copy"||e.kind==="guidance"||e.kind==="question"&&typeof e.plan_id=="string"||e.kind==="checklist"&&Array.isArray(e.content?.items)&&e.content.items.length>0&&e.content.items.every(ln))&&typeof e.path=="string"&&an(e.anchor)&&typeof e.content?.text=="string"&&typeof e.holdout_pct=="number"}function un(t,e,n,r=null){return t.filter(o=>o.kind==="checklist"||We(o.path,e)).flatMap(o=>o.id===r?[{change:o,arm:"change",preview:!0}]:n?[{change:o,arm:De(o.id,n,o.holdout_pct),preview:!1}]:[])}function Ge(t,e){let n=null;try{n=new URLSearchParams(t).get(on)}catch{n=null}try{if(n!==null)return he.test(n)?(e?.setItem(pe,n),n):(e?.removeItem(pe),null);let r=e?.getItem(pe)??null;return r&&he.test(r)?r:null}catch{return n!==null&&he.test(n)?n:null}}function O(t){try{return t==="local"?window.localStorage:window.sessionStorage}catch{return}}function B(t,e){try{return new Set(JSON.parse(t?.getItem(e)??"[]"))}catch{return new Set}}function ne(t,e,n){try{let r=B(t,e);r.add(n),t?.setItem(e,JSON.stringify([...r].slice(-200)))}catch{return}}function dn(t){try{return document.querySelector(t)}catch{return null}}var fn='button,a,[role="button"],label,summary,h1,h2,h3,h4,li,td,th,p,span,strong',pn=3e3;function hn(t){let e=H(t),n=null,r=Number.POSITIVE_INFINITY,o=document.querySelectorAll(fn),l=Math.min(o.length,pn);for(let c=0;c<l;c+=1){let f=o[c],m=f.textContent??"";m.length>=r||H(m)!==e||(n=f,r=m.length)}return n}function gn(t){return t.kind==="page"?null:t.kind==="selector"?dn(t.value):hn(t.value)}function mn(t,e){let n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(let r=n.nextNode();r;r=n.nextNode())if(e(H(r.textContent??"")))return r;return null}function Je(t){if(typeof window>"u"||typeof document>"u")return{onNavigate:()=>{},onEvent:()=>{},refresh:async()=>{},teardown:()=>{}};let e=[],n=0,r=null,o=null,l=null,c=new Map,f=new Map,m=new Map,y=new Map,b=new Map,v=null,w=Ge(location.search,O("session")),C=i=>{t.debug&&console.warn(`[holdy] ${i}`)},P=(i,s)=>{let a=`${i.id}:${s}`,d=O("session");B(d,Be).has(a)||(ne(d,Be,a),t.track("$change_exposure",{change_id:i.id,arm:s,kind:i.kind}))},K=(i,s)=>{let a=s.expected_text?H(s.expected_text):null,d=H(s.content.text);return mn(i,g=>g.length>0&&(g===d||a===null||g===a))},I=(i,s)=>{let a=H(s.content.text),d=c.get(s.id);if(d&&d.node.isConnected&&H(d.node.textContent??"")===a)return!0;let g=K(i,s);if(!g)return!1;let p=g.textContent??"";return H(p)!==a&&(c.set(s.id,{node:g,original:p,next:s.content.text}),g.textContent=p.replace(p.trim(),s.content.text)),!0},D=i=>{let s=c.get(i);s&&(s.node.isConnected&&H(s.node.textContent??"")===H(s.next)&&(s.node.textContent=s.original),c.delete(i))},j=()=>{if(o)return o;if(!document.body)return null;l=document.createElement("holdy-changes"),l.setAttribute("data-holdy-root","1"),l.style.cssText="position:fixed;top:0;left:0;width:0;height:0;z-index:2147483647;pointer-events:none",o=l.attachShadow({mode:"closed"});let i=document.createElement("style");return i.textContent=qe,o.appendChild(i),document.body.appendChild(l),o},V=!1,X=()=>{let i=document.createElement("span");return i.className="preview",i.textContent="Pr\xE9via, s\xF3 voc\xEA v\xEA",i},u=(i,s,a)=>{if(f.has(s.id)||!a&&B(O("local"),Ve).has(s.id))return!0;let d=s.kind==="question";if(!a&&d&&B(O("local"),je).has(s.id))return!0;let g=j();if(!g)return!1;l&&Re(l,te(document,T=>window.getComputedStyle(T),i));let p=document.createElement("div");p.className=d?"tip ask":"tip",p.setAttribute("role",d?"dialog":"tooltip");let U=document.createElement("p");U.textContent=s.content.text;let A=document.createElement("button");if(A.type="button",A.setAttribute("aria-label","Fechar"),A.textContent="\xD7",d){let T=document.createElement("div");T.className="head",T.append(U,A);let L=document.createElement("textarea");L.maxLength=Ye,L.setAttribute("aria-label",s.content.text);let S=document.createElement("button");S.type="button",S.className="send",S.textContent="Enviar",S.disabled=!0,L.addEventListener("input",()=>{S.disabled=L.value.trim().length===0}),S.addEventListener("click",()=>{let F=L.value.trim().slice(0,Ye);F&&(a||(ne(O("local"),je,s.id),t.track(nn,{question:s.content.text,text:F,action_plan_id:s.plan_id,change_id:s.id,path:location.pathname})),p.replaceChildren(Object.assign(document.createElement("p"),{textContent:"Obrigado pela resposta."})),setTimeout(q,rn))}),p.append(T,L,S)}else p.append(U,A);a&&p.prepend(X()),p.style.top="-9999px",p.style.left="-9999px",g.appendChild(p);let q=()=>{p.remove(),window.removeEventListener("scroll",N,!0),window.removeEventListener("resize",N),f.delete(s.id)};function N(){if(!i){let $=p.getBoundingClientRect();p.style.top=`${Math.max(8,window.innerHeight-$.height-16)}px`,p.style.left=`${Math.max(8,window.innerWidth-$.width-16)}px`;return}if(!i.isConnected){q();return}let T=i.getBoundingClientRect(),L=p.getBoundingClientRect(),S=T.bottom+Xe;S+L.height>window.innerHeight-8&&(S=T.top-L.height-Xe);let F=Math.min(Math.max(8,T.left+T.width/2-L.width/2),window.innerWidth-L.width-8);p.style.top=`${Math.max(8,S)}px`,p.style.left=`${Math.max(8,F)}px`}return A.addEventListener("click",()=>{if(a){V=!0,q();return}ne(O("local"),Ve,s.id),t.track("$change_dismissed",{change_id:s.id,kind:s.kind}),q()}),f.set(s.id,q),requestAnimationFrame(N),window.addEventListener("scroll",N,!0),window.addEventListener("resize",N),!0},h=i=>m.get(i.id)??new Set,_=i=>{let s=h(i);return(i.content.items??[]).every(a=>s.has(a.definition_name))},x=async i=>{let s=t.getAccountKey();if(!s)return;let a=y.get(i.id)??0;if(!(Date.now()-a<tn)){y.set(i.id,Date.now());try{let d=await fetch(`${t.baseUrl}/runtime/checklist?change_id=${encodeURIComponent(i.id)}&account=${encodeURIComponent(s)}`,{headers:{Authorization:`Bearer ${t.apiKey}`}});if(!d.ok)return;let g=await d.json(),p=Array.isArray(g.done)?g.done.filter(A=>typeof A=="string"):[],U=h(i);for(let A of p)U.add(A);m.set(i.id,U),b.get(i.id)?.()}catch(d){C(`checklist progress error: ${d.message}`)}}},k=(i,s)=>{if(b.has(i.id)||!s&&B(O("local"),ze).has(i.id))return!0;let a=j();if(!a)return!1;let d=i.content.items??[],g=document.createElement("div");g.className="tip list",g.setAttribute("role","region"),g.setAttribute("aria-label",i.content.text);let p=document.createElement("div");p.className="head";let U=document.createElement("p"),A=document.createElement("strong");A.textContent=i.content.text;let q=document.createElement("span");q.className="count",U.append(A,q);let N=document.createElement("button");N.type="button",p.append(U,N);let T=document.createElement("ul");g.append(p,T),s&&g.prepend(X()),g.style.position="fixed",g.style.right="16px",g.style.bottom="16px",a.appendChild(g);let L=()=>{g.remove(),b.delete(i.id)},S=()=>{let F=h(i),$=d.filter(Q=>F.has(Q.definition_name)).length;q.textContent=`${$} de ${d.length}`;let oe=B(O("local"),fe).has(i.id);g.classList.toggle("folded",oe),N.textContent=oe?"+":"\u2013",N.setAttribute("aria-label",oe?"Abrir":"Recolher"),T.replaceChildren(...d.map(Q=>{let ie=document.createElement("li"),ve=F.has(Q.definition_name);ve&&(ie.className="done");let Z=document.createElement("span");Z.className="mark",Z.setAttribute("aria-hidden","true"),Z.textContent=ve?"\u2713":"";let be=document.createElement("span");return be.textContent=Q.label,ie.append(Z,be),ie})),!s&&$===d.length&&d.length>0&&(ne(O("local"),ze,i.id),t.track("$checklist_completed",{change_id:i.id}),L())};return N.addEventListener("click",()=>{let F=O("local"),$=B(F,fe);$.has(i.id)?$.delete(i.id):$.add(i.id);try{F?.setItem(fe,JSON.stringify([...$].slice(-200)))}catch{}S()}),b.set(i.id,S),S(),x(i),!0},M=()=>{r=null;let i=un(e,location.pathname,t.getAccountKey(),w),s=new Set(i.map(a=>a.change.id));for(let a of[...c.keys()])s.has(a)||D(a);for(let[a,d]of[...f])s.has(a)||d();for(let[a,d]of[...b])s.has(a)||(b.delete(a),d());for(let{change:a,arm:d,preview:g}of i){let p=gn(a.anchor);if(!p&&a.anchor.kind!=="page"){g&&C(`preview: \xE2ncora n\xE3o encontrada em ${location.pathname}`);continue}if(g){a.kind==="checklist"?k(a,!0):a.kind==="copy"?p&&I(p,a):V||u(p,a,!0);continue}if(a.kind==="checklist")(d==="holdout"||_(a)||k(a,!1))&&P(a,d),d==="change"&&x(a);else if(a.kind==="copy"){if(!p)continue;(d==="change"?I(p,a):K(p,a)!==null)&&P(a,d)}else(d==="holdout"||u(p,a,!1))&&P(a,d)}},E=()=>{r===null&&(r=setTimeout(M,en))},W=async()=>{n=Date.now();let i=t.getAccountKey();v=i;let s=new URLSearchParams;i&&s.set("account",i),w&&s.set("preview",w);let a=s.toString();try{let d=await fetch(`${t.baseUrl}/runtime/changes${a?`?${a}`:""}`,{headers:{Authorization:`Bearer ${t.apiKey}`}});if(!d.ok){C(`changes ${d.status}`);return}e=sn(await d.json()),E()}catch(d){C(`changes network error: ${d.message}`)}},me=typeof MutationObserver<"u"?new MutationObserver(()=>{(e.length>0||c.size>0||f.size>0)&&E()}):null,ye=()=>{document.body&&me?.observe(document.body,{childList:!0,subtree:!0,characterData:!0})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",ye,{once:!0}):ye();let Ze=setInterval(()=>void W(),Qt);return W(),{onNavigate:()=>{let i=Ge(location.search,O("session")),s=i!==w;if(s){w=i,V=!1;for(let a of[...c.keys()])D(a);for(let a of[...f.values()])a()}(s||Date.now()-n>Zt||t.getAccountKey()!==v)&&W(),E()},onEvent:i=>{for(let s of e){if(s.kind!=="checklist")continue;let a=(s.content.items??[]).filter(g=>g.events.includes(i));if(a.length===0)continue;let d=h(s);for(let g of a)d.add(g.definition_name);m.set(s.id,d),b.get(s.id)?.()}},refresh:W,teardown:()=>{clearInterval(Ze),r!==null&&clearTimeout(r),me?.disconnect();for(let i of[...c.keys()])D(i);for(let i of[...f.values()])i();for(let i of[...b.keys()])b.delete(i);l?.remove(),l=null,o=null,e=[]}}}var ge="holdy_anon_id",re=class extends ee{teardownAutoCapture=null;friction=null;changes=null;skeleton=null;constructor(e){if(super("sdk_web",e),this.anonymousId=Qe(),typeof window<"u"&&(window.addEventListener("pagehide",()=>void this.flush()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush()})),e.friction!==!1){let n=typeof e.friction=="object"?e.friction:{};this.friction=Ae({...n,ignoreUrls:[...n.ignoreUrls??[],this.baseUrl],onFriction:r=>this.track(`$${r.kind}`,r.properties)})}e.skeleton!==!1&&(this.skeleton=Oe({onSkeleton:n=>this.track("$page_skeleton",{...n})})),e.autoCapture!==!1&&(this.teardownAutoCapture=xe({onNavigate:n=>{this.page(void 0,{navigation:n});let r=typeof location<"u"?location.pathname:"/";this.friction?.onNavigate(r),this.changes?.onNavigate(),this.skeleton?.onNavigate(r)}})),e.productChanges!==!1&&typeof window<"u"&&(this.changes=Je({baseUrl:this.baseUrl,apiKey:this.apiKey,getAccountKey:()=>this.accountKey,track:(n,r)=>this.track(n,r),debug:e.debug}))}page(e,n){this.track("$pageview",{...n??{},...e?{page_name:e}:{},...typeof document<"u"&&document.title?{title:document.title}:{}})}group(e,n){super.group(e,n),this.changes?.onNavigate()}track(e,n,r){super.track(e,n,r),e.startsWith("$")||this.changes?.onEvent(e)}reset(){this.userId=null,this.accountKey=null;try{localStorage.removeItem(ge)}catch{}He(),this.anonymousId=Qe(),this.changes?.onNavigate()}async shutdown(){this.teardownAutoCapture?.(),this.teardownAutoCapture=null,this.friction?.teardown(),this.friction=null,this.changes?.teardown(),this.changes=null,this.skeleton?.teardown(),this.skeleton=null,await super.shutdown()}environmentContext(){return Ke()}};function Qe(){try{let t=localStorage.getItem(ge);if(t)return t;let e=crypto.randomUUID();return localStorage.setItem(ge,e),e}catch{return crypto.randomUUID()}}var R=null;function yn(t){return R||(R=new re(t)),R}function vn(t,e){R?.track(t,e)}function bn(t,e){R?.identify(t,e)}function wn(t,e){R?.group(t,e)}function xn(t,e){R?.page(t,e)}function kn(){R?.reset()}async function En(){await R?.flush()}async function Sn(){await R?.shutdown(),R=null}function _n(){return R}return it(Cn);})();
|
|
7
28
|
//# sourceMappingURL=holdy.js.map
|