const manifest = {"name":"Example Plugin"};
const API_VERSION = 2;
const internalAPIConnection = window.__DECKY_SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_deckyLoaderAPIInit;
if (!internalAPIConnection) {
    throw new Error('[@decky/api]: Failed to connect to the loader as as the loader API was not initialized. This is likely a bug in Decky Loader.');
}
let api;
try {
    api = internalAPIConnection.connect(API_VERSION, manifest.name);
}
catch {
    api = internalAPIConnection.connect(1, manifest.name);
    console.warn(`[@decky/api] Requested API version ${API_VERSION} but the running loader only supports version 1. Some features may not work.`);
}
if (api._version != API_VERSION) {
    console.warn(`[@decky/api] Requested API version ${API_VERSION} but the running loader only supports version ${api._version}. Some features may not work.`);
}
const callable = api.callable;
const addEventListener = api.addEventListener;
const removeEventListener = api.removeEventListener;
const toaster = api.toaster;
const definePlugin = (fn) => {
    return (...args) => {
        return fn(...args);
    };
};

var DefaultContext = {
  color: undefined,
  size: undefined,
  className: undefined,
  style: undefined,
  attr: undefined
};
var IconContext = SP_REACT.createContext && /*#__PURE__*/SP_REACT.createContext(DefaultContext);

var _excluded = ["attr", "size", "title"];
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } } return target; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function Tree2Element(tree) {
  return tree && tree.map((node, i) => /*#__PURE__*/SP_REACT.createElement(node.tag, _objectSpread({
    key: i
  }, node.attr), Tree2Element(node.child)));
}
function GenIcon(data) {
  return props => /*#__PURE__*/SP_REACT.createElement(IconBase, _extends({
    attr: _objectSpread({}, data.attr)
  }, props), Tree2Element(data.child));
}
function IconBase(props) {
  var elem = conf => {
    var {
        attr,
        size,
        title
      } = props,
      svgProps = _objectWithoutProperties(props, _excluded);
    var computedSize = size || conf.size || "1em";
    var className;
    if (conf.className) className = conf.className;
    if (props.className) className = (className ? className + " " : "") + props.className;
    return /*#__PURE__*/SP_REACT.createElement("svg", _extends({
      stroke: "currentColor",
      fill: "currentColor",
      strokeWidth: "0"
    }, conf.attr, attr, svgProps, {
      className: className,
      style: _objectSpread(_objectSpread({
        color: props.color || conf.color
      }, conf.style), props.style),
      height: computedSize,
      width: computedSize,
      xmlns: "http://www.w3.org/2000/svg"
    }), title && /*#__PURE__*/SP_REACT.createElement("title", null, title), props.children);
  };
  return IconContext !== undefined ? /*#__PURE__*/SP_REACT.createElement(IconContext.Consumer, null, conf => elem(conf)) : elem(DefaultContext);
}

// THIS FILE IS AUTO GENERATED
function FaShip (props) {
  return GenIcon({"attr":{"viewBox":"0 0 640 512"},"child":[{"tag":"path","attr":{"d":"M496.616 372.639l70.012-70.012c16.899-16.9 9.942-45.771-12.836-53.092L512 236.102V96c0-17.673-14.327-32-32-32h-64V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v40h-64c-17.673 0-32 14.327-32 32v140.102l-41.792 13.433c-22.753 7.313-29.754 36.173-12.836 53.092l70.012 70.012C125.828 416.287 85.587 448 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24 61.023 0 107.499-20.61 143.258-59.396C181.677 487.432 216.021 512 256 512h128c39.979 0 74.323-24.568 88.742-59.396C508.495 491.384 554.968 512 616 512c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24-60.817 0-101.542-31.001-119.384-75.361zM192 128h256v87.531l-118.208-37.995a31.995 31.995 0 0 0-19.584 0L192 215.531V128z"},"child":[]}]})(props);
}

