"use strict";
(self["webpackChunkggblab"] = self["webpackChunkggblab"] || []).push([["lib_index_js"],{

/***/ "./lib/comm/kernel_comm.js"
/*!*********************************!*\
  !*** ./lib/comm/kernel_comm.js ***!
  \*********************************/
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   initKernelCommHelpers: () => (/* binding */ initKernelCommHelpers)
/* harmony export */ });
// Kernel communication helpers extracted from `src/widget.tsx`.
// Provides an initializer that accepts a resource bag (`res`) and a
// debug function and returns comm-related helpers bound to that bag.
function initKernelCommHelpers(resources, dbg) {
    // Per-init send chain to serialize socket sends
    let sendChain = Promise.resolve();
    async function callRemoteSocketSend(message) {
        try {
            dbg &&
                dbg('callRemoteSocketSend: sending message', {
                    socketPath: resources.socketPath,
                    wsUrl: `ws://localhost:${resources.wsPort}/`,
                    messagePreview: (message || '').slice(0, 200)
                });
            const wsUrl = `ws://localhost:${resources.wsPort}/`;
            const socketPath = resources.socketPath;
            const doSend = async () => {
                // Prefer executing the helper socket-send on the helper kernel (`kernel2`).
                // If `kernel2` is not available (e.g., running outside full JupyterLab),
                // attempt a best-effort fallback:
                //  - For websocket URLs: open a browser `WebSocket` and send directly.
                //  - For unix socket paths: log and skip (browser cannot open unix sockets).
                if (resources.kernel2 && typeof resources.kernel2.requestExecute === 'function') {
                    if (socketPath) {
                        await resources.kernel2.requestExecute({
                            code: `\nwith unix_connect("${socketPath}") as ws:\n\t\tws.send(r"""${message}""")\n`
                        }).done;
                    }
                    else {
                        await resources.kernel2.requestExecute({
                            code: `\nwith connect("${wsUrl}") as ws:\n\t\tws.send(r"""${message}""")\n`
                        }).done;
                    }
                }
                else {
                    // Fallback: try direct browser WebSocket (only works for wsUrl)
                    if (!socketPath) {
                        try {
                            await new Promise((resolve, reject) => {
                                const ws = new WebSocket(wsUrl);
                                const timer = setTimeout(() => {
                                    try {
                                        ws.close();
                                    }
                                    catch (_) { }
                                    resolve();
                                }, 3000);
                                ws.onopen = () => {
                                    try {
                                        ws.send(message);
                                    }
                                    catch (e) {
                                        // continue to close
                                    }
                                    clearTimeout(timer);
                                    try {
                                        ws.close();
                                    }
                                    catch (_) { }
                                    resolve();
                                };
                                ws.onerror = (ev) => {
                                    clearTimeout(timer);
                                    dbg && dbg('Browser WebSocket fallback error', ev);
                                    try {
                                        ws.close();
                                    }
                                    catch (_) { }
                                    resolve();
                                };
                            });
                        }
                        catch (e) {
                            dbg && dbg('Browser WebSocket fallback failed', e);
                        }
                    }
                    else {
                        dbg && dbg('Cannot send via unix socket: no helper kernel available');
                    }
                }
                await new Promise(resolve => setTimeout(resolve, 30));
            };
            const next = sendChain.then(() => doSend());
            sendChain = next.catch(e => {
                dbg && dbg('callRemoteSocketSend chain error', e);
            });
            await next;
            dbg && dbg('callRemoteSocketSend: sent', { idPreview: (message || '').slice(0, 40) });
        }
        catch (err) {
            console.error('callRemoteSocketSend: error sending message', err);
            throw err;
        }
    }
    function attachCommCloseHandler(opts) {
        const { c, setClosed, commTarget, dbg: _dbg } = opts;
        try {
            c.onClose = (m) => {
                try {
                    setClosed(true);
                    const closedId = (m && m.content && m.content.comm_id) || (c === null || c === void 0 ? void 0 : c.comm_id) || (c === null || c === void 0 ? void 0 : c.commId) || null;
                    _dbg && _dbg('Kernel comm closed', { target: commTarget, commId: closedId, message: m });
                }
                catch (e) {
                    _dbg && _dbg('Kernel comm closed (no id available)', commTarget, m);
                }
            };
        }
        catch (e) {
            _dbg && _dbg('Unable to attach onClose to kernel comm', e);
        }
    }
    async function ensureKernelComm(opts) {
        var _a, _b, _c;
        const { kernelConn: kconn, commTarget: ct, handleIncomingCommMessage: h, attachCloseHandler: ach, dbg: _dbg } = opts;
        try {
            if (!kconn) {
                throw new Error('No kernelConn available to create comm');
            }
            resources.comm = kconn.createComm(ct);
            try {
                const maybeId = ((_a = resources.comm) === null || _a === void 0 ? void 0 : _a.comm_id) || ((_b = resources.comm) === null || _b === void 0 ? void 0 : _b.commId) || ((_c = resources.comm) === null || _c === void 0 ? void 0 : _c.id) || null;
                _dbg && _dbg('Recreated kernel comm', { target: ct, commObject: resources.comm, commId: maybeId });
            }
            catch (err) {
                _dbg && _dbg('Recreated kernel comm (unable to read id)', ct, resources.comm);
            }
            try {
                resources.comm.onMsg = h;
            }
            catch (err) {
                _dbg && _dbg('Failed to attach onMsg to recreated comm', err);
            }
            try {
                ach && ach(resources.comm);
            }
            catch (err) {
                _dbg && _dbg('Failed to attach close handler to recreated comm', err);
            }
            try {
                resources.comm.open && resources.comm.open('REOPEN from GGB').done;
            }
            catch (err) {
                _dbg && _dbg('Failed to open recreated comm', err);
            }
            return resources.comm;
        }
        catch (e) {
            _dbg && _dbg('ensureKernelComm failed', e);
            return null;
        }
    }
    function makeIncomingHandler(processCommandMessage) {
        let commClosed = false;
        const attachCommCloseHandlerLocal = (c) => attachCommCloseHandler({
            c,
            setClosed: (v) => {
                commClosed = v;
            },
            commTarget: resources.commTarget,
            dbg
        });
        return async function handler(msg) {
            var _a, _b;
            const _dbg = dbg || (() => { });
            _dbg('handleIncomingCommMessage:', msg);
            try {
                _dbg('Kernel comm onMsg received', { commTarget: resources.commTarget || '', msg });
                const command = JSON.parse(msg.content.data);
                _dbg('Parsed command:', command.type, command.payload);
                let rmsg = null;
                try {
                    rmsg = await processCommandMessage(command);
                }
                catch (e) {
                    _dbg('Error processing command', e);
                    rmsg = JSON.stringify({ type: 'error', id: (command === null || command === void 0 ? void 0 : command.id) || null, payload: { message: 'Processing failed' } });
                }
                try {
                    const cId = ((_a = resources.comm) === null || _a === void 0 ? void 0 : _a.comm_id) || ((_b = resources.comm) === null || _b === void 0 ? void 0 : _b.commId) || null;
                    _dbg('Sending via kernel comm', { commTarget: resources.commTarget, commId: cId, preview: (rmsg || '').slice(0, 200) });
                    if (!resources.comm || commClosed) {
                        try {
                            const created = await ensureKernelComm({
                                kernelConn: resources.kernelConn,
                                commTarget: resources.commTarget,
                                handleIncomingCommMessage: handler,
                                attachCloseHandler: attachCommCloseHandlerLocal,
                                dbg: _dbg
                            });
                            if (created) {
                                resources.comm = created;
                                commClosed = false;
                            }
                        }
                        catch (e) {
                            _dbg('ensureKernelComm failed before sending reply', e);
                        }
                    }
                    if (resources.comm) {
                        try {
                            resources.comm.send(rmsg);
                        }
                        catch (e) {
                            _dbg('Failed to send via kernel comm, will still attempt remote socket send', e, { rmsgPreview: (rmsg || '').slice(0, 200) });
                        }
                    }
                    else {
                        _dbg('No kernel comm available to send reply; will mirror via remote socket');
                    }
                }
                catch (e) {
                    _dbg('Failed to send via kernel comm, will still attempt remote socket send', e, { rmsgPreview: (rmsg || '').slice(0, 200) });
                }
                await callRemoteSocketSend(rmsg);
            }
            catch (e) {
                (dbg || (() => { }))('Error in handleIncomingCommMessage', e);
            }
        };
    }
    return {
        callRemoteSocketSend,
        ensureKernelComm,
        attachCommCloseHandler,
        makeIncomingHandler
    };
}


/***/ },

/***/ "./lib/components/GeoGebraApplet.js"
/*!******************************************!*\
  !*** ./lib/components/GeoGebraApplet.js ***!
  \******************************************/
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   isArrayOfArrays: () => (/* binding */ isArrayOfArrays)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _jupyterlab__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./jupyterlab */ "./lib/components/jupyterlab.js");
/* harmony import */ var _widgets__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../widgets */ "./lib/widgets/widgetManager.js");
// comm helper functions inlined from kernel_comm.ts to reduce indirection

//import MetaTags from 'react-meta-tags';


// Global typings are provided in src/declarations.d.ts; avoid duplicate declarations here.
// Debug logging helper controlled from the browser console.
// Enable message logging in the JS console by running:
//   window.ggblabDebugMessages = true
function dbg(...args) {
    if (window.ggblabDebugMessages) {
        // eslint-disable-next-line no-console
        console.log(...args);
    }
}
function isArrayOfArrays(value) {
    return Array.isArray(value) && value.every((subArray) => Array.isArray(subArray));
}
/**
 * React component for a GeoGebra.
 *
 * @returns The React component
 */
