{"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/viewport-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\n\nimport { ViewportPluginConfig } from './types';\n\nexport const VIEWPORT_PLUGIN_ID = 'viewport';\n\nexport const manifest: PluginManifest<ViewportPluginConfig> = {\n  id: VIEWPORT_PLUGIN_ID,\n  name: 'Viewport Plugin',\n  version: '1.0.0',\n  provides: ['viewport'],\n  requires: [],\n  optional: [],\n  defaultConfig: {\n    viewportGap: 10,\n    scrollEndDelay: 300,\n  },\n};\n","import { Action } from '@embedpdf/core';\nimport { ViewportInputMetrics, ViewportScrollMetrics } from './types';\n\n// Document lifecycle (state persistence)\nexport const INIT_VIEWPORT_STATE = 'INIT_VIEWPORT_STATE';\nexport const CLEANUP_VIEWPORT_STATE = 'CLEANUP_VIEWPORT_STATE';\n\n// Viewport registration (DOM lifecycle)\nexport const REGISTER_VIEWPORT = 'REGISTER_VIEWPORT';\nexport const UNREGISTER_VIEWPORT = 'UNREGISTER_VIEWPORT';\n\n// Viewport operations\nexport const SET_VIEWPORT_METRICS = 'SET_VIEWPORT_METRICS';\nexport const SET_VIEWPORT_SCROLL_METRICS = 'SET_VIEWPORT_SCROLL_METRICS';\nexport const SET_VIEWPORT_GAP = 'SET_VIEWPORT_GAP';\nexport const SET_SCROLL_ACTIVITY = 'SET_SCROLL_ACTIVITY';\nexport const SET_SMOOTH_SCROLL_ACTIVITY = 'SET_SMOOTH_SCROLL_ACTIVITY';\nexport const SET_ACTIVE_VIEWPORT_DOCUMENT = 'SET_ACTIVE_VIEWPORT_DOCUMENT';\n\n// NEW: Named gate actions\nexport const ADD_VIEWPORT_GATE = 'ADD_VIEWPORT_GATE';\nexport const REMOVE_VIEWPORT_GATE = 'REMOVE_VIEWPORT_GATE';\n\n// State persistence actions\nexport interface InitViewportStateAction extends Action {\n  type: typeof INIT_VIEWPORT_STATE;\n  payload: {\n    documentId: string;\n  };\n}\n\nexport interface CleanupViewportStateAction extends Action {\n  type: typeof CLEANUP_VIEWPORT_STATE;\n  payload: {\n    documentId: string;\n  };\n}\n\n// Registration actions (DOM lifecycle)\nexport interface RegisterViewportAction extends Action {\n  type: typeof REGISTER_VIEWPORT;\n  payload: {\n    documentId: string;\n  };\n}\n\nexport interface UnregisterViewportAction extends Action {\n  type: typeof UNREGISTER_VIEWPORT;\n  payload: {\n    documentId: string;\n  };\n}\n\nexport interface SetActiveViewportDocumentAction extends Action {\n  type: typeof SET_ACTIVE_VIEWPORT_DOCUMENT;\n  payload: string | null; // documentId\n}\n\nexport interface SetViewportMetricsAction extends Action {\n  type: typeof SET_VIEWPORT_METRICS;\n  payload: {\n    documentId: string;\n    metrics: ViewportInputMetrics;\n  };\n}\n\nexport interface SetViewportScrollMetricsAction extends Action {\n  type: typeof SET_VIEWPORT_SCROLL_METRICS;\n  payload: {\n    documentId: string;\n    scrollMetrics: ViewportScrollMetrics;\n  };\n}\n\nexport interface SetViewportGapAction extends Action {\n  type: typeof SET_VIEWPORT_GAP;\n  payload: number;\n}\n\nexport interface SetScrollActivityAction extends Action {\n  type: typeof SET_SCROLL_ACTIVITY;\n  payload: {\n    documentId: string;\n    isScrolling: boolean;\n  };\n}\n\nexport interface SetSmoothScrollActivityAction extends Action {\n  type: typeof SET_SMOOTH_SCROLL_ACTIVITY;\n  payload: {\n    documentId: string;\n    isSmoothScrolling: boolean;\n  };\n}\n\n// NEW: Named gate actions\nexport interface AddViewportGateAction extends Action {\n  type: typeof ADD_VIEWPORT_GATE;\n  payload: {\n    documentId: string;\n    key: string;\n  };\n}\n\nexport interface RemoveViewportGateAction extends Action {\n  type: typeof REMOVE_VIEWPORT_GATE;\n  payload: {\n    documentId: string;\n    key: string;\n  };\n}\n\nexport type ViewportAction =\n  | InitViewportStateAction\n  | CleanupViewportStateAction\n  | RegisterViewportAction\n  | UnregisterViewportAction\n  | SetActiveViewportDocumentAction\n  | SetViewportMetricsAction\n  | SetViewportScrollMetricsAction\n  | SetViewportGapAction\n  | SetScrollActivityAction\n  | SetSmoothScrollActivityAction\n  | AddViewportGateAction\n  | RemoveViewportGateAction;\n\n// Action Creators\n\nexport function initViewportState(documentId: string): InitViewportStateAction {\n  return { type: INIT_VIEWPORT_STATE, payload: { documentId } };\n}\n\nexport function cleanupViewportState(documentId: string): CleanupViewportStateAction {\n  return { type: CLEANUP_VIEWPORT_STATE, payload: { documentId } };\n}\n\nexport function registerViewport(documentId: string): RegisterViewportAction {\n  return { type: REGISTER_VIEWPORT, payload: { documentId } };\n}\n\nexport function unregisterViewport(documentId: string): UnregisterViewportAction {\n  return { type: UNREGISTER_VIEWPORT, payload: { documentId } };\n}\n\nexport function setActiveViewportDocument(\n  documentId: string | null,\n): SetActiveViewportDocumentAction {\n  return { type: SET_ACTIVE_VIEWPORT_DOCUMENT, payload: documentId };\n}\n\nexport function setViewportGap(viewportGap: number): SetViewportGapAction {\n  return { type: SET_VIEWPORT_GAP, payload: viewportGap };\n}\n\nexport function setViewportMetrics(\n  documentId: string,\n  metrics: ViewportInputMetrics,\n): SetViewportMetricsAction {\n  return { type: SET_VIEWPORT_METRICS, payload: { documentId, metrics } };\n}\n\nexport function setViewportScrollMetrics(\n  documentId: string,\n  scrollMetrics: ViewportScrollMetrics,\n): SetViewportScrollMetricsAction {\n  return { type: SET_VIEWPORT_SCROLL_METRICS, payload: { documentId, scrollMetrics } };\n}\n\nexport function setScrollActivity(\n  documentId: string,\n  isScrolling: boolean,\n): SetScrollActivityAction {\n  return { type: SET_SCROLL_ACTIVITY, payload: { documentId, isScrolling } };\n}\n\nexport function setSmoothScrollActivity(\n  documentId: string,\n  isSmoothScrolling: boolean,\n): SetSmoothScrollActivityAction {\n  return { type: SET_SMOOTH_SCROLL_ACTIVITY, payload: { documentId, isSmoothScrolling } };\n}\n\nexport function addViewportGate(documentId: string, key: string): AddViewportGateAction {\n  return { type: ADD_VIEWPORT_GATE, payload: { documentId, key } };\n}\n\nexport function removeViewportGate(documentId: string, key: string): RemoveViewportGateAction {\n  return { type: REMOVE_VIEWPORT_GATE, payload: { documentId, key } };\n}\n","import { Reducer } from '@embedpdf/core';\nimport {\n  ViewportAction,\n  INIT_VIEWPORT_STATE,\n  CLEANUP_VIEWPORT_STATE,\n  REGISTER_VIEWPORT,\n  UNREGISTER_VIEWPORT,\n  SET_ACTIVE_VIEWPORT_DOCUMENT,\n  SET_VIEWPORT_METRICS,\n  SET_VIEWPORT_SCROLL_METRICS,\n  SET_VIEWPORT_GAP,\n  SET_SCROLL_ACTIVITY,\n  SET_SMOOTH_SCROLL_ACTIVITY,\n  ADD_VIEWPORT_GATE,\n  REMOVE_VIEWPORT_GATE,\n} from './actions';\nimport { ViewportState, ViewportDocumentState } from './types';\n\nconst initialViewportDocumentState: ViewportDocumentState = {\n  viewportMetrics: {\n    width: 0,\n    height: 0,\n    scrollTop: 0,\n    scrollLeft: 0,\n    clientWidth: 0,\n    clientHeight: 0,\n    scrollWidth: 0,\n    scrollHeight: 0,\n    clientLeft: 0,\n    clientTop: 0,\n    relativePosition: { x: 0, y: 0 },\n  },\n  isScrolling: false,\n  isSmoothScrolling: false,\n  gates: new Set<string>(),\n};\n\nexport const initialState: ViewportState = {\n  viewportGap: 0,\n  documents: {},\n  activeViewports: new Set(),\n  activeDocumentId: null,\n};\n\nexport const viewportReducer: Reducer<ViewportState, ViewportAction> = (\n  state = initialState,\n  action,\n) => {\n  switch (action.type) {\n    // ─────────────────────────────────────────────────────────\n    // State Persistence (Document Lifecycle)\n    // ─────────────────────────────────────────────────────────\n\n    case INIT_VIEWPORT_STATE: {\n      const { documentId } = action.payload;\n      return {\n        ...state,\n        documents: {\n          ...state.documents,\n          [documentId]: { ...initialViewportDocumentState, gates: new Set() },\n        },\n      };\n    }\n\n    case CLEANUP_VIEWPORT_STATE: {\n      const { documentId } = action.payload;\n      const { [documentId]: removed, ...remainingDocs } = state.documents;\n\n      // Also remove from active viewports if present\n      const newActiveViewports = new Set(state.activeViewports);\n      newActiveViewports.delete(documentId);\n\n      return {\n        ...state,\n        documents: remainingDocs,\n        activeViewports: newActiveViewports,\n        activeDocumentId: state.activeDocumentId === documentId ? null : state.activeDocumentId,\n      };\n    }\n\n    // ─────────────────────────────────────────────────────────\n    // Viewport Registration (DOM Lifecycle)\n    // ─────────────────────────────────────────────────────────\n\n    case REGISTER_VIEWPORT: {\n      const { documentId } = action.payload;\n      const newActiveViewports = new Set(state.activeViewports);\n      newActiveViewports.add(documentId);\n\n      return {\n        ...state,\n        activeViewports: newActiveViewports,\n        // Set as active if no active document\n        activeDocumentId: state.activeDocumentId ?? documentId,\n      };\n    }\n\n    case UNREGISTER_VIEWPORT: {\n      const { documentId } = action.payload;\n      const newActiveViewports = new Set(state.activeViewports);\n      newActiveViewports.delete(documentId);\n\n      return {\n        ...state,\n        activeViewports: newActiveViewports,\n      };\n    }\n\n    case SET_ACTIVE_VIEWPORT_DOCUMENT: {\n      return {\n        ...state,\n        activeDocumentId: action.payload,\n      };\n    }\n\n    // ─────────────────────────────────────────────────────────\n    // Viewport Operations\n    // ─────────────────────────────────────────────────────────\n\n    case SET_VIEWPORT_GAP: {\n      return {\n        ...state,\n        viewportGap: action.payload,\n      };\n    }\n\n    case SET_VIEWPORT_METRICS: {\n      const { documentId, metrics } = action.payload;\n      const viewport = state.documents[documentId];\n      if (!viewport) return state;\n\n      return {\n        ...state,\n        documents: {\n          ...state.documents,\n          [documentId]: {\n            ...viewport,\n            viewportMetrics: {\n              width: metrics.width,\n              height: metrics.height,\n              scrollTop: metrics.scrollTop,\n              scrollLeft: metrics.scrollLeft,\n              clientWidth: metrics.clientWidth,\n              clientHeight: metrics.clientHeight,\n              scrollWidth: metrics.scrollWidth,\n              scrollHeight: metrics.scrollHeight,\n              clientLeft: metrics.clientLeft,\n              clientTop: metrics.clientTop,\n              relativePosition: {\n                x:\n                  metrics.scrollWidth <= metrics.clientWidth\n                    ? 0\n                    : metrics.scrollLeft / (metrics.scrollWidth - metrics.clientWidth),\n                y:\n                  metrics.scrollHeight <= metrics.clientHeight\n                    ? 0\n                    : metrics.scrollTop / (metrics.scrollHeight - metrics.clientHeight),\n              },\n            },\n          },\n        },\n      };\n    }\n\n    case SET_VIEWPORT_SCROLL_METRICS: {\n      const { documentId, scrollMetrics } = action.payload;\n      const viewport = state.documents[documentId];\n      if (!viewport) return state;\n\n      return {\n        ...state,\n        documents: {\n          ...state.documents,\n          [documentId]: {\n            ...viewport,\n            viewportMetrics: {\n              ...viewport.viewportMetrics,\n              scrollTop: scrollMetrics.scrollTop,\n              scrollLeft: scrollMetrics.scrollLeft,\n            },\n            isScrolling: true,\n          },\n        },\n      };\n    }\n\n    case SET_SCROLL_ACTIVITY: {\n      const { documentId, isScrolling } = action.payload;\n      const viewport = state.documents[documentId];\n      if (!viewport) return state;\n\n      return {\n        ...state,\n        documents: {\n          ...state.documents,\n          [documentId]: {\n            ...viewport,\n            isScrolling,\n          },\n        },\n      };\n    }\n\n    case SET_SMOOTH_SCROLL_ACTIVITY: {\n      const { documentId, isSmoothScrolling } = action.payload;\n      const viewport = state.documents[documentId];\n      if (!viewport) return state;\n\n      return {\n        ...state,\n        documents: {\n          ...state.documents,\n          [documentId]: {\n            ...viewport,\n            isSmoothScrolling,\n          },\n        },\n      };\n    }\n\n    // ─────────────────────────────────────────────────────────\n    // Named Gate Operations\n    // ─────────────────────────────────────────────────────────\n\n    case ADD_VIEWPORT_GATE: {\n      const { documentId, key } = action.payload;\n      const viewport = state.documents[documentId];\n      if (!viewport) return state;\n\n      // Create new Set with the added gate\n      const newGates = new Set(viewport.gates);\n      newGates.add(key);\n\n      return {\n        ...state,\n        documents: {\n          ...state.documents,\n          [documentId]: {\n            ...viewport,\n            gates: newGates,\n          },\n        },\n      };\n    }\n\n    case REMOVE_VIEWPORT_GATE: {\n      const { documentId, key } = action.payload;\n      const viewport = state.documents[documentId];\n      if (!viewport) return state;\n\n      // Create new Set without the removed gate\n      const newGates = new Set(viewport.gates);\n      newGates.delete(key);\n\n      return {\n        ...state,\n        documents: {\n          ...state.documents,\n          [documentId]: {\n            ...viewport,\n            gates: newGates,\n          },\n        },\n      };\n    }\n\n    default:\n      return state;\n  }\n};\n","import {\n  BasePlugin,\n  PluginRegistry,\n  createEmitter,\n  createBehaviorEmitter,\n  Listener,\n} from '@embedpdf/core';\nimport { Rect } from '@embedpdf/models';\n\nimport {\n  ViewportAction,\n  initViewportState,\n  cleanupViewportState,\n  registerViewport,\n  unregisterViewport,\n  setViewportMetrics,\n  setViewportScrollMetrics,\n  setViewportGap,\n  setScrollActivity,\n  setSmoothScrollActivity,\n  addViewportGate,\n  removeViewportGate,\n} from './actions';\nimport {\n  ViewportPluginConfig,\n  ViewportState,\n  ViewportCapability,\n  ViewportScope,\n  ViewportMetrics,\n  ViewportScrollMetrics,\n  ViewportInputMetrics,\n  ScrollToPayload,\n  ScrollActivity,\n  ViewportEvent,\n  ScrollActivityEvent,\n  ScrollChangeEvent,\n  GateChangeEvent,\n} from './types';\n\nexport class ViewportPlugin extends BasePlugin<\n  ViewportPluginConfig,\n  ViewportCapability,\n  ViewportState,\n  ViewportAction\n> {\n  static readonly id = 'viewport' as const;\n\n  private readonly viewportResize$ = createBehaviorEmitter<ViewportEvent>();\n  private readonly viewportMetrics$ = createBehaviorEmitter<ViewportEvent>();\n  private readonly scrollMetrics$ = createBehaviorEmitter<ScrollChangeEvent>();\n  private readonly scrollActivity$ = createBehaviorEmitter<ScrollActivityEvent>();\n  private readonly gateState$ = createBehaviorEmitter<GateChangeEvent>();\n\n  // Scroll request emitters per document (persisted with state)\n  private readonly scrollRequests$ = new Map<\n    string,\n    ReturnType<typeof createEmitter<ScrollToPayload>>\n  >();\n\n  private readonly scrollEndDelay: number;\n\n  constructor(\n    public readonly id: string,\n    registry: PluginRegistry,\n    config: ViewportPluginConfig,\n  ) {\n    super(id, registry);\n\n    if (config.viewportGap) {\n      this.dispatch(setViewportGap(config.viewportGap));\n    }\n\n    this.scrollEndDelay = config.scrollEndDelay || 100;\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Document Lifecycle (from BasePlugin)\n  // ─────────────────────────────────────────────────────────\n\n  protected override onDocumentLoadingStarted(documentId: string): void {\n    // Initialize viewport state for this document\n    this.dispatch(initViewportState(documentId));\n\n    // Create scroll request emitter\n    this.scrollRequests$.set(documentId, createEmitter<ScrollToPayload>());\n\n    this.logger.debug(\n      'ViewportPlugin',\n      'DocumentOpened',\n      `Initialized viewport state for document: ${documentId}`,\n    );\n  }\n\n  protected override onDocumentClosed(documentId: string): void {\n    // Cleanup viewport state\n    this.dispatch(cleanupViewportState(documentId));\n\n    // Cleanup scroll request emitter\n    this.scrollRequests$.get(documentId)?.clear();\n    this.scrollRequests$.delete(documentId);\n\n    this.logger.debug(\n      'ViewportPlugin',\n      'DocumentClosed',\n      `Cleaned up viewport state for document: ${documentId}`,\n    );\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Capability\n  // ─────────────────────────────────────────────────────────\n\n  protected buildCapability(): ViewportCapability {\n    return {\n      // Global\n      getViewportGap: () => this.state.viewportGap,\n\n      // Active document operations\n      getMetrics: () => this.getMetrics(),\n      scrollTo: (pos: ScrollToPayload) => this.scrollTo(pos),\n      isScrolling: () => this.isScrolling(),\n      isSmoothScrolling: () => this.isSmoothScrolling(),\n      isGated: (documentId?: string) => this.isGated(documentId),\n      hasGate: (key: string, documentId?: string) => this.hasGate(key, documentId),\n      getGates: (documentId?: string) => this.getGates(documentId),\n\n      // Document-scoped operations\n      forDocument: (documentId: string) => this.createViewportScope(documentId),\n      gate: (key: string, documentId: string) => this.gate(key, documentId),\n      releaseGate: (key: string, documentId: string) => this.releaseGate(key, documentId),\n\n      // Check if viewport is currently mounted\n      isViewportMounted: (documentId: string) => this.state.activeViewports.has(documentId),\n\n      // Events\n      onViewportChange: this.viewportMetrics$.on,\n      onViewportResize: this.viewportResize$.on,\n      onScrollChange: this.scrollMetrics$.on,\n      onScrollActivity: this.scrollActivity$.on,\n      onGateChange: this.gateState$.on,\n    };\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Document Scoping\n  // ─────────────────────────────────────────────────────────\n\n  private createViewportScope(documentId: string): ViewportScope {\n    return {\n      getMetrics: () => this.getMetrics(documentId),\n      scrollTo: (pos: ScrollToPayload) => this.scrollTo(pos, documentId),\n      isScrolling: () => this.isScrolling(documentId),\n      isSmoothScrolling: () => this.isSmoothScrolling(documentId),\n      isGated: () => this.isGated(documentId),\n      hasGate: (key: string) => this.hasGate(key, documentId),\n      getGates: () => this.getGates(documentId),\n      gate: (key: string) => this.gate(key, documentId),\n      releaseGate: (key: string) => this.releaseGate(key, documentId),\n      onViewportChange: (listener: Listener<ViewportMetrics>) =>\n        this.viewportMetrics$.on((event) => {\n          if (event.documentId === documentId) listener(event.metrics);\n        }),\n      onScrollChange: (listener: Listener<ViewportScrollMetrics>) =>\n        this.scrollMetrics$.on((event) => {\n          if (event.documentId === documentId) listener(event.scrollMetrics);\n        }),\n      onScrollActivity: (listener: Listener<ScrollActivity>) =>\n        this.scrollActivity$.on((event) => {\n          if (event.documentId === documentId) listener(event.activity);\n        }),\n      onGateChange: (listener: Listener<GateChangeEvent>) =>\n        this.gateState$.on((event) => {\n          if (event?.documentId === documentId) listener(event);\n        }),\n    };\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Viewport Registration (Public API for components)\n  // ─────────────────────────────────────────────────────────\n\n  public registerViewport(documentId: string): void {\n    // Check if state exists (document must be opened first)\n    if (!this.state.documents[documentId]) {\n      throw new Error(\n        `Cannot register viewport for ${documentId}: document state not found. ` +\n          `Document must be opened before registering viewport.`,\n      );\n    }\n\n    // Mark as active/mounted\n    if (!this.state.activeViewports.has(documentId)) {\n      this.dispatch(registerViewport(documentId));\n\n      this.logger.debug(\n        'ViewportPlugin',\n        'RegisterViewport',\n        `Registered viewport (DOM mounted) for document: ${documentId}`,\n      );\n    }\n  }\n\n  public unregisterViewport(documentId: string): void {\n    if (this.registry.isDestroyed()) return;\n\n    // Mark as inactive/unmounted (but preserve state!)\n    if (this.state.activeViewports.has(documentId)) {\n      this.dispatch(unregisterViewport(documentId));\n\n      this.logger.debug(\n        'ViewportPlugin',\n        'UnregisterViewport',\n        `Unregistered viewport (DOM unmounted) for document: ${documentId}. State preserved.`,\n      );\n    }\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Per-Document Operations\n  // ─────────────────────────────────────────────────────────\n\n  public setViewportResizeMetrics(documentId: string, metrics: ViewportInputMetrics): void {\n    /**\n     * Guard against late ResizeObserver/scroll callbacks during teardown.\n     * On unmount the Registry may be destroyed before pending browser callbacks\n     * run—short-circuit so we don’t dispatch into a torn-down store.\n     */\n    if (this.registry.isDestroyed()) return;\n\n    this.dispatch(setViewportMetrics(documentId, metrics));\n\n    const viewport = this.state.documents[documentId];\n    if (viewport) {\n      this.viewportResize$.emit({\n        documentId,\n        metrics: viewport.viewportMetrics,\n      });\n    }\n  }\n\n  public setViewportScrollMetrics(documentId: string, scrollMetrics: ViewportScrollMetrics): void {\n    /**\n     * Guard against late ResizeObserver/scroll callbacks during teardown.\n     * On unmount the Registry may be destroyed before pending browser callbacks\n     * run—short-circuit so we don’t dispatch into a torn-down store.\n     */\n    if (this.registry.isDestroyed()) return;\n\n    const viewport = this.state.documents[documentId];\n    if (!viewport) return;\n\n    if (\n      scrollMetrics.scrollTop !== viewport.viewportMetrics.scrollTop ||\n      scrollMetrics.scrollLeft !== viewport.viewportMetrics.scrollLeft\n    ) {\n      this.dispatch(setViewportScrollMetrics(documentId, scrollMetrics));\n      this.bumpScrollActivity(documentId);\n\n      this.scrollMetrics$.emit({\n        documentId,\n        scrollMetrics,\n      });\n    }\n  }\n\n  public onScrollRequest(documentId: string, listener: Listener<ScrollToPayload>) {\n    const emitter = this.scrollRequests$.get(documentId);\n    if (!emitter) {\n      throw new Error(\n        `Cannot subscribe to scroll requests for ${documentId}: ` +\n          `document state not initialized`,\n      );\n    }\n    return emitter.on(listener);\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Public Gating API\n  // ─────────────────────────────────────────────────────────\n\n  public gate(key: string, documentId: string): void {\n    const viewport = this.state.documents[documentId];\n    if (!viewport) {\n      this.logger.warn(\n        'ViewportPlugin',\n        'GateViewport',\n        `Cannot gate viewport for ${documentId}: document not found`,\n      );\n      return;\n    }\n\n    // Only dispatch if gate doesn't already exist\n    if (!viewport.gates.has(key)) {\n      this.dispatch(addViewportGate(documentId, key));\n      this.logger.debug(\n        'ViewportPlugin',\n        'GateAdded',\n        `Added gate '${key}' for document: ${documentId}. Total gates: ${viewport.gates.size + 1}`,\n      );\n    }\n  }\n\n  public releaseGate(key: string, documentId: string): void {\n    const viewport = this.state.documents[documentId];\n    if (!viewport) {\n      this.logger.warn(\n        'ViewportPlugin',\n        'ReleaseGate',\n        `Cannot release gate for ${documentId}: document not found`,\n      );\n      return;\n    }\n\n    // Only dispatch if gate exists\n    if (viewport.gates.has(key)) {\n      this.dispatch(removeViewportGate(documentId, key));\n      this.logger.debug(\n        'ViewportPlugin',\n        'GateReleased',\n        `Released gate '${key}' for document: ${documentId}. Remaining gates: ${viewport.gates.size - 1}`,\n      );\n    }\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Helper Methods\n  // ─────────────────────────────────────────────────────────\n\n  private getViewportState(documentId?: string) {\n    const id = documentId ?? this.getActiveDocumentId();\n    const viewport = this.state.documents[id];\n    if (!viewport) {\n      throw new Error(`Viewport state not found for document: ${id}`);\n    }\n    return viewport;\n  }\n\n  private getMetrics(documentId?: string): ViewportMetrics {\n    return this.getViewportState(documentId).viewportMetrics;\n  }\n\n  private isScrolling(documentId?: string): boolean {\n    return this.getViewportState(documentId).isScrolling;\n  }\n\n  private isSmoothScrolling(documentId?: string): boolean {\n    return this.getViewportState(documentId).isSmoothScrolling;\n  }\n\n  private isGated(documentId?: string): boolean {\n    const viewport = this.getViewportState(documentId);\n    return viewport.gates.size > 0;\n  }\n\n  private hasGate(key: string, documentId?: string): boolean {\n    const viewport = this.getViewportState(documentId);\n    return viewport.gates.has(key);\n  }\n\n  private getGates(documentId?: string): string[] {\n    const viewport = this.getViewportState(documentId);\n    return Array.from(viewport.gates);\n  }\n\n  private scrollTo(pos: ScrollToPayload, documentId?: string): void {\n    const id = documentId ?? this.getActiveDocumentId();\n    const viewport = this.getViewportState(id);\n    const { x, y, alignX, alignY, behavior = 'auto' } = pos;\n\n    if (behavior === 'smooth') {\n      this.dispatch(setSmoothScrollActivity(id, true));\n    }\n\n    const metrics = viewport.viewportMetrics;\n    let finalX = x;\n    let finalY = y;\n\n    // Handle percentage-based alignment (0-100)\n    // alignX/alignY take precedence over deprecated center\n    if (alignX !== undefined) {\n      finalX = x - metrics.clientWidth * (alignX / 100);\n    }\n\n    if (alignY !== undefined) {\n      finalY = y - metrics.clientHeight * (alignY / 100);\n    }\n\n    const emitter = this.scrollRequests$.get(id);\n    if (emitter) {\n      emitter.emit({ x: finalX, y: finalY, behavior });\n    }\n  }\n\n  private bumpScrollActivity(documentId: string): void {\n    this.debouncedDispatch(setScrollActivity(documentId, false), this.scrollEndDelay);\n    this.debouncedDispatch(setSmoothScrollActivity(documentId, false), this.scrollEndDelay);\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // State Change Handling\n  // ─────────────────────────────────────────────────────────\n\n  override onStoreUpdated(prevState: ViewportState, newState: ViewportState): void {\n    // Emit viewport change events for each changed document\n    for (const documentId in newState.documents) {\n      const prevViewport = prevState.documents[documentId];\n      const newViewport = newState.documents[documentId];\n\n      if (prevViewport !== newViewport) {\n        this.viewportMetrics$.emit({\n          documentId,\n          metrics: newViewport.viewportMetrics,\n        });\n\n        // Emit scroll activity when scrolling state changes\n        if (\n          prevViewport &&\n          (prevViewport.isScrolling !== newViewport.isScrolling ||\n            prevViewport.isSmoothScrolling !== newViewport.isSmoothScrolling)\n        ) {\n          this.scrollActivity$.emit({\n            documentId,\n            activity: {\n              isScrolling: newViewport.isScrolling,\n              isSmoothScrolling: newViewport.isSmoothScrolling,\n            },\n          });\n        }\n\n        // Emit gate state change when gates change\n        if (prevViewport && prevViewport.gates !== newViewport.gates) {\n          const prevGates = Array.from(prevViewport.gates);\n          const newGates = Array.from(newViewport.gates);\n\n          // Determine what changed\n          const addedGate = newGates.find((g) => !prevGates.includes(g));\n          const removedGate = prevGates.find((g) => !newGates.includes(g));\n\n          this.gateState$.emit({\n            documentId,\n            isGated: newViewport.gates.size > 0,\n            gates: newGates,\n            addedGate,\n            removedGate,\n          });\n\n          this.logger.debug(\n            'ViewportPlugin',\n            'GateStateChanged',\n            `Gate state changed for document ${documentId}. ` +\n              `Gates: [${newGates.join(', ')}], Gated: ${newViewport.gates.size > 0}`,\n          );\n        }\n      }\n    }\n  }\n\n  // ─────────────────────────────────────────────────────────\n  // Lifecycle\n  // ─────────────────────────────────────────────────────────\n\n  async initialize(_config: ViewportPluginConfig) {\n    this.logger.info('ViewportPlugin', 'Initialize', 'Viewport plugin initialized');\n  }\n\n  async destroy(): Promise<void> {\n    // Clear all emitters\n    this.viewportMetrics$.clear();\n    this.viewportResize$.clear();\n    this.scrollMetrics$.clear();\n    this.scrollActivity$.clear();\n    this.gateState$.clear();\n\n    this.scrollRequests$.forEach((emitter) => emitter.clear());\n    this.scrollRequests$.clear();\n\n    super.destroy();\n  }\n}\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { ViewportAction } from './actions';\nimport { manifest, VIEWPORT_PLUGIN_ID } from './manifest';\nimport { viewportReducer, initialState } from './reducer';\nimport { ViewportPluginConfig, ViewportState } from './types';\nimport { ViewportPlugin } from './viewport-plugin';\n\nexport const ViewportPluginPackage: PluginPackage<\n  ViewportPlugin,\n  ViewportPluginConfig,\n  ViewportState,\n  ViewportAction\n> = {\n  manifest,\n  create: (registry, config) => new ViewportPlugin(VIEWPORT_PLUGIN_ID, registry, config),\n  reducer: viewportReducer,\n  initialState: initialState,\n};\n\nexport * from './viewport-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["VIEWPORT_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","viewportGap","scrollEndDelay","INIT_VIEWPORT_STATE","CLEANUP_VIEWPORT_STATE","REGISTER_VIEWPORT","UNREGISTER_VIEWPORT","SET_VIEWPORT_METRICS","SET_VIEWPORT_SCROLL_METRICS","SET_VIEWPORT_GAP","SET_SCROLL_ACTIVITY","SET_SMOOTH_SCROLL_ACTIVITY","ADD_VIEWPORT_GATE","REMOVE_VIEWPORT_GATE","setSmoothScrollActivity","documentId","isSmoothScrolling","type","payload","initialViewportDocumentState","viewportMetrics","width","height","scrollTop","scrollLeft","clientWidth","clientHeight","scrollWidth","scrollHeight","clientLeft","clientTop","relativePosition","x","y","isScrolling","gates","Set","initialState","documents","activeViewports","activeDocumentId","_ViewportPlugin","BasePlugin","constructor","registry","config","super","this","viewportResize$","createBehaviorEmitter","viewportMetrics$","scrollMetrics$","scrollActivity$","gateState$","scrollRequests$","Map","dispatch","onDocumentLoadingStarted","initViewportState","set","createEmitter","logger","debug","onDocumentClosed","cleanupViewportState","_a","get","clear","delete","buildCapability","getViewportGap","state","getMetrics","scrollTo","pos","isGated","hasGate","key","getGates","forDocument","createViewportScope","gate","releaseGate","isViewportMounted","has","onViewportChange","on","onViewportResize","onScrollChange","onScrollActivity","onGateChange","listener","event","metrics","scrollMetrics","activity","registerViewport","Error","unregisterViewport","isDestroyed","setViewportResizeMetrics","setViewportMetrics","viewport","emit","setViewportScrollMetrics","bumpScrollActivity","onScrollRequest","emitter","addViewportGate","size","warn","removeViewportGate","getViewportState","getActiveDocumentId","Array","from","alignX","alignY","behavior","finalX","finalY","debouncedDispatch","setScrollActivity","onStoreUpdated","prevState","newState","prevViewport","newViewport","prevGates","newGates","addedGate","find","g","includes","removedGate","join","initialize","_config","info","destroy","forEach","ViewportPlugin","ViewportPluginPackage","create","reducer","action","removed","remainingDocs","newActiveViewports","add"],"mappings":"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"}