@screeb/rrweb 1.0.15 → 1.0.17

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.
@@ -1,2 +1,2 @@
1
- .replayer-wrapper{position:relative}.replayer-mouse{position:absolute;width:20px;height:20px;transition:left .05s linear,top .05s linear;background-size:contain;background-position:center center;background-repeat:no-repeat;background-image:url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjMDAwMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iTGF5ZXIgMSIgdmlld0JveD0iMCAwIDUwIDUwIiB4PSIwcHgiIHk9IjBweCI+PHRpdGxlPkRlc2lnbl90bnA8L3RpdGxlPjxwYXRoIGQ9Ik00OC43MSw0Mi45MUwzNC4wOCwyOC4yOSw0NC4zMywxOEExLDEsMCwwLDAsNDQsMTYuMzlMMi4zNSwxLjA2QTEsMSwwLDAsMCwxLjA2LDIuMzVMMTYuMzksNDRhMSwxLDAsMCwwLDEuNjUuMzZMMjguMjksMzQuMDgsNDIuOTEsNDguNzFhMSwxLDAsMCwwLDEuNDEsMGw0LjM4LTQuMzhBMSwxLDAsMCwwLDQ4LjcxLDQyLjkxWm0tNS4wOSwzLjY3TDI5LDMyYTEsMSwwLDAsMC0xLjQxLDBsLTkuODUsOS44NUwzLjY5LDMuNjlsMzguMTIsMTRMMzIsMjcuNThBMSwxLDAsMCwwLDMyLDI5TDQ2LjU5LDQzLjYyWiI+PC9wYXRoPjwvc3ZnPg==);border-color:transparent}.replayer-mouse:after{content:"";display:inline-block;width:20px;height:20px;background:#4950f6;border-radius:100%;transform:translate(-50%,-50%);opacity:.3}.replayer-mouse.active:after{animation:click .2s ease-in-out 1}.replayer-mouse.touch-device{background-image:none;width:70px;height:70px;border-width:4px;border-style:solid;border-radius:100%;margin-left:-37px;margin-top:-37px;border-color:#4950f600;transition:left 0s linear,top 0s linear,border-color .2s ease-in-out}.replayer-mouse.touch-device.touch-active{border-color:#4950f6;transition:left .25s linear,top .25s linear,border-color .2s ease-in-out}.replayer-mouse.touch-device:after{opacity:0}.replayer-mouse.touch-device.active:after{animation:touch-click .2s ease-in-out 1}.replayer-mouse-tail{position:absolute;pointer-events:none}@keyframes click{0%{opacity:.3;width:20px;height:20px}50%{opacity:.5;width:10px;height:10px}}@keyframes touch-click{0%{opacity:0;width:20px;height:20px}50%{opacity:.5;width:10px;height:10px}}
1
+ .replayer-wrapper{position:relative}.replayer-mouse{position:absolute;width:20px;height:20px;transition:left .05s linear,top .05s linear;background-size:contain;background-position:center center;background-repeat:no-repeat;background-image:url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjMDAwMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iTGF5ZXIgMSIgdmlld0JveD0iMCAwIDUwIDUwIiB4PSIwcHgiIHk9IjBweCI+PHRpdGxlPkRlc2lnbl90bnA8L3RpdGxlPjxwYXRoIGQ9Ik00OC43MSw0Mi45MUwzNC4wOCwyOC4yOSw0NC4zMywxOEExLDEsMCwwLDAsNDQsMTYuMzlMMi4zNSwxLjA2QTEsMSwwLDAsMCwxLjA2LDIuMzVMMTYuMzksNDRhMSwxLDAsMCwwLDEuNjUuMzZMMjguMjksMzQuMDgsNDIuOTEsNDguNzFhMSwxLDAsMCwwLDEuNDEsMGw0LjM4LTQuMzhBMSwxLDAsMCwwLDQ4LjcxLDQyLjkxWm0tNS4wOSwzLjY3TDI5LDMyYTEsMSwwLDAsMC0xLjQxLDBsLTkuODUsOS44NUwzLjY5LDMuNjlsMzguMTIsMTRMMzIsMjcuNThBMSwxLDAsMCwwLDMyLDI5TDQ2LjU5LDQzLjYyWiI+PC9wYXRoPjwvc3ZnPg==);border-color:transparent}.replayer-mouse:after{content:"";display:inline-block;width:20px;height:20px;background:rgb(73,80,246);border-radius:100%;transform:translate(-50%,-50%);opacity:.3}.replayer-mouse.active:after{animation:click .2s ease-in-out 1}.replayer-mouse.touch-device{background-image:none;width:70px;height:70px;border-width:4px;border-style:solid;border-radius:100%;margin-left:-37px;margin-top:-37px;border-color:#4950f600;transition:left 0s linear,top 0s linear,border-color .2s ease-in-out}.replayer-mouse.touch-device.touch-active{border-color:#4950f6;transition:left .25s linear,top .25s linear,border-color .2s ease-in-out}.replayer-mouse.touch-device:after{opacity:0}.replayer-mouse.touch-device.active:after{animation:touch-click .2s ease-in-out 1}.replayer-mouse-tail{position:absolute;pointer-events:none}@keyframes click{0%{opacity:.3;width:20px;height:20px}50%{opacity:.5;width:10px;height:10px}}@keyframes touch-click{0%{opacity:0;width:20px;height:20px}50%{opacity:.5;width:10px;height:10px}}
2
2
  /*# sourceMappingURL=style.min.css.map */
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["style.css"],
4
4
  "sourcesContent": [".replayer-wrapper {\n position: relative;\n}\n.replayer-mouse {\n position: absolute;\n width: 20px;\n height: 20px;\n transition: left 0.05s linear, top 0.05s linear;\n background-size: contain;\n background-position: center center;\n background-repeat: no-repeat;\n background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjMDAwMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iTGF5ZXIgMSIgdmlld0JveD0iMCAwIDUwIDUwIiB4PSIwcHgiIHk9IjBweCI+PHRpdGxlPkRlc2lnbl90bnA8L3RpdGxlPjxwYXRoIGQ9Ik00OC43MSw0Mi45MUwzNC4wOCwyOC4yOSw0NC4zMywxOEExLDEsMCwwLDAsNDQsMTYuMzlMMi4zNSwxLjA2QTEsMSwwLDAsMCwxLjA2LDIuMzVMMTYuMzksNDRhMSwxLDAsMCwwLDEuNjUuMzZMMjguMjksMzQuMDgsNDIuOTEsNDguNzFhMSwxLDAsMCwwLDEuNDEsMGw0LjM4LTQuMzhBMSwxLDAsMCwwLDQ4LjcxLDQyLjkxWm0tNS4wOSwzLjY3TDI5LDMyYTEsMSwwLDAsMC0xLjQxLDBsLTkuODUsOS44NUwzLjY5LDMuNjlsMzguMTIsMTRMMzIsMjcuNThBMSwxLDAsMCwwLDMyLDI5TDQ2LjU5LDQzLjYyWiI+PC9wYXRoPjwvc3ZnPg==');\n border-color: transparent; /* otherwise we transition from black when .touch-device class is added */\n}\n.replayer-mouse::after {\n content: '';\n display: inline-block;\n width: 20px;\n height: 20px;\n background: rgb(73, 80, 246);\n border-radius: 100%;\n transform: translate(-50%, -50%);\n opacity: 0.3;\n}\n.replayer-mouse.active::after {\n animation: click 0.2s ease-in-out 1;\n}\n.replayer-mouse.touch-device {\n background-image: none; /* there's no passive cursor on touch-only screens */\n width: 70px;\n height: 70px;\n border-width: 4px;\n border-style: solid;\n border-radius: 100%;\n margin-left: -37px;\n margin-top: -37px;\n border-color: rgba(73, 80, 246, 0);\n transition: left 0s linear, top 0s linear, border-color 0.2s ease-in-out;\n}\n.replayer-mouse.touch-device.touch-active {\n border-color: rgba(73, 80, 246, 1);\n transition: left 0.25s linear, top 0.25s linear, border-color 0.2s ease-in-out;\n}\n.replayer-mouse.touch-device::after {\n opacity: 0; /* there's no passive cursor on touch-only screens */\n}\n.replayer-mouse.touch-device.active::after {\n animation: touch-click 0.2s ease-in-out 1;\n}\n.replayer-mouse-tail {\n position: absolute;\n pointer-events: none;\n}\n\n@keyframes click {\n 0% {\n opacity: 0.3;\n width: 20px;\n height: 20px;\n }\n 50% {\n opacity: 0.5;\n width: 10px;\n height: 10px;\n }\n}\n\n@keyframes touch-click {\n 0% {\n opacity: 0;\n width: 20px;\n height: 20px;\n }\n 50% {\n opacity: 0.5;\n width: 10px;\n height: 10px;\n }\n}\n"],
5
- "mappings": "AAAA,CAAC,iBACC,SAAU,QACZ,CACA,CAAC,eACC,SAAU,SACV,MAAO,KACP,OAAQ,KACR,WAAY,KAAK,KAAM,MAAM,CAAE,IAAI,KAAM,OACzC,gBAAiB,QACjB,oBAAqB,OAAO,OAC5B,kBAAmB,UACnB,iBAAkB,4pBAClB,aAAc,WAChB,CACA,CAXC,cAWc,OACb,QAAS,GACT,QAAS,aACT,MAAO,KACP,OAAQ,KACR,WAAY,QAnBd,cAoBiB,KACf,UAAW,UAAU,IAAI,CAAE,MAC3B,QAAS,EACX,CACA,CArBC,cAqBc,CAAC,MAAM,OACpB,UAAW,MAAM,IAAK,YAAY,CACpC,CACA,CAxBC,cAwBc,CAAC,aACd,iBAAkB,KAClB,MAAO,KACP,OAAQ,KACR,aAAc,IACd,aAAc,MAhChB,cAiCiB,KACf,YAAa,MACb,WAAY,MACZ,aAAc,UACd,WAAY,KAAK,GAAG,MAAM,CAAE,IAAI,GAAG,MAAM,CAAE,aAAa,IAAK,WAC/D,CACA,CApCC,cAoCc,CAZC,YAYY,CAAC,aAC3B,aAAc,QACd,WAAY,KAAK,KAAM,MAAM,CAAE,IAAI,KAAM,MAAM,CAAE,aAAa,IAAK,WACrE,CACA,CAxCC,cAwCc,CAhBC,YAgBY,OAC1B,QAAS,CACX,CACA,CA3CC,cA2Cc,CAnBC,YAmBY,CAtBZ,MAsBmB,OACjC,UAAW,YAAY,IAAK,YAAY,CAC1C,CACA,CAAC,oBACC,SAAU,SACV,eAAgB,IAClB,CAEA,WA7Ba,MA8BX,GACE,QAAS,GACT,MAAO,KACP,OAAQ,IACV,CACA,IACE,QAAS,GACT,MAAO,KACP,OAAQ,IACV,CACF,CAEA,WApBa,YAqBX,GACE,QAAS,EACT,MAAO,KACP,OAAQ,IACV,CACA,IACE,QAAS,GACT,MAAO,KACP,OAAQ,IACV,CACF",
5
+ "mappings": "AAAA,CAAC,iBACC,SAAU,QACZ,CACA,CAAC,eACC,SAAU,SACV,MAAO,KACP,OAAQ,KACR,WAAY,KAAK,KAAM,MAAM,CAAE,IAAI,KAAM,OACzC,gBAAiB,QACjB,oBAAqB,OAAO,OAC5B,kBAAmB,UACnB,iBAAkB,4pBAClB,aAAc,WAChB,CACA,CAXC,cAWc,OACb,QAAS,GACT,QAAS,aACT,MAAO,KACP,OAAQ,KACR,WAAY,IAAI,EAAE,CAAE,EAAE,CAAE,KAnB1B,cAoBiB,KACf,UAAW,UAAU,IAAI,CAAE,MAC3B,QAAS,EACX,CACA,CArBC,cAqBc,CAAC,MAAM,OACpB,UAAW,MAAM,IAAK,YAAY,CACpC,CACA,CAxBC,cAwBc,CAAC,aACd,iBAAkB,KAClB,MAAO,KACP,OAAQ,KACR,aAAc,IACd,aAAc,MAhChB,cAiCiB,KACf,YAAa,MACb,WAAY,MACZ,aAAc,UACd,WAAY,KAAK,GAAG,MAAM,CAAE,IAAI,GAAG,MAAM,CAAE,aAAa,IAAK,WAC/D,CACA,CApCC,cAoCc,CAZC,YAYY,CAAC,aAC3B,aAAc,QACd,WAAY,KAAK,KAAM,MAAM,CAAE,IAAI,KAAM,MAAM,CAAE,aAAa,IAAK,WACrE,CACA,CAxCC,cAwCc,CAhBC,YAgBY,OAC1B,QAAS,CACX,CACA,CA3CC,cA2Cc,CAnBC,YAmBY,CAtBZ,MAsBmB,OACjC,UAAW,YAAY,IAAK,YAAY,CAC1C,CACA,CAAC,oBACC,SAAU,SACV,eAAgB,IAClB,CAEA,WA7Ba,MA8BX,GACE,QAAS,GACT,MAAO,KACP,OAAQ,IACV,CACA,IACE,QAAS,GACT,MAAO,KACP,OAAQ,IACV,CACF,CAEA,WApBa,YAqBX,GACE,QAAS,EACT,MAAO,KACP,OAAQ,IACV,CACA,IACE,QAAS,GACT,MAAO,KACP,OAAQ,IACV,CACF",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,481 @@
1
+ import { actionWithDelay } from '@sentry-internal/rrweb-types';
2
+ import { addedNodeMutation } from '@sentry-internal/rrweb-types';
3
+ import { blockClass } from '@sentry-internal/rrweb-types';
4
+ import { CanvasArg } from '@sentry-internal/rrweb-types';
5
+ import { canvasMutationCallback } from '@sentry-internal/rrweb-types';
6
+ import { canvasMutationData } from '@sentry-internal/rrweb-types';
7
+ import { canvasMutationParam } from '@sentry-internal/rrweb-types';
8
+ import { DataURLOptions } from '@sentry-internal/rrweb-snapshot';
9
+ import { DeprecatedMirror } from '@sentry-internal/rrweb-types';
10
+ import { DocumentDimension } from '@sentry-internal/rrweb-types';
11
+ import { Emitter } from '@sentry-internal/rrweb-types';
12
+ import { EventType } from '@sentry-internal/rrweb-types';
13
+ import { eventWithTime } from '@sentry-internal/rrweb-types';
14
+ import { fullSnapshotEvent } from '@sentry-internal/rrweb-types';
15
+ import { Handler } from '@sentry-internal/rrweb-types';
16
+ import { hookResetter } from '@sentry-internal/rrweb-types';
17
+ import { hooksParam } from '@sentry-internal/rrweb-types';
18
+ import { IMirror } from '@sentry-internal/rrweb-snapshot';
19
+ import { incrementalSnapshotEvent } from '@sentry-internal/rrweb-types';
20
+ import { IncrementalSource } from '@sentry-internal/rrweb-types';
21
+ import { inputData } from '@sentry-internal/rrweb-types';
22
+ import { IWindow } from '@sentry-internal/rrweb-types';
23
+ import { KeepIframeSrcFn } from '@sentry-internal/rrweb-types';
24
+ import { listenerHandler } from '@sentry-internal/rrweb-types';
25
+ import { MaskAttributeFn } from '@sentry-internal/rrweb-snapshot';
26
+ import { MaskInputFn } from '@sentry-internal/rrweb-snapshot';
27
+ import { MaskInputOptions } from '@sentry-internal/rrweb-snapshot';
28
+ import { maskTextClass } from '@sentry-internal/rrweb-types';
29
+ import { MaskTextFn } from '@sentry-internal/rrweb-snapshot';
30
+ import { Mirror } from '@sentry-internal/rrweb-snapshot';
31
+ import { MouseInteractions } from '@sentry-internal/rrweb-types';
32
+ import { PackFn } from '@sentry-internal/rrweb-types';
33
+ import { playerMetaData } from '@sentry-internal/rrweb-types';
34
+ import { RecordPlugin } from '@sentry-internal/rrweb-types';
35
+ import { ReplayerEvents } from '@sentry-internal/rrweb-types';
36
+ import { RRDocument } from '@sentry-internal/rrdom';
37
+ import { RRIFrameElement } from '@sentry-internal/rrdom';
38
+ import { RRNode } from '@sentry-internal/rrdom';
39
+ import { SamplingStrategy } from '@sentry-internal/rrweb-types';
40
+ import { SlimDOMOptions } from '@sentry-internal/rrweb-snapshot';
41
+ import { StateMachine } from '@xstate/fsm';
42
+ import { textMutation } from '@sentry-internal/rrweb-types';
43
+ import { throttleOptions } from '@sentry-internal/rrweb-types';
44
+ import { unmaskTextClass } from '@sentry-internal/rrweb-types';
45
+ import { UnpackFn } from '@sentry-internal/rrweb-types';
46
+ export declare function addCustomEvent<T>(tag: string, payload: T): void;
47
+ declare type AppendedIframe = {
48
+ mutationInQueue: addedNodeMutation;
49
+ builtNode: HTMLIFrameElement | RRIFrameElement;
50
+ };
51
+ export declare class CanvasManager implements CanvasManagerInterface {
52
+ private pendingCanvasMutations;
53
+ private rafStamps;
54
+ private options;
55
+ private mirror;
56
+ private shadowDoms;
57
+ private windowsSet;
58
+ private windows;
59
+ private mutationCb;
60
+ private restoreHandlers;
61
+ private frozen;
62
+ private locked;
63
+ private snapshotInProgressMap;
64
+ private worker;
65
+ private lastSnapshotTime;
66
+ reset(): void;
67
+ freeze(): void;
68
+ unfreeze(): void;
69
+ lock(): void;
70
+ unlock(): void;
71
+ constructor(options: CanvasManagerConstructorOptions);
72
+ addWindow(win: IWindow): void;
73
+ addShadowRoot(shadowRoot: ShadowRoot): void;
74
+ resetShadowRoots(): void;
75
+ snapshot(canvasElement?: HTMLCanvasElement, options?: SnapshotOptions): void;
76
+ private initFPSWorker;
77
+ private processMutation;
78
+ private initCanvasFPSObserver;
79
+ private initCanvasMutationObserver;
80
+ private getCanvasElements;
81
+ private takeSnapshot;
82
+ private startPendingCanvasMutationFlusher;
83
+ private startRAFTimestamping;
84
+ flushPendingCanvasMutations(): void;
85
+ flushPendingCanvasMutationFor(canvas: HTMLCanvasElement, id: number): void;
86
+ }
87
+ export declare interface CanvasManagerConstructorOptions {
88
+ recordCanvas: boolean;
89
+ enableManualSnapshot?: boolean;
90
+ mutationCb: canvasMutationCallback;
91
+ win: IWindow;
92
+ blockClass: blockClass;
93
+ blockSelector: string | null;
94
+ unblockSelector: string | null;
95
+ maxCanvasSize?: MaxCanvasSize | null;
96
+ mirror: Mirror;
97
+ dataURLOptions: DataURLOptions;
98
+ errorHandler?: ErrorHandler;
99
+ sampling?: 'all' | number;
100
+ }
101
+ declare interface CanvasManagerInterface {
102
+ reset(): void;
103
+ freeze(): void;
104
+ unfreeze(): void;
105
+ lock(): void;
106
+ unlock(): void;
107
+ snapshot(canvasElement?: HTMLCanvasElement, options?: SnapshotOptions): void;
108
+ addWindow(win: IWindow): void;
109
+ addShadowRoot(shadowRoot: ShadowRoot): void;
110
+ resetShadowRoots(): void;
111
+ }
112
+ export declare function canvasMutation({ event, mutation, target, imageMap, canvasEventMap, errorHandler, }: {
113
+ event: Parameters<Replayer['applyIncremental']>[0];
114
+ mutation: canvasMutationData;
115
+ target: HTMLCanvasElement;
116
+ imageMap: Replayer['imageMap'];
117
+ canvasEventMap: Replayer['canvasEventMap'];
118
+ errorHandler: Replayer['warnCanvasMutationFailed'];
119
+ }): Promise<void>;
120
+ export { canvasMutationData };
121
+ export { canvasMutationParam };
122
+ declare function clearTimeout_2(...rest: Parameters<typeof window.clearTimeout>): ReturnType<typeof window.clearTimeout>;
123
+ declare function closestElementOfNode(node: Node | null): HTMLElement | null;
124
+ declare function createPlayerService(context: PlayerContext, { getCastFn, applyEventsSynchronously, emitter }: PlayerAssets): StateMachine.Service<PlayerContext, PlayerEvent, PlayerState>;
125
+ declare function createSpeedService(context: SpeedContext): StateMachine.Service<SpeedContext, SpeedEvent, SpeedState>;
126
+ export declare function deserializeArg(imageMap: Replayer['imageMap'], ctx: CanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext | null, preload?: {
127
+ isUnchanged: boolean;
128
+ }): (arg: CanvasArg) => Promise<any>;
129
+ declare type ErrorHandler = (error: unknown) => void | boolean;
130
+ export { EventType };
131
+ export { eventWithTime };
132
+ export declare function freezePage(): void;
133
+ export { fullSnapshotEvent };
134
+ declare function getBaseDimension(node: Node, rootIframe: Node): DocumentDimension;
135
+ declare function getNestedRule(rules: CSSRuleList, position: number[]): CSSGroupingRule;
136
+ declare function getPositionsAndIndex(nestedIndex: number[]): {
137
+ positions: number[];
138
+ index: number | undefined;
139
+ };
140
+ declare function getRootShadowHost(n: Node): Node;
141
+ declare function getShadowHost(n: Node): Element | null;
142
+ declare function getWindowHeight(win: Window): number;
143
+ declare function getWindowScroll(win: Window): {
144
+ left: number;
145
+ top: number;
146
+ };
147
+ declare function getWindowWidth(win: Window): number;
148
+ declare function hasShadowRoot<T extends Node | RRNode>(n: T): n is T & {
149
+ shadowRoot: ShadowRoot;
150
+ };
151
+ declare function hookSetter<T>(target: T, key: string | number | symbol, d: PropertyDescriptor, isRevoked?: boolean, win?: Window & typeof globalThis): hookResetter;
152
+ export { incrementalSnapshotEvent };
153
+ export { IncrementalSource };
154
+ declare function inDom(n: Node): boolean;
155
+ export { inputData };
156
+ declare function isAncestorRemoved(target: Node, mirror: Mirror): boolean;
157
+ declare function isBlocked(node: Node | null, blockClass: blockClass, blockSelector: string | null, unblockSelector: string | null, checkAncestors: boolean): boolean;
158
+ declare function isIgnored(n: Node, mirror: Mirror): boolean;
159
+ declare function isSerialized(n: Node, mirror: Mirror): boolean;
160
+ declare function isSerializedIframe<TNode extends Node | RRNode>(n: TNode, mirror: IMirror<TNode>): boolean;
161
+ declare function isSerializedStylesheet<TNode extends Node | RRNode>(n: TNode, mirror: IMirror<TNode>): boolean;
162
+ declare function iterateResolveTree(tree: ResolveTree, cb: (mutation: addedNodeMutation) => unknown): void;
163
+ declare function legacy_isTouchEvent(event: MouseEvent | TouchEvent | PointerEvent): event is TouchEvent;
164
+ declare type MaxCanvasSize = [
165
+ number,
166
+ number
167
+ ];
168
+ declare let _mirror: DeprecatedMirror;
169
+ export { MouseInteractions };
170
+ declare let nowTimestamp: () => number;
171
+ declare function on(type: string, fn: EventListenerOrEventListenerObject, target?: Document | IWindow): listenerHandler;
172
+ declare function onRequestAnimationFrame(...rest: Parameters<typeof requestAnimationFrame>): ReturnType<typeof requestAnimationFrame>;
173
+ declare function patch(source: {
174
+ [key: string]: any;
175
+ }, name: string, replacement: (...args: unknown[]) => unknown): () => void;
176
+ declare type PlayerAssets = {
177
+ emitter: Emitter;
178
+ applyEventsSynchronously(events: Array<eventWithTime>): void;
179
+ getCastFn(event: eventWithTime, isSync: boolean): () => void;
180
+ };
181
+ export declare type playerConfig = {
182
+ speed: number;
183
+ maxSpeed: number;
184
+ root: Element;
185
+ loadTimeout: number;
186
+ skipInactive: boolean;
187
+ inactivePeriodThreshold: number;
188
+ showWarning: boolean;
189
+ showDebug: boolean;
190
+ blockClass: string;
191
+ liveMode: boolean;
192
+ insertStyleRules: string[];
193
+ triggerFocus: boolean;
194
+ UNSAFE_replayCanvas: boolean;
195
+ pauseAnimation?: boolean;
196
+ mouseTail: boolean | {
197
+ duration?: number;
198
+ lineCap?: string;
199
+ lineWidth?: number;
200
+ strokeStyle?: string;
201
+ };
202
+ unpackFn?: UnpackFn;
203
+ useVirtualDom: boolean;
204
+ logger: {
205
+ log: (...args: Parameters<typeof console.log>) => void;
206
+ warn: (...args: Parameters<typeof console.warn>) => void;
207
+ };
208
+ plugins?: ReplayPlugin[];
209
+ };
210
+ declare type PlayerContext = {
211
+ events: eventWithTime[];
212
+ timer: Timer;
213
+ timeOffset: number;
214
+ baselineTime: number;
215
+ lastPlayedEvent: eventWithTime | null;
216
+ };
217
+ declare type PlayerEvent = {
218
+ type: 'PLAY';
219
+ payload: {
220
+ timeOffset: number;
221
+ };
222
+ } | {
223
+ type: 'CAST_EVENT';
224
+ payload: {
225
+ event: eventWithTime;
226
+ };
227
+ } | {
228
+ type: 'PAUSE';
229
+ } | {
230
+ type: 'TO_LIVE';
231
+ payload: {
232
+ baselineTime?: number;
233
+ };
234
+ } | {
235
+ type: 'ADD_EVENT';
236
+ payload: {
237
+ event: eventWithTime;
238
+ };
239
+ } | {
240
+ type: 'END';
241
+ };
242
+ export declare type PlayerMachineState = StateMachine.State<PlayerContext, PlayerEvent, PlayerState>;
243
+ export declare type PlayerState = {
244
+ value: 'playing';
245
+ context: PlayerContext;
246
+ } | {
247
+ value: 'paused';
248
+ context: PlayerContext;
249
+ } | {
250
+ value: 'live';
251
+ context: PlayerContext;
252
+ };
253
+ declare function polyfill(win?: Window & typeof globalThis): void;
254
+ declare function queueToResolveTrees(queue: addedNodeMutation[]): ResolveTree[];
255
+ export declare function record<T = eventWithTime>(options?: recordOptions<T>): listenerHandler | undefined;
256
+ export declare namespace record {
257
+ var mirror: Mirror;
258
+ var takeFullSnapshot: takeFullSnapshot;
259
+ }
260
+ export declare type recordOptions<T> = {
261
+ emit?: (e: T, isCheckout?: boolean) => void;
262
+ checkoutEveryNth?: number;
263
+ checkoutEveryNms?: number;
264
+ blockClass?: blockClass;
265
+ blockSelector?: string;
266
+ unblockSelector?: string;
267
+ ignoreClass?: string;
268
+ ignoreSelector?: string;
269
+ maskAllText?: boolean;
270
+ maskTextClass?: maskTextClass;
271
+ unmaskTextClass?: unmaskTextClass;
272
+ maskTextSelector?: string;
273
+ unmaskTextSelector?: string;
274
+ maskAllInputs?: boolean;
275
+ maskInputOptions?: MaskInputOptions;
276
+ maskAttributeFn?: MaskAttributeFn;
277
+ maskInputFn?: MaskInputFn;
278
+ maskTextFn?: MaskTextFn;
279
+ maxCanvasSize?: [
280
+ number,
281
+ number
282
+ ];
283
+ slimDOMOptions?: SlimDOMOptions | 'all' | true;
284
+ ignoreCSSAttributes?: Set<string>;
285
+ inlineStylesheet?: boolean;
286
+ hooks?: hooksParam;
287
+ packFn?: PackFn;
288
+ sampling?: SamplingStrategy;
289
+ dataURLOptions?: DataURLOptions;
290
+ recordDOM?: boolean;
291
+ recordCanvas?: boolean;
292
+ recordCrossOriginIframes?: boolean;
293
+ recordAfter?: 'DOMContentLoaded' | 'load';
294
+ userTriggeredOnInput?: boolean;
295
+ collectFonts?: boolean;
296
+ inlineImages?: boolean;
297
+ win?: Window;
298
+ plugins?: RecordPlugin[];
299
+ mousemoveWait?: number;
300
+ keepIframeSrcFn?: KeepIframeSrcFn;
301
+ errorHandler?: ErrorHandler;
302
+ onMutation?: (mutations: MutationRecord[]) => boolean;
303
+ getCanvasManager?: (options: CanvasManagerConstructorOptions) => CanvasManagerInterface;
304
+ };
305
+ export declare class Replayer {
306
+ wrapper: HTMLDivElement;
307
+ iframe: HTMLIFrameElement;
308
+ service: ReturnType<typeof createPlayerService>;
309
+ speedService: ReturnType<typeof createSpeedService>;
310
+ readonly timer: Timer;
311
+ config: playerConfig;
312
+ usingVirtualDom: boolean;
313
+ virtualDom: RRDocument;
314
+ private emitter;
315
+ private nextUserInteractionEvent;
316
+ private legacy_missingNodeRetryMap;
317
+ private cache;
318
+ private imageMap;
319
+ private canvasEventMap;
320
+ private mirror;
321
+ private styleMirror;
322
+ private firstFullSnapshot;
323
+ private newDocumentQueue;
324
+ private pointers;
325
+ private mouseTailAnimationFrame;
326
+ private lastMouseDownEvent;
327
+ private lastHoveredRootNode;
328
+ private lastSelectionData;
329
+ private constructedStyleMutations;
330
+ private adoptedStyleSheets;
331
+ constructor(events: Array<eventWithTime | string>, config?: Partial<playerConfig>);
332
+ private createPointer;
333
+ on(event: string, handler: Handler): this;
334
+ off(event: string, handler: Handler): this;
335
+ setConfig(config: Partial<playerConfig>): void;
336
+ getMetaData(): playerMetaData;
337
+ getCurrentTime(): number;
338
+ getTimeOffset(): number;
339
+ getMirror(): Mirror;
340
+ play(timeOffset?: number): void;
341
+ pause(timeOffset?: number): void;
342
+ resume(timeOffset?: number): void;
343
+ destroy(): void;
344
+ startLive(baselineTime?: number): void;
345
+ addEvent(rawEvent: eventWithTime | string): void;
346
+ enableInteract(): void;
347
+ disableInteract(): void;
348
+ resetCache(): void;
349
+ private reevaluateFastForward;
350
+ private setupDom;
351
+ private handleResize;
352
+ private applyEventsSynchronously;
353
+ private getCastFn;
354
+ private rebuildFullSnapshot;
355
+ private insertStyleRules;
356
+ private attachDocumentToIframe;
357
+ private collectIframeAndAttachDocument;
358
+ private waitForStylesheetLoad;
359
+ private preloadAllImages;
360
+ private preloadImages;
361
+ private deserializeAndPreloadCanvasEvents;
362
+ private applyIncremental;
363
+ private applyMutation;
364
+ private applyScroll;
365
+ private applyInput;
366
+ private applySelection;
367
+ private applyStyleSheetMutation;
368
+ private applyStyleSheetRule;
369
+ private applyStyleDeclaration;
370
+ private applyAdoptedStyleSheet;
371
+ private legacy_resolveMissingNode;
372
+ private moveAndHover;
373
+ private drawMouseTail;
374
+ private stepMouseTails;
375
+ private hoverElements;
376
+ private isUserInteraction;
377
+ private backToNormal;
378
+ private warnNodeNotFound;
379
+ private warnCanvasMutationFailed;
380
+ private debugNodeNotFound;
381
+ private warn;
382
+ private debug;
383
+ }
384
+ export { ReplayerEvents };
385
+ export declare type ReplayPlugin = {
386
+ handler?: (event: eventWithTime, isSync: boolean, context: {
387
+ replayer: Replayer;
388
+ }) => void;
389
+ onBuild?: (node: Node | RRNode, context: {
390
+ id: number;
391
+ replayer: Replayer;
392
+ }) => void;
393
+ getMirror?: (mirrors: {
394
+ nodeMirror: Mirror;
395
+ }) => void;
396
+ };
397
+ declare type ResolveTree = {
398
+ value: addedNodeMutation;
399
+ children: ResolveTree[];
400
+ parent: ResolveTree | null;
401
+ };
402
+ declare function setTimeout_2(...rest: Parameters<typeof window.setTimeout>): ReturnType<typeof window.setTimeout>;
403
+ declare function shadowHostInDom(n: Node): boolean;
404
+ declare type SnapshotOptions = {
405
+ skipRequestAnimationFrame?: boolean;
406
+ };
407
+ declare type SpeedContext = {
408
+ normalSpeed: playerConfig['speed'];
409
+ timer: Timer;
410
+ };
411
+ declare type SpeedEvent = {
412
+ type: 'FAST_FORWARD';
413
+ payload: {
414
+ speed: playerConfig['speed'];
415
+ };
416
+ } | {
417
+ type: 'BACK_TO_NORMAL';
418
+ } | {
419
+ type: 'SET_SPEED';
420
+ payload: {
421
+ speed: playerConfig['speed'];
422
+ };
423
+ };
424
+ export declare type SpeedMachineState = StateMachine.State<SpeedContext, SpeedEvent, SpeedState>;
425
+ export declare type SpeedState = {
426
+ value: 'normal';
427
+ context: SpeedContext;
428
+ } | {
429
+ value: 'skipping';
430
+ context: SpeedContext;
431
+ };
432
+ declare class StyleSheetMirror {
433
+ private id;
434
+ private styleIDMap;
435
+ private idStyleMap;
436
+ getId(stylesheet: CSSStyleSheet): number;
437
+ has(stylesheet: CSSStyleSheet): boolean;
438
+ add(stylesheet: CSSStyleSheet, id?: number): number;
439
+ getStyle(id: number): CSSStyleSheet | null;
440
+ reset(): void;
441
+ generateId(): number;
442
+ }
443
+ export declare function takeFullSnapshot(isCheckout?: boolean): void;
444
+ declare function throttle<T>(func: (arg: T) => void, wait: number, options?: throttleOptions): (...args: T[]) => void;
445
+ declare class Timer {
446
+ timeOffset: number;
447
+ speed: number;
448
+ private actions;
449
+ private raf;
450
+ private lastTimestamp;
451
+ constructor(actions: actionWithDelay[] | undefined, config: {
452
+ speed: number;
453
+ });
454
+ addAction(action: actionWithDelay): void;
455
+ start(): void;
456
+ private rafCheck;
457
+ clear(): void;
458
+ setSpeed(speed: number): void;
459
+ isActive(): boolean;
460
+ private findActionIndex;
461
+ }
462
+ declare function uniqueTextMutations(mutations: textMutation[]): textMutation[];
463
+ declare namespace utils {
464
+ export { on, throttle, hookSetter, patch, getWindowScroll, getWindowHeight, getWindowWidth, closestElementOfNode, isBlocked, isSerialized, isIgnored, isAncestorRemoved, legacy_isTouchEvent, polyfill, queueToResolveTrees, iterateResolveTree, isSerializedIframe, isSerializedStylesheet, getBaseDimension, hasShadowRoot, getNestedRule, getPositionsAndIndex, uniqueTextMutations, getShadowHost, getRootShadowHost, shadowHostInDom, inDom, onRequestAnimationFrame, setTimeout_2 as setTimeout, clearTimeout_2 as clearTimeout, _mirror, nowTimestamp, AppendedIframe, StyleSheetMirror };
465
+ }
466
+ export { utils };
467
+ export {};
468
+ declare global {
469
+ const __RRWEB_EXCLUDE_SHADOW_DOM__: boolean;
470
+ const __RRWEB_EXCLUDE_IFRAME__: boolean;
471
+ }
472
+ declare namespace record {
473
+ var mirror: import("@sentry-internal/rrweb-snapshot").Mirror;
474
+ var takeFullSnapshot: typeof import(".").takeFullSnapshot;
475
+ }
476
+ declare global {
477
+ interface Window {
478
+ FontFace: typeof FontFace;
479
+ Array: typeof Array;
480
+ }
481
+ }
package/package.json CHANGED
@@ -1,25 +1,24 @@
1
1
  {
2
2
  "name": "@screeb/rrweb",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "record and replay the web",
5
5
  "scripts": {
6
- "prepare": "npm run prepack",
7
- "prepack": "npm run build",
8
- "retest": "cross-env PUPPETEER_HEADLESS=true yarn retest:headful",
9
- "retest:headful": "vitest run --exclude test/benchmark",
6
+ "retest": "vitest run --exclude test/benchmark",
10
7
  "build-and-test": "yarn build && yarn retest",
11
- "test:headless": "cross-env PUPPETEER_HEADLESS=true yarn build-and-test",
12
- "test:headful": "cross-env PUPPETEER_HEADLESS=false yarn build-and-test",
8
+ "test:headless": "PUPPETEER_HEADLESS=true yarn build-and-test",
9
+ "test:headful": "PUPPETEER_HEADLESS=false yarn build-and-test",
13
10
  "test": "yarn test:headless",
14
- "test:watch": "yarn build && cross-env PUPPETEER_HEADLESS=true yarn vitest --exclude test/benchmark",
11
+ "test:watch": "yarn build && PUPPETEER_HEADLESS=true yarn vitest --exclude test/benchmark",
15
12
  "test:update": "yarn test:headless --update",
16
- "retest:update": "cross-env PUPPETEER_HEADLESS=true yarn retest --update",
13
+ "retest:update": "PUPPETEER_HEADLESS=true yarn retest --update",
17
14
  "repl": "yarn build && node scripts/repl.js",
18
15
  "live-stream": "yarn build && node scripts/stream.js",
19
16
  "dev": "vite build --watch",
20
- "build": "yarn turbo run prepublish",
21
- "check-types": "tsc -noEmit",
22
- "prepublish": "tsc -noEmit && vite build",
17
+ "build": "yarn run check-types && vite build",
18
+ "build:tarball": "npm pack",
19
+ "typings:downlevel": "downlevel-dts dist dist/ts3.8 --to ts3.8",
20
+ "check-types": "tsc --noEmit",
21
+ "prepack": "yarn run build && yarn run typings:downlevel",
23
22
  "lint": "yarn eslint src",
24
23
  "benchmark": "vitest run --maxConcurrency 1 --no-file-parallelism test/benchmark"
25
24
  },
@@ -35,6 +34,13 @@
35
34
  "module": "./dist/rrweb.js",
36
35
  "unpkg": "./dist/rrweb.umd.cjs",
37
36
  "typings": "dist/rrweb.d.ts",
37
+ "typesVersions": {
38
+ "<3.9": {
39
+ "dist/rrweb.d.ts": [
40
+ "dist/ts3.8/rrweb.d.ts"
41
+ ]
42
+ }
43
+ },
38
44
  "exports": {
39
45
  ".": {
40
46
  "import": {
@@ -60,12 +66,15 @@
60
66
  },
61
67
  "homepage": "https://github.com/rrweb-io/rrweb#readme",
62
68
  "devDependencies": {
69
+ "@sentry-internal/rrweb-worker": "2.39.0",
63
70
  "@types/dom-mediacapture-transform": "0.1.4",
64
71
  "@types/inquirer": "^8.2.1",
65
72
  "@types/jest-image-snapshot": "^6.1.0",
66
73
  "@types/node": "^18.15.11",
67
74
  "@types/offscreencanvas": "^2019.6.4",
68
75
  "construct-style-sheets-polyfill": "^3.1.0",
76
+ "cross-env": "^5.2.0",
77
+ "downlevel-dts": "https://github.com/getsentry/downlevel-dts",
69
78
  "fast-mhtml": "^1.1.9",
70
79
  "identity-obj-proxy": "^3.0.0",
71
80
  "ignore-styles": "^5.0.1",
@@ -75,18 +84,18 @@
75
84
  "simple-peer-light": "^9.10.0",
76
85
  "ts-node": "^10.9.1",
77
86
  "tslib": "^2.3.1",
78
- "typescript": "^5.4.5",
79
- "vite": "^5.3.1",
80
- "vite-plugin-dts": "^3.9.1"
87
+ "typescript": "^4.7.3",
88
+ "vite": "^5.2.8",
89
+ "vite-plugin-dts": "^3.8.1"
81
90
  },
82
91
  "dependencies": {
83
- "@rrweb/types": "^2.0.0-alpha.18",
84
- "@rrweb/utils": "^2.0.0-alpha.18",
92
+ "@sentry-internal/rrdom": "2.39.0",
93
+ "@sentry-internal/rrweb-snapshot": "2.39.0",
94
+ "@sentry-internal/rrweb-types": "2.39.0",
85
95
  "@types/css-font-loading-module": "0.0.7",
86
96
  "@xstate/fsm": "^1.4.0",
87
97
  "base64-arraybuffer": "^1.0.1",
88
- "mitt": "^3.0.0",
89
- "rrdom": "^2.0.0-alpha.18",
90
- "rrweb-snapshot": "^2.0.0-alpha.18"
98
+ "fflate": "^0.4.4",
99
+ "mitt": "^3.0.0"
91
100
  }
92
101
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-bitmap-data-url-worker-IJpC7g_b.js","sources":["../../../node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js","../src/record/workers/image-bitmap-data-url-worker.ts"],"sourcesContent":["/*\n * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n}\nvar encode = function (arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';\n for (i = 0; i < len; i += 3) {\n base64 += chars[bytes[i] >> 2];\n base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n base64 += chars[bytes[i + 2] & 63];\n }\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + '=';\n }\n else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + '==';\n }\n return base64;\n};\nvar decode = function (base64) {\n var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n if (base64[base64.length - 1] === '=') {\n bufferLength--;\n if (base64[base64.length - 2] === '=') {\n bufferLength--;\n }\n }\n var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);\n for (i = 0; i < len; i += 4) {\n encoded1 = lookup[base64.charCodeAt(i)];\n encoded2 = lookup[base64.charCodeAt(i + 1)];\n encoded3 = lookup[base64.charCodeAt(i + 2)];\n encoded4 = lookup[base64.charCodeAt(i + 3)];\n bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n return arraybuffer;\n};\n\nexport { decode, encode };\n//# sourceMappingURL=base64-arraybuffer.es5.js.map\n","import { encode } from 'base64-arraybuffer';\nimport type {\n DataURLOptions,\n ImageBitmapDataURLWorkerParams,\n ImageBitmapDataURLWorkerResponse,\n} from '@rrweb/types';\n\nconst lastBlobMap: Map<number, string> = new Map();\nconst transparentBlobMap: Map<string, string> = new Map();\n\nexport interface ImageBitmapDataURLRequestWorker {\n postMessage: (\n message: ImageBitmapDataURLWorkerParams,\n transfer?: [ImageBitmap],\n ) => void;\n onmessage: (message: MessageEvent<ImageBitmapDataURLWorkerResponse>) => void;\n}\n\ninterface ImageBitmapDataURLResponseWorker {\n onmessage:\n | null\n | ((message: MessageEvent<ImageBitmapDataURLWorkerParams>) => void);\n postMessage(e: ImageBitmapDataURLWorkerResponse): void;\n}\n\nasync function getTransparentBlobFor(\n width: number,\n height: number,\n dataURLOptions: DataURLOptions,\n): Promise<string> {\n const id = `${width}-${height}`;\n if ('OffscreenCanvas' in globalThis) {\n if (transparentBlobMap.has(id)) return transparentBlobMap.get(id)!;\n const offscreen = new OffscreenCanvas(width, height);\n offscreen.getContext('2d'); // creates rendering context for `converToBlob`\n const blob = await offscreen.convertToBlob(dataURLOptions); // takes a while\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer); // cpu intensive\n transparentBlobMap.set(id, base64);\n return base64;\n } else {\n return '';\n }\n}\n\n// `as any` because: https://github.com/Microsoft/TypeScript/issues/20595\nconst worker: ImageBitmapDataURLResponseWorker = self;\n\n// eslint-disable-next-line @typescript-eslint/no-misused-promises\nworker.onmessage = async function (e) {\n if ('OffscreenCanvas' in globalThis) {\n const { id, bitmap, width, height, dataURLOptions } = e.data;\n\n const transparentBase64 = getTransparentBlobFor(\n width,\n height,\n dataURLOptions,\n );\n\n const offscreen = new OffscreenCanvas(width, height);\n const ctx = offscreen.getContext('2d')!;\n\n ctx.drawImage(bitmap, 0, 0);\n bitmap.close();\n const blob = await offscreen.convertToBlob(dataURLOptions); // takes a while\n const type = blob.type;\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer); // cpu intensive\n\n // on first try we should check if canvas is transparent,\n // no need to save it's contents in that case\n if (!lastBlobMap.has(id) && (await transparentBase64) === base64) {\n lastBlobMap.set(id, base64);\n return worker.postMessage({ id });\n }\n\n if (lastBlobMap.get(id) === base64) return worker.postMessage({ id }); // unchanged\n worker.postMessage({\n id,\n type,\n base64,\n width,\n height,\n });\n lastBlobMap.set(id, base64);\n } else {\n return worker.postMessage({ id: e.data.id });\n }\n};\n"],"names":["i"],"mappings":";;AAKA,MAAI,QAAQ;AAEZ,MAAI,SAAS,OAAO,eAAe,cAAc,CAAE,IAAG,IAAI,WAAW,GAAG;AACxE,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,WAAO,MAAM,WAAW,CAAC,CAAC,IAAI;AAAA,EAClC;AACA,MAAI,SAAS,SAAU,aAAa;AAChC,QAAI,QAAQ,IAAI,WAAW,WAAW,GAAGA,IAAG,MAAM,MAAM,QAAQ,SAAS;AACzE,SAAKA,KAAI,GAAGA,KAAI,KAAKA,MAAK,GAAG;AACzB,gBAAU,MAAM,MAAMA,EAAC,KAAK,CAAC;AAC7B,gBAAU,OAAQ,MAAMA,EAAC,IAAI,MAAM,IAAM,MAAMA,KAAI,CAAC,KAAK,CAAE;AAC3D,gBAAU,OAAQ,MAAMA,KAAI,CAAC,IAAI,OAAO,IAAM,MAAMA,KAAI,CAAC,KAAK,CAAE;AAChE,gBAAU,MAAM,MAAMA,KAAI,CAAC,IAAI,EAAE;AAAA,IACpC;AACD,QAAI,MAAM,MAAM,GAAG;AACf,eAAS,OAAO,UAAU,GAAG,OAAO,SAAS,CAAC,IAAI;AAAA,IACrD,WACQ,MAAM,MAAM,GAAG;AACpB,eAAS,OAAO,UAAU,GAAG,OAAO,SAAS,CAAC,IAAI;AAAA,IACrD;AACD,WAAO;AAAA,EACX;ACnBA,QAAM,kCAAuC;AAC7C,QAAM,yCAA8C;AAiBpD,iBAAe,sBACb,OACA,QACA,gBACiB;AACjB,UAAM,KAAK,GAAG,KAAK,IAAI,MAAM;AAC7B,QAAI,qBAAqB,YAAY;AACnC,UAAI,mBAAmB,IAAI,EAAE,EAAU,QAAA,mBAAmB,IAAI,EAAE;AAChE,YAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AACnD,gBAAU,WAAW,IAAI;AACzB,YAAM,OAAO,MAAM,UAAU,cAAc,cAAc;AACnD,YAAA,cAAc,MAAM,KAAK;AACzB,YAAA,SAAS,OAAO,WAAW;AACd,yBAAA,IAAI,IAAI,MAAM;AAC1B,aAAA;AAAA,IAAA,OACF;AACE,aAAA;AAAA,IACT;AAAA,EACF;AAGA,QAAM,SAA2C;AAGjD,SAAO,YAAY,eAAgB,GAAG;AACpC,QAAI,qBAAqB,YAAY;AACnC,YAAM,EAAE,IAAI,QAAQ,OAAO,QAAQ,mBAAmB,EAAE;AAExD,YAAM,oBAAoB;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AAC7C,YAAA,MAAM,UAAU,WAAW,IAAI;AAEjC,UAAA,UAAU,QAAQ,GAAG,CAAC;AAC1B,aAAO,MAAM;AACb,YAAM,OAAO,MAAM,UAAU,cAAc,cAAc;AACzD,YAAM,OAAO,KAAK;AACZ,YAAA,cAAc,MAAM,KAAK;AACzB,YAAA,SAAS,OAAO,WAAW;AAIjC,UAAI,CAAC,YAAY,IAAI,EAAE,KAAM,MAAM,sBAAuB,QAAQ;AACpD,oBAAA,IAAI,IAAI,MAAM;AAC1B,eAAO,OAAO,YAAY,EAAE,GAAI,CAAA;AAAA,MAClC;AAEI,UAAA,YAAY,IAAI,EAAE,MAAM,eAAe,OAAO,YAAY,EAAE,GAAA,CAAI;AACpE,aAAO,YAAY;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AACW,kBAAA,IAAI,IAAI,MAAM;AAAA,IAAA,OACrB;AACL,aAAO,OAAO,YAAY,EAAE,IAAI,EAAE,KAAK,IAAI;AAAA,IAC7C;AAAA,EACF;;","x_google_ignoreList":[0]}