const GeoGebraApplet = (props) => {
    // const [kernels, setKernels] = React.useState<any[]>([]);
    const widgetRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
    // const [size, setSize] = useState<{width: number; height: number}>({width: 800, height: 600});
    // The following `useState` + resize-listener is intentionally commented out.
    // Lumino's layout and `onResize` handling are the primary resize signals
    // for this widget; the code is kept as a reference for future experiments
    // (ResizeObserver and alternate strategies were unreliable across themes).
    // // Listen to resize events to update size state
    // // but not working as expected in Lumino
    //   useEffect(() => {
    //     window.addEventListener('resize', () => {
    //     if (widgetRef.current) {
    //         setSize({
    //             width: widgetRef.current.offsetWidth,
    //             height: widgetRef.current.offsetHeight,
    //         });
    //         console.log("Resized to:", size.width, size.height);
    //     }
    //     });
    //   }, []);
    dbg('Component props: ', props.kernelId, props.commTarget, props.socketPath, props.wsPort);
    // window.dispatchEvent(new Event('resize'));
    const elementId = 'ggb-element-' + ((props === null || props === void 0 ? void 0 : props.kernelId) || '').substring(0, 8);
    dbg('Element ID:', elementId);
    let applet = null;
    // use exported `isArrayOfArrays`
    /**
     * Calls a remote procedure on kernel2 to send a message via remote socket between kernel2 to kernel.
     * Executes Python code on kernel2 that sends the message through either a unix socket or websocket.
     *
     * Note on WebSocket Connection Handling:
     * Previous attempts to maintain persistent websocket connections using ping/pong (keep-alive)
     * were unsuccessful. Websocket connections established via kernel2.requestExecute() execute
     * within isolated contexts that are torn down immediately after the code execution completes.
     * Even with ping/pong mechanisms, connections would be disconnected once the kernel's
     * requestExecute() context ended. Therefore, the implementation creates new socket connections
     * for each message send operation, which is more reliable than attempting to maintain
     * persistent but fragile connections.
     *
     * @param kernel2 - The kernel to execute the remote procedure on
     * @param message - The message to send (as a JSON string)
     * @param socketPath - Optional unix socket path (if provided, uses unix socket; otherwise uses websocket)
     * @param wsUrl - WebSocket URL (used if socketPath is not provided)
     */
    // `sendChain` handled inside kernel_comm helpers when initialized.
    (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
        // Move frequently-used props into the resource bag for consistency
        // Resource bag: consolidate disposable resources into a single
        // object with a `dispose()` helper so teardown is consistent.
        class Resources {
            constructor(kernelId, commTarget, socketPath, wsPort) {
                this.kernel2 = null;
                this.kernelManager = null;
                this.kernelConn = null;
                this.comm = null;
                this.widgetComm = null;
                this.appletApi = null;
                // unregister function returned by `registerWidgetCommTargets`
                this.unregisterWidgetCommTargets = null;
                this.observer = null;
                this.resizeHandler = null;
                this.closeHandler = null;
                this.metaViewport = null;
                this.scriptTag = null;
                // store last-seen string values for objects to suppress redundant updates
                this._lastValues = {};
                this.kernelId = kernelId;
                this.commTarget = commTarget;
                this.socketPath = socketPath;
                this.wsPort = wsPort;
            }
            async dispose() {
                var _a, _b, _c, _d, _e;
                try {
                    if (this.comm) {
                        try {
                            (_b = (_a = this.comm).close) === null || _b === void 0 ? void 0 : _b.call(_a);
                        }
                        catch (err) {
                            dbg('Error closing comm during cleanup', err);
                        }
                        this.comm = null;
                    }
                    if (this.kernel2) {
                        try {
                            await this.kernel2.shutdown();
                        }
                        catch (err) {
                            dbg('Error shutting down kernel2 during cleanup', err);
                        }
                        this.kernel2 = null;
                    }
                    this.widgetComm = null;
                    this.appletApi = null;
                    if (this.kernelManager) {
                        try {
                            await ((_d = (_c = this.kernelManager).shutdown) === null || _d === void 0 ? void 0 : _d.call(_c));
                        }
                        catch (err) {
                            dbg('Error shutting down kernelManager', err);
                        }
                        this.kernelManager = null;
                    }
                    if (this.observer) {
                        try {
                            this.observer.disconnect();
                        }
                        catch (err) {
                            dbg('Error disconnecting observer', err);
                        }
                        this.observer = null;
                    }
                    if (this.resizeHandler) {
                        try {
                            window.removeEventListener('resize', this.resizeHandler);
                        }
                        catch (err) {
                            dbg('Error removing resize handler', err);
                        }
                        this.resizeHandler = null;
                    }
                    if (this.closeHandler) {
                        try {
                            window.removeEventListener('close', this.closeHandler);
                        }
                        catch (err) {
                            dbg('Error removing close handler', err);
                        }
                        this.closeHandler = null;
                    }
                    if (this.metaViewport && this.metaViewport.parentNode) {
                        this.metaViewport.parentNode.removeChild(this.metaViewport);
                        this.metaViewport = null;
                    }
                    if (this.scriptTag && this.scriptTag.parentNode) {
                        this.scriptTag.parentNode.removeChild(this.scriptTag);
                        this.scriptTag = null;
                    }
                    try {
                        // call the unregister function if present
                        (_e = this.unregisterWidgetCommTargets) === null || _e === void 0 ? void 0 : _e.call(this);
                        this.unregisterWidgetCommTargets = null;
                    }
                    catch (err) {
                        dbg('Error unregistering widget comm targets', err);
                    }
                }
                catch (err) {
                    console.error('Error during resources.dispose():', err);
                }
            }
        }
        const resources = new Resources(props.kernelId || '', props.commTarget || '', props.socketPath || null, props.wsPort || 8888);
        // Quick debug probe: confirm the IIFE below is entered at runtime.
        dbg('useEffect: created Resources, about to run setup IIFE', {
            kernelId: props.kernelId,
            commTarget: props.commTarget
        });
        (async () => {
            dbg('IIFE: entered - calling setupKernelResources');
            const { callRemoteSocketSend, makeIncomingHandler } = await (0,_jupyterlab__WEBPACK_IMPORTED_MODULE_1__["default"])(resources, props, dbg);
            // Kernel comm lifecycle is managed inside kernel_comm helpers
            // Process a parsed command and return the reply message string.
            // This function lives in the same `useEffect` scope so it can be
            // called from multiple places (including outside
            // `handleIncomingCommMessage`). It captures `appletApi` and other
            // surrounding variables as needed.
            const processCommandMessage = async (command) => {
                let rmsg = null;
                // Handler dictionary for command types. Keep each handler focused
                // on producing the reply payload; the common send/mirroring logic
                // is handled by the caller.
                const handlers = {
                    command: async (cmd) => {
                        if (resources.appletApi && typeof resources.appletApi.evalCommandGetLabels === 'function') {
                            const label = resources.appletApi.evalCommandGetLabels(cmd.payload);
                            return JSON.stringify({
                                type: 'created',
                                id: cmd.id,
                                payload: label
                            });
                        }
                        return JSON.stringify({
                            type: 'error',
                            id: cmd.id,
                            payload: { message: 'applet API not available' }
                        });
                    },
                    function: async (cmd) => {
                        const apiName = cmd.payload.name;
                        dbg('apiName:', apiName);
                        let value = [];
                        const args = cmd.payload.args;
                        value = [];
                        (Array.isArray(apiName) ? apiName : [apiName]).forEach((f) => {
                            dbg('call', f, args);
                            if (isArrayOfArrays(args)) {
                                const value2 = [];
                                args.forEach((arg2) => {
                                    if (resources.appletApi && typeof resources.appletApi[f] === 'function') {
                                        value2.push(resources.appletApi[f](...arg2) || null);
                                    }
                                    else {
                                        value2.push(null);
                                    }
                                });
                                value.push(value2);
                            }
                            else {
                                if (args) {
                                    value.push(resources.appletApi && typeof resources.appletApi[f] === 'function'
                                        ? resources.appletApi[f](...args) || null
                                        : null);
                                }
                                else {
                                    value.push(resources.appletApi && typeof resources.appletApi[f] === 'function'
                                        ? resources.appletApi[f]() || null
                                        : null);
                                }
                            }
                        });
                        value = Array.isArray(apiName) ? value : value[0];
                        dbg('Function value:', value);
                        return JSON.stringify({
                            type: 'value',
                            id: cmd.id,
                            payload: { value: value }
                        });
                    },
                    // Lightweight listen handler: acknowledge subscription. More
                    // elaborate listener registration can be added later if needed.
                    listen: async (cmd) => {
                        dbg('Register listen request:', cmd.payload);
                        try {
                            // Accept multiple payload shapes: [name, enabled],
                            // {name, enabled}, or a simple string (enabled=true).
                            let name = null;
                            let enabled = true;
                            const p = cmd.payload;
                            if (Array.isArray(p)) {
                                name = p[0];
                                enabled = !!p[1];
                            }
                            else if (p && typeof p === 'object') {
                                if (typeof p.name === 'string') {
                                    name = p.name;
                                }
                                if (p.enabled !== undefined) {
                                    enabled = !!p.enabled;
                                }
                                else if (p.enable !== undefined) {
                                    enabled = !!p.enable;
                                }
                            }
                            else if (typeof p === 'string') {
                                name = p;
                                enabled = true;
                            }
                            if (!name) {
                                throw new Error('listen payload must include object name');
                            }
                            let result = null;
                            if (enabled) {
                                if (resources.appletApi && typeof resources.appletApi.registerObjectUpdateListener === 'function') {
                                    try {
                                        // Provide a callback that forwards updates to the
                                        // remote socket; keep it lightweight and non-blocking.
                                        // Listener callback: no update argument is provided by the
                                        // applet runtime. Instead, call `appletApi.getValueString`
                                        // to obtain a serializable representation of the object's
                                        // current value and forward it as the event payload.
                                        const cb = () => {
                                            var _a;
                                            try {
                                                let value = null;
                                                try {
                                                    if (resources.appletApi && typeof resources.appletApi.getValueString === 'function') {
                                                        value = resources.appletApi.getValueString(name);
                                                    }
                                                    else {
                                                        value = null;
                                                    }
                                                }
                                                catch (e) {
                                                    dbg('getValueString failed', e);
                                                    value = null;
                                                }
                                                // Suppress sending when the string value hasn't changed since last send.
                                                try {
                                                    const last = (_a = resources._lastValues[name]) !== null && _a !== void 0 ? _a : null;
                                                    const cur = value == null ? null : String(value);
                                                    if (last !== null && last === cur) {
                                                        // unchanged, skip notification
                                                        dbg('Suppressing unchanged value for', name, ':', cur);
                                                        return;
                                                    }
                                                    // update last seen value
                                                    resources._lastValues[name] = cur;
                                                }
                                                catch (e) {
                                                    dbg('value-comparison in object update failed', e);
                                                }
                                                const msg = JSON.stringify({
                                                    type: 'object_update',
                                                    // id: cmd.id, // intentionally omitted: object_update events are
                                                    // queued as asynchronous events and should not carry a
                                                    // request/response id.
                                                    payload: { name, value }
                                                });
                                                // fire-and-forget
                                                callRemoteSocketSend(msg).catch((e) => dbg('object_update send failed', e));
                                            }
                                            catch (e) {
                                                dbg('Error in object update callback', e);
                                            }
                                        };
                                        // Some implementations may return a listener token.
                                        result = await Promise.resolve(resources.appletApi.registerObjectUpdateListener(name, cb));
                                        // Ensure the current value is delivered immediately after registration
                                        try {
                                            cb();
                                        }
                                        catch (e) {
                                            dbg('initial object_update send failed', e);
                                        }
                                    }
                                    catch (e) {
                                        dbg('registerObjectUpdateListener failed', e);
                                        result = { ok: false, error: String(e) };
                                    }
                                }
                                else {
                                    result = {
                                        ok: false,
                                        error: 'registerObjectUpdateListener not available'
                                    };
                                }
                            }
                            else {
                                if (resources.appletApi && typeof resources.appletApi.unregisterObjectUpdateListener === 'function') {
                                    try {
                                        result = await Promise.resolve(resources.appletApi.unregisterObjectUpdateListener(name));
                                    }
                                    catch (e) {
                                        dbg('unregisterObjectUpdateListener failed', e);
                                        result = { ok: false, error: String(e) };
                                    }
                                }
                                else {
                                    result = {
                                        ok: false,
                                        error: 'unregisterObjectUpdateListener not available'
                                    };
                                }
                            }
                            return JSON.stringify({
                                type: 'listen',
                                id: cmd.id,
                                payload: { result }
                            });
                        }
                        catch (e) {
                            dbg('Error in listen handler', e);
                            return JSON.stringify({
                                type: 'error',
                                id: cmd.id,
                                payload: { message: String(e) }
                            });
                        }
                    }
                };
                try {
                    const h = handlers[command.type];
                    if (h) {
                        rmsg = await h(command);
                    }
                    else {
                        dbg('No handler for command type', command.type);
                        rmsg = JSON.stringify({
                            type: 'error',
                            id: command.id,
                            payload: { message: 'Unsupported command type' }
                        });
                    }
                }
                catch (e) {
                    dbg('Handler error for command type', command.type, e);
                    rmsg = JSON.stringify({
                        type: 'error',
                        id: command.id,
                        payload: { message: 'Handler execution failed' }
                    });
                }
                return rmsg;
            };
            // Handler for incoming messages on the kernel-created comm; defined
            // via kernel_comm helper so it can reuse the shared logic.
            const handleIncomingCommMessage = makeIncomingHandler(processCommandMessage);
            /*
              Widget comm passthrough fallback
              -------------------------------
              Reason: In some host environments (non-JupyterLab pages, timing differences,
              or when the optional ipywidgets bridge isn't available), the centralized
              `register_widget_manager_plugin` may not be able to detect or register a
              frontend `WidgetManager` early enough for the GeoGebra applet to handle
              incoming widget-related comms. To avoid breaking ipywidgets (which expect
              the `jupyter.widget` comm target to be handled), we provide a lightweight
              passthrough here as a guarded fallback.
            
              How this relates to `register_widget_manager_plugin`:
              - `register_widget_manager_plugin` (exported from `src/register_widget_manager_plugin.ts`
                and exposed in `src/index.ts`) is the preferred mechanism: it runs
                during JupyterLab activation and attempts to detect the real
                ipywidgets manager and call `setWidgetManager(...)` so the applet can
                delegate message routing to the manager.
              - However, that plugin may be unavailable (optional dependency), run
                later, or be ineffective in non-Lab contexts. This inline fallback
                ensures correct behavior in those cases while remaining no-op when a
                real manager is present (`props.widgetManager` guard).
            */
            try {
                if (props.widgetManager) {
                    dbg('widgetManager present; skipping raw jupyter.widget comm registration to avoid stealing widget opens');
                }
                else {
                    const opts = {
                        callRemoteSocketSend,
                        kernel2: resources.kernel2,
                        socketPath: resources.socketPath,
                        wsUrl: `ws://localhost:${resources.wsPort}/`,
                        getAppletApi: () => resources.appletApi,
                        isArrayOfArrays: isArrayOfArrays,
                        dbg
                    };
                    const unregisterFn = (0,_widgets__WEBPACK_IMPORTED_MODULE_2__.registerWidgetCommTargets)(resources.kernelConn, opts);
                    resources.unregisterWidgetCommTargets = unregisterFn;
                }
            }
            catch (e) {
                dbg('Widget comm target registration skipped or failed', e);
            }
            async function ggbOnLoad(api) {
                var _a, _b, _c;
                dbg('GeoGebra applet loaded:', api);
                // expose applet API to other handlers (widgetComm etc.)
                resources.appletApi = api;
                (async function () {
                    const msg = { type: 'start', payload: {} };
                    await callRemoteSocketSend(JSON.stringify(msg));
                })();
                resources.resizeHandler = function () {
                    const wrapperDiv = document.getElementById(elementId);
                    const parentDiv = wrapperDiv === null || wrapperDiv === void 0 ? void 0 : wrapperDiv.parentElement;
                    const width = parseInt((parentDiv === null || parentDiv === void 0 ? void 0 : parentDiv.style.width) || '800');
                    const height = parseInt((parentDiv === null || parentDiv === void 0 ? void 0 : parentDiv.style.height) || '600');
                    api.recalculateEnvironments();
                    api.setSize(width, height);
                };
                window.addEventListener('resize', resources.resizeHandler);
                resources.resizeHandler();
                // // Observe size changes of the widget's DOM element
                // // but not working as expected in Lumino
                // const widgetElemnt = window.document.querySelector('div.lm-DockPanel-widget');
                // const widgetElemnt = window.document.querySelector('div.lm-SplitPanel-child');
                // const widgetElemnt = window.document.querySelector('div[class*="Panel"]');
                // if (widgetElemnt) {
                // if (widgetRef.current) {
                //     const resizeObserver = new ResizeObserver(() => {
                //         console.log("Panel resized.");
                //         resize();
                //     });
                //     resizeObserver.observe(widgetRef.current); //widgetElemnt);
                // }
                if (resources.commTarget) {
                    resources.comm = resources.kernelConn.createComm(resources.commTarget);
                    try {
                        // Log comm creation details for debugging 'Comm not found' issues
                        try {
                            const maybeId = ((_a = resources.comm) === null || _a === void 0 ? void 0 : _a.comm_id) ||
                                ((_b = resources.comm) === null || _b === void 0 ? void 0 : _b.commId) ||
                                ((_c = resources.comm) === null || _c === void 0 ? void 0 : _c.id) ||
                                null;
                            dbg('Created kernel comm', {
                                target: resources.commTarget,
                                commObject: resources.comm,
                                commId: maybeId
                            });
                        }
                        catch (_d) {
                            dbg('Created kernel comm (unable to read id)', resources.commTarget, resources.comm);
                        }
                        resources.comm.open('HELO from GGB').done;
                    }
                    catch (e) {
                        dbg('Failed to open kernel comm for', resources.commTarget, e);
                    }
                    // Attach close handler to surface unexpected closes
                    try {
                        resources.comm.onClose = (m) => {
                            var _a, _b;
                            try {
                                const closedId = (m && m.content && m.content.comm_id) ||
                                    ((_a = resources.comm) === null || _a === void 0 ? void 0 : _a.comm_id) ||
                                    ((_b = resources.comm) === null || _b === void 0 ? void 0 : _b.commId) ||
                                    null;
                                dbg('Kernel comm closed', {
                                    target: resources.commTarget,
                                    commId: closedId,
                                    message: m
                                });
                            }
                            catch (e) {
                                dbg('Kernel comm closed (no id available)', resources.commTarget, m);
                            }
                        };
                    }
                    catch (e) {
                        dbg('Unable to attach onClose to kernel comm', e);
                    }
                }
                else {
                    // No kernel-level comm target provided: rely on remote socket
                    resources.comm = null;
                    dbg('No commTarget provided; skipping kernel comm creation');
                }
                // comm.send('HELO2').done
                // kernel.registerCommTarget('test', (comm, commMsg) => {
                // console.log("Comm opened from kernel with message:", commMsg['content']['data']);
                resources.closeHandler = () => {
                    var _a, _b, _c;
                    // Attempt to close comm and shutdown helper kernel
                    try {
                        (_b = (_a = resources.comm) === null || _a === void 0 ? void 0 : _a.close) === null || _b === void 0 ? void 0 : _b.call(_a);
                    }
                    catch (e) {
                        console.error(e);
                    }
                    (_c = resources.kernel2) === null || _c === void 0 ? void 0 : _c.shutdown().catch((err) => console.error(err));
                    dbg('Kernel and comm closed.');
                    if (resources.resizeHandler) {
                        window.removeEventListener('resize', resources.resizeHandler);
                    }
                };
                window.addEventListener('close', resources.closeHandler);
                if (resources.comm) {
                    try {
                        resources.comm.onMsg = handleIncomingCommMessage;
                    }
                    catch (e) {
                        dbg('Failed to attach handleIncomingCommMessage to comm', e);
                    }
                }
                else {
                    dbg('No kernel comm available; messages will be sent via remote socket only');
                }
                const addListener = async function (data) {
                    dbg('Add listener triggered for:', data);
                    const msg = {
                        type: 'add',
                        payload: data
                    };
                    // console.log("Add detected:", JSON.stringify(msg));
                    // Prefer to send via widget comm bridge if available
                    const s = JSON.stringify(msg);
                    if (resources.widgetComm) {
                        try {
                            resources.widgetComm.send(s);
                            return;
                        }
                        catch (e) {
                            dbg('widgetComm.send failed, falling back', e);
                        }
                    }
                    await callRemoteSocketSend(s);
                };
                api.registerAddListener(addListener);
                const removeListener = async function (data) {
                    dbg('Remove listener triggered for:', data);
                    const msg = {
                        type: 'remove',
                        payload: data
                    };
                    // console.log("Remove detected:", JSON.stringify(msg));
                    const s = JSON.stringify(msg);
                    if (resources.widgetComm) {
                        try {
                            resources.widgetComm.send(s);
                            return;
                        }
                        catch (e) {
                            dbg('widgetComm.send failed, falling back', e);
                        }
                    }
                    await callRemoteSocketSend(s);
                };
                api.registerRemoveListener(removeListener);
                const renameListener = async function (data) {
                    dbg('Rename listener triggered for:', data);
                    const msg = {
                        type: 'rename',
                        payload: data
                    };
                    // console.log("Rename detected:", JSON.stringify(msg));
                    const s = JSON.stringify(msg);
                    if (resources.widgetComm) {
                        try {
                            resources.widgetComm.send(s);
                            return;
                        }
                        catch (e) {
                            dbg('widgetComm.send failed, falling back', e);
                        }
                    }
                    await callRemoteSocketSend(s);
                };
                api.registerRenameListener(renameListener);
                const clearListener = async function (data) {
                    dbg('Clear listener triggered for:', data);
                    const msg = {
                        type: 'clear',
                        payload: data
                    };
                    // console.log("Rename detected:", JSON.stringify(msg));
                    const s = JSON.stringify(msg);
                    if (resources.widgetComm) {
                        try {
                            resources.widgetComm.send(s);
                            return;
                        }
                        catch (e) {
                            dbg('widgetComm.send failed, falling back', e);
                        }
                    }
                    await callRemoteSocketSend(s);
                };
                api.registerClearListener(clearListener);
                // The `clientListener` example below is kept commented out as a
                // reference for future event types. It's disabled because it
                // was not used in production and could generate noisy traffic.
                // // nothing triggered?
                // var clientListener = async function(data: any) {
                // // console.log("Add listener triggered for:", data);
                //     var msg = {
                //         "type": "client",
                //         "payload": data
                //     }
                //     console.log("Client detected:", JSON.stringify(msg));
                //     await callRemoteSocketSend(kernel2, JSON.stringify(msg), socketPath, wsUrl);
                // }
                // api.registerClearListener(clientListener);
                resources.observer = new MutationObserver(mutations => {
                    mutations.forEach(mutation => {
                        mutation.addedNodes.forEach(node => {
                            try {
                                node
                                    .querySelectorAll('div.dialogMainPanel > div.dialogTitle')
                                    .forEach(n => {
                                    dbg(n.textContent); // detect titles like 'Error'
                                    node.querySelector('div.dialogContent')
                                        .querySelectorAll("[class$='Label']")
                                        .forEach(async (n2) => {
                                        dbg(n2.textContent);
                                        const msg = JSON.stringify({
                                            type: n.textContent,
                                            payload: n2.textContent
                                        });
                                        // comm.send(msg);
                                        await callRemoteSocketSend(msg);
                                    });
                                });
                            }
                            catch (e) {
                                // console.log(e, node);
                            }
                        });
                    });
                });
                resources.observer.observe(document.body, { childList: true, subtree: true });
            }
            // Avoid duplicate meta/script inserts: reuse if already present
            const existingMeta = document.getElementById('ggblab-viewport-meta');
            if (existingMeta) {
                resources.metaViewport = existingMeta;
            }
            else {
                resources.metaViewport = document.createElement('meta');
                resources.metaViewport.id = 'ggblab-viewport-meta';
                resources.metaViewport.name = 'viewport';
                resources.metaViewport.content = 'width=device-width, initial-scale=1';
                document.head.appendChild(resources.metaViewport);
            }
            const existingScript = document.getElementById('ggblab-deployggb-script');
            dbg('Script element lookup', { existingScript: !!existingScript, scriptId: 'ggblab-deployggb-script' });
            const createApplet = () => {
                const params = {
                    id: 'ggbApplet' + ((props === null || props === void 0 ? void 0 : props.kernelId) || '').substring(0, 8), // applet ID
                    appName: (props === null || props === void 0 ? void 0 : props.appName) || 'suite', // allow overriding appName via props
                    width: 800, // applet width
                    height: 600, // applet height
                    showToolBar: true, // show the toolbar
                    showAlgebraInput: false, // show algebra input field
                    showMenuBar: true, // show the menu bar
                    autoHeight: true,
                    scaleContainerClass: 'lm-Panel', // "lm-DockPanel-widget",
                    // autoWidth: false,
                    // scale: 2,
                    allowUpscale: false,
                    appletOnLoad: ggbOnLoad
                };
                applet = new window.GGBApplet(params, true);
                applet.inject(elementId);
                // Expose the active applet instance on `window.ggbApplet` for
                // consistency across the codebase and for debug tooling.
                window.ggbApplet = applet;
            };
            if (existingScript) {
                resources.scriptTag = existingScript;
                // If script already loaded and GGBApplet is available, instantiate immediately
                if (window.GGBApplet) {
                    dbg('GGBApplet already present on window; creating applet immediately');
                    try {
                        createApplet();
                    }
                    catch (err) {
                        dbg('createApplet threw when called immediately', err);
                    }
                }
                else {
                    // Otherwise ensure we call createApplet once it loads
                    dbg('GGBApplet not present; attaching load listener to existing script');
                    resources.scriptTag.addEventListener('load', () => {
                        dbg('Existing script load event fired; invoking createApplet');
                        try {
                            createApplet();
                        }
                        catch (err) {
                            dbg('createApplet threw during existing script load handler', err);
                        }
                    }, { once: true });
                }
            }
            else {
                resources.scriptTag = document.createElement('script');
                resources.scriptTag.id = 'ggblab-deployggb-script';
                resources.scriptTag.src = 'https://cdn.geogebra.org/apps/deployggb.js';
                resources.scriptTag.async = true;
                resources.scriptTag.onload = () => {
                    dbg('Injected script onload fired; invoking createApplet');
                    try {
                        createApplet();
                    }
                    catch (err) {
                        dbg('createApplet threw during injected script onload', err);
                    }
                };
                dbg('Appending new script tag to document.body', { src: resources.scriptTag.src });
                document.body.appendChild(resources.scriptTag);
            }
        })();
        return () => {
            var _a;
            // Remove resize listener
            if (resources.resizeHandler) {
                window.removeEventListener('resize', resources.resizeHandler);
                resources.resizeHandler = null;
            }
            // Remove close listener
            if (resources.closeHandler) {
                window.removeEventListener('close', resources.closeHandler);
                resources.closeHandler = null;
            }
            // Disconnect mutation observer
            if (resources.observer) {
                try {
                    resources.observer.disconnect();
                }
                catch (e) {
                    console.error(e);
                }
                resources.observer = null;
            }
            // Unregister widget comm handlers if we registered them
            try {
                (_a = resources.unregisterWidgetCommTargets) === null || _a === void 0 ? void 0 : _a.call(resources);
                resources.unregisterWidgetCommTargets = null;
            }
            catch (e) {
                dbg('Error unregistering widget comm targets', e);
            }
            // Remove injected meta tag
            if (resources.metaViewport && resources.metaViewport.parentNode) {
                resources.metaViewport.parentNode.removeChild(resources.metaViewport);
                resources.metaViewport = null;
            }
            // Remove injected script tag
            if (resources.scriptTag && resources.scriptTag.parentNode) {
                resources.scriptTag.parentNode.removeChild(resources.scriptTag);
                resources.scriptTag = null;
            }
            // Clean up GeoGebra applet
            if (applet) {
                try {
                    dbg('Cleaning up GeoGebra applet.');
                    // Use the unified `window.ggbApplet` reference when available
                    const winApplet = window.ggbApplet || applet;
                    try {
                        winApplet.remove();
                    }
                    catch (e) {
                        dbg('Error removing applet instance', e);
                    }
                }
                catch (e) {
                    dbg('Error while removing GeoGebra applet', e);
                }
                applet = null;
                delete window.ggbApplet;
            }
            // Close comm and shutdown helper kernel asynchronously via resource bag
            (async () => {
                try {
                    await resources.dispose();
                }
                catch (e) {
                    console.error('Error during cleanup:', e);
                }
            })();
        };
    }, []);
    return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { id: elementId, ref: widgetRef, style: { width: '100%', height: '100%' } }));
};
/**
 * A GeoGebra Lumino Widget that wraps a GeoGebraComponent.
 */
