{"version":3,"file":"GeoGebra-mtrUCuDl.cjs","sources":["../app/components/geogebra/GeoGebra.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ndeclare global {\n  interface Window {\n    GGBApplet?: new (\n      params: Readonly<{\n        appName: GeoGebraAppName;\n        showToolBar: boolean;\n        showAlgebraInput: boolean;\n        showMenuBar: boolean;\n        enableRightClick: boolean;\n        enableShiftDragZoom: boolean;\n        useBrowserForJS: boolean;\n        scaleContainerClass: string;\n        width: number;\n        height: number;\n      }>,\n      version: string\n    ) => { inject: (container: HTMLElement) => void };\n    ggbApplet?: {\n      setSize?: (w: number, h: number) => void;\n      zoomIn?: () => void;\n      zoomOut?: () => void;\n      setStandardView?: () => void;\n      reset?: () => void;\n    } | null;\n  }\n}\n\ntype GeoGebraAppName = \"geometry\" | \"graphing\" | \"3d\" | \"cas\" | \"suite\";\n\nconst GEO_GEBRA_SCRIPT_SRC = \"https://www.geogebra.org/apps/deployggb.js\";\n\nlet geogebraLoaderPromise: Promise<void> | null = null;\n\nfunction loadGeoGebraScript(): Promise<void> {\n  if (typeof window === \"undefined\") return Promise.resolve();\n  if (window.GGBApplet) return Promise.resolve();\n  if (geogebraLoaderPromise) return geogebraLoaderPromise;\n  geogebraLoaderPromise = new Promise<void>((resolve, reject) => {\n    const script = document.createElement(\"script\");\n    script.src = GEO_GEBRA_SCRIPT_SRC;\n    script.async = true;\n    script.onload = () => resolve();\n    script.onerror = () => reject(new Error(\"Failed to load GeoGebra script\"));\n    document.head.appendChild(script);\n  });\n  return geogebraLoaderPromise;\n}\n\nexport default function GeoGebra() {\n  const wrapperRef = useRef<HTMLDivElement | null>(null);\n  const appletRef = useRef<HTMLDivElement | null>(null);\n  const [appName, setAppName] = useState<GeoGebraAppName>(\"geometry\");\n  const [isReady, setIsReady] = useState(false);\n  const [error, setError] = useState<string | null>(null);\n  const [showToolBar, setShowToolBar] = useState(true);\n  const [showAlgebraInput] = useState(true);\n  const reinjectTimerRef = useRef<number | null>(null);\n  const rafRef = useRef<number | null>(null);\n  const lastSizeRef = useRef<{ w: number; h: number } | null>(null);\n\n  // Load initial preferences from localStorage\n  useEffect(() => {\n    try {\n      const raw = localStorage.getItem(\"ggb:prefs\");\n      if (raw) {\n        const prefs = JSON.parse(raw) as {\n          appName?: GeoGebraAppName;\n          showToolBar?: boolean;\n        };\n        if (prefs.appName) setAppName(prefs.appName);\n        if (typeof prefs.showToolBar === \"boolean\")\n          setShowToolBar(prefs.showToolBar);\n      }\n    } catch {}\n  }, []);\n\n  // Persist preferences\n  useEffect(() => {\n    try {\n      localStorage.setItem(\n        \"ggb:prefs\",\n        JSON.stringify({ appName, showToolBar })\n      );\n    } catch {}\n  }, [appName, showToolBar]);\n\n  const inject = useCallback(async () => {\n    if (!wrapperRef.current || !appletRef.current) return;\n    setIsReady(false);\n    setError(null);\n    await loadGeoGebraScript();\n    if (!window.GGBApplet) return;\n\n    const node = appletRef.current;\n    // Clear any previous instance markup\n    node.innerHTML = \"\";\n\n    const width = wrapperRef.current.clientWidth || 800;\n    const height = wrapperRef.current.clientHeight || 600;\n\n    const params = {\n      appName,\n      showToolBar,\n      showAlgebraInput,\n      showMenuBar: false,\n      enableRightClick: false,\n      enableShiftDragZoom: true,\n      useBrowserForJS: false,\n      scaleContainerClass: \"ggb-scale\",\n      width,\n      height,\n    } as const;\n\n    try {\n      // Per GeoGebra docs: new GGBApplet(parameters, '5.0')\n      const Applet = window.GGBApplet;\n      const applet = new Applet(params, \"5.0\");\n      // Inject into our container\n      applet.inject(node);\n      setIsReady(true);\n    } catch (e) {\n      console.error(\"GeoGebra inject error\", e);\n      setError(\n        e instanceof Error ? e.message : \"Failed to initialize GeoGebra\"\n      );\n    }\n  }, [appName, showToolBar, showAlgebraInput]);\n\n  useEffect(() => {\n    inject();\n  }, [inject]);\n\n  // Resize handling: observe wrapper, throttle via rAF, prefer setSize; fallback to reinject\n  useEffect(() => {\n    if (!wrapperRef.current) return;\n    const node = wrapperRef.current;\n    const ro = new ResizeObserver((entries) => {\n      const entry = entries[0];\n      if (!entry) return;\n      const cr = entry.contentRect;\n      const w = Math.max(320, Math.floor(cr.width));\n      const h = Math.max(240, Math.floor(cr.height));\n      lastSizeRef.current = { w, h };\n      if (rafRef.current) cancelAnimationFrame(rafRef.current);\n      rafRef.current = requestAnimationFrame(() => {\n        try {\n          if (\n            window.ggbApplet &&\n            typeof window.ggbApplet.setSize === \"function\" &&\n            lastSizeRef.current\n          ) {\n            window.ggbApplet.setSize(\n              lastSizeRef.current.w,\n              lastSizeRef.current.h\n            );\n          } else {\n            if (reinjectTimerRef.current) {\n              clearTimeout(reinjectTimerRef.current);\n            }\n            reinjectTimerRef.current = window.setTimeout(() => {\n              inject();\n            }, 150);\n          }\n        } catch {\n          // ignore\n        }\n      });\n    });\n    ro.observe(node);\n    return () => {\n      ro.disconnect();\n      if (rafRef.current) cancelAnimationFrame(rafRef.current);\n      if (reinjectTimerRef.current) {\n        clearTimeout(reinjectTimerRef.current);\n        reinjectTimerRef.current = null;\n      }\n    };\n  }, [inject]);\n\n  // Keyboard shortcuts for quick actions (zoom/reset only)\n  useEffect(() => {\n    const onKey = (e: KeyboardEvent) => {\n      if (!window.ggbApplet) return;\n      if (e.key === \"+\" || (e.key === \"+\" && e.shiftKey)) {\n        e.preventDefault();\n        try {\n          if (\n            window.ggbApplet &&\n            typeof window.ggbApplet.zoomIn === \"function\"\n          ) {\n            window.ggbApplet.zoomIn();\n          }\n        } catch {}\n      } else if (e.key === \"-\") {\n        e.preventDefault();\n        try {\n          if (\n            window.ggbApplet &&\n            typeof window.ggbApplet.zoomOut === \"function\"\n          ) {\n            window.ggbApplet.zoomOut();\n          }\n        } catch {}\n      } else if (e.key.toLowerCase() === \"r\") {\n        e.preventDefault();\n        try {\n          if (typeof window.ggbApplet.setStandardView === \"function\") {\n            window.ggbApplet.setStandardView();\n          } else if (typeof window.ggbApplet.reset === \"function\") {\n            window.ggbApplet.reset();\n          }\n        } catch {}\n      }\n    };\n    window.addEventListener(\"keydown\", onKey);\n    return () => window.removeEventListener(\"keydown\", onKey);\n  }, []);\n\n  // Grid/Axes toggles were removed from UI; no-op hooks deleted\n\n  const options = useMemo(\n    () =>\n      [\n        { id: \"geometry\", label: \"Geometry\" },\n        { id: \"graphing\", label: \"Graphing\" },\n        { id: \"3d\", label: \"3D\" },\n        { id: \"cas\", label: \"CAS\" },\n        { id: \"suite\", label: \"Suite\" },\n      ] as Array<{ id: GeoGebraAppName; label: string }>,\n    []\n  );\n\n  return (\n    <div\n      className=\"w-full h-full flex flex-col\"\n      role=\"region\"\n      aria-label=\"GeoGebra\"\n      aria-busy={!isReady}\n    >\n      <div className=\"px-3 py-2 border-b border-[--color-border] bg-[--color-card] flex items-center gap-2 select-none\">\n        <label className=\"text-sm text-muted-foreground\" htmlFor=\"ggb-view\">\n          View\n        </label>\n        <select\n          id=\"ggb-view\"\n          className=\"text-sm rounded-md border border-[--color-border] bg-background px-2 py-1\"\n          value={appName}\n          onChange={(e) => setAppName(e.target.value as GeoGebraAppName)}\n        >\n          {options.map((o) => (\n            <option key={o.id} value={o.id}>\n              {o.label}\n            </option>\n          ))}\n        </select>\n        <div className=\"h-5 w-px bg-[--color-border] mx-1\" aria-hidden=\"true\" />\n        <label className=\"inline-flex items-center gap-1 text-sm\">\n          <input\n            type=\"checkbox\"\n            className=\"accent-[--color-accent]\"\n            checked={showToolBar}\n            onChange={(e) => setShowToolBar(e.target.checked)}\n          />\n          Toolbar\n        </label>\n        <div className=\"ml-auto text-xs text-muted-foreground\">\n          {error ? (\n            <span className=\"text-red-500\">{error}</span>\n          ) : isReady ? (\n            \"Ready\"\n          ) : (\n            \"Loading...\"\n          )}\n        </div>\n        {error && (\n          <button\n            className=\"ml-2 text-sm rounded-md border border-[--color-border] bg-background px-2 py-1\"\n            onClick={() => inject()}\n          >\n            Retry\n          </button>\n        )}\n      </div>\n      <div ref={wrapperRef} className=\"relative flex-1 min-h-0 ggb-scale\">\n        <div ref={appletRef} className=\"absolute inset-0\" />\n        {!isReady && !error && (\n          <div className=\"absolute inset-0 grid place-items-center\">\n            <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n              <div\n                className=\"h-4 w-4 rounded-full border-2 border-[--color-border] border-t-transparent animate-spin\"\n                aria-hidden=\"true\"\n              />\n              Loading GeoGebra...\n            </div>\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n"],"names":["GEO_GEBRA_SCRIPT_SRC","geogebraLoaderPromise","loadGeoGebraScript","resolve","reject","script","GeoGebra","wrapperRef","useRef","appletRef","appName","setAppName","useState","isReady","setIsReady","error","setError","showToolBar","setShowToolBar","showAlgebraInput","reinjectTimerRef","rafRef","lastSizeRef","useEffect","raw","prefs","inject","useCallback","node","width","height","params","Applet","e","ro","entries","entry","cr","w","h","onKey","options","useMemo","jsxs","jsx","o"],"mappings":"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"}