(function () {
  const WIDGET_SHELL_SELECTOR = ".js-gia-widget-shell";
  const WIDGET_SPAWN_SELECTOR = ".js-widget-spawn-trigger";
  const WIDGET_ACTION_SELECTOR = ".js-gia-widget-action";
  const TASKBAR_SELECTOR = "#gia-taskbar";
  const TASKBAR_ITEMS_SELECTOR = "#gia-taskbar-items";
  const WORKSPACE_STASH_SELECTOR = "#gia-workspace-stash";
  const SNAP_ASSISTANT_SELECTOR = "#gia-snap-assistant";
  const SNAP_ASSISTANT_OPTIONS_SELECTOR = "#gia-snap-assistant-options";
  const SNAP_ASSISTANT_CLOSE_SELECTOR = ".js-gia-snap-assistant-close";
  const MOBILE_MEDIA_QUERY = "(max-width: 768px)";
  const DESKTOP_MEDIA_QUERY = "(min-width: 1216px)";
  const GRID_COLUMNS = 12;
  const GRID_ROWS = 12;
  const MIN_QUARTER_TILE_HEIGHT = 340;
  const MIN_QUARTER_TILE_WIDTH = 420;
  const assetPromises = {
    styles: {},
    scripts: {},
  };
  const workspaceState = {
    order: [],
    minimized: new Map(),
    activeWidgetId: "",
    snapLeftId: "",
    snapRightId: "",
    snapAssistantSourceId: "",
  };

  function withDocumentRoot(root) {
    return root && typeof root.querySelectorAll === "function" ? root : document;
  }

  function toArray(value) {
    return Array.isArray(value) ? value : Array.from(value || []);
  }

  function getGridElement() {
    return window.gridElement || document.getElementById("grid-stack-main");
  }

  function getTaskbar() {
    return document.querySelector(TASKBAR_SELECTOR);
  }

  function getTaskbarItems() {
    return document.querySelector(TASKBAR_ITEMS_SELECTOR);
  }

  function getWorkspaceStash() {
    return document.querySelector(WORKSPACE_STASH_SELECTOR);
  }

  function getSnapAssistant() {
    return document.querySelector(SNAP_ASSISTANT_SELECTOR);
  }

  function getSnapAssistantOptions() {
    return document.querySelector(SNAP_ASSISTANT_OPTIONS_SELECTOR);
  }

  function getGridViewportMetrics() {
    const gridElement = getGridElement();
    const gridColumn = gridElement && gridElement.parentElement ? gridElement.parentElement : null;
    const main = gridColumn && gridColumn.parentElement ? gridColumn.parentElement : null;
    const source = gridColumn || main;
    const rect = source && source.getBoundingClientRect ? source.getBoundingClientRect() : null;
    return {
      width: Math.max(0, Math.floor((rect && rect.width) || window.innerWidth || 0)),
      height: Math.max(0, Math.floor((rect && rect.height) || window.innerHeight || 0)),
    };
  }

  function getWidgetNode(widgetId) {
    const id = String(widgetId || "").trim();
    return id ? document.getElementById(id) : null;
  }

  function syncKnownWidgetOrder() {
    const ordered = workspaceState.order.filter(function (widgetId, index, items) {
      return !!widgetId && items.indexOf(widgetId) === index && hasWidget(widgetId);
    });
    toArray(document.querySelectorAll(".grid-stack-item[id]")).forEach(function (node) {
      if (!ordered.includes(node.id)) {
        ordered.push(node.id);
      }
    });
    workspaceState.order = ordered;
    return ordered;
  }

  function getVisibleWidgetNodes() {
    const gridElement = getGridElement();
    return syncKnownWidgetOrder()
      .map(getWidgetNode)
      .filter(function (node) {
        return !!(node && node.parentElement === gridElement);
      });
  }

  function getVisibleWidgetIds() {
    return getVisibleWidgetNodes().map(function (node) {
      return node.id;
    });
  }

  function hasWidget(widgetId) {
    return !!getWidgetNode(widgetId);
  }

  function executeWidgetScript(scriptNode) {
    if (!scriptNode) {
      return;
    }
    const replacement = document.createElement("script");
    toArray(scriptNode.attributes).forEach(function (attribute) {
      replacement.setAttribute(attribute.name, attribute.value);
    });
    replacement.text = scriptNode.textContent || "";
    document.body.appendChild(replacement);
    replacement.remove();
    scriptNode.remove();
  }

  function parseAssetList(value) {
    return String(value || "")
      .split("|")
      .map(function (item) {
        return String(item || "").trim();
      })
      .filter(Boolean);
  }

  function findStylesheet(href) {
    return toArray(document.querySelectorAll('link[rel="stylesheet"]')).find(
      function (node) {
        return node.getAttribute("href") === href;
      }
    );
  }

  function findScript(src) {
    return toArray(document.querySelectorAll("script[src]")).find(function (node) {
      return node.getAttribute("src") === src;
    });
  }

  function ensureStylesheet(href) {
    if (!href) {
      return Promise.resolve(null);
    }
    if (assetPromises.styles[href]) {
      return assetPromises.styles[href];
    }
    const existing = findStylesheet(href);
    if (existing) {
      assetPromises.styles[href] = Promise.resolve(existing);
      return assetPromises.styles[href];
    }
    assetPromises.styles[href] = new Promise(function (resolve) {
      const node = document.createElement("link");
      node.rel = "stylesheet";
      node.href = href;
      node.addEventListener(
        "load",
        function () {
          resolve(node);
        },
        { once: true }
      );
      node.addEventListener(
        "error",
        function () {
          resolve(node);
        },
        { once: true }
      );
      document.head.appendChild(node);
    });
    return assetPromises.styles[href];
  }

  function ensureScript(src) {
    if (!src) {
      return Promise.resolve(null);
    }
    if (assetPromises.scripts[src]) {
      return assetPromises.scripts[src];
    }
    const existing = findScript(src);
    if (existing) {
      assetPromises.scripts[src] = Promise.resolve(existing);
      return assetPromises.scripts[src];
    }
    assetPromises.scripts[src] = new Promise(function (resolve) {
      const node = document.createElement("script");
      node.src = src;
      node.async = false;
      node.addEventListener(
        "load",
        function () {
          resolve(node);
        },
        { once: true }
      );
      node.addEventListener(
        "error",
        function () {
          resolve(node);
        },
        { once: true }
      );
      document.head.appendChild(node);
    });
    return assetPromises.scripts[src];
  }

  function ensureContainerAssets(container) {
    if (!container) {
      return Promise.resolve();
    }
    const styleHrefs = parseAssetList(container.getAttribute("data-gia-style-hrefs"));
    const scriptSrcs = parseAssetList(container.getAttribute("data-gia-script-srcs"));
    const styleTasks = styleHrefs.map(function (href) {
      return ensureStylesheet(href);
    });
    const scriptChain = scriptSrcs.reduce(function (promise, src) {
      return promise.then(function () {
        return ensureScript(src);
      });
    }, Promise.resolve());
    return Promise.all(styleTasks).then(function () {
      return scriptChain;
    });
  }

  function getWidgetTitle(widgetNode) {
    if (!widgetNode) {
      return "Window";
    }
    const heading = widgetNode.querySelector(".gia-widget-title");
    const title = String(heading ? heading.textContent || "" : "").trim();
    return title || "Window";
  }

  function getWidgetIconClass(widgetNode) {
    if (!widgetNode) {
      return "fa-solid fa-window-maximize";
    }
    const icon = widgetNode.querySelector(".gia-widget-heading-icon i");
    const value = String(icon ? icon.className || "" : "").trim();
    return value || "fa-solid fa-window-maximize";
  }

  function clearSnapAssistant() {
    workspaceState.snapAssistantSourceId = "";
    const assistant = getSnapAssistant();
    if (assistant) {
      assistant.classList.add("is-hidden");
    }
    const options = getSnapAssistantOptions();
    if (options) {
      options.innerHTML = "";
    }
  }

  function normalizeSnapState() {
    if (!hasWidget(workspaceState.snapLeftId)) {
      workspaceState.snapLeftId = "";
    }
    if (!hasWidget(workspaceState.snapRightId)) {
      workspaceState.snapRightId = "";
    }
    if (workspaceState.snapLeftId && workspaceState.snapLeftId === workspaceState.snapRightId) {
      workspaceState.snapRightId = "";
    }
    if (
      workspaceState.snapAssistantSourceId
      && workspaceState.snapAssistantSourceId !== workspaceState.snapLeftId
    ) {
      workspaceState.snapAssistantSourceId = "";
    }
  }

  function setActiveWidget(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    workspaceState.activeWidgetId = id;
    toArray(document.querySelectorAll(".grid-stack-item.is-gia-active")).forEach(
      function (node) {
        node.classList.remove("is-gia-active");
      }
    );
    const widgetNode = getWidgetNode(id);
    if (widgetNode) {
      widgetNode.classList.add("is-gia-active");
    }
    renderTaskbar();
  }

  function bindWidgetLifecycle(widgetNode) {
    if (!widgetNode || widgetNode.dataset.giaWidgetBound === "1") {
      return;
    }
    widgetNode.dataset.giaWidgetBound = "1";
    widgetNode.addEventListener("pointerdown", function () {
      setActiveWidget(widgetNode.id);
    });
  }

  function registerWidget(widgetNode, insertIndex) {
    if (!widgetNode || !widgetNode.id) {
      return;
    }
    if (!workspaceState.order.includes(widgetNode.id)) {
      if (typeof insertIndex === "number" && insertIndex >= 0) {
        const boundedIndex = Math.min(insertIndex, workspaceState.order.length);
        workspaceState.order.splice(boundedIndex, 0, widgetNode.id);
      } else {
        workspaceState.order.push(widgetNode.id);
      }
    }
    bindWidgetLifecycle(widgetNode);
    setActiveWidget(widgetNode.id);
  }

  function renderTaskbar() {
    const taskbar = getTaskbar();
    const itemsNode = getTaskbarItems();
    if (!taskbar || !itemsNode) {
      return;
    }
    const widgetIds = syncKnownWidgetOrder();
    itemsNode.innerHTML = "";
    if (!widgetIds.length) {
      taskbar.classList.add("is-hidden");
      return;
    }
    widgetIds.forEach(function (widgetId) {
      const widgetNode = getWidgetNode(widgetId);
      const minimized = workspaceState.minimized.has(widgetId);
      const meta = minimized
        ? (workspaceState.minimized.get(widgetId) || {})
        : {
            title: getWidgetTitle(widgetNode),
            iconClass: getWidgetIconClass(widgetNode),
          };
      const item = document.createElement("li");
      if (widgetId === workspaceState.activeWidgetId) {
        item.classList.add("is-active");
      }
      item.classList.add(minimized ? "is-minimized" : "is-open");
      const link = document.createElement("a");
      link.href = "#";
      link.className = "js-gia-taskbar-item";
      link.dataset.giaWidgetId = widgetId;
      link.dataset.giaWidgetState = minimized ? "minimized" : "open";
      link.setAttribute(
        "aria-label",
        (minimized ? "Restore " : "Minimize ") + String(meta.title || "window")
      );
      const iconWrap = document.createElement("span");
      iconWrap.className = "icon is-small";
      const icon = document.createElement("i");
      icon.className = String(meta.iconClass || "fa-solid fa-window-maximize");
      iconWrap.appendChild(icon);
      const label = document.createElement("span");
      label.textContent = String(meta.title || "Window");
      link.appendChild(iconWrap);
      link.appendChild(label);
      item.appendChild(link);
      itemsNode.appendChild(item);
    });
    taskbar.classList.remove("is-hidden");
  }

  function buildSnapAssistantOption(widgetId, widgetNode) {
    const button = document.createElement("button");
    button.type = "button";
    button.className = "button is-light js-gia-snap-target";
    button.dataset.giaWidgetId = widgetId;
    const leftGroup = document.createElement("span");
    leftGroup.className = "is-inline-flex is-align-items-center";
    const iconWrap = document.createElement("span");
    iconWrap.className = "icon is-small mr-2";
    const icon = document.createElement("i");
    icon.className = getWidgetIconClass(widgetNode);
    iconWrap.appendChild(icon);
    const label = document.createElement("span");
    label.textContent = getWidgetTitle(widgetNode);
    leftGroup.appendChild(iconWrap);
    leftGroup.appendChild(label);
    const actionLabel = document.createElement("span");
    actionLabel.textContent = "Use";
    button.appendChild(leftGroup);
    button.appendChild(actionLabel);
    return button;
  }

  function renderSnapAssistant() {
    const assistant = getSnapAssistant();
    const options = getSnapAssistantOptions();
    if (!assistant || !options) {
      return;
    }
    normalizeSnapState();
    const sourceId = workspaceState.snapAssistantSourceId;
    if (!sourceId) {
      clearSnapAssistant();
      return;
    }
    const candidates = getVisibleWidgetNodes().filter(function (node) {
      return node.id !== sourceId;
    });
    if (!candidates.length) {
      clearSnapAssistant();
      return;
    }
    options.innerHTML = "";
    candidates.forEach(function (node) {
      options.appendChild(buildSnapAssistantOption(node.id, node));
    });
    assistant.classList.remove("is-hidden");
  }

  function getLayoutProfile() {
    const isMobile = window.matchMedia(MOBILE_MEDIA_QUERY).matches;
    const isDesktop = window.matchMedia(DESKTOP_MEDIA_QUERY).matches;
    const viewport = getGridViewportMetrics();
    const canFitQuarterTiles = (
      isDesktop
      && viewport.width >= MIN_QUARTER_TILE_WIDTH * 2
      && viewport.height >= MIN_QUARTER_TILE_HEIGHT * 2
    );
    return {
      isMobile: isMobile,
      isDesktop: isDesktop,
      maxVisible: isMobile ? 1 : canFitQuarterTiles ? 4 : 2,
    };
  }

  function syncGridMetrics() {
    if (!window.grid || typeof window.grid.cellHeight !== "function") {
      return;
    }
    const gridElement = getGridElement();
    if (!gridElement) {
      return;
    }
    const viewport = getGridViewportMetrics();
    const height = Math.max(240, viewport.height || 0);
    const cellHeight = Math.max(32, Math.floor(height / GRID_ROWS));
    gridElement.style.height = height + "px";
    window.grid.cellHeight(cellHeight);
    if (typeof window.grid.column === "function") {
      window.grid.column(GRID_COLUMNS);
    }
  }

  function buildDefaultLayout(widgetNodes, profile) {
    if (!widgetNodes.length) {
      return [];
    }
    if (profile.isMobile) {
      return [
        {
          node: widgetNodes[0],
          x: 0,
          y: 0,
          w: GRID_COLUMNS,
          h: GRID_ROWS,
        },
      ];
    }
    if (widgetNodes.length === 1) {
      return [
        {
          node: widgetNodes[0],
          x: 0,
          y: 0,
          w: GRID_COLUMNS,
          h: GRID_ROWS,
        },
      ];
    }
    if (!profile.isDesktop) {
      return widgetNodes.slice(0, 2).map(function (node, index) {
        return {
          node: node,
          x: 0,
          y: index * (GRID_ROWS / 2),
          w: GRID_COLUMNS,
          h: GRID_ROWS / 2,
        };
      });
    }
    if (widgetNodes.length === 2) {
      return widgetNodes.map(function (node, index) {
        return {
          node: node,
          x: index * (GRID_COLUMNS / 2),
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS,
        };
      });
    }
    if (widgetNodes.length === 3) {
      const dominantNode = widgetNodes.find(function (node) {
        return node.id === workspaceState.activeWidgetId;
      }) || widgetNodes[widgetNodes.length - 1];
      const secondaryNodes = widgetNodes.filter(function (node) {
        return node !== dominantNode;
      });
      return [
        {
          node: dominantNode,
          x: 0,
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS,
        },
        {
          node: secondaryNodes[0],
          x: GRID_COLUMNS / 2,
          y: 0,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS / 2,
        },
        {
          node: secondaryNodes[1],
          x: GRID_COLUMNS / 2,
          y: GRID_ROWS / 2,
          w: GRID_COLUMNS / 2,
          h: GRID_ROWS / 2,
        },
      ];
    }
    return widgetNodes.slice(0, 4).map(function (node, index) {
      return {
        node: node,
        x: (index % 2) * (GRID_COLUMNS / 2),
        y: Math.floor(index / 2) * (GRID_ROWS / 2),
        w: GRID_COLUMNS / 2,
        h: GRID_ROWS / 2,
      };
    });
  }

  function buildSnappedLayout(profile) {
    if (profile.isMobile) {
      return null;
    }
    const leftNode = getWidgetNode(workspaceState.snapLeftId);
    const rightNode = getWidgetNode(workspaceState.snapRightId);
    if (!leftNode || !rightNode) {
      return null;
    }
    if (leftNode.parentElement !== getGridElement()) {
      return null;
    }
    if (rightNode.parentElement !== getGridElement()) {
      return null;
    }
    return [
      {
        node: leftNode,
        x: 0,
        y: 0,
        w: GRID_COLUMNS / 2,
        h: GRID_ROWS,
      },
      {
        node: rightNode,
        x: GRID_COLUMNS / 2,
        y: 0,
        w: GRID_COLUMNS / 2,
        h: GRID_ROWS,
      },
    ];
  }

  function detachWidgetFromGrid(widgetNode) {
    if (
      widgetNode
      && window.grid
      && typeof window.grid.removeWidget === "function"
      && widgetNode.parentElement === getGridElement()
    ) {
      window.grid.removeWidget(widgetNode, false, false);
    }
  }

  function attachWidgetToGrid(widgetNode) {
    if (!widgetNode || !window.grid || !getGridElement()) {
      return;
    }
    widgetNode.classList.remove("is-hidden");
    if (widgetNode.parentElement !== getGridElement()) {
      getGridElement().appendChild(widgetNode);
    }
    if (typeof window.grid.makeWidget === "function") {
      window.grid.makeWidget(widgetNode);
    }
    if (window.htmx && typeof window.htmx.process === "function") {
      window.htmx.process(widgetNode);
    }
  }

  function chooseFallbackActiveWidget() {
    const visibleIds = getVisibleWidgetIds();
    if (!visibleIds.length) {
      workspaceState.activeWidgetId = "";
      return;
    }
    workspaceState.activeWidgetId = visibleIds[visibleIds.length - 1];
  }

  function minimizeWidget(widgetId, options) {
    const config = options || {};
    const widgetNode = getWidgetNode(widgetId);
    if (!widgetNode || workspaceState.minimized.has(widgetId)) {
      return;
    }
    workspaceState.minimized.set(widgetId, {
      title: getWidgetTitle(widgetNode),
      iconClass: getWidgetIconClass(widgetNode),
      ts: Date.now(),
    });
    if (workspaceState.activeWidgetId === widgetId) {
      chooseFallbackActiveWidget();
    }
    if (workspaceState.snapLeftId === widgetId) {
      workspaceState.snapLeftId = "";
      workspaceState.snapRightId = "";
      clearSnapAssistant();
    }
    if (workspaceState.snapRightId === widgetId) {
      workspaceState.snapRightId = "";
      clearSnapAssistant();
    }
    detachWidgetFromGrid(widgetNode);
    const stash = getWorkspaceStash();
    if (stash) {
      stash.appendChild(widgetNode);
    }
    widgetNode.classList.add("is-hidden");
    renderTaskbar();
    if (!config.skipLayout) {
      layoutWorkspace();
    }
  }

  function restoreWidget(widgetId, options) {
    const config = options || {};
    const widgetNode = getWidgetNode(widgetId);
    if (!widgetNode || !workspaceState.minimized.has(widgetId)) {
      return;
    }
    workspaceState.minimized.delete(widgetId);
    attachWidgetToGrid(widgetNode);
    registerWidget(widgetNode);
    renderTaskbar();
    if (!config.skipLayout) {
      layoutWorkspace();
    }
  }

  function clearWidgetState(widgetId) {
    workspaceState.order = workspaceState.order.filter(function (item) {
      return item !== widgetId;
    });
    workspaceState.minimized.delete(widgetId);
    if (workspaceState.activeWidgetId === widgetId) {
      workspaceState.activeWidgetId = "";
    }
    if (workspaceState.snapLeftId === widgetId) {
      workspaceState.snapLeftId = "";
    }
    if (workspaceState.snapRightId === widgetId) {
      workspaceState.snapRightId = "";
    }
    if (workspaceState.snapAssistantSourceId === widgetId) {
      clearSnapAssistant();
    }
  }

  function removeWidget(widgetId) {
    const widgetNode = getWidgetNode(widgetId);
    if (!widgetNode) {
      return;
    }
    clearWidgetState(widgetId);
    if (
      window.grid
      && typeof window.grid.removeWidget === "function"
      && widgetNode.parentElement === getGridElement()
    ) {
      window.grid.removeWidget(widgetNode, true, false);
    } else {
      widgetNode.remove();
    }
    chooseFallbackActiveWidget();
    renderTaskbar();
    layoutWorkspace();
  }

  function enforceVisibleLimit(profile) {
    normalizeSnapState();
    const snappedLayout = buildSnappedLayout(profile);
    const visibleIds = getVisibleWidgetIds();
    const protectedIds = new Set(
      [
        workspaceState.activeWidgetId,
        workspaceState.snapLeftId,
        workspaceState.snapRightId,
      ].filter(Boolean)
    );
    const maxVisible = snappedLayout ? 2 : profile.maxVisible;
    if (visibleIds.length <= maxVisible) {
      return;
    }
    const removableIds = visibleIds.filter(function (widgetId) {
      return !protectedIds.has(widgetId);
    });
    while (getVisibleWidgetIds().length > maxVisible && removableIds.length) {
      minimizeWidget(removableIds.shift(), { skipLayout: true });
    }
    const remainingIds = getVisibleWidgetIds();
    while (remainingIds.length > maxVisible) {
      const candidate = remainingIds.find(function (widgetId) {
        return widgetId !== workspaceState.activeWidgetId;
      });
      if (!candidate) {
        break;
      }
      minimizeWidget(candidate, { skipLayout: true });
      remainingIds.splice(remainingIds.indexOf(candidate), 1);
    }
  }

  function applyLayout(layoutItems) {
    if (!window.grid || !layoutItems.length) {
      return;
    }
    syncGridMetrics();
    if (typeof window.grid.batchUpdate === "function") {
      window.grid.batchUpdate(true);
    }
    layoutItems.forEach(function (item) {
      window.grid.update(item.node, {
        x: item.x,
        y: item.y,
        w: item.w,
        h: item.h,
      });
    });
    if (typeof window.grid.batchUpdate === "function") {
      window.grid.batchUpdate(false);
    }
  }

  function layoutWorkspace() {
    if (!window.grid || !getGridElement()) {
      return;
    }
    normalizeSnapState();
    const profile = getLayoutProfile();
    enforceVisibleLimit(profile);
    renderSnapAssistant();
    const snappedLayout = buildSnappedLayout(profile);
    const layoutItems = snappedLayout || buildDefaultLayout(getVisibleWidgetNodes(), profile);
    applyLayout(layoutItems);
    if (!workspaceState.activeWidgetId && layoutItems.length) {
      setActiveWidget(layoutItems[layoutItems.length - 1].node.id);
    } else if (workspaceState.activeWidgetId) {
      const activeNode = getWidgetNode(workspaceState.activeWidgetId);
      if (activeNode) {
        activeNode.classList.add("is-gia-active");
      }
    }
    renderTaskbar();
  }

  function tileWidget(widgetId) {
    if (!widgetId) {
      return;
    }
    if (workspaceState.snapLeftId === widgetId || workspaceState.snapRightId === widgetId) {
      workspaceState.snapLeftId = "";
      workspaceState.snapRightId = "";
    }
    if (workspaceState.snapAssistantSourceId === widgetId) {
      clearSnapAssistant();
    }
    setActiveWidget(widgetId);
    layoutWorkspace();
  }

  function chooseSnapCandidate(excludeId) {
    const candidates = getVisibleWidgetNodes().filter(function (node) {
      return node.id !== excludeId;
    });
    if (!candidates.length) {
      return "";
    }
    const active = candidates.find(function (node) {
      return node.id === workspaceState.activeWidgetId;
    });
    return active ? active.id : candidates[candidates.length - 1].id;
  }

  function snapWidgetLeft(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    workspaceState.snapLeftId = id;
    workspaceState.snapRightId = "";
    workspaceState.snapAssistantSourceId = id;
    setActiveWidget(id);
    layoutWorkspace();
  }

  function snapWidgetRight(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    if (!workspaceState.snapLeftId || workspaceState.snapLeftId === id) {
      workspaceState.snapLeftId = chooseSnapCandidate(id);
    }
    workspaceState.snapRightId = id;
    clearSnapAssistant();
    setActiveWidget(id);
    layoutWorkspace();
  }

  function chooseSnapRight(widgetId) {
    const id = String(widgetId || "").trim();
    if (!id) {
      return;
    }
    workspaceState.snapRightId = id;
    clearSnapAssistant();
    setActiveWidget(id);
    layoutWorkspace();
  }

  function replaceExistingWidget(widgetNode) {
    if (!widgetNode || !widgetNode.id) {
      return -1;
    }
    const existingWidget = document.getElementById(widgetNode.id);
    if (!existingWidget) {
      return -1;
    }
    const previousIndex = workspaceState.order.indexOf(widgetNode.id);
    clearWidgetState(widgetNode.id);
    if (
      window.grid
      && typeof window.grid.removeWidget === "function"
      && existingWidget.parentElement === getGridElement()
    ) {
      window.grid.removeWidget(existingWidget, true, false);
    } else {
      existingWidget.remove();
    }
    return previousIndex;
  }

  function processWidgetShell(container) {
    if (!container || container.dataset.giaWidgetProcessed === "1") {
      return Promise.resolve();
    }
    container.dataset.giaWidgetProcessed = "1";
    const widgetNode = container.firstElementChild
      ? container.firstElementChild.cloneNode(true)
      : null;
    if (!widgetNode) {
      container.remove();
      return Promise.resolve();
    }
    const scripts = toArray(widgetNode.querySelectorAll("script"));
    const previousIndex = replaceExistingWidget(widgetNode);
    container.remove();
    if (!window.grid || !getGridElement()) {
      return Promise.resolve();
    }
    getGridElement().appendChild(widgetNode);
    if (typeof window.grid.makeWidget === "function") {
      window.grid.makeWidget(widgetNode);
    } else if (typeof window.grid.addWidget === "function") {
      window.grid.addWidget(widgetNode);
    }
    if (window.htmx && typeof window.htmx.process === "function") {
      window.htmx.process(widgetNode);
    }
    window.giaEnableWidgetSpawnButtons(widgetNode);
    const liveWidget = widgetNode.id ? document.getElementById(widgetNode.id) : widgetNode;
    registerWidget(liveWidget, previousIndex);
    return ensureContainerAssets(container).then(function () {
      scripts.forEach(executeWidgetScript);
      if (window.GIAComposePanel && typeof window.GIAComposePanel.initAll === "function") {
        window.GIAComposePanel.initAll(liveWidget);
      }
      layoutWorkspace();
    });
  }

  function processPendingWidgetShells(root) {
    const scope = withDocumentRoot(root);
    const containers = [];
    if (
      scope !== document
      && typeof scope.matches === "function"
      && scope.matches(WIDGET_SHELL_SELECTOR)
    ) {
      containers.push(scope);
    }
    scope.querySelectorAll(WIDGET_SHELL_SELECTOR).forEach(function (node) {
      containers.push(node);
    });
    Promise.all(containers.map(processWidgetShell)).finally(function () {
      layoutWorkspace();
      window.giaEnableWidgetSpawnButtons(document);
    });
  }

  function enableFloatingWindowInteractions(windowEl) {
    if (!windowEl || windowEl.dataset.giaWindowInteractive === "1") {
      return;
    }
    windowEl.dataset.giaWindowInteractive = "1";
    windowEl.setAttribute("unmovable", "");
    const heading = windowEl.querySelector(".panel-heading");
    if (!heading) {
      return;
    }
    let dragging = false;
    let startX = 0;
    let startY = 0;
    let startLeft = 0;
    let startTop = 0;

    const onMove = function (event) {
      if (!dragging) {
        return;
      }
      const deltaX = event.clientX - startX;
      const deltaY = event.clientY - startY;
      windowEl.style.left = startLeft + deltaX + "px";
      windowEl.style.top = startTop + deltaY + "px";
      windowEl.style.right = "auto";
      windowEl.style.bottom = "auto";
    };

    const stopDrag = function () {
      dragging = false;
      document.removeEventListener("pointermove", onMove);
      document.removeEventListener("pointerup", stopDrag);
    };

    heading.addEventListener("pointerdown", function (event) {
      if (event.button !== 0) {
        return;
      }
      const interactive = event.target.closest(
        "button, a, input, textarea, select, label, .delete, .icon"
      );
      if (interactive) {
        return;
      }
      const windowRect = windowEl.getBoundingClientRect();
      windowEl.style.position = "fixed";
      startLeft = windowRect.left;
      startTop = windowRect.top;
      startX = event.clientX;
      startY = event.clientY;
      dragging = true;
      document.addEventListener("pointermove", onMove);
      document.addEventListener("pointerup", stopDrag);
      event.preventDefault();
    });
  }

  function positionFloatingWindow(windowEl) {
    if (!windowEl) {
      return;
    }
    const margin = 12;
    const rect = windowEl.getBoundingClientRect();
    const anchor = window.giaWindowAnchor || null;
    windowEl.style.position = "fixed";
    if (!anchor || Date.now() - anchor.ts > 10000) {
      const fallbackLeft = Math.max(margin, Math.round((window.innerWidth - rect.width) / 2));
      const fallbackTop = Math.max(margin, Math.round((window.innerHeight - rect.height) / 2));
      windowEl.style.left = fallbackLeft + "px";
      windowEl.style.top = fallbackTop + "px";
      return;
    }
    const desiredLeftViewport = anchor.left;
    const desiredTopViewport = anchor.bottom + 6;
    const maxLeftViewport = window.innerWidth - rect.width - margin;
    const maxTopViewport = window.innerHeight - rect.height - margin;
    const boundedLeftViewport = Math.max(
      margin,
      Math.min(desiredLeftViewport, maxLeftViewport)
    );
    const boundedTopViewport = Math.max(
      margin,
      Math.min(desiredTopViewport, maxTopViewport)
    );
    windowEl.style.left = boundedLeftViewport + "px";
    windowEl.style.top = boundedTopViewport + "px";
    windowEl.style.right = "auto";
    windowEl.style.bottom = "auto";
    windowEl.style.transform = "none";
    window.giaWindowAnchor = null;
  }

  function handleWidgetAction(action, widgetId) {
    if (!action || !widgetId) {
      return;
    }
    if (action === "close") {
      removeWidget(widgetId);
      return;
    }
    if (action === "minimize") {
      minimizeWidget(widgetId);
      return;
    }
    if (action === "tile") {
      tileWidget(widgetId);
      return;
    }
    if (action === "snap-left") {
      snapWidgetLeft(widgetId);
      return;
    }
    if (action === "snap-right") {
      snapWidgetRight(widgetId);
    }
  }

  function initWorkspaceShell() {
    if (window.giaWorkspaceShellInitialised) {
      processPendingWidgetShells(document);
      return;
    }

    const gridElement = document.getElementById("grid-stack-main");
    if (!gridElement || !window.GridStack) {
      return;
    }

    window.giaWorkspaceShellInitialised = true;
    window.gridElement = gridElement;
    window.giaWindowAnchor = null;
    document.body.classList.add("gia-has-workspace");
    document.documentElement.classList.add("gia-has-workspace-root");

    window.giaPrepareWidgetTarget = function () {
      return document.getElementById("widgets-here");
    };

    window.giaCanSpawnWidgets = function () {
      return !!(
        window.grid &&
        typeof window.grid.addWidget === "function" &&
        document.getElementById("widgets-here")
      );
    };

    window.giaEnableWidgetSpawnButtons = function (root) {
      const scope = withDocumentRoot(root);
      const canSpawn = window.giaCanSpawnWidgets();
      scope.querySelectorAll(WIDGET_SPAWN_SELECTOR).forEach(function (button) {
        const widgetUrl = String(
          button.getAttribute("data-widget-url")
          || button.getAttribute("hx-get")
          || ""
        ).trim();
        const visible = canSpawn && !!widgetUrl;
        button.classList.toggle("is-hidden", !visible);
        button.setAttribute("aria-hidden", visible ? "false" : "true");
      });
    };

    window.giaPrepareWindowAnchor = function (trigger) {
      if (!trigger || !trigger.getBoundingClientRect) {
        window.giaWindowAnchor = null;
        return;
      }
      const rect = trigger.getBoundingClientRect();
      window.giaWindowAnchor = {
        left: rect.left,
        right: rect.right,
        top: rect.top,
        bottom: rect.bottom,
        width: rect.width,
        height: rect.height,
        ts: Date.now(),
      };
    };

    window.giaPositionFloatingWindow = positionFloatingWindow;
    window.giaEnableFloatingWindowInteractions = enableFloatingWindowInteractions;
    window.giaCompactGrid = layoutWorkspace;
    window.giaRemoveWidget = removeWidget;
    window.giaMinimizeWidget = minimizeWidget;
    window.giaRestoreWidget = restoreWidget;
    window.giaProcessWidgetShells = processPendingWidgetShells;

    window.grid = window.GridStack.init(
      {
        animate: true,
        auto: false,
        cellHeight: 40,
        column: GRID_COLUMNS,
        float: false,
        margin: 8,
        removable: false,
        staticGrid: true,
      },
      gridElement
    );

    document.addEventListener("click", function (event) {
      const spawnTrigger = event.target.closest(WIDGET_SPAWN_SELECTOR);
      if (spawnTrigger) {
        window.giaPrepareWidgetTarget();
      }

      const widgetAction = event.target.closest(WIDGET_ACTION_SELECTOR);
      if (widgetAction) {
        event.preventDefault();
        event.stopPropagation();
        handleWidgetAction(
          String(widgetAction.dataset.giaAction || ""),
          String(widgetAction.dataset.giaWidgetId || "")
        );
        return;
      }

      const taskbarItem = event.target.closest(".js-gia-taskbar-item");
      if (taskbarItem) {
        event.preventDefault();
        const widgetId = String(taskbarItem.dataset.giaWidgetId || "");
        if (workspaceState.minimized.has(widgetId)) {
          restoreWidget(widgetId);
        } else {
          minimizeWidget(widgetId);
        }
        return;
      }

      const snapTarget = event.target.closest(".js-gia-snap-target");
      if (snapTarget) {
        event.preventDefault();
        chooseSnapRight(String(snapTarget.dataset.giaWidgetId || ""));
        return;
      }

      if (event.target.closest(SNAP_ASSISTANT_CLOSE_SELECTOR)) {
        event.preventDefault();
        clearSnapAssistant();
      }
    });

    document.body.addEventListener("htmx:afterSwap", function (event) {
      const target = (event && event.target) || document;
      window.giaEnableWidgetSpawnButtons(target);
      if (((target && target.id) || "") === "widgets-here") {
        processPendingWidgetShells(target);
        return;
      }
      if (((target && target.id) || "") !== "windows-here") {
        return;
      }
      target.querySelectorAll(".floating-window").forEach(function (floatingWindow) {
        window.setTimeout(function () {
          positionFloatingWindow(floatingWindow);
          enableFloatingWindowInteractions(floatingWindow);
        }, 0);
      });
    });

    document.addEventListener("load-widget", function (event) {
      processPendingWidgetShells(event && event.detail && event.detail.root);
    });
    document.addEventListener("gia:load-widget", function (event) {
      processPendingWidgetShells(event && event.detail && event.detail.root);
    });

    window.addEventListener("resize", function () {
      window.requestAnimationFrame(layoutWorkspace);
    });

    window.giaEnableWidgetSpawnButtons(document);
    processPendingWidgetShells(document);
    window.requestAnimationFrame(layoutWorkspace);
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initWorkspaceShell);
  } else {
    initWorkspaceShell();
  }
})();