// Lumino-specific `GeoGebraWidget` has been moved to `lumino.tsx`.
// // Example of attaching the GeoGebraWidget to a DockPanel
// // but commented out to avoid automatic execution.
// const dock = new DockPanel();
// ReactWidget.attach(dock, document.body);
// // window.addEventListener('resize', () => { dock.update(); });
// dock.layoutModified.connect(() => {
//     console.log("Dock layout modified.");
//     dock.update();
// });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GeoGebraApplet);


/***/ },

/***/ "./lib/components/jupyterlab.js"
/*!**************************************!*\
  !*** ./lib/components/jupyterlab.js ***!
  \**************************************/
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   isArrayOfArrays: () => (/* binding */ isArrayOfArrays),
/* harmony export */   setupKernelResources: () => (/* binding */ setupKernelResources)
/* harmony export */ });
/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/services */ "webpack/sharing/consume/default/@jupyterlab/services");
/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/coreutils */ "webpack/sharing/consume/default/@jupyterlab/coreutils");
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _comm__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../comm */ "./lib/comm/kernel_comm.js");



// Small utility copied from the applet to avoid circular imports
function isArrayOfArrays(value) {
    return Array.isArray(value) && value.every((subArray) => Array.isArray(subArray));
}
/**
 * Initialize JupyterLab-specific kernel resources.
 * - starts a helper kernel (kernel2)
 * - creates a KernelConnection for the target kernel id
 * - initializes kernel_comm helpers and returns the send/handler factories
 * - registers widget comm passthrough when appropriate
 */