// import logo from "../assets/logo.png";
// This function calls the python function "add", which takes in two numbers and returns their sum (as a number)
// Note the type annotations:
//  the first one: [first: number, second: number] is for the arguments
//  the second one: number is for the return value
const add = callable("add");
// This function calls the python function "start_timer", which takes in no arguments and returns nothing.
// It starts a (python) timer which eventually emits the event 'timer_event'
const startTimer = callable("start_timer");
function Content() {
    const [result, setResult] = SP_REACT.useState();
    const onClick = async () => {
        const result = await add(Math.random(), Math.random());
        setResult(result);
    };
    return (SP_JSX.jsxs(DFL.PanelSection, { title: "Panel Section", children: [SP_JSX.jsx(DFL.PanelSectionRow, { children: SP_JSX.jsx(DFL.ButtonItem, { layout: "below", onClick: onClick, children: result ?? "Add two numbers via Python" }) }), SP_JSX.jsx(DFL.PanelSectionRow, { children: SP_JSX.jsx(DFL.ButtonItem, { layout: "below", onClick: () => startTimer(), children: "Start Python timer" }) })] }));
}
var index = definePlugin(() => {
    console.log("Template plugin initializing, this is called once on frontend startup");
    const storagePrefix = "store-scroll:";
    const now = () => Date.now();
    const ttlMs = 30 * 60 * 1000;
    const cap = 50;
    const locKey = (loc) => `${loc.pathname}${loc.search}`;
    const storageKey = (key) => `${storagePrefix}${key}`;
    const readRecord = (key) => {
        try {
            const raw = sessionStorage.getItem(storageKey(key));
            if (!raw)
                return undefined;
            const data = JSON.parse(raw);
            if (typeof data.y !== "number" || typeof data.ts !== "number")
                return undefined;
            if (now() - data.ts > ttlMs)
                return undefined;
            return data;
        }
        catch {
            return undefined;
        }
    };
    const writeRecord = (key, rec) => {
        try {
            sessionStorage.setItem(storageKey(key), JSON.stringify(rec));
            const keys = Object.keys(sessionStorage).filter(k => k.startsWith(storagePrefix));
            if (keys.length > cap) {
                const items = keys.map(k => {
                    try {
                        const v = JSON.parse(sessionStorage.getItem(k) || "{}");
                        return { k, ts: v.ts || 0 };
                    }
                    catch {
                        return { k, ts: 0 };
                    }
                });
                items.sort((a, b) => a.ts - b.ts);
                for (let i = 0; i < items.length - cap; i++)
                    sessionStorage.removeItem(items[i].k);
            }
        }
        catch { }
    };
    const getScrollY = () => {
        const el = document.scrollingElement;
        if (el)
            return el.scrollTop;
        return window.scrollY;
    };
    const scrollToY = (y) => {
        window.scrollTo(0, Math.max(0, y));
    };
    const findNearestAnchorHref = () => {
        const anchors = Array.from(document.querySelectorAll('a[href*="/app/"]'));
        if (anchors.length === 0)
            return undefined;
        const center = window.scrollY + window.innerHeight / 2;
        let best;
        for (const a of anchors) {
            const rect = a.getBoundingClientRect();
            const top = rect.top + window.scrollY;
            const d = Math.abs(top - center);
            const href = a.getAttribute("href") || "";
            if (!href)
                continue;
            if (!best || d < best.d)
                best = { href, d };
        }
        return best?.href;
    };
    const storeCurrentScroll = () => {
        const key = locKey(window.location);
        const y = getScrollY();
        const anchorHref = findNearestAnchorHref();
        writeRecord(key, { y, ts: now(), anchorHref });
    };
    let restoreObserver = null;
    let restoreScheduled = false;
    const tryRestoreOnce = (rec) => {
        const docH = document.scrollingElement ? document.scrollingElement.scrollHeight : document.body.scrollHeight;
        if (docH > window.innerHeight && rec.y <= docH - window.innerHeight + 100) {
            scrollToY(rec.y);
            return true;
        }
        if (rec.anchorHref) {
            const target = document.querySelector(`a[href='${rec.anchorHref}']`) || document.querySelector(`a[href*='${rec.anchorHref}']`);
            if (target) {
                const rect = target.getBoundingClientRect();
                const top = rect.top + window.scrollY;
                scrollToY(top);
                return true;
            }
        }
        return false;
    };
    const scheduleRestore = (rec) => {
        if (restoreScheduled)
            return;
        restoreScheduled = true;
        let attempts = 0;
        const maxAttempts = 50;
        const rafLoop = () => {
            attempts++;
            if (tryRestoreOnce(rec) || attempts >= maxAttempts) {
                restoreScheduled = false;
                if (restoreObserver) {
                    restoreObserver.disconnect();
                    restoreObserver = null;
                }
                return;
            }
            requestAnimationFrame(rafLoop);
        };
        restoreObserver = new MutationObserver(() => { tryRestoreOnce(rec); });
        restoreObserver.observe(document.body, { childList: true, subtree: true });
        requestAnimationFrame(rafLoop);
    };
    const onPopState = () => {
        const key = locKey(window.location);
        const rec = readRecord(key);
        if (rec)
            scheduleRestore(rec);
    };
    const origPushState = history.pushState.bind(history);
    const origReplaceState = history.replaceState.bind(history);
    const wrapNav = (orig) => {
        return function (state, title, url) {
            try {
                storeCurrentScroll();
            }
            catch { }
            const r = orig.apply(this, [state, title, url]);
            return r;
        };
    };
    history.pushState = wrapNav(origPushState);
    history.replaceState = wrapNav(origReplaceState);
    window.addEventListener("popstate", onPopState);
    // Add an event listener to the "timer_event" event from the backend
    const listener = addEventListener("timer_event", (test1, test2, test3) => {
        console.log("Template got timer_event with:", test1, test2, test3);
        toaster.toast({
            title: "template got timer_event",
            body: `${test1}, ${test2}, ${test3}`
        });
    });
    return {
        // The name shown in various decky menus
        name: "Test Plugin",
        // The element displayed at the top of your plugin's menu
        titleView: SP_JSX.jsx("div", { className: DFL.staticClasses.Title, children: "Decky Example Plugin" }),
        // The content of your plugin's menu
        content: SP_JSX.jsx(Content, {}),
        // The icon displayed in the plugin list
        icon: SP_JSX.jsx(FaShip, {}),
        // The function triggered when your plugin unloads
        onDismount() {
            console.log("Unloading");
            try {
                history.pushState = origPushState;
            }
            catch { }
            try {
                history.replaceState = origReplaceState;
            }
            catch { }
            try {
                window.removeEventListener("popstate", onPopState);
            }
            catch { }
            try {
                if (restoreObserver) {
                    restoreObserver.disconnect();
                    restoreObserver = null;
                }
            }
            catch { }
            removeEventListener("timer_event", listener);
            // serverApi.routerHook.removeRoute("/decky-plugin-test");
        },
    };
});

export { index as default };
//# sourceMappingURL=index.js.map
