@embedpdf/plugin-interaction-manager 1.0.15 → 1.0.16

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.
@@ -62,63 +62,131 @@ function useIsPageExclusive() {
62
62
  }, [cap]);
63
63
  return isPageExclusive;
64
64
  }
65
+ const domEventMap = {
66
+ pointerdown: "onPointerDown",
67
+ pointerup: "onPointerUp",
68
+ pointermove: "onPointerMove",
69
+ pointerenter: "onPointerEnter",
70
+ pointerleave: "onPointerLeave",
71
+ pointercancel: "onPointerCancel",
72
+ mousedown: "onMouseDown",
73
+ mouseup: "onMouseUp",
74
+ mousemove: "onMouseMove",
75
+ mouseenter: "onMouseEnter",
76
+ mouseleave: "onMouseLeave",
77
+ mousecancel: "onMouseCancel",
78
+ click: "onClick",
79
+ dblclick: "onDoubleClick",
80
+ /* touch → pointer fallback for very old browsers */
81
+ touchstart: "onPointerDown",
82
+ touchend: "onPointerUp",
83
+ touchmove: "onPointerMove",
84
+ touchcancel: "onPointerCancel"
85
+ };
86
+ const pointerEventTypes = [
87
+ "pointerdown",
88
+ "pointerup",
89
+ "pointermove",
90
+ "pointerenter",
91
+ "pointerleave",
92
+ "pointercancel",
93
+ "mousedown",
94
+ "mouseup",
95
+ "mousemove",
96
+ "mouseenter",
97
+ "mouseleave",
98
+ "mousecancel",
99
+ "click",
100
+ "dblclick"
101
+ ];
102
+ const touchEventTypes = ["touchstart", "touchend", "touchmove", "touchcancel"];
103
+ const allEventTypes = [...pointerEventTypes, ...touchEventTypes];
104
+ function listenerOpts(eventType, wantsRawTouch) {
105
+ return eventType.startsWith("touch") ? { passive: !wantsRawTouch } : { passive: false };
106
+ }
65
107
  function createPointerProvider(cap, scope, element, convertEventToPoint) {
66
108
  let active = cap.getHandlersForScope(scope);
109
+ const wantsRawTouchNow = () => {
110
+ var _a;
111
+ return ((_a = cap.getActiveInteractionMode()) == null ? void 0 : _a.wantsRawTouch) !== false;
112
+ };
113
+ const listeners = {};
114
+ let attachedWithRawTouch = wantsRawTouchNow();
115
+ const addListeners = (raw) => {
116
+ allEventTypes.forEach((type) => {
117
+ const fn = listeners[type] ?? (listeners[type] = handleEvent);
118
+ element.addEventListener(type, fn, listenerOpts(type, raw));
119
+ });
120
+ };
121
+ const removeListeners = () => {
122
+ allEventTypes.forEach((type) => {
123
+ const fn = listeners[type];
124
+ if (fn) element.removeEventListener(type, fn);
125
+ });
126
+ };
127
+ addListeners(attachedWithRawTouch);
67
128
  const stopMode = cap.onModeChange(() => {
68
129
  if (scope.type === "global") {
69
130
  const mode = cap.getActiveInteractionMode();
70
131
  element.style.cursor = (mode == null ? void 0 : mode.scope) === "global" ? mode.cursor ?? "auto" : "auto";
71
132
  }
72
133
  active = cap.getHandlersForScope(scope);
134
+ const raw = wantsRawTouchNow();
135
+ if (raw !== attachedWithRawTouch) {
136
+ removeListeners();
137
+ addListeners(raw);
138
+ attachedWithRawTouch = raw;
139
+ }
73
140
  });
74
141
  const stopHandler = cap.onHandlerChange(() => {
75
142
  active = cap.getHandlersForScope(scope);
76
143
  });
77
- const modeNow = cap.getActiveInteractionMode();
78
- const cursorNow = cap.getCurrentCursor();
79
- if (scope.type === "global") {
80
- element.style.cursor = (modeNow == null ? void 0 : modeNow.scope) === "global" ? cursorNow : "auto";
81
- } else {
82
- element.style.cursor = cursorNow;
83
- }
144
+ const initialMode = cap.getActiveInteractionMode();
145
+ const initialCursor = cap.getCurrentCursor();
146
+ element.style.cursor = scope.type === "global" && (initialMode == null ? void 0 : initialMode.scope) !== "global" ? "auto" : initialCursor;
84
147
  const stopCursor = cap.onCursorChange((c) => {
85
148
  var _a;
86
- if (scope.type === "global") {
87
- const isGlobalMode = ((_a = cap.getActiveInteractionMode()) == null ? void 0 : _a.scope) === "global";
88
- if (!isGlobalMode) return;
89
- }
149
+ if (scope.type === "global" && ((_a = cap.getActiveInteractionMode()) == null ? void 0 : _a.scope) !== "global") return;
90
150
  element.style.cursor = c;
91
151
  });
92
- const domEvent = {
93
- onPointerDown: "pointerdown",
94
- onPointerUp: "pointerup",
95
- onPointerMove: "pointermove",
96
- onPointerEnter: "pointerenter",
97
- onPointerLeave: "pointerleave",
98
- onPointerCancel: "pointercancel",
99
- onClick: "click",
100
- onDoubleClick: "dblclick"
101
- };
102
- const listeners = {};
103
152
  const toPos = (e, host) => {
104
153
  if (convertEventToPoint) return convertEventToPoint(e, host);
105
154
  const r = host.getBoundingClientRect();
106
155
  return { x: e.clientX - r.left, y: e.clientY - r.top };
107
156
  };
108
- Object.keys(domEvent).forEach((k) => {
109
- listeners[k] = (evt) => {
110
- var _a;
111
- if (cap.isPaused()) return;
157
+ function handleEvent(evt) {
158
+ var _a;
159
+ if (cap.isPaused()) return;
160
+ const handlerKey = domEventMap[evt.type];
161
+ if (!handlerKey || !(active == null ? void 0 : active[handlerKey])) return;
162
+ if (evt instanceof TouchEvent && attachedWithRawTouch && (evt.type === "touchmove" || evt.type === "touchcancel")) {
163
+ evt.preventDefault();
164
+ }
165
+ let pos;
166
+ let normEvt;
167
+ if (evt instanceof TouchEvent) {
168
+ const tp = evt.type === "touchend" || evt.type === "touchcancel" ? evt.changedTouches[0] : evt.touches[0];
169
+ if (!tp) return;
170
+ pos = toPos(tp, element);
171
+ normEvt = {
172
+ clientX: tp.clientX,
173
+ clientY: tp.clientY,
174
+ ctrlKey: evt.ctrlKey,
175
+ shiftKey: evt.shiftKey,
176
+ altKey: evt.altKey,
177
+ metaKey: evt.metaKey,
178
+ target: evt.target,
179
+ currentTarget: evt.currentTarget
180
+ };
181
+ } else {
112
182
  const pe = evt;
113
- const currentModeId = cap.getActiveMode();
114
- (_a = active == null ? void 0 : active[k]) == null ? void 0 : _a.call(active, toPos(pe, element), pe, currentModeId);
115
- };
116
- element.addEventListener(domEvent[k], listeners[k]);
117
- });
183
+ pos = toPos(pe, element);
184
+ normEvt = pe;
185
+ }
186
+ (_a = active[handlerKey]) == null ? void 0 : _a.call(active, pos, normEvt, cap.getActiveMode());
187
+ }
118
188
  return () => {
119
- Object.keys(domEvent).forEach(
120
- (k) => element.removeEventListener(domEvent[k], listeners[k])
121
- );
189
+ removeListeners();
122
190
  stopMode();
123
191
  stopCursor();
124
192
  stopHandler();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n} from '@embedpdf/plugin-interaction-manager';\n\n/**\n * Hook one DOM element into the interaction-manager.\n * – keeps handlers & cursor in-sync with the current mode\n * – returns a teardown fn for React/Preact effects\n */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ------------------------------------------------------------------ */\n /* active handler set – hot-swapped on every mode change */\n /* ------------------------------------------------------------------ */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n const stopMode = cap.onModeChange(() => {\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n active = cap.getHandlersForScope(scope);\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ------------------------------------------------------------------ */\n /* cursor */\n /* ------------------------------------------------------------------ */\n const modeNow = cap.getActiveInteractionMode();\n const cursorNow = cap.getCurrentCursor();\n\n /** initial cursor -------------------------------------------------- */\n if (scope.type === 'global') {\n // global wrapper only shows the cursor while a *global* mode is active\n element.style.cursor = modeNow?.scope === 'global' ? cursorNow : 'auto';\n } else {\n // page wrappers always mirror the latest cursor\n element.style.cursor = cursorNow;\n }\n\n const stopCursor = cap.onCursorChange((c) => {\n /** ❖ Propagation rule\n * ─────────────────\n * • global provider updates its cursor *only* while the active\n * mode itself is ‘global’.\n * • page providers always sync (so they show the cursor during\n * a global mode as well). */\n if (scope.type === 'global') {\n const isGlobalMode = cap.getActiveInteractionMode()?.scope === 'global';\n if (!isGlobalMode) return; // active mode is page-scoped → ignore\n }\n element.style.cursor = c;\n });\n\n /* ------------------------------------------------------------------ */\n /* event wiring */\n /* ------------------------------------------------------------------ */\n type K = keyof PointerEventHandlers;\n const domEvent: Record<K, keyof HTMLElementEventMap> = {\n onPointerDown: 'pointerdown',\n onPointerUp: 'pointerup',\n onPointerMove: 'pointermove',\n onPointerEnter: 'pointerenter',\n onPointerLeave: 'pointerleave',\n onPointerCancel: 'pointercancel',\n onClick: 'click',\n onDoubleClick: 'dblclick',\n };\n\n /* one stable EventListener per key -> needed for removeEventListener */\n const listeners: Partial<Record<K, EventListener>> = {};\n\n const toPos = (e: PointerEvent, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n (Object.keys(domEvent) as K[]).forEach((k) => {\n listeners[k] = (evt: Event) => {\n if (cap.isPaused()) return;\n\n const pe = evt as PointerEvent; // safe – we only attach to pointer*\n const currentModeId = cap.getActiveMode();\n active?.[k]?.(toPos(pe, element), pe, currentModeId);\n /* if you need to stop default behaviour when no handler is active:\n * if (!active?.[k]) pe.preventDefault(); */\n };\n element.addEventListener(domEvent[k], listeners[k]!);\n });\n\n /* ------------------------------------------------------------------ */\n /* teardown */\n /* ------------------------------------------------------------------ */\n return () => {\n (Object.keys(domEvent) as K[]).forEach((k) =>\n element.removeEventListener(domEvent[k], listeners[k]!),\n );\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["state"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n EmbedPdfPointerEvent,\n} from '@embedpdf/plugin-interaction-manager';\n\n/* -------------------------------------------------- */\n/* event → handler key lookup */\n/* -------------------------------------------------- */\ntype K = keyof PointerEventHandlers;\nconst domEventMap: Record<string, K> = {\n pointerdown: 'onPointerDown',\n pointerup: 'onPointerUp',\n pointermove: 'onPointerMove',\n pointerenter: 'onPointerEnter',\n pointerleave: 'onPointerLeave',\n pointercancel: 'onPointerCancel',\n\n mousedown: 'onMouseDown',\n mouseup: 'onMouseUp',\n mousemove: 'onMouseMove',\n mouseenter: 'onMouseEnter',\n mouseleave: 'onMouseLeave',\n mousecancel: 'onMouseCancel',\n\n click: 'onClick',\n dblclick: 'onDoubleClick',\n\n /* touch → pointer fallback for very old browsers */\n touchstart: 'onPointerDown',\n touchend: 'onPointerUp',\n touchmove: 'onPointerMove',\n touchcancel: 'onPointerCancel',\n};\n\nconst pointerEventTypes = [\n 'pointerdown',\n 'pointerup',\n 'pointermove',\n 'pointerenter',\n 'pointerleave',\n 'pointercancel',\n 'mousedown',\n 'mouseup',\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'mousecancel',\n 'click',\n 'dblclick',\n];\n\nconst touchEventTypes = ['touchstart', 'touchend', 'touchmove', 'touchcancel'];\nconst allEventTypes = [...pointerEventTypes, ...touchEventTypes];\n\n/* -------------------------------------------------- */\n/* helper: decide listener options per event type */\n/* -------------------------------------------------- */\nfunction listenerOpts(eventType: string, wantsRawTouch: boolean): AddEventListenerOptions {\n // Only touch events are toggled; pointer/mouse stay non-passive\n return eventType.startsWith('touch') ? { passive: !wantsRawTouch } : { passive: false };\n}\n\n/* -------------------------------------------------- */\n/* createPointerProvider */\n/* -------------------------------------------------- */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ---------- live handler set --------------------------------------------------- */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n /* ---------- helper to compute current wantsRawTouch (defaults to true) --------- */\n const wantsRawTouchNow = () => cap.getActiveInteractionMode()?.wantsRawTouch !== false; // default → true\n\n /* ---------- dynamic listener (re)attachment ------------------------------------ */\n const listeners: Record<string, (evt: Event) => void> = {};\n let attachedWithRawTouch = wantsRawTouchNow(); // remember current mode’s wish\n\n const addListeners = (raw: boolean) => {\n allEventTypes.forEach((type) => {\n const fn = (listeners[type] ??= handleEvent);\n element.addEventListener(type, fn, listenerOpts(type, raw));\n });\n };\n const removeListeners = () => {\n allEventTypes.forEach((type) => {\n const fn = listeners[type];\n if (fn) element.removeEventListener(type, fn);\n });\n };\n\n /* attach for the first time */\n addListeners(attachedWithRawTouch);\n\n /* ---------- mode & handler change hooks --------------------------------------- */\n const stopMode = cap.onModeChange(() => {\n /* cursor baseline update for global wrapper */\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n\n active = cap.getHandlersForScope(scope);\n\n /* re-attach listeners if wantsRawTouch toggled */\n const raw = wantsRawTouchNow();\n if (raw !== attachedWithRawTouch) {\n removeListeners();\n addListeners(raw);\n attachedWithRawTouch = raw;\n }\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ---------- cursor sync -------------------------------------------------------- */\n const initialMode = cap.getActiveInteractionMode();\n const initialCursor = cap.getCurrentCursor();\n element.style.cursor =\n scope.type === 'global' && initialMode?.scope !== 'global' ? 'auto' : initialCursor;\n\n const stopCursor = cap.onCursorChange((c) => {\n if (scope.type === 'global' && cap.getActiveInteractionMode()?.scope !== 'global') return;\n element.style.cursor = c;\n });\n\n /* ---------- point conversion --------------------------------------------------- */\n const toPos = (e: { clientX: number; clientY: number }, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e as PointerEvent, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n /* ---------- central event handler --------------------------------------------- */\n function handleEvent(evt: Event) {\n if (cap.isPaused()) return;\n\n const handlerKey = domEventMap[evt.type];\n if (!handlerKey || !active?.[handlerKey]) return;\n\n /* preventDefault only when mode really wants raw touch */\n if (\n evt instanceof TouchEvent &&\n attachedWithRawTouch &&\n (evt.type === 'touchmove' || evt.type === 'touchcancel')\n ) {\n evt.preventDefault();\n }\n\n // ----- normalise ----------------------------------------------------------------\n let pos!: Position;\n let normEvt!: EmbedPdfPointerEvent & {\n target: EventTarget | null;\n currentTarget: EventTarget | null;\n };\n\n if (evt instanceof TouchEvent) {\n const tp =\n evt.type === 'touchend' || evt.type === 'touchcancel'\n ? evt.changedTouches[0]\n : evt.touches[0];\n if (!tp) return;\n\n pos = toPos(tp, element);\n normEvt = {\n clientX: tp.clientX,\n clientY: tp.clientY,\n ctrlKey: evt.ctrlKey,\n shiftKey: evt.shiftKey,\n altKey: evt.altKey,\n metaKey: evt.metaKey,\n target: evt.target,\n currentTarget: evt.currentTarget,\n };\n } else {\n const pe = evt as PointerEvent;\n pos = toPos(pe, element);\n normEvt = pe;\n }\n\n active[handlerKey]?.(pos, normEvt, cap.getActiveMode());\n }\n\n /* ---------- teardown ----------------------------------------------------------- */\n return () => {\n removeListeners();\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["state"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-interaction-manager"),n=require("react"),r=require("react/jsx-runtime"),o=require("@embedpdf/models"),i=()=>e.useCapability(t.InteractionManagerPlugin.id);function l(){const{provides:e}=i(),[t,r]=n.useState((()=>{const t=null==e?void 0:e.getActiveInteractionMode();return"page"===(null==t?void 0:t.scope)&&!!t.exclusive}));return n.useEffect((()=>{if(e)return e.onModeChange((()=>{const t=e.getActiveInteractionMode();r("page"===(null==t?void 0:t.scope)&&!!(null==t?void 0:t.exclusive))}))}),[e]),t}function s(e,t,n,r){let o=e.getHandlersForScope(t);const i=e.onModeChange((()=>{if("global"===t.type){const t=e.getActiveInteractionMode();n.style.cursor="global"===(null==t?void 0:t.scope)?t.cursor??"auto":"auto"}o=e.getHandlersForScope(t)})),l=e.onHandlerChange((()=>{o=e.getHandlersForScope(t)})),s=e.getActiveInteractionMode(),u=e.getCurrentCursor();"global"===t.type?n.style.cursor="global"===(null==s?void 0:s.scope)?u:"auto":n.style.cursor=u;const c=e.onCursorChange((r=>{var o;if("global"===t.type){if(!("global"===(null==(o=e.getActiveInteractionMode())?void 0:o.scope)))return}n.style.cursor=r})),a={onPointerDown:"pointerdown",onPointerUp:"pointerup",onPointerMove:"pointermove",onPointerEnter:"pointerenter",onPointerLeave:"pointerleave",onPointerCancel:"pointercancel",onClick:"click",onDoubleClick:"dblclick"},d={};return Object.keys(a).forEach((t=>{d[t]=i=>{var l;if(e.isPaused())return;const s=i,u=e.getActiveMode();null==(l=null==o?void 0:o[t])||l.call(o,((e,t)=>{if(r)return r(e,t);const n=t.getBoundingClientRect();return{x:e.clientX-n.left,y:e.clientY-n.top}})(s,n),s,u)},n.addEventListener(a[t],d[t])})),()=>{Object.keys(a).forEach((e=>n.removeEventListener(a[e],d[e]))),i(),c(),l()}}exports.GlobalPointerProvider=({children:e,style:t,...o})=>{const l=n.useRef(null),{provides:u}=i();return n.useEffect((()=>{if(u&&l.current)return s(u,{type:"global"},l.current)}),[u]),r.jsx("div",{ref:l,style:{width:"100%",height:"100%",...t},...o,children:e})},exports.PagePointerProvider=({pageIndex:e,children:t,pageWidth:u,pageHeight:c,rotation:a,scale:d,convertEventToPoint:p,style:g,...v})=>{const f=n.useRef(null),{provides:x}=i(),y=l(),b=n.useCallback(((e,t)=>{const n=t.getBoundingClientRect(),r={x:e.clientX-n.left,y:e.clientY-n.top};return o.restorePosition({width:u,height:c},r,a,d)}),[u,c,a,d]);return n.useEffect((()=>{if(x&&f.current)return s(x,{type:"page",pageIndex:e},f.current,p||b)}),[x,e,p,b]),r.jsxs("div",{ref:f,style:{...g},...v,children:[t,y&&r.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:10}})]})},exports.useCursor=function(){const{provides:e}=i();return{setCursor:(t,n,r=0)=>{null==e||e.setCursor(t,n,r)},removeCursor:t=>{null==e||e.removeCursor(t)}}},exports.useInteractionManager=function(){const{provides:e}=i(),[r,o]=n.useState(t.initialState);return n.useEffect((()=>{if(e)return e.onStateChange((e=>{o(e)}))}),[e]),{provides:e,state:r}},exports.useInteractionManagerCapability=i,exports.useInteractionManagerPlugin=()=>e.usePlugin(t.InteractionManagerPlugin.id),exports.useIsPageExclusive=l,exports.usePointerHandlers=function({modeId:e,pageIndex:t}){const{provides:n}=i();return{register:(r,o)=>{const i=(null==o?void 0:o.modeId)??e,l=(null==o?void 0:o.pageIndex)??t;return i?null==n?void 0:n.registerHandlers({modeId:i,handlers:r,pageIndex:l}):null==n?void 0:n.registerAlways({scope:void 0!==l?{type:"page",pageIndex:l}:{type:"global"},handlers:r})}}};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-interaction-manager"),o=require("react"),n=require("react/jsx-runtime"),r=require("@embedpdf/models"),i=()=>e.useCapability(t.InteractionManagerPlugin.id);function c(){const{provides:e}=i(),[t,n]=o.useState((()=>{const t=null==e?void 0:e.getActiveInteractionMode();return"page"===(null==t?void 0:t.scope)&&!!t.exclusive}));return o.useEffect((()=>{if(e)return e.onModeChange((()=>{const t=e.getActiveInteractionMode();n("page"===(null==t?void 0:t.scope)&&!!(null==t?void 0:t.exclusive))}))}),[e]),t}const s={pointerdown:"onPointerDown",pointerup:"onPointerUp",pointermove:"onPointerMove",pointerenter:"onPointerEnter",pointerleave:"onPointerLeave",pointercancel:"onPointerCancel",mousedown:"onMouseDown",mouseup:"onMouseUp",mousemove:"onMouseMove",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",mousecancel:"onMouseCancel",click:"onClick",dblclick:"onDoubleClick",touchstart:"onPointerDown",touchend:"onPointerUp",touchmove:"onPointerMove",touchcancel:"onPointerCancel"},u=["pointerdown","pointerup","pointermove","pointerenter","pointerleave","pointercancel","mousedown","mouseup","mousemove","mouseenter","mouseleave","mousecancel","click","dblclick","touchstart","touchend","touchmove","touchcancel"];function l(e,t,o,n){let r=e.getHandlersForScope(t);const i=()=>{var t;return!1!==(null==(t=e.getActiveInteractionMode())?void 0:t.wantsRawTouch)},c={};let l=i();const a=e=>{u.forEach((t=>{const n=c[t]??(c[t]=y);var r;o.addEventListener(t,n,(r=e,t.startsWith("touch")?{passive:!r}:{passive:!1}))}))},d=()=>{u.forEach((e=>{const t=c[e];t&&o.removeEventListener(e,t)}))};a(l);const p=e.onModeChange((()=>{if("global"===t.type){const t=e.getActiveInteractionMode();o.style.cursor="global"===(null==t?void 0:t.scope)?t.cursor??"auto":"auto"}r=e.getHandlersForScope(t);const n=i();n!==l&&(d(),a(n),l=n)})),v=e.onHandlerChange((()=>{r=e.getHandlersForScope(t)})),g=e.getActiveInteractionMode(),h=e.getCurrentCursor();o.style.cursor="global"===t.type&&"global"!==(null==g?void 0:g.scope)?"auto":h;const f=e.onCursorChange((n=>{var r;"global"===t.type&&"global"!==(null==(r=e.getActiveInteractionMode())?void 0:r.scope)||(o.style.cursor=n)})),m=(e,t)=>{if(n)return n(e,t);const o=t.getBoundingClientRect();return{x:e.clientX-o.left,y:e.clientY-o.top}};function y(t){var n;if(e.isPaused())return;const i=s[t.type];if(!i||!(null==r?void 0:r[i]))return;let c,u;if(t instanceof TouchEvent&&l&&("touchmove"===t.type||"touchcancel"===t.type)&&t.preventDefault(),t instanceof TouchEvent){const e="touchend"===t.type||"touchcancel"===t.type?t.changedTouches[0]:t.touches[0];if(!e)return;c=m(e,o),u={clientX:e.clientX,clientY:e.clientY,ctrlKey:t.ctrlKey,shiftKey:t.shiftKey,altKey:t.altKey,metaKey:t.metaKey,target:t.target,currentTarget:t.currentTarget}}else{const e=t;c=m(e,o),u=e}null==(n=r[i])||n.call(r,c,u,e.getActiveMode())}return()=>{d(),p(),f(),v()}}exports.GlobalPointerProvider=({children:e,style:t,...r})=>{const c=o.useRef(null),{provides:s}=i();return o.useEffect((()=>{if(s&&c.current)return l(s,{type:"global"},c.current)}),[s]),n.jsx("div",{ref:c,style:{width:"100%",height:"100%",...t},...r,children:e})},exports.PagePointerProvider=({pageIndex:e,children:t,pageWidth:s,pageHeight:u,rotation:a,scale:d,convertEventToPoint:p,style:v,...g})=>{const h=o.useRef(null),{provides:f}=i(),m=c(),y=o.useCallback(((e,t)=>{const o=t.getBoundingClientRect(),n={x:e.clientX-o.left,y:e.clientY-o.top};return r.restorePosition({width:s,height:u},n,a,d)}),[s,u,a,d]);return o.useEffect((()=>{if(f&&h.current)return l(f,{type:"page",pageIndex:e},h.current,p||y)}),[f,e,p,y]),n.jsxs("div",{ref:h,style:{...v},...g,children:[t,m&&n.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:10}})]})},exports.useCursor=function(){const{provides:e}=i();return{setCursor:(t,o,n=0)=>{null==e||e.setCursor(t,o,n)},removeCursor:t=>{null==e||e.removeCursor(t)}}},exports.useInteractionManager=function(){const{provides:e}=i(),[n,r]=o.useState(t.initialState);return o.useEffect((()=>{if(e)return e.onStateChange((e=>{r(e)}))}),[e]),{provides:e,state:n}},exports.useInteractionManagerCapability=i,exports.useInteractionManagerPlugin=()=>e.usePlugin(t.InteractionManagerPlugin.id),exports.useIsPageExclusive=c,exports.usePointerHandlers=function({modeId:e,pageIndex:t}){const{provides:o}=i();return{register:(n,r)=>{const i=(null==r?void 0:r.modeId)??e,c=(null==r?void 0:r.pageIndex)??t;return i?null==o?void 0:o.registerHandlers({modeId:i,handlers:n,pageIndex:c}):null==o?void 0:o.registerAlways({scope:void 0!==c?{type:"page",pageIndex:c}:{type:"global"},handlers:n})}}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n} from '@embedpdf/plugin-interaction-manager';\n\n/**\n * Hook one DOM element into the interaction-manager.\n * – keeps handlers & cursor in-sync with the current mode\n * – returns a teardown fn for React/Preact effects\n */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ------------------------------------------------------------------ */\n /* active handler set – hot-swapped on every mode change */\n /* ------------------------------------------------------------------ */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n const stopMode = cap.onModeChange(() => {\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n active = cap.getHandlersForScope(scope);\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ------------------------------------------------------------------ */\n /* cursor */\n /* ------------------------------------------------------------------ */\n const modeNow = cap.getActiveInteractionMode();\n const cursorNow = cap.getCurrentCursor();\n\n /** initial cursor -------------------------------------------------- */\n if (scope.type === 'global') {\n // global wrapper only shows the cursor while a *global* mode is active\n element.style.cursor = modeNow?.scope === 'global' ? cursorNow : 'auto';\n } else {\n // page wrappers always mirror the latest cursor\n element.style.cursor = cursorNow;\n }\n\n const stopCursor = cap.onCursorChange((c) => {\n /** ❖ Propagation rule\n * ─────────────────\n * • global provider updates its cursor *only* while the active\n * mode itself is ‘global’.\n * • page providers always sync (so they show the cursor during\n * a global mode as well). */\n if (scope.type === 'global') {\n const isGlobalMode = cap.getActiveInteractionMode()?.scope === 'global';\n if (!isGlobalMode) return; // active mode is page-scoped → ignore\n }\n element.style.cursor = c;\n });\n\n /* ------------------------------------------------------------------ */\n /* event wiring */\n /* ------------------------------------------------------------------ */\n type K = keyof PointerEventHandlers;\n const domEvent: Record<K, keyof HTMLElementEventMap> = {\n onPointerDown: 'pointerdown',\n onPointerUp: 'pointerup',\n onPointerMove: 'pointermove',\n onPointerEnter: 'pointerenter',\n onPointerLeave: 'pointerleave',\n onPointerCancel: 'pointercancel',\n onClick: 'click',\n onDoubleClick: 'dblclick',\n };\n\n /* one stable EventListener per key -> needed for removeEventListener */\n const listeners: Partial<Record<K, EventListener>> = {};\n\n const toPos = (e: PointerEvent, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n (Object.keys(domEvent) as K[]).forEach((k) => {\n listeners[k] = (evt: Event) => {\n if (cap.isPaused()) return;\n\n const pe = evt as PointerEvent; // safe – we only attach to pointer*\n const currentModeId = cap.getActiveMode();\n active?.[k]?.(toPos(pe, element), pe, currentModeId);\n /* if you need to stop default behaviour when no handler is active:\n * if (!active?.[k]) pe.preventDefault(); */\n };\n element.addEventListener(domEvent[k], listeners[k]!);\n });\n\n /* ------------------------------------------------------------------ */\n /* teardown */\n /* ------------------------------------------------------------------ */\n return () => {\n (Object.keys(domEvent) as K[]).forEach((k) =>\n element.removeEventListener(domEvent[k], listeners[k]!),\n );\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["useInteractionManagerCapability","useCapability","InteractionManagerPlugin","id","useIsPageExclusive","provides","cap","isPageExclusive","setIsPageExclusive","useState","m","getActiveInteractionMode","scope","exclusive","useEffect","onModeChange","mode","createPointerProvider","element","convertEventToPoint","active","getHandlersForScope","stopMode","type","style","cursor","stopHandler","onHandlerChange","modeNow","cursorNow","getCurrentCursor","stopCursor","onCursorChange","c","_a","domEvent","onPointerDown","onPointerUp","onPointerMove","onPointerEnter","onPointerLeave","onPointerCancel","onClick","onDoubleClick","listeners","Object","keys","forEach","k","evt","isPaused","pe","currentModeId","getActiveMode","call","e","host","r","getBoundingClientRect","x","clientX","left","y","clientY","top","toPos","addEventListener","removeEventListener","children","props","ref","useRef","current","jsxRuntime","jsx","width","height","pageIndex","pageWidth","pageHeight","rotation","scale","defaultConvertEventToPoint","useCallback","event","rect","displayPoint","restorePosition","jsxs","position","right","bottom","zIndex","setCursor","token","prio","removeCursor","state","setState","initialState","onStateChange","usePlugin","modeId","register","handlers","options","finalModeId","finalPageIndex","registerHandlers","registerAlways"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n EmbedPdfPointerEvent,\n} from '@embedpdf/plugin-interaction-manager';\n\n/* -------------------------------------------------- */\n/* event → handler key lookup */\n/* -------------------------------------------------- */\ntype K = keyof PointerEventHandlers;\nconst domEventMap: Record<string, K> = {\n pointerdown: 'onPointerDown',\n pointerup: 'onPointerUp',\n pointermove: 'onPointerMove',\n pointerenter: 'onPointerEnter',\n pointerleave: 'onPointerLeave',\n pointercancel: 'onPointerCancel',\n\n mousedown: 'onMouseDown',\n mouseup: 'onMouseUp',\n mousemove: 'onMouseMove',\n mouseenter: 'onMouseEnter',\n mouseleave: 'onMouseLeave',\n mousecancel: 'onMouseCancel',\n\n click: 'onClick',\n dblclick: 'onDoubleClick',\n\n /* touch → pointer fallback for very old browsers */\n touchstart: 'onPointerDown',\n touchend: 'onPointerUp',\n touchmove: 'onPointerMove',\n touchcancel: 'onPointerCancel',\n};\n\nconst pointerEventTypes = [\n 'pointerdown',\n 'pointerup',\n 'pointermove',\n 'pointerenter',\n 'pointerleave',\n 'pointercancel',\n 'mousedown',\n 'mouseup',\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'mousecancel',\n 'click',\n 'dblclick',\n];\n\nconst touchEventTypes = ['touchstart', 'touchend', 'touchmove', 'touchcancel'];\nconst allEventTypes = [...pointerEventTypes, ...touchEventTypes];\n\n/* -------------------------------------------------- */\n/* helper: decide listener options per event type */\n/* -------------------------------------------------- */\nfunction listenerOpts(eventType: string, wantsRawTouch: boolean): AddEventListenerOptions {\n // Only touch events are toggled; pointer/mouse stay non-passive\n return eventType.startsWith('touch') ? { passive: !wantsRawTouch } : { passive: false };\n}\n\n/* -------------------------------------------------- */\n/* createPointerProvider */\n/* -------------------------------------------------- */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ---------- live handler set --------------------------------------------------- */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n /* ---------- helper to compute current wantsRawTouch (defaults to true) --------- */\n const wantsRawTouchNow = () => cap.getActiveInteractionMode()?.wantsRawTouch !== false; // default → true\n\n /* ---------- dynamic listener (re)attachment ------------------------------------ */\n const listeners: Record<string, (evt: Event) => void> = {};\n let attachedWithRawTouch = wantsRawTouchNow(); // remember current mode’s wish\n\n const addListeners = (raw: boolean) => {\n allEventTypes.forEach((type) => {\n const fn = (listeners[type] ??= handleEvent);\n element.addEventListener(type, fn, listenerOpts(type, raw));\n });\n };\n const removeListeners = () => {\n allEventTypes.forEach((type) => {\n const fn = listeners[type];\n if (fn) element.removeEventListener(type, fn);\n });\n };\n\n /* attach for the first time */\n addListeners(attachedWithRawTouch);\n\n /* ---------- mode & handler change hooks --------------------------------------- */\n const stopMode = cap.onModeChange(() => {\n /* cursor baseline update for global wrapper */\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n\n active = cap.getHandlersForScope(scope);\n\n /* re-attach listeners if wantsRawTouch toggled */\n const raw = wantsRawTouchNow();\n if (raw !== attachedWithRawTouch) {\n removeListeners();\n addListeners(raw);\n attachedWithRawTouch = raw;\n }\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ---------- cursor sync -------------------------------------------------------- */\n const initialMode = cap.getActiveInteractionMode();\n const initialCursor = cap.getCurrentCursor();\n element.style.cursor =\n scope.type === 'global' && initialMode?.scope !== 'global' ? 'auto' : initialCursor;\n\n const stopCursor = cap.onCursorChange((c) => {\n if (scope.type === 'global' && cap.getActiveInteractionMode()?.scope !== 'global') return;\n element.style.cursor = c;\n });\n\n /* ---------- point conversion --------------------------------------------------- */\n const toPos = (e: { clientX: number; clientY: number }, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e as PointerEvent, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n /* ---------- central event handler --------------------------------------------- */\n function handleEvent(evt: Event) {\n if (cap.isPaused()) return;\n\n const handlerKey = domEventMap[evt.type];\n if (!handlerKey || !active?.[handlerKey]) return;\n\n /* preventDefault only when mode really wants raw touch */\n if (\n evt instanceof TouchEvent &&\n attachedWithRawTouch &&\n (evt.type === 'touchmove' || evt.type === 'touchcancel')\n ) {\n evt.preventDefault();\n }\n\n // ----- normalise ----------------------------------------------------------------\n let pos!: Position;\n let normEvt!: EmbedPdfPointerEvent & {\n target: EventTarget | null;\n currentTarget: EventTarget | null;\n };\n\n if (evt instanceof TouchEvent) {\n const tp =\n evt.type === 'touchend' || evt.type === 'touchcancel'\n ? evt.changedTouches[0]\n : evt.touches[0];\n if (!tp) return;\n\n pos = toPos(tp, element);\n normEvt = {\n clientX: tp.clientX,\n clientY: tp.clientY,\n ctrlKey: evt.ctrlKey,\n shiftKey: evt.shiftKey,\n altKey: evt.altKey,\n metaKey: evt.metaKey,\n target: evt.target,\n currentTarget: evt.currentTarget,\n };\n } else {\n const pe = evt as PointerEvent;\n pos = toPos(pe, element);\n normEvt = pe;\n }\n\n active[handlerKey]?.(pos, normEvt, cap.getActiveMode());\n }\n\n /* ---------- teardown ----------------------------------------------------------- */\n return () => {\n removeListeners();\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["useInteractionManagerCapability","useCapability","InteractionManagerPlugin","id","useIsPageExclusive","provides","cap","isPageExclusive","setIsPageExclusive","useState","m","getActiveInteractionMode","scope","exclusive","useEffect","onModeChange","mode","domEventMap","pointerdown","pointerup","pointermove","pointerenter","pointerleave","pointercancel","mousedown","mouseup","mousemove","mouseenter","mouseleave","mousecancel","click","dblclick","touchstart","touchend","touchmove","touchcancel","allEventTypes","createPointerProvider","element","convertEventToPoint","active","getHandlersForScope","wantsRawTouchNow","_a","wantsRawTouch","listeners","attachedWithRawTouch","addListeners","raw","forEach","type","fn","handleEvent","addEventListener","startsWith","passive","removeListeners","removeEventListener","stopMode","style","cursor","stopHandler","onHandlerChange","initialMode","initialCursor","getCurrentCursor","stopCursor","onCursorChange","c","toPos","e","host","r","getBoundingClientRect","x","clientX","left","y","clientY","top","evt","isPaused","handlerKey","pos","normEvt","TouchEvent","preventDefault","tp","changedTouches","touches","ctrlKey","shiftKey","altKey","metaKey","target","currentTarget","pe","call","getActiveMode","children","props","ref","useRef","current","jsxRuntime","jsx","width","height","pageIndex","pageWidth","pageHeight","rotation","scale","defaultConvertEventToPoint","useCallback","event","rect","displayPoint","restorePosition","jsxs","position","right","bottom","zIndex","setCursor","token","prio","removeCursor","state","setState","initialState","onStateChange","usePlugin","modeId","register","handlers","options","finalModeId","finalPageIndex","registerHandlers","registerAlways"],"mappings":"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"}
@@ -62,63 +62,131 @@ function useIsPageExclusive() {
62
62
  }, [cap]);
63
63
  return isPageExclusive;
64
64
  }
65
+ const domEventMap = {
66
+ pointerdown: "onPointerDown",
67
+ pointerup: "onPointerUp",
68
+ pointermove: "onPointerMove",
69
+ pointerenter: "onPointerEnter",
70
+ pointerleave: "onPointerLeave",
71
+ pointercancel: "onPointerCancel",
72
+ mousedown: "onMouseDown",
73
+ mouseup: "onMouseUp",
74
+ mousemove: "onMouseMove",
75
+ mouseenter: "onMouseEnter",
76
+ mouseleave: "onMouseLeave",
77
+ mousecancel: "onMouseCancel",
78
+ click: "onClick",
79
+ dblclick: "onDoubleClick",
80
+ /* touch → pointer fallback for very old browsers */
81
+ touchstart: "onPointerDown",
82
+ touchend: "onPointerUp",
83
+ touchmove: "onPointerMove",
84
+ touchcancel: "onPointerCancel"
85
+ };
86
+ const pointerEventTypes = [
87
+ "pointerdown",
88
+ "pointerup",
89
+ "pointermove",
90
+ "pointerenter",
91
+ "pointerleave",
92
+ "pointercancel",
93
+ "mousedown",
94
+ "mouseup",
95
+ "mousemove",
96
+ "mouseenter",
97
+ "mouseleave",
98
+ "mousecancel",
99
+ "click",
100
+ "dblclick"
101
+ ];
102
+ const touchEventTypes = ["touchstart", "touchend", "touchmove", "touchcancel"];
103
+ const allEventTypes = [...pointerEventTypes, ...touchEventTypes];
104
+ function listenerOpts(eventType, wantsRawTouch) {
105
+ return eventType.startsWith("touch") ? { passive: !wantsRawTouch } : { passive: false };
106
+ }
65
107
  function createPointerProvider(cap, scope, element, convertEventToPoint) {
66
108
  let active = cap.getHandlersForScope(scope);
109
+ const wantsRawTouchNow = () => {
110
+ var _a;
111
+ return ((_a = cap.getActiveInteractionMode()) == null ? void 0 : _a.wantsRawTouch) !== false;
112
+ };
113
+ const listeners = {};
114
+ let attachedWithRawTouch = wantsRawTouchNow();
115
+ const addListeners = (raw) => {
116
+ allEventTypes.forEach((type) => {
117
+ const fn = listeners[type] ?? (listeners[type] = handleEvent);
118
+ element.addEventListener(type, fn, listenerOpts(type, raw));
119
+ });
120
+ };
121
+ const removeListeners = () => {
122
+ allEventTypes.forEach((type) => {
123
+ const fn = listeners[type];
124
+ if (fn) element.removeEventListener(type, fn);
125
+ });
126
+ };
127
+ addListeners(attachedWithRawTouch);
67
128
  const stopMode = cap.onModeChange(() => {
68
129
  if (scope.type === "global") {
69
130
  const mode = cap.getActiveInteractionMode();
70
131
  element.style.cursor = (mode == null ? void 0 : mode.scope) === "global" ? mode.cursor ?? "auto" : "auto";
71
132
  }
72
133
  active = cap.getHandlersForScope(scope);
134
+ const raw = wantsRawTouchNow();
135
+ if (raw !== attachedWithRawTouch) {
136
+ removeListeners();
137
+ addListeners(raw);
138
+ attachedWithRawTouch = raw;
139
+ }
73
140
  });
74
141
  const stopHandler = cap.onHandlerChange(() => {
75
142
  active = cap.getHandlersForScope(scope);
76
143
  });
77
- const modeNow = cap.getActiveInteractionMode();
78
- const cursorNow = cap.getCurrentCursor();
79
- if (scope.type === "global") {
80
- element.style.cursor = (modeNow == null ? void 0 : modeNow.scope) === "global" ? cursorNow : "auto";
81
- } else {
82
- element.style.cursor = cursorNow;
83
- }
144
+ const initialMode = cap.getActiveInteractionMode();
145
+ const initialCursor = cap.getCurrentCursor();
146
+ element.style.cursor = scope.type === "global" && (initialMode == null ? void 0 : initialMode.scope) !== "global" ? "auto" : initialCursor;
84
147
  const stopCursor = cap.onCursorChange((c) => {
85
148
  var _a;
86
- if (scope.type === "global") {
87
- const isGlobalMode = ((_a = cap.getActiveInteractionMode()) == null ? void 0 : _a.scope) === "global";
88
- if (!isGlobalMode) return;
89
- }
149
+ if (scope.type === "global" && ((_a = cap.getActiveInteractionMode()) == null ? void 0 : _a.scope) !== "global") return;
90
150
  element.style.cursor = c;
91
151
  });
92
- const domEvent = {
93
- onPointerDown: "pointerdown",
94
- onPointerUp: "pointerup",
95
- onPointerMove: "pointermove",
96
- onPointerEnter: "pointerenter",
97
- onPointerLeave: "pointerleave",
98
- onPointerCancel: "pointercancel",
99
- onClick: "click",
100
- onDoubleClick: "dblclick"
101
- };
102
- const listeners = {};
103
152
  const toPos = (e, host) => {
104
153
  if (convertEventToPoint) return convertEventToPoint(e, host);
105
154
  const r = host.getBoundingClientRect();
106
155
  return { x: e.clientX - r.left, y: e.clientY - r.top };
107
156
  };
108
- Object.keys(domEvent).forEach((k) => {
109
- listeners[k] = (evt) => {
110
- var _a;
111
- if (cap.isPaused()) return;
157
+ function handleEvent(evt) {
158
+ var _a;
159
+ if (cap.isPaused()) return;
160
+ const handlerKey = domEventMap[evt.type];
161
+ if (!handlerKey || !(active == null ? void 0 : active[handlerKey])) return;
162
+ if (evt instanceof TouchEvent && attachedWithRawTouch && (evt.type === "touchmove" || evt.type === "touchcancel")) {
163
+ evt.preventDefault();
164
+ }
165
+ let pos;
166
+ let normEvt;
167
+ if (evt instanceof TouchEvent) {
168
+ const tp = evt.type === "touchend" || evt.type === "touchcancel" ? evt.changedTouches[0] : evt.touches[0];
169
+ if (!tp) return;
170
+ pos = toPos(tp, element);
171
+ normEvt = {
172
+ clientX: tp.clientX,
173
+ clientY: tp.clientY,
174
+ ctrlKey: evt.ctrlKey,
175
+ shiftKey: evt.shiftKey,
176
+ altKey: evt.altKey,
177
+ metaKey: evt.metaKey,
178
+ target: evt.target,
179
+ currentTarget: evt.currentTarget
180
+ };
181
+ } else {
112
182
  const pe = evt;
113
- const currentModeId = cap.getActiveMode();
114
- (_a = active == null ? void 0 : active[k]) == null ? void 0 : _a.call(active, toPos(pe, element), pe, currentModeId);
115
- };
116
- element.addEventListener(domEvent[k], listeners[k]);
117
- });
183
+ pos = toPos(pe, element);
184
+ normEvt = pe;
185
+ }
186
+ (_a = active[handlerKey]) == null ? void 0 : _a.call(active, pos, normEvt, cap.getActiveMode());
187
+ }
118
188
  return () => {
119
- Object.keys(domEvent).forEach(
120
- (k) => element.removeEventListener(domEvent[k], listeners[k])
121
- );
189
+ removeListeners();
122
190
  stopMode();
123
191
  stopCursor();
124
192
  stopHandler();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n} from '@embedpdf/plugin-interaction-manager';\n\n/**\n * Hook one DOM element into the interaction-manager.\n * – keeps handlers & cursor in-sync with the current mode\n * – returns a teardown fn for React/Preact effects\n */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ------------------------------------------------------------------ */\n /* active handler set – hot-swapped on every mode change */\n /* ------------------------------------------------------------------ */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n const stopMode = cap.onModeChange(() => {\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n active = cap.getHandlersForScope(scope);\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ------------------------------------------------------------------ */\n /* cursor */\n /* ------------------------------------------------------------------ */\n const modeNow = cap.getActiveInteractionMode();\n const cursorNow = cap.getCurrentCursor();\n\n /** initial cursor -------------------------------------------------- */\n if (scope.type === 'global') {\n // global wrapper only shows the cursor while a *global* mode is active\n element.style.cursor = modeNow?.scope === 'global' ? cursorNow : 'auto';\n } else {\n // page wrappers always mirror the latest cursor\n element.style.cursor = cursorNow;\n }\n\n const stopCursor = cap.onCursorChange((c) => {\n /** ❖ Propagation rule\n * ─────────────────\n * • global provider updates its cursor *only* while the active\n * mode itself is ‘global’.\n * • page providers always sync (so they show the cursor during\n * a global mode as well). */\n if (scope.type === 'global') {\n const isGlobalMode = cap.getActiveInteractionMode()?.scope === 'global';\n if (!isGlobalMode) return; // active mode is page-scoped → ignore\n }\n element.style.cursor = c;\n });\n\n /* ------------------------------------------------------------------ */\n /* event wiring */\n /* ------------------------------------------------------------------ */\n type K = keyof PointerEventHandlers;\n const domEvent: Record<K, keyof HTMLElementEventMap> = {\n onPointerDown: 'pointerdown',\n onPointerUp: 'pointerup',\n onPointerMove: 'pointermove',\n onPointerEnter: 'pointerenter',\n onPointerLeave: 'pointerleave',\n onPointerCancel: 'pointercancel',\n onClick: 'click',\n onDoubleClick: 'dblclick',\n };\n\n /* one stable EventListener per key -> needed for removeEventListener */\n const listeners: Partial<Record<K, EventListener>> = {};\n\n const toPos = (e: PointerEvent, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n (Object.keys(domEvent) as K[]).forEach((k) => {\n listeners[k] = (evt: Event) => {\n if (cap.isPaused()) return;\n\n const pe = evt as PointerEvent; // safe – we only attach to pointer*\n const currentModeId = cap.getActiveMode();\n active?.[k]?.(toPos(pe, element), pe, currentModeId);\n /* if you need to stop default behaviour when no handler is active:\n * if (!active?.[k]) pe.preventDefault(); */\n };\n element.addEventListener(domEvent[k], listeners[k]!);\n });\n\n /* ------------------------------------------------------------------ */\n /* teardown */\n /* ------------------------------------------------------------------ */\n return () => {\n (Object.keys(domEvent) as K[]).forEach((k) =>\n element.removeEventListener(domEvent[k], listeners[k]!),\n );\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["state"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-interaction-manager.ts","../../src/shared/utils.ts","../../src/shared/components/global-pointer-provider.tsx","../../src/shared/components/page-pointer-provider.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialState,\n InteractionManagerPlugin,\n InteractionManagerState,\n PointerEventHandlers,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\nimport { useState, useEffect } from '@framework';\n\nexport const useInteractionManagerPlugin = () =>\n usePlugin<InteractionManagerPlugin>(InteractionManagerPlugin.id);\nexport const useInteractionManagerCapability = () =>\n useCapability<InteractionManagerPlugin>(InteractionManagerPlugin.id);\n\nexport function useInteractionManager() {\n const { provides } = useInteractionManagerCapability();\n const [state, setState] = useState<InteractionManagerState>(initialState);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onStateChange((state) => {\n setState(state);\n });\n }, [provides]);\n\n return {\n provides,\n state,\n };\n}\n\nexport function useCursor() {\n const { provides } = useInteractionManagerCapability();\n return {\n setCursor: (token: string, cursor: string, prio = 0) => {\n provides?.setCursor(token, cursor, prio);\n },\n removeCursor: (token: string) => {\n provides?.removeCursor(token);\n },\n };\n}\n\ninterface UsePointerHandlersOptions {\n modeId?: string | string[];\n pageIndex?: number;\n}\n\nexport function usePointerHandlers({ modeId, pageIndex }: UsePointerHandlersOptions) {\n const { provides } = useInteractionManagerCapability();\n return {\n register: (\n handlers: PointerEventHandlersWithLifecycle,\n options?: { modeId?: string | string[]; pageIndex?: number },\n ) => {\n // Use provided options or fall back to hook-level options\n const finalModeId = options?.modeId ?? modeId;\n const finalPageIndex = options?.pageIndex ?? pageIndex;\n\n return finalModeId\n ? provides?.registerHandlers({\n modeId: finalModeId,\n handlers,\n pageIndex: finalPageIndex,\n })\n : provides?.registerAlways({\n scope:\n finalPageIndex !== undefined\n ? { type: 'page', pageIndex: finalPageIndex }\n : { type: 'global' },\n handlers,\n });\n },\n };\n}\n\nexport function useIsPageExclusive() {\n const { provides: cap } = useInteractionManagerCapability();\n\n const [isPageExclusive, setIsPageExclusive] = useState<boolean>(() => {\n const m = cap?.getActiveInteractionMode();\n return m?.scope === 'page' && !!m.exclusive;\n });\n\n useEffect(() => {\n if (!cap) return;\n\n return cap.onModeChange(() => {\n const mode = cap.getActiveInteractionMode();\n setIsPageExclusive(mode?.scope === 'page' && !!mode?.exclusive);\n });\n }, [cap]);\n\n return isPageExclusive;\n}\n","import { Position } from '@embedpdf/models';\nimport type {\n InteractionManagerCapability,\n InteractionScope,\n PointerEventHandlers,\n EmbedPdfPointerEvent,\n} from '@embedpdf/plugin-interaction-manager';\n\n/* -------------------------------------------------- */\n/* event → handler key lookup */\n/* -------------------------------------------------- */\ntype K = keyof PointerEventHandlers;\nconst domEventMap: Record<string, K> = {\n pointerdown: 'onPointerDown',\n pointerup: 'onPointerUp',\n pointermove: 'onPointerMove',\n pointerenter: 'onPointerEnter',\n pointerleave: 'onPointerLeave',\n pointercancel: 'onPointerCancel',\n\n mousedown: 'onMouseDown',\n mouseup: 'onMouseUp',\n mousemove: 'onMouseMove',\n mouseenter: 'onMouseEnter',\n mouseleave: 'onMouseLeave',\n mousecancel: 'onMouseCancel',\n\n click: 'onClick',\n dblclick: 'onDoubleClick',\n\n /* touch → pointer fallback for very old browsers */\n touchstart: 'onPointerDown',\n touchend: 'onPointerUp',\n touchmove: 'onPointerMove',\n touchcancel: 'onPointerCancel',\n};\n\nconst pointerEventTypes = [\n 'pointerdown',\n 'pointerup',\n 'pointermove',\n 'pointerenter',\n 'pointerleave',\n 'pointercancel',\n 'mousedown',\n 'mouseup',\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'mousecancel',\n 'click',\n 'dblclick',\n];\n\nconst touchEventTypes = ['touchstart', 'touchend', 'touchmove', 'touchcancel'];\nconst allEventTypes = [...pointerEventTypes, ...touchEventTypes];\n\n/* -------------------------------------------------- */\n/* helper: decide listener options per event type */\n/* -------------------------------------------------- */\nfunction listenerOpts(eventType: string, wantsRawTouch: boolean): AddEventListenerOptions {\n // Only touch events are toggled; pointer/mouse stay non-passive\n return eventType.startsWith('touch') ? { passive: !wantsRawTouch } : { passive: false };\n}\n\n/* -------------------------------------------------- */\n/* createPointerProvider */\n/* -------------------------------------------------- */\nexport function createPointerProvider(\n cap: InteractionManagerCapability,\n scope: InteractionScope,\n element: HTMLElement,\n convertEventToPoint?: (evt: PointerEvent, host: HTMLElement) => Position,\n) {\n /* ---------- live handler set --------------------------------------------------- */\n let active: PointerEventHandlers | null = cap.getHandlersForScope(scope);\n\n /* ---------- helper to compute current wantsRawTouch (defaults to true) --------- */\n const wantsRawTouchNow = () => cap.getActiveInteractionMode()?.wantsRawTouch !== false; // default → true\n\n /* ---------- dynamic listener (re)attachment ------------------------------------ */\n const listeners: Record<string, (evt: Event) => void> = {};\n let attachedWithRawTouch = wantsRawTouchNow(); // remember current mode’s wish\n\n const addListeners = (raw: boolean) => {\n allEventTypes.forEach((type) => {\n const fn = (listeners[type] ??= handleEvent);\n element.addEventListener(type, fn, listenerOpts(type, raw));\n });\n };\n const removeListeners = () => {\n allEventTypes.forEach((type) => {\n const fn = listeners[type];\n if (fn) element.removeEventListener(type, fn);\n });\n };\n\n /* attach for the first time */\n addListeners(attachedWithRawTouch);\n\n /* ---------- mode & handler change hooks --------------------------------------- */\n const stopMode = cap.onModeChange(() => {\n /* cursor baseline update for global wrapper */\n if (scope.type === 'global') {\n const mode = cap.getActiveInteractionMode();\n element.style.cursor = mode?.scope === 'global' ? (mode.cursor ?? 'auto') : 'auto';\n }\n\n active = cap.getHandlersForScope(scope);\n\n /* re-attach listeners if wantsRawTouch toggled */\n const raw = wantsRawTouchNow();\n if (raw !== attachedWithRawTouch) {\n removeListeners();\n addListeners(raw);\n attachedWithRawTouch = raw;\n }\n });\n\n const stopHandler = cap.onHandlerChange(() => {\n active = cap.getHandlersForScope(scope);\n });\n\n /* ---------- cursor sync -------------------------------------------------------- */\n const initialMode = cap.getActiveInteractionMode();\n const initialCursor = cap.getCurrentCursor();\n element.style.cursor =\n scope.type === 'global' && initialMode?.scope !== 'global' ? 'auto' : initialCursor;\n\n const stopCursor = cap.onCursorChange((c) => {\n if (scope.type === 'global' && cap.getActiveInteractionMode()?.scope !== 'global') return;\n element.style.cursor = c;\n });\n\n /* ---------- point conversion --------------------------------------------------- */\n const toPos = (e: { clientX: number; clientY: number }, host: HTMLElement): Position => {\n if (convertEventToPoint) return convertEventToPoint(e as PointerEvent, host);\n const r = host.getBoundingClientRect();\n return { x: e.clientX - r.left, y: e.clientY - r.top };\n };\n\n /* ---------- central event handler --------------------------------------------- */\n function handleEvent(evt: Event) {\n if (cap.isPaused()) return;\n\n const handlerKey = domEventMap[evt.type];\n if (!handlerKey || !active?.[handlerKey]) return;\n\n /* preventDefault only when mode really wants raw touch */\n if (\n evt instanceof TouchEvent &&\n attachedWithRawTouch &&\n (evt.type === 'touchmove' || evt.type === 'touchcancel')\n ) {\n evt.preventDefault();\n }\n\n // ----- normalise ----------------------------------------------------------------\n let pos!: Position;\n let normEvt!: EmbedPdfPointerEvent & {\n target: EventTarget | null;\n currentTarget: EventTarget | null;\n };\n\n if (evt instanceof TouchEvent) {\n const tp =\n evt.type === 'touchend' || evt.type === 'touchcancel'\n ? evt.changedTouches[0]\n : evt.touches[0];\n if (!tp) return;\n\n pos = toPos(tp, element);\n normEvt = {\n clientX: tp.clientX,\n clientY: tp.clientY,\n ctrlKey: evt.ctrlKey,\n shiftKey: evt.shiftKey,\n altKey: evt.altKey,\n metaKey: evt.metaKey,\n target: evt.target,\n currentTarget: evt.currentTarget,\n };\n } else {\n const pe = evt as PointerEvent;\n pos = toPos(pe, element);\n normEvt = pe;\n }\n\n active[handlerKey]?.(pos, normEvt, cap.getActiveMode());\n }\n\n /* ---------- teardown ----------------------------------------------------------- */\n return () => {\n removeListeners();\n stopMode();\n stopCursor();\n stopHandler();\n };\n}\n","import { ReactNode, useEffect, useRef, HTMLAttributes, CSSProperties } from '@framework';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability } from '../hooks';\n\ninterface GlobalPointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport const GlobalPointerProvider = ({\n children,\n style,\n ...props\n}: GlobalPointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(cap, { type: 'global' }, ref.current);\n }, [cap]);\n\n return (\n <div\n ref={ref}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n","import {\n ReactNode,\n useEffect,\n useRef,\n useCallback,\n HTMLAttributes,\n CSSProperties,\n} from '@framework';\nimport { Position, restorePosition } from '@embedpdf/models';\nimport { createPointerProvider } from '../utils';\n\nimport { useInteractionManagerCapability, useIsPageExclusive } from '../hooks';\n\ninterface PagePointerProviderProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n pageIndex: number;\n pageWidth: number;\n pageHeight: number;\n rotation: number;\n scale: number;\n style?: CSSProperties;\n convertEventToPoint?: (event: PointerEvent, element: HTMLElement) => Position;\n}\n\nexport const PagePointerProvider = ({\n pageIndex,\n children,\n pageWidth,\n pageHeight,\n rotation,\n scale,\n convertEventToPoint,\n style,\n ...props\n}: PagePointerProviderProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const { provides: cap } = useInteractionManagerCapability();\n const isPageExclusive = useIsPageExclusive();\n\n // Memoize the default conversion function\n const defaultConvertEventToPoint = useCallback(\n (event: PointerEvent, element: HTMLElement): Position => {\n const rect = element.getBoundingClientRect();\n const displayPoint = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n return restorePosition(\n { width: pageWidth, height: pageHeight },\n displayPoint,\n rotation,\n scale,\n );\n },\n [pageWidth, pageHeight, rotation, scale],\n );\n\n useEffect(() => {\n if (!cap || !ref.current) return;\n\n return createPointerProvider(\n cap,\n { type: 'page', pageIndex },\n ref.current,\n convertEventToPoint || defaultConvertEventToPoint,\n );\n }, [cap, pageIndex, convertEventToPoint, defaultConvertEventToPoint]);\n\n return (\n <div\n ref={ref}\n style={{\n ...style,\n }}\n {...props}\n >\n {children}\n {isPageExclusive && (\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10 }} />\n )}\n </div>\n );\n};\n"],"names":["state"],"mappings":"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"}