async function setupKernelResources(resources, props, dbg) {
    let _result = null;
    // If requested via props or PageConfig option, clear browser storage on startup.
    // This helps remove stale widget manager state that can conflict after refactors.
    const shouldClearFromProps = !!(props && (props.clearBrowserStorageOnStartup === true || props.clearBrowserStorageOnStartup === 'true'));
    const shouldClearFromPageConfig = (() => {
        try {
            const v = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__.PageConfig.getOption && _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__.PageConfig.getOption('ggblab.clearBrowserStorageOnStartup');
            return v === 'true';
        }
        catch (e) {
            return false;
        }
    })();
    const shouldClearFromGlobal = (() => {
        try {
            return !!(window.__ggblab_clearBrowserStorageOnStartup === true || window.__ggblab_clearBrowserStorageOnStartup === 'true');
        }
        catch (e) {
            return false;
        }
    })();
    const shouldClear = shouldClearFromProps || shouldClearFromPageConfig || shouldClearFromGlobal;
    try {
        console.debug('ggblab: clearBrowserStorage flags', { shouldClearFromProps, shouldClearFromPageConfig, shouldClearFromGlobal, shouldClear });
    }
    catch (e) { }
    async function clearBrowserStorage() {
        var _a;
        try {
            // Determine mode: selective (default) or full when explicitly requested
            const selective = !(props && props.clearBrowserStorageFull === true);
            const defaultPatterns = [
                'ggblab',
                'widget',
                'jupyterlab-workspace',
                'jupyterlab',
                'jupyter-widgets',
                '@jupyter-widgets'
            ];
            const patterns = (props && Array.isArray(props.clearBrowserStoragePatterns) && props.clearBrowserStoragePatterns.length)
                ? props.clearBrowserStoragePatterns
                : defaultPatterns;
            const matches = (name) => {
                if (!name)
                    return false;
                try {
                    return patterns.some(p => name.toLowerCase().includes(String(p).toLowerCase()));
                }
                catch (e) {
                    return false;
                }
            };
            // localStorage: either clear all or only keys that match patterns
            const removedLocalKeys = [];
            try {
                if (!selective) {
                    try {
                        localStorage.clear();
                    }
                    catch (e) { /* ignore */ }
                }
                else {
                    for (let i = localStorage.length - 1; i >= 0; i--) {
                        const k = localStorage.key(i);
                        if (k && matches(k)) {
                            try {
                                localStorage.removeItem(k);
                                removedLocalKeys.push(k);
                            }
                            catch (e) { /* ignore */ }
                        }
                    }
                }
            }
            catch (e) { /* ignore */ }
            // sessionStorage: selective removal
            const removedSessionKeys = [];
            try {
                if (!selective) {
                    try {
                        sessionStorage.clear();
                    }
                    catch (e) { /* ignore */ }
                }
                else {
                    for (let i = sessionStorage.length - 1; i >= 0; i--) {
                        const k = sessionStorage.key(i);
                        if (k && matches(k)) {
                            try {
                                sessionStorage.removeItem(k);
                                removedSessionKeys.push(k);
                            }
                            catch (e) { /* ignore */ }
                        }
                    }
                }
            }
            catch (e) { /* ignore */ }
            // indexedDB: delete databases whose name matches patterns (where supported)
            const removedIndexedDB = [];
            try {
                if (indexedDB && typeof indexedDB.databases === 'function') {
                    const dbs = await indexedDB.databases();
                    for (const d of dbs) {
                        try {
                            const name = d && d.name ? d.name : null;
                            if (!name)
                                continue;
                            if (!selective || matches(name)) {
                                try {
                                    indexedDB.deleteDatabase(name);
                                    removedIndexedDB.push(name);
                                }
                                catch (e) { /* ignore */ }
                            }
                        }
                        catch (e) { /* ignore per-db */ }
                    }
                }
            }
            catch (e) { /* ignore */ }
            // caches: delete caches whose key matches patterns
            const removedCaches = [];
            try {
                if (window.caches) {
                    const keys = await caches.keys();
                    for (const k of keys) {
                        try {
                            if (!selective || matches(k)) {
                                const ok = await caches.delete(k);
                                if (ok) {
                                    removedCaches.push(k);
                                }
                            }
                        }
                        catch (e) { /* ignore per-cache */ }
                    }
                }
            }
            catch (e) { /* ignore */ }
            // cookies: delete cookies whose name matches patterns (best-effort)
            const removedCookies = [];
            try {
                const cookies = document.cookie ? document.cookie.split(';') : [];
                for (const c of cookies) {
                    const name = (_a = c.split('=')[0]) === null || _a === void 0 ? void 0 : _a.trim();
                    if (!name)
                        continue;
                    if (!selective || matches(name)) {
                        try {
                            document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
                            removedCookies.push(name);
                        }
                        catch (e) { /* ignore */ }
                    }
                }
            }
            catch (e) { /* ignore */ }
            try {
                console.info('ggblab: selective browser storage clear complete', {
                    removedLocalKeys,
                    removedSessionKeys,
                    removedIndexedDB,
                    removedCaches,
                    removedCookies
                });
            }
            catch (e) { /* ignore logging failure */ }
        }
        catch (e) {
            try {
                console.warn('ggblab: clearBrowserStorage failed', e);
            }
            catch (ee) { }
        }
    }
    if (shouldClear) {
        try {
            console.info('ggblab: clearBrowserStorageOnStartup active — clearing storages (selective mode default)');
        }
        catch (e) { }
        clearBrowserStorage().catch(() => { });
    }
    await (async () => {
        return await _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.listRunning();
    })().then(async (kernels) => {
        // setKernels(kernels);
        dbg('Running kernels:', kernels);
        const baseUrl = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__.PageConfig.getBaseUrl();
        const token = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__.PageConfig.getToken();
        dbg(`Base URL: ${baseUrl}`);
        dbg(`Token: ${token}`);
        const settings = _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.ServerConnection.makeSettings({
            baseUrl: baseUrl,
            token: token,
            appendToken: true
        });
        resources.kernelManager = new _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelManager({ serverSettings: settings });
        resources.kernel2 = await resources.kernelManager.startNew({ name: 'python3' });
        dbg('Started new kernel:', resources.kernel2, resources.kernelId);
        await resources.kernel2.requestExecute({ code: 'from websockets.sync.client import unix_connect, connect' }).done;
        // ws/socket values managed inside kernel_comm helpers
        // Initialize comm helpers from shared module
        const { callRemoteSocketSend, makeIncomingHandler } = (0,_comm__WEBPACK_IMPORTED_MODULE_2__.initKernelCommHelpers)(resources, dbg);
        resources.kernelConn = new _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelConnection({
            model: { name: 'python3', id: resources.kernelId || kernels[0]['id'] },
            serverSettings: settings
        });
        dbg('Connected to kernel:', resources.kernelConn);
        _result = { callRemoteSocketSend, makeIncomingHandler, kernelConn: resources.kernelConn };
    });
    // Widget comm passthrough registration is handled by the applet fallback
    // or by the optional widget-manager detection plugin. Keeping this module
    // focused on kernel/service initialization avoids duplicating registration
    // logic with `GeoGebraApplet.tsx`.
    return _result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setupKernelResources);


