{"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-zoom.svelte.ts","../../src/shared/utils/zoom-gesture-logic.ts","../../src/svelte/hooks/use-zoom-gesture.svelte.ts","../../src/svelte/components/MarqueeZoom.svelte","../../src/svelte/components/ZoomGestureWrapper.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport {\n  initialDocumentState,\n  ZoomDocumentState,\n  ZoomPlugin,\n  ZoomScope,\n} from '@embedpdf/plugin-zoom';\n\nexport const useZoomCapability = () => useCapability<ZoomPlugin>(ZoomPlugin.id);\nexport const useZoomPlugin = () => usePlugin<ZoomPlugin>(ZoomPlugin.id);\n\n// Define the return type explicitly to maintain type safety\ninterface UseZoomReturn {\n  provides: ZoomScope | null;\n  state: ZoomDocumentState;\n}\n\n/**\n * Hook for zoom state for a specific document\n * @param getDocumentId Function that returns the document ID\n */\nexport const useZoom = (getDocumentId: () => string | null): UseZoomReturn => {\n  const capability = useZoomCapability();\n\n  let state = $state<ZoomDocumentState>(initialDocumentState);\n\n  // Reactive documentId\n  const documentId = $derived(getDocumentId());\n\n  // Scoped capability for current docId\n  const scopedProvides = $derived(\n    capability.provides && documentId ? capability.provides.forDocument(documentId) : null,\n  );\n\n  $effect(() => {\n    const provides = capability.provides;\n    const docId = documentId;\n\n    if (!provides || !docId) {\n      state = initialDocumentState;\n      return;\n    }\n\n    const scope = provides.forDocument(docId);\n\n    // Get initial state\n    state = scope.getState();\n\n    // Subscribe to state changes for this document\n    return scope.onStateChange((newState) => {\n      state = newState;\n    });\n  });\n\n  return {\n    get provides() {\n      return scopedProvides;\n    },\n    get state() {\n      return state;\n    },\n  };\n};\n","import type { ZoomCapability } from '@embedpdf/plugin-zoom';\n\nexport interface ZoomGestureOptions {\n  /** Enable pinch-to-zoom gesture (default: true) */\n  enablePinch?: boolean;\n  /** Enable wheel zoom with ctrl/cmd key (default: true) */\n  enableWheel?: boolean;\n}\n\nexport interface ZoomGestureDeps {\n  element: HTMLDivElement;\n  /** Viewport container element for attaching events */\n  container: HTMLElement;\n  documentId: string;\n  zoomProvides: ZoomCapability;\n  /** Viewport gap in pixels (default: 0) */\n  viewportGap?: number;\n  options?: ZoomGestureOptions;\n}\n\nfunction getTouchDistance(touches: TouchList): number {\n  const [t1, t2] = [touches[0], touches[1]];\n  const dx = t2.clientX - t1.clientX;\n  const dy = t2.clientY - t1.clientY;\n  return Math.hypot(dx, dy);\n}\n\nfunction getTouchCenter(touches: TouchList): { x: number; y: number } {\n  const [t1, t2] = [touches[0], touches[1]];\n  return {\n    x: (t1.clientX + t2.clientX) / 2,\n    y: (t1.clientY + t2.clientY) / 2,\n  };\n}\n\nexport function setupZoomGestures({\n  element,\n  container,\n  documentId,\n  zoomProvides,\n  viewportGap = 0,\n  options = {},\n}: ZoomGestureDeps) {\n  const { enablePinch = true, enableWheel = true } = options;\n  if (typeof window === 'undefined') {\n    return () => {};\n  }\n\n  const zoomScope = zoomProvides.forDocument(documentId);\n  const getState = () => zoomScope.getState();\n\n  // Shared state\n  let initialZoom = 0;\n  let currentScale = 1;\n  let isPinching = false;\n  let initialDistance = 0;\n\n  // Wheel state\n  let wheelZoomTimeout: ReturnType<typeof setTimeout> | null = null;\n  let accumulatedWheelScale = 1;\n\n  // Gesture state\n  let initialElementWidth = 0;\n  let initialElementHeight = 0;\n  let initialElementLeft = 0;\n  let initialElementTop = 0;\n\n  // Container Dimensions (Bounding Box)\n  let containerRectWidth = 0;\n  let containerRectHeight = 0;\n\n  // Layout Dimensions (Client Box from Metrics)\n  let layoutWidth = 0;\n  let layoutCenterX = 0;\n\n  let pointerLocalY = 0;\n  let pointerContainerX = 0;\n  let pointerContainerY = 0;\n\n  let currentGap = 0;\n  let pivotLocalX = 0;\n\n  const clamp = (val: number, min: number, max: number) => Math.min(Math.max(val, min), max);\n\n  // --- Margin calculation ---\n  const updateMargin = () => {\n    const availableWidth = container.clientWidth - 2 * viewportGap;\n    const elementWidth = element.offsetWidth;\n\n    const newMargin = elementWidth < availableWidth ? (availableWidth - elementWidth) / 2 : 0;\n    element.style.marginLeft = `${newMargin}px`;\n  };\n\n  const calculateTransform = (scale: number) => {\n    const finalWidth = initialElementWidth * scale;\n    const finalHeight = initialElementHeight * scale;\n\n    let ty = pointerLocalY * (1 - scale);\n\n    const targetX = layoutCenterX - finalWidth / 2;\n    const txCenter = targetX - initialElementLeft;\n    const txMouse = pointerContainerX - pivotLocalX * scale - initialElementLeft;\n\n    const overflow = Math.max(0, finalWidth - layoutWidth);\n    const blendRange = layoutWidth * 0.3;\n    const blend = Math.min(1, overflow / blendRange);\n\n    let tx = txCenter + (txMouse - txCenter) * blend;\n\n    const safeHeight = containerRectHeight - currentGap * 2;\n    if (finalHeight > safeHeight) {\n      const currentTop = initialElementTop + ty;\n      const maxTop = currentGap;\n      const minTop = containerRectHeight - currentGap - finalHeight;\n      const constrainedTop = clamp(currentTop, minTop, maxTop);\n      ty = constrainedTop - initialElementTop;\n    }\n\n    const safeWidth = containerRectWidth - currentGap * 2;\n    if (finalWidth > safeWidth) {\n      const currentLeft = initialElementLeft + tx;\n      const maxLeft = currentGap;\n      const minLeft = containerRectWidth - currentGap - finalWidth;\n      const constrainedLeft = clamp(currentLeft, minLeft, maxLeft);\n      tx = constrainedLeft - initialElementLeft;\n    }\n\n    return { tx, ty, blend, finalWidth };\n  };\n\n  const updateTransform = (scale: number) => {\n    currentScale = scale;\n    const { tx, ty } = calculateTransform(scale);\n    element.style.transformOrigin = '0 0';\n    element.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;\n  };\n\n  const resetTransform = () => {\n    element.style.transform = 'none';\n    element.style.transformOrigin = '0 0';\n    currentScale = 1;\n  };\n\n  const commitZoom = () => {\n    const { tx, finalWidth } = calculateTransform(currentScale);\n    const delta = (currentScale - 1) * initialZoom;\n\n    let anchorX: number;\n    let anchorY: number = pointerContainerY;\n\n    if (finalWidth <= layoutWidth) {\n      anchorX = layoutCenterX;\n    } else {\n      const scaleDiff = 1 - currentScale;\n      anchorX =\n        Math.abs(scaleDiff) > 0.001 ? initialElementLeft + tx / scaleDiff : pointerContainerX;\n    }\n\n    zoomScope.requestZoomBy(delta, { vx: anchorX, vy: anchorY });\n    resetTransform();\n    initialZoom = 0;\n  };\n\n  const initializeGestureState = (clientX: number, clientY: number) => {\n    const containerRect = container.getBoundingClientRect();\n    const innerRect = element.getBoundingClientRect();\n\n    currentGap = viewportGap;\n    initialElementWidth = innerRect.width;\n    initialElementHeight = innerRect.height;\n    initialElementLeft = innerRect.left - containerRect.left;\n    initialElementTop = innerRect.top - containerRect.top;\n\n    containerRectWidth = containerRect.width;\n    containerRectHeight = containerRect.height;\n\n    // Layout dimensions from container's client area\n    layoutWidth = container.clientWidth;\n    layoutCenterX = container.clientLeft + layoutWidth / 2;\n\n    const rawPointerLocalX = clientX - innerRect.left;\n    pointerLocalY = clientY - innerRect.top;\n    pointerContainerX = clientX - containerRect.left;\n    pointerContainerY = clientY - containerRect.top;\n\n    if (initialElementWidth < layoutWidth) {\n      pivotLocalX = (pointerContainerX * initialElementWidth) / layoutWidth;\n    } else {\n      pivotLocalX = rawPointerLocalX;\n    }\n  };\n\n  // --- Handlers ---\n  const handleTouchStart = (e: TouchEvent) => {\n    if (e.touches.length !== 2) return;\n    isPinching = true;\n    initialZoom = getState().currentZoomLevel;\n    initialDistance = getTouchDistance(e.touches);\n    const center = getTouchCenter(e.touches);\n    initializeGestureState(center.x, center.y);\n    e.preventDefault();\n  };\n\n  const handleTouchMove = (e: TouchEvent) => {\n    if (!isPinching || e.touches.length !== 2) return;\n    const currentDistance = getTouchDistance(e.touches);\n    const scale = currentDistance / initialDistance;\n    updateTransform(scale);\n    e.preventDefault();\n  };\n\n  const handleTouchEnd = (e: TouchEvent) => {\n    if (!isPinching) return;\n    if (e.touches.length >= 2) return;\n    isPinching = false;\n    commitZoom();\n  };\n\n  const handleWheel = (e: WheelEvent) => {\n    if (!e.ctrlKey && !e.metaKey) return;\n    e.preventDefault();\n\n    if (wheelZoomTimeout === null) {\n      initialZoom = getState().currentZoomLevel;\n      accumulatedWheelScale = 1;\n      initializeGestureState(e.clientX, e.clientY);\n    } else {\n      clearTimeout(wheelZoomTimeout);\n    }\n\n    const zoomFactor = 1 - e.deltaY * 0.01;\n    accumulatedWheelScale *= zoomFactor;\n    accumulatedWheelScale = Math.max(0.1, Math.min(10, accumulatedWheelScale));\n    updateTransform(accumulatedWheelScale);\n\n    wheelZoomTimeout = setTimeout(() => {\n      wheelZoomTimeout = null;\n      commitZoom();\n      accumulatedWheelScale = 1;\n    }, 150);\n  };\n\n  // Subscribe to zoom changes to update margin\n  const unsubZoom = zoomScope.onStateChange(() => updateMargin());\n\n  // Use ResizeObserver to update margin when element or container size changes\n  const resizeObserver = new ResizeObserver(() => updateMargin());\n  resizeObserver.observe(element);\n  resizeObserver.observe(container);\n\n  // Initial margin calculation\n  updateMargin();\n\n  // Attach events to the viewport container for better UX\n  // (gestures work anywhere in viewport, not just on the PDF)\n  if (enablePinch) {\n    container.addEventListener('touchstart', handleTouchStart, { passive: false });\n    container.addEventListener('touchmove', handleTouchMove, { passive: false });\n    container.addEventListener('touchend', handleTouchEnd);\n    container.addEventListener('touchcancel', handleTouchEnd);\n  }\n  if (enableWheel) {\n    container.addEventListener('wheel', handleWheel, { passive: false });\n  }\n\n  return () => {\n    if (enablePinch) {\n      container.removeEventListener('touchstart', handleTouchStart);\n      container.removeEventListener('touchmove', handleTouchMove);\n      container.removeEventListener('touchend', handleTouchEnd);\n      container.removeEventListener('touchcancel', handleTouchEnd);\n    }\n    if (enableWheel) {\n      container.removeEventListener('wheel', handleWheel);\n    }\n    if (wheelZoomTimeout) {\n      clearTimeout(wheelZoomTimeout);\n    }\n    unsubZoom();\n    resizeObserver.disconnect();\n    resetTransform();\n    element.style.marginLeft = '';\n  };\n}\n","import { getContext } from 'svelte';\nimport { useCapability } from '@embedpdf/core/svelte';\nimport type { ViewportPlugin } from '@embedpdf/plugin-viewport';\nimport { setupZoomGestures, type ZoomGestureOptions } from '../../shared/utils/zoom-gesture-logic';\nimport { useZoomCapability } from './use-zoom.svelte';\n\nexport type { ZoomGestureOptions };\n\n/** Context type for viewport element */\ntype ViewportElementContext = { readonly current: HTMLDivElement | null };\n\nexport interface UseZoomGestureOptions {\n  /** Enable pinch-to-zoom gesture (default: true) */\n  enablePinch?: () => boolean;\n  /** Enable wheel zoom with ctrl/cmd key (default: true) */\n  enableWheel?: () => boolean;\n}\n\n/**\n * Hook for setting up zoom gesture functionality (pinch and wheel zoom) on an element\n * @param getDocumentId Function that returns the document ID\n * @param options Optional configuration for enabling/disabling gestures\n */\nexport function useZoomGesture(\n  getDocumentId: () => string | null,\n  options: UseZoomGestureOptions = {},\n) {\n  const viewportCapability = useCapability<ViewportPlugin>('viewport');\n  const zoomCapability = useZoomCapability();\n  const viewportElementCtx = getContext<ViewportElementContext | undefined>('viewport-element');\n\n  let elementRef = $state<HTMLDivElement | null>(null);\n  let cleanup: (() => void) | undefined;\n\n  // Reactive documentId and options\n  const documentId = $derived(getDocumentId());\n  const enablePinch = $derived(options.enablePinch?.() ?? true);\n  const enableWheel = $derived(options.enableWheel?.() ?? true);\n\n  $effect(() => {\n    const element = elementRef;\n    const container = viewportElementCtx?.current;\n    const viewport = viewportCapability.provides;\n    const zoom = zoomCapability.provides;\n    const docId = documentId;\n    const pinchEnabled = enablePinch;\n    const wheelEnabled = enableWheel;\n\n    // Clean up previous setup\n    if (cleanup) {\n      cleanup();\n      cleanup = undefined;\n    }\n\n    // Setup new zoom gestures if all dependencies are available\n    if (!element || !container || !zoom || !docId) {\n      return;\n    }\n\n    cleanup = setupZoomGestures({\n      element,\n      container,\n      documentId: docId,\n      zoomProvides: zoom,\n      viewportGap: viewport?.getViewportGap() || 0,\n      options: { enablePinch: pinchEnabled, enableWheel: wheelEnabled },\n    });\n\n    return () => {\n      if (cleanup) {\n        cleanup();\n        cleanup = undefined;\n      }\n    };\n  });\n\n  return {\n    get elementRef() {\n      return elementRef;\n    },\n    set elementRef(value: HTMLDivElement | null) {\n      elementRef = value;\n    },\n  };\n}\n","<script lang=\"ts\">\n  import type { Rect } from '@embedpdf/models';\n  import { useDocumentState } from '@embedpdf/core/svelte';\n  import { useZoomCapability } from '../hooks/use-zoom.svelte';\n\n  interface MarqueeZoomProps {\n    /** The ID of the document */\n    documentId: string;\n    /** Index of the page this layer lives on */\n    pageIndex: number;\n    /** Scale of the page */\n    scale?: number;\n    /** Optional CSS class applied to the marquee rectangle */\n    class?: string;\n    /** Stroke / fill colours (defaults below) */\n    stroke?: string;\n    fill?: string;\n  }\n\n  let {\n    documentId,\n    pageIndex,\n    scale: scaleOverride,\n    class: propsClass,\n    stroke = 'rgba(33,150,243,0.8)',\n    fill = 'rgba(33,150,243,0.15)',\n  }: MarqueeZoomProps = $props();\n\n  const zoomCapability = useZoomCapability();\n  const documentState = useDocumentState(() => documentId);\n\n  let rect = $state<Rect | null>(null);\n\n  const actualScale = $derived(\n    scaleOverride !== undefined ? scaleOverride : (documentState.current?.scale ?? 1),\n  );\n\n  $effect(() => {\n    rect = null;\n\n    if (!zoomCapability.provides) {\n      return;\n    }\n\n    return zoomCapability.provides.registerMarqueeOnPage({\n      documentId,\n      pageIndex,\n      scale: actualScale,\n      callback: {\n        onPreview: (newRect) => {\n          rect = newRect;\n        },\n      },\n    });\n  });\n</script>\n\n{#if rect}\n  <div\n    style:position=\"absolute\"\n    style:pointer-events=\"none\"\n    style:left={`${rect.origin.x * actualScale}px`}\n    style:top={`${rect.origin.y * actualScale}px`}\n    style:width={`${rect.size.width * actualScale}px`}\n    style:height={`${rect.size.height * actualScale}px`}\n    style:border={`1px solid ${stroke}`}\n    style:background={fill}\n    style:box-sizing=\"border-box\"\n    class={propsClass}\n  ></div>\n{/if}\n","<script lang=\"ts\">\n  import { useZoomGesture } from '../hooks';\n  import type { Snippet } from 'svelte';\n  import type { HTMLAttributes } from 'svelte/elements';\n\n  type ZoomGestureWrapperProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n    documentId: string;\n    children: Snippet;\n    class?: string;\n    /** Enable pinch-to-zoom gesture (default: true) */\n    enablePinch?: boolean;\n    /** Enable wheel zoom with ctrl/cmd key (default: true) */\n    enableWheel?: boolean;\n  };\n\n  let {\n    documentId,\n    children,\n    class: propsClass,\n    enablePinch = true,\n    enableWheel = true,\n    ...restProps\n  }: ZoomGestureWrapperProps = $props();\n\n  const zoomGesture = useZoomGesture(() => documentId, {\n    enablePinch: () => enablePinch,\n    enableWheel: () => enableWheel,\n  });\n</script>\n\n<div\n  bind:this={zoomGesture.elementRef}\n  {...restProps}\n  style:display=\"inline-block\"\n  style:overflow=\"visible\"\n  style:box-sizing=\"border-box\"\n  class={propsClass}\n>\n  {@render children()}\n</div>\n"],"names":["useZoomCapability","useCapability","ZoomPlugin","id","getTouchDistance","touches","t1","t2","dx","clientX","dy","clientY","Math","hypot","useZoomGesture","getDocumentId","options","viewportCapability","zoomCapability","viewportElementCtx","getContext","cleanup","elementRef","$","state","documentId","enablePinch","derived","_a","call","enableWheel","user_effect","element","container","current","viewport","provides","zoom","docId","pinchEnabled","wheelEnabled","zoomProvides","viewportGap","window","zoomScope","forDocument","getState","initialZoom","currentScale","isPinching","initialDistance","wheelZoomTimeout","accumulatedWheelScale","initialElementWidth","initialElementHeight","initialElementLeft","initialElementTop","containerRectWidth","containerRectHeight","layoutWidth","layoutCenterX","pointerLocalY","pointerContainerX","pointerContainerY","currentGap","pivotLocalX","clamp","val","min","max","updateMargin","availableWidth","clientWidth","elementWidth","offsetWidth","newMargin","style","marginLeft","calculateTransform","scale","finalWidth","finalHeight","ty","txCenter","txMouse","overflow","blendRange","blend","tx","updateTransform","transformOrigin","transform","resetTransform","commitZoom","delta","anchorX","anchorY","scaleDiff","abs","requestZoomBy","vx","vy","initializeGestureState","containerRect","getBoundingClientRect","innerRect","width","height","left","top","clientLeft","rawPointerLocalX","handleTouchStart","e","length","currentZoomLevel","center","x","y","getTouchCenter","preventDefault","handleTouchMove","currentDistance","handleTouchEnd","handleWheel","ctrlKey","metaKey","clearTimeout","zoomFactor","deltaY","setTimeout","unsubZoom","onStateChange","resizeObserver","ResizeObserver","observe","addEventListener","passive","removeEventListener","disconnect","setupZoomGestures","getViewportGap","value","set","stroke","fill","documentState","useDocumentState","$$props","rect","actualScale","registerMarqueeOnPage","pageIndex","callback","onPreview","newRect","div","root_1","clsx","class","styles","get","origin","size","consequent","restProps","$$rest_props_compat","zoomGesture","root","bind_this","$$value","capability","initialDocumentState","scopedProvides","scope","newState","usePlugin"],"mappings":"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"}