/***/ },

/***/ "./lib/components/lumino.js"
/*!**********************************!*\
  !*** ./lib/components/lumino.js ***!
  \**********************************/
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   GeoGebraWidget: () => (/* binding */ GeoGebraWidget),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/ui-components */ "webpack/sharing/consume/default/@jupyterlab/ui-components");
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _GeoGebraApplet__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./GeoGebraApplet */ "./lib/components/GeoGebraApplet.js");



/**
 * Lumino wrapper that renders the React `GeoGebraApplet` inside a widget.
 */
class GeoGebraWidget extends _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_0__.ReactWidget {
    constructor(props) {
        super();
        this.addClass('jp-ggblabWidget');
        this.props = props;
    }
    render() {
        var _a, _b, _c, _d, _e, _f;
        return (react__WEBPACK_IMPORTED_MODULE_1___default().createElement(_GeoGebraApplet__WEBPACK_IMPORTED_MODULE_2__["default"], { kernelId: (_a = this.props) === null || _a === void 0 ? void 0 : _a.kernelId, commTarget: (_b = this.props) === null || _b === void 0 ? void 0 : _b.commTarget, wsPort: (_c = this.props) === null || _c === void 0 ? void 0 : _c.wsPort, socketPath: (_d = this.props) === null || _d === void 0 ? void 0 : _d.socketPath, appName: (_e = this.props) === null || _e === void 0 ? void 0 : _e.appName, widgetManager: (_f = this.props) === null || _f === void 0 ? void 0 : _f.widgetManager }));
    }
    onResize(msg) {
        // Let the React component handle resize via window resize events
        window.dispatchEvent(new Event('resize'));
        super.onResize(msg);
    }
    onCloseRequest(msg) {
        window.dispatchEvent(new Event('close'));
        super.onCloseRequest(msg);
    }
    dispose() {
        super.dispose();
    }
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (GeoGebraWidget);


/***/ },

/***/ "./lib/index.js"
/*!**********************!*\
  !*** ./lib/index.js ***!
  \**********************/
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createWidgetManagerLegacy: () => (/* binding */ createWidgetManagerLegacy),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _jupyterlab_application__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/application */ "webpack/sharing/consume/default/@jupyterlab/application");
/* harmony import */ var _jupyterlab_application__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_application__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/apputils */ "webpack/sharing/consume/default/@jupyterlab/apputils");
/* harmony import */ var _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _jupyterlab_settingregistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jupyterlab/settingregistry */ "webpack/sharing/consume/default/@jupyterlab/settingregistry");
/* harmony import */ var _jupyterlab_settingregistry__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_settingregistry__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @jupyterlab/ui-components */ "webpack/sharing/consume/default/@jupyterlab/ui-components");
/* harmony import */ var _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _widget__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./widget */ "./lib/components/lumino.js");
/* harmony import */ var _widgets__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./widgets */ "./lib/widgets/widgetManager.js");
/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../package.json */ "./package.json");
/* harmony import */ var _widgets__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./widgets */ "./lib/widgets/register_widget_manager_plugin.js");


// ILauncher removed: launcher integration is not used in this build

//import { DockLayout } from '@lumino/widgets';



/**
 * Legacy/compatibility note:
 * Historically the plugin created a `widgetManager` inline in this
 * module during activation. The implementation has been moved to
 * `src/widgetManager.ts` to centralize widget-manager logic and to
 * allow different manager implementations (or `undefined`) to be
 * swapped in. We keep a tiny forwarding helper here as a documented
 * placeholder so future maintainers can see the original intent and
 * have a single place to adapt call-sites if needed.
 */
function createWidgetManagerLegacy() {
    // Forward to the real factory in widgetManager.ts for now.
    return (0,_widgets__WEBPACK_IMPORTED_MODULE_5__.createWidgetManager)();
}
// Import package.json to reflect the package version in the UI log.


var CommandIDs;
(function (CommandIDs) {
    CommandIDs.create = 'ggblab:create';
})(CommandIDs || (CommandIDs = {}));
// const PANEL_CLASS = 'jp-ggblabPanel';
/**
 * Initialization data for the ggblab extension.
 */
const plugin = {
    id: 'ggblab:plugin',
    description: 'A JupyterLab extension.',
    autoStart: true,
    optional: [_jupyterlab_settingregistry__WEBPACK_IMPORTED_MODULE_2__.ISettingRegistry, _jupyterlab_application__WEBPACK_IMPORTED_MODULE_0__.ILayoutRestorer],
    activate: (app, settingRegistry, restorer) => {
        console.debug(`JupyterLab extension ggblab-${_package_json__WEBPACK_IMPORTED_MODULE_6__.version} is activated!`);
        // Pragmatic global registration (option B): register a `jupyter.ggblab`
        // comm target on all currently running kernels so kernels that open
        // comms to that target will be delivered to the front-end. Keep the
        // returned unregister function so we can clean up on unload.
        let _unregisterGlobalGGBlab = null;
        (0,_widgets__WEBPACK_IMPORTED_MODULE_5__.registerGlobalGGBlabCommTargets)(app)
            .then(unreg => {
            _unregisterGlobalGGBlab = unreg;
        })
            .catch(e => console.warn('Failed to register global ggblab comm targets', e));
        // Ensure we clean up registrations when the page unloads to avoid
        // leaving dangling front-end KernelConnection objects.
        window.addEventListener('beforeunload', () => {
            _unregisterGlobalGGBlab === null || _unregisterGlobalGGBlab === void 0 ? void 0 : _unregisterGlobalGGBlab();
        });
        if (settingRegistry) {
            settingRegistry
                .load(plugin.id)
                .then(settings => {
                console.debug('ggblab settings loaded:', settings.composite);
            })
                .catch(reason => {
                console.error('Failed to load settings for ggblab.', reason);
            });
        }
        const { commands } = app;
        // Tracker for created GeoGebra widgets so they can be restored after reload
        // @ts-ignore: cross-package Lumino types may differ in consumers
        const tracker = new _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.WidgetTracker({
            namespace: 'ggblab-tracker'
        });
        const command = CommandIDs.create;
        commands.addCommand(command, {
            caption: 'Create a new React Widget',
            label: 'React Widget',
            icon: args => (args['isPalette'] ? undefined : _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_3__.reactIcon),
            execute: async (args) => {
                console.debug('socketPath:', args['socketPath']);
                // Precompute widget id so we can detect and remove any existing panel
                const idPart = (args['kernelId'] || '').substring(0, 8);
                const widgetId = `ggblab-${idPart}`;
                // If a widget with the same id exists, close and remove it first.
                try {
                    const existing = tracker.find((w) => w.id === widgetId);
                    if (existing) {
                        try {
                            existing.close();
                        }
                        catch (e) {
                            console.warn('Failed to close existing widget:', e);
                        }
                        try {
                            // tracker.remove may return a Promise
                            await tracker.remove(existing);
                        }
                        catch (e) {
                            // non-fatal
                            console.warn('Failed to remove existing widget from tracker:', e);
                        }
                    }
                }
                catch (e) {
                    // If tracker API differs, ignore and continue
                }
                // Centralized widget-manager factory (currently returns `undefined`)
                // to avoid interfering with ipywidgets. See src/widgetManager.ts
                // for future changes to this behavior.
                const widgetManager = (0,_widgets__WEBPACK_IMPORTED_MODULE_5__.createWidgetManager)();
                const content = new _widget__WEBPACK_IMPORTED_MODULE_4__.GeoGebraWidget({
                    kernelId: args['kernelId'] || '',
                    commTarget: args['commTarget'] || '',
                    insertMode: args['insertMode'] || 'split-right',
                    socketPath: args['socketPath'] || '',
                    appName: args['appName'] || 'suite',
                    wsPort: args['wsPort'] || 8888,
                    widgetManager: widgetManager
                });
                // @ts-ignore: cross-package Lumino Title/Layout type mismatch
                const widget = new _jupyterlab_apputils__WEBPACK_IMPORTED_MODULE_1__.MainAreaWidget({ content });
                // make widget id unique so restorer can identify it later
                widget.id = widgetId;
                widget.title.label = `GeoGebra (${idPart})`;
                widget.title.icon = _jupyterlab_ui_components__WEBPACK_IMPORTED_MODULE_3__.reactIcon;
                // register with tracker so state will be saved for restoration
                try {
                    await tracker.add(widget);
                }
                catch (e) {
                    console.warn('Failed to add widget to tracker:', e);
                }
                app.shell.add(widget, 'main', {
                    mode: args['insertMode'] || 'split-right'
                });
            }
        });
        // palette.addItem({
        //   command,
        //   category: "Tutorial",
        // });
        if (restorer) {
            // Note: we may in future support restoring the applet's internal
            // state from an autosave (e.g. localStorage or a persistent store).
            // That would involve fetching a saved XML/Base64 snapshot and
            // passing it through `args` or a dedicated `initialXml` prop so the
            // recreated widget can rehydrate the GeoGebra applet.
            restorer.restore(tracker, {
                command,
                // use widget.id as the saved name so it is unique per widget
                name: widget => widget.id,
                // reconstruct args (kernelId) from the saved widget id so the
                // command can recreate the widget with the same kernel association
                args: widget => {
                    // Prefer to read the original creation props from the widget content
                    const content = (widget && widget.content) || {};
                    const p = content.props || {};
                    // Fallback to reconstructing kernelId from the widget id if not present
                    const id = widget.id || '';
                    const kernelId = p.kernelId || (id.startsWith('ggblab-') ? id.slice('ggblab-'.length) : '');
                    return {
                        kernelId,
                        commTarget: p.commTarget || '',
                        socketPath: p.socketPath || '',
                        appName: p.appName || 'suite',
                        wsPort: p.wsPort || 8888,
                        insertMode: p.insertMode || 'split-right'
                    };
                }
            });
        }
        // Launcher integration removed: no launcher item will be added.
    }
};
// Export both the main plugin and the manager-detection plugin so JupyterLab
// will activate the manager probe and allow `setWidgetManager` to be called
// when the jupyter-widgets manager becomes available.
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ([plugin, _widgets__WEBPACK_IMPORTED_MODULE_7__["default"]]);


/***/ },

/***/ "./lib/widgets/register_widget_manager_plugin.js"
/*!*******************************************************!*\
  !*** ./lib/widgets/register_widget_manager_plugin.js ***!
  \*******************************************************/
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _widgetManager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./widgetManager */ "./lib/widgets/widgetManager.js");

/**
 * Plugin that tries to detect the jupyter-widgets manager plugins at runtime
 * and wraps their activate function to call our global registrar
 * `window.__ggblab_register_widget_manager(kernelId, manager)` when a
 * per-kernel manager instance becomes available.
 */
const registerWidgetManagerPlugin = {
    id: 'ggblab:register-widget-manager',
    autoStart: true,
    activate: (app) => {
        try {
            window.__ggblab_register_widget_manager = function (kernelId, manager) {
                try {
                    (0,_widgetManager__WEBPACK_IMPORTED_MODULE_0__.setWidgetManager)(manager);
                    console.debug('ggblab: __ggblab_register_widget_manager called for', kernelId);
                }
                catch (e) {
                    console.debug('ggblab: __ggblab_register_widget_manager handler failed', e);
                }
            };
        }
        catch (e) {
            console.debug('ggblab: failed to define __ggblab_register_widget_manager', e);
        }
        (async () => {
            try {
                let mod = null;
                try {
                    if (typeof globalThis.require === 'function') {
                        mod = globalThis.require('@jupyter-widgets/jupyterlab-manager');
                        console.debug('ggblab: register-widget-manager found jupyter-widgets module via global require');
                    }
                }
                catch (e) {
                    console.debug('ggblab: jupyter-widgets manager not available via global require', e);
                    mod = null;
                }
                if (!mod) {
                    console.debug('ggblab: jupyter-widgets manager not available for auto-plugin');
                    return;
                }
                const candidates = Array.isArray(mod.default) ? mod.default : Array.isArray(mod) ? mod : [];
                console.debug('ggblab: register-widget-manager candidates count', candidates.length);
                for (const p of candidates) {
                    if (!p || typeof p.activate !== 'function') {
                        continue;
                    }
                    const origActivate = p.activate.bind(p);
                    // Wrap activate to probe its args for manager instances and register them
                    // with our global registrar when detected.
                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                    // @ts-ignore
                    p.activate = function (appArg, ...args) {
                        console.info('ggblab: wrapped widget-manager activate called', { argsCount: args.length });
                        const summaries = args.map((a) => {
                            try {
                                return { type: typeof a, keys: Object.keys(a || {}).slice(0, 10) };
                            }
                            catch (e) {
                                return { type: typeof a };
                            }
                        });
                        console.debug('ggblab: wrapped activate args summary', summaries);
                        const result = origActivate(appArg, ...args);
                        try {
                            for (const a of args) {
                                if (!a || typeof a !== 'object')
                                    continue;
                                const isManager = typeof a.create_view === 'function' || typeof a.display_view_for_model === 'function' || !!a._create_views_for_model;
                                if (!isManager)
                                    continue;
                                const manager = a;
                                let kernelId = '';
                                try {
                                    kernelId = (manager.context && manager.context.session && manager.context.session.kernel && manager.context.session.kernel.id) || (manager.kernel && manager.kernel.id) || '';
                                }
                                catch (e) {
                                    kernelId = '';
                                }
                                if (kernelId && window.__ggblab_register_widget_manager) {
                                    try {
                                        window.__ggblab_register_widget_manager(kernelId, manager);
                                        console.debug('ggblab: auto-registered widgetManager for kernel', kernelId);
                                    }
                                    catch (e) {
                                        console.warn('ggblab: failed to auto-register widgetManager', e);
                                    }
                                    try {
                                        (0,_widgetManager__WEBPACK_IMPORTED_MODULE_0__.setWidgetManager)(manager);
                                    }
                                    catch (e) {
                                        console.debug('ggblab: setWidgetManager failed', e);
                                    }
                                }
                                else if (manager && manager.context && manager.context.session) {
                                    try {
                                        const sess = manager.context.session;
                                        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                                        // @ts-ignore
                                        if (sess.kernelChanged && typeof sess.kernelChanged.connect === 'function') {
                                            const handler = (_s, kernel) => {
                                                try {
                                                    const kid = kernel ? kernel.id : '';
                                                    if (kid && window.__ggblab_register_widget_manager) {
                                                        window.__ggblab_register_widget_manager(kid, manager);
                                                        console.debug('ggblab: auto-registered widgetManager on kernelChanged for', kid);
                                                        try {
                                                            (0,_widgetManager__WEBPACK_IMPORTED_MODULE_0__.setWidgetManager)(manager);
                                                        }
                                                        catch (e) {
                                                            console.debug('ggblab: setWidgetManager failed', e);
                                                        }
                                                        try { /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ /* @ts-ignore */
                                                            sess.kernelChanged.disconnect(handler);
                                                        }
                                                        catch (ee) {
                                                            console.debug('ggblab: ignored', ee);
                                                        }
                                                    }
                                                }
                                                catch (ee) {
                                                    console.debug('ggblab: ignored', ee);
                                                }
                                            };
                                            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                                            // @ts-ignore
                                            sess.kernelChanged.connect(handler);
                                        }
                                    }
                                    catch (e) {
                                        console.debug('ggblab: ignored', e);
                                    }
                                }
                            }
                        }
                        catch (e) {
                            console.warn('ggblab: error while probing widget-manager activate args', e);
                        }
                        return result;
                    };
                }
            }
            catch (e) {
                console.debug('ggblab: jupyter-widgets manager not available for auto-plugin', e);
            }
        })();
    }
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (registerWidgetManagerPlugin);


/***/ },

/***/ "./lib/widgets/widgetManager.js"
/*!**************************************!*\
  !*** ./lib/widgets/widgetManager.js ***!
  \**************************************/
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ENABLE_RUNNING_CHANGED: () => (/* binding */ ENABLE_RUNNING_CHANGED),
/* harmony export */   createWidgetManager: () => (/* binding */ createWidgetManager),
/* harmony export */   registerGlobalGGBlabCommTargets: () => (/* binding */ registerGlobalGGBlabCommTargets),
/* harmony export */   registerWidgetCommTargets: () => (/* binding */ registerWidgetCommTargets),
/* harmony export */   setWidgetManager: () => (/* binding */ setWidgetManager)
/* harmony export */ });
/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jupyterlab/services */ "webpack/sharing/consume/default/@jupyterlab/services");
/* harmony import */ var _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jupyterlab/coreutils */ "webpack/sharing/consume/default/@jupyterlab/coreutils");
/* harmony import */ var _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__);
// Minimal widget-manager adapter extracted from plugin/widget code.
// This module centralizes how a frontend WidgetManager (ipywidgets bridge)
// would be created or provided.
let _injectedWidgetManager = undefined;
function setWidgetManager(m) {
    _injectedWidgetManager = m;
    try {
        globalThis.__GGWIDGET_MANAGER__ = m;
        try {
            console.debug('ggblab: setWidgetManager called', { hasManager: !!m });
        }
        catch (e) {
            // ignore
        }
    }
    catch (e) {
        // ignore
    }
}
function detectWidgetManager() {
    const g = globalThis;
    try {
        console.debug('ggblab: detectWidgetManager probing globals');
    }
    catch (e) {
        // ignore
    }
    if (g && g.__GGWIDGET_MANAGER__) {
        try {
            console.debug('ggblab: detected manager via __GGWIDGET_MANAGER__');
        }
        catch (_) { }
        return g.__GGWIDGET_MANAGER__;
    }
    if (g && g.jupyterWidgetManager) {
        try {
            console.debug('ggblab: detected manager via jupyterWidgetManager');
        }
        catch (_) { }
        return g.jupyterWidgetManager;
    }
    if (g && g.widgetManager) {
        try {
            console.debug('ggblab: detected manager via widgetManager');
        }
        catch (_) { }
        return g.widgetManager;
    }
    try {
        console.debug('ggblab: no widget manager detected in globals');
    }
    catch (_) { }
    return undefined;
}
function createWidgetManager() {
    if (_injectedWidgetManager) {
        return _injectedWidgetManager;
    }
    return detectWidgetManager();
}
function registerWidgetCommTargets(kernelConn, opts) {
    const managerAvailable = Boolean(createWidgetManager());
    const ENABLE_WIDGET_COMM_PASSTHROUGH = !managerAvailable;
    if (!ENABLE_WIDGET_COMM_PASSTHROUGH) {
        opts.dbg && opts.dbg('Widget comm passthrough disabled: WidgetManager present');
        return () => { };
    }
    opts.dbg && opts.dbg('Widget comm passthrough enabled: no WidgetManager detected');
    const dbg = opts.dbg || (() => { });
    const simpleHandler = (commOp, msg) => {
        dbg('widget comm opened (jupyter.widget)', commOp, msg);
        try {
            commOp.onMsg = async (m) => {
                var _a;
                const content = ((_a = m === null || m === void 0 ? void 0 : m.content) === null || _a === void 0 ? void 0 : _a.data) || m;
                try {
                    const command = typeof content === 'string' ? JSON.parse(content) : content;
                    let rmsg = null;
                    const appletApi = opts.getAppletApi();
                    if (command.type === 'command' && appletApi && typeof appletApi.evalCommandGetLabels === 'function') {
                        const label = appletApi.evalCommandGetLabels(command.payload);
                        rmsg = JSON.stringify({ type: 'created', id: command.id, payload: label });
                    }
                    else if (command.type === 'function' && appletApi) {
                        const apiName = command.payload.name;
                        const args = command.payload.args;
                        let value = [];
                        (Array.isArray(apiName) ? apiName : [apiName]).forEach((f) => {
                            if (typeof opts.isArrayOfArrays === 'function' && opts.isArrayOfArrays(args)) {
                                const v2 = [];
                                args.forEach((a) => {
                                    v2.push(typeof appletApi[f] === 'function' ? appletApi[f](...a) : null);
                                });
                                value.push(v2);
                            }
                            else {
                                value.push(args ? (typeof appletApi[f] === 'function' ? appletApi[f](...args) : null) : typeof appletApi[f] === 'function' ? appletApi[f]() : null);
                            }
                        });
                        value = Array.isArray(apiName) ? value : value[0];
                        rmsg = JSON.stringify({ type: 'value', id: command.id, payload: { value } });
                    }
                    if (rmsg) {
                        try {
                            commOp.send(rmsg);
                        }
                        catch (e) {
                            dbg('commOp.send failed', e);
                        }
                        try {
                            await opts.callRemoteSocketSend(rmsg);
                        }
                        catch (e) {
                            dbg('callRemoteSocketSend failed', e);
                        }
                    }
                }
                catch (e) {
                    dbg('Error handling widget comm message', e);
                }
            };
        }
        catch (e) {
            dbg('Failed to attach onMsg to widget comm', e);
        }
    };
    try {
        kernelConn.registerCommTarget('jupyter.widget', simpleHandler);
        kernelConn.registerCommTarget('jupyter.widget.control', simpleHandler);
    }
    catch (e) {
        dbg('Widget comm target registration failed', e);
    }
    return () => {
        try {
            if (typeof kernelConn.unregisterCommTarget === 'function') {
                kernelConn.unregisterCommTarget('jupyter.widget');
                kernelConn.unregisterCommTarget('jupyter.widget.control');
            }
        }
        catch (e) {
            dbg('Error during widget comm cleanup', e);
        }
    };
}


const ENABLE_RUNNING_CHANGED = false;
async function registerGlobalGGBlabCommTargets(app) {
    const baseUrl = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__.PageConfig.getBaseUrl();
    const token = _jupyterlab_coreutils__WEBPACK_IMPORTED_MODULE_1__.PageConfig.getToken();
    const settings = _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.ServerConnection.makeSettings({ baseUrl: baseUrl, token: token, appendToken: true });
    const registry = new Map();
    const dbg = (..._args) => {
        if (!ENABLE_RUNNING_CHANGED) {
            return;
        }
        console.debug(..._args);
    };
    const registerKernel = (k) => {
        const id = k.id || k.kernelId || (k.model && k.model.id) || null;
        if (!id)
            return;
        if (registry.has(id)) {
            dbg('Already registered jupyter.ggblab for kernel', id);
            return;
        }
        try {
            const manager = createWidgetManager();
            if (manager && typeof manager.registerGGBlabHandler === 'function') {
                try {
                    const unregisterFromManager = manager.registerGGBlabHandler(id, (commOp, msg) => {
                        try { }
                        catch (e) {
                            console.warn('Error delegating jupyter.ggblab to manager', e);
                        }
                    });
                    registry.set(id, () => { unregisterFromManager && unregisterFromManager(); });
                    return;
                }
                catch (e) {
                    console.warn('Widget manager failed to register jupyter.ggblab', id, e);
                }
            }
            const kc = new _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelConnection({ model: { name: 'python3', id }, serverSettings: settings });
            try {
                kc.registerCommTarget('jupyter.ggblab', (commOp, msg) => {
                    try {
                        dbg('jupyter.ggblab comm opened', { kernelId: id, msg });
                        commOp.onMsg = (m) => { dbg('jupyter.ggblab message', { kernelId: id, m }); };
                    }
                    catch (e) {
                        console.warn('Error in jupyter.ggblab handler', e);
                    }
                });
            }
            catch (e) {
                console.warn('Failed to register jupyter.ggblab on kernel', id, e);
            }
            const unregister = () => {
                try {
                    if (typeof kc.unregisterCommTarget === 'function') {
                        kc.unregisterCommTarget('jupyter.ggblab');
                    }
                }
                catch (e) {
                    console.warn('Error while unregistering jupyter.ggblab', e);
                }
            };
            registry.set(id, unregister);
        }
        catch (e) {
            console.warn('Failed to create KernelConnection for kernel', id, e);
        }
    };
    const unregisterKernel = (id) => {
        const fn = registry.get(id);
        if (fn) {
            try {
                fn();
            }
            catch (e) {
                console.warn('Error during unregister for kernel', id, e);
            }
            registry.delete(id);
        }
    };
    try {
        const kernels = await _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.listRunning();
        (kernels || []).forEach(registerKernel);
    }
    catch (e) {
        console.warn('Failed to list running kernels for ggblab registration', e);
    }
    const onRunningChanged = async () => {
        try {
            const current = await _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.listRunning();
            const currentIds = new Set((current || []).map((k) => k.id));
            (current || []).forEach(k => registerKernel(k));
            Array.from(registry.keys()).forEach(id => { if (!currentIds.has(id)) {
                unregisterKernel(id);
            } });
        }
        catch (e) {
            console.warn('Error handling runningChanged for ggblab', e);
        }
    };
    try {
        if (ENABLE_RUNNING_CHANGED) {
            try {
                if (app && app.serviceManager && app.serviceManager.sessions && typeof app.serviceManager.sessions.runningChanged === 'object' && typeof app.serviceManager.sessions.runningChanged.connect === 'function') {
                    app.serviceManager.sessions.runningChanged.connect(onRunningChanged);
                }
                else if (_jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.runningChanged && typeof _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.runningChanged.connect === 'function') {
                    _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.runningChanged.connect(onRunningChanged);
                }
                else {
                    const pollInterval = 5000;
                    const timer = setInterval(onRunningChanged, pollInterval);
                    registry.set('__poll_timer__', () => clearInterval(timer));
                }
            }
            catch (e) {
                console.warn('Failed to attach runningChanged listener', e);
            }
        }
        else {
            dbg('Kernel runningChanged detection is disabled (ENABLE_RUNNING_CHANGED=false)');
        }
    }
    catch (e) {
        console.warn('Failed to attach runningChanged listener', e);
    }
    return () => {
        try {
            if (app && app.serviceManager && app.serviceManager.sessions && typeof app.serviceManager.sessions.runningChanged === 'object' && typeof app.serviceManager.sessions.runningChanged.disconnect === 'function') {
                app.serviceManager.sessions.runningChanged.disconnect(onRunningChanged);
            }
            else if (_jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.runningChanged && typeof _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.runningChanged.disconnect === 'function') {
                _jupyterlab_services__WEBPACK_IMPORTED_MODULE_0__.KernelAPI.runningChanged.disconnect(onRunningChanged);
            }
            Array.from(registry.keys()).forEach(k => { const fn = registry.get(k); if (fn) {
                fn();
            } });
            registry.clear();
        }
        catch (e) {
            console.warn('Error during global ggblab unregister-all', e);
        }
    };
}


/***/ },

/***/ "./package.json"
/*!**********************!*\
  !*** ./package.json ***!
  \**********************/
(module) {

module.exports = /*#__PURE__*/JSON.parse('{"name":"ggblab","version":"1.4.2","description":"A JupyterLab extension for learning geometry and Python programming side-by-side with GeoGebra.","keywords":["jupyter","jupyterlab","jupyterlab-extension"],"homepage":"https://github.com/moyhig-ecs/ggblab#readme","bugs":{"url":"https://github.com/moyhig-ecs/ggblab/issues"},"license":"BSD-3-Clause","author":{"name":"Manabu Higashida","email":"manabu@higashida.net"},"files":["lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}","style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}","src/**/*.{ts,tsx}","schema/*.json"],"main":"lib/index.js","types":"lib/index.d.ts","style":"style/index.css","repository":{"type":"git","url":"https://github.com/moyhig-ecs/ggblab"},"scripts":{"build":"jlpm build:lib && jlpm build:labextension:dev","build:prod":"jlpm clean && jlpm build:lib:prod && jlpm build:labextension","build:labextension":"jupyter labextension build .","build:labextension:dev":"jupyter labextension build --development True .","build:lib":"tsc --sourceMap","build:lib:prod":"tsc","clean":"jlpm clean:lib","clean:lib":"rimraf lib tsconfig.tsbuildinfo","clean:lintcache":"rimraf .eslintcache .stylelintcache","clean:labextension":"rimraf ggblab/labextension ggblab/_version.py","clean:all":"jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache","eslint":"jlpm eslint:check --fix","eslint:check":"eslint . --cache --ext .ts,.tsx","install:extension":"jlpm build","lint":"jlpm stylelint && jlpm prettier && jlpm eslint","lint:check":"jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check","prettier":"jlpm prettier:base --write --list-different","prettier:base":"prettier \\"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\\"","prettier:check":"jlpm prettier:base --check","stylelint":"jlpm stylelint:check --fix","stylelint:check":"stylelint --cache \\"style/**/*.css\\"","test":"jest --coverage","watch":"run-p watch:src watch:labextension","watch:src":"tsc -w --sourceMap","watch:labextension":"jupyter labextension watch ."},"dependencies":{"@jupyter-widgets/base":"^4.0.0","@jupyterlab/application":"^4.0.0","@jupyterlab/apputils":"^4.6.1","@jupyterlab/launcher":"^4.5.1","@jupyterlab/settingregistry":"^4.0.0","@lumino/widgets":"^2.7.2","@marshallku/react-postscribe":"^0.2.0","react-meta-tags":"^1.0.1"},"devDependencies":{"@jupyterlab/builder":"^4.5.2","@jupyterlab/testutils":"^4.0.0","@types/jest":"^29.2.0","@types/json-schema":"^7.0.11","@types/react":"^18.0.26","@types/react-addons-linked-state-mixin":"^0.14.22","@typescript-eslint/eslint-plugin":"^6.1.0","@typescript-eslint/parser":"^6.1.0","css-loader":"^6.7.1","eslint":"^8.36.0","eslint-config-prettier":"^8.8.0","eslint-plugin-prettier":"^5.0.0","jest":"^29.2.0","npm-run-all2":"^7.0.1","prettier":"^3.0.0","rimraf":"^5.0.1","source-map-loader":"^1.0.2","style-loader":"^3.3.1","stylelint":"^15.10.1","stylelint-config-recommended":"^13.0.0","stylelint-config-standard":"^34.0.0","stylelint-csstree-validator":"^3.0.0","stylelint-prettier":"^4.0.0","typescript":"~5.5.4","yjs":"^13.5.0"},"resolutions":{"lib0":"0.2.111"},"sideEffects":["style/*.css","style/index.js"],"styleModule":"style/index.js","publishConfig":{"access":"public"},"jupyterlab":{"extension":true,"outputDir":"ggblab/labextension","schemaDir":"schema"},"eslintIgnore":["node_modules","dist","coverage","**/*.d.ts","tests","**/__tests__","ui-tests"],"eslintConfig":{"extends":["eslint:recommended","plugin:@typescript-eslint/eslint-recommended","plugin:@typescript-eslint/recommended","plugin:prettier/recommended"],"parser":"@typescript-eslint/parser","parserOptions":{"project":"tsconfig.json","sourceType":"module"},"plugins":["@typescript-eslint"],"rules":{"@typescript-eslint/naming-convention":["error",{"selector":"interface","format":["PascalCase"],"custom":{"regex":"^I[A-Z]","match":true}}],"@typescript-eslint/no-unused-vars":["warn",{"args":"none"}],"@typescript-eslint/no-explicit-any":"off","@typescript-eslint/no-namespace":"off","@typescript-eslint/no-use-before-define":"off","@typescript-eslint/quotes":["error","single",{"avoidEscape":true,"allowTemplateLiterals":false}],"curly":["error","all"],"eqeqeq":"error","prefer-arrow-callback":"error"}},"prettier":{"singleQuote":true,"trailingComma":"none","arrowParens":"avoid","endOfLine":"auto","printWidth":200,"bracketSameLine":true,"jsxSingleQuote":true,"proseWrap":"never","overrides":[{"files":"package.json","options":{"tabWidth":4}}]},"stylelint":{"extends":["stylelint-config-recommended","stylelint-config-standard","stylelint-prettier/recommended"],"plugins":["stylelint-csstree-validator"],"rules":{"csstree/validator":true,"property-no-vendor-prefix":null,"selector-class-pattern":"^([a-z][A-z\\\\d]*)(-[A-z\\\\d]+)*$","selector-no-vendor-prefix":null,"value-no-vendor-prefix":null}}}');

/***/ }

}]);
//# sourceMappingURL=lib_index_js.dd3e16761be387b9d33c.js.map