Plugin Directory

Changeset 3122653


Ignore:
Timestamp:
07/20/2024 10:09:10 PM (21 months ago)
Author:
magicroundabout
Message:

Update to version 1.15.2 from GitHub

Location:
turbo-admin
Files:
1 deleted
20 edited
1 copied

Legend:

Unmodified
Added
Removed
  • turbo-admin/tags/1.15.2/dist/main.min.js

    r2919322 r3122653  
    13711371      if (e.code === "ArrowDown" && this.paletteShown()) {
    13721372        e.preventDefault();
     1373        e.stopImmediatePropagation();
     1374        e.stopPropagation();
    13731375        this.moveDown();
    13741376        return;
     
    13761378      if (e.code === "ArrowUp" && this.paletteShown()) {
    13771379        e.preventDefault();
     1380        e.stopImmediatePropagation();
     1381        e.stopPropagation();
    13781382        this.moveUp();
    13791383        return;
     
    13811385      if (e.code === "Enter" && this.paletteShown()) {
    13821386        e.preventDefault();
     1387        e.stopImmediatePropagation();
     1388        e.stopPropagation();
    13831389        this.doAction(this.metaPressed(e));
    13841390        return;
     
    17731779            return;
    17741780          }
     1781          console.log("Modal detected");
    17751782          const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
    1776           if (welcomeGuide) {
     1783          const newPagePatterns = document.querySelector(".edit-post-start-page-options__modal");
     1784          const newPagePatterns2 = document.querySelector(".editor-start-page-options__modal-content");
     1785          if (welcomeGuide || newPagePatterns || newPagePatterns2) {
    17771786            this.killWelcomeGuide();
    17781787          }
     
    17811790      attrObserver.observe(document.body, {attributes: true});
    17821791      this.killWelcomeGuide();
     1792      this.killDashboardWelcomePanel();
    17831793    }
    17841794    killWelcomeGuide() {
    1785       const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
     1795      let welcomeGuide = document.querySelector(".edit-post-welcome-guide");
     1796      if (!welcomeGuide) {
     1797        welcomeGuide = document.querySelector(".edit-post-start-page-options__modal");
     1798      }
     1799      if (!welcomeGuide) {
     1800        welcomeGuide = document.querySelector(".editor-start-page-options__modal-content");
     1801      }
    17861802      if (welcomeGuide) {
    1787         const closeButton = welcomeGuide.querySelector(".components-modal__header button");
     1803        const closeButton = document.querySelector(".components-modal__header button");
    17881804        if (closeButton) {
    17891805          closeButton.click();
    17901806          document.body.classList.add("ta-killed-post-welcome-guide");
    17911807        }
     1808      }
     1809    }
     1810    killDashboardWelcomePanel() {
     1811      const welcomePanel = document.getElementById("welcome-panel");
     1812      if (!welcomePanel) {
     1813        return;
     1814      }
     1815      const welcomePanelClose = welcomePanel.querySelector(".welcome-panel-close");
     1816      if (welcomePanelClose) {
     1817        welcomePanelClose.click();
    17921818      }
    17931819    }
     
    19271953    saveRememberedNotice(noticeId) {
    19281954      this.rememberedNoticeIds.push(noticeId);
    1929       if (typeof browser === "object") {
     1955      if (typeof chrome === "object") {
    19301956        chrome.runtime.sendMessage({
    19311957          action: "rememberNotice",
     
    19571983    saveForgottenNotice(noticeId) {
    19581984      this.rememberedNoticeIds.push(noticeId);
    1959       if (typeof browser === "object") {
     1985      if (typeof chrome === "object") {
    19601986        chrome.runtime.sendMessage({
    19611987          action: "rememberNotice",
     
    20612087      this.currentRow = null;
    20622088      this.currentRowIndex = 0;
     2089      this.actionsOpen = false;
    20632090      this.listTable = document.querySelector(".wp-list-table");
     2091      this.isWooCommerce = false;
     2092      this.isPluginInstall = false;
    20642093      if (!this.listTable) {
    20652094        return;
    20662095      }
     2096      if (document.body.classList.contains("woocommerce-admin-page") && document.body.classList.contains("post-type-shop_order")) {
     2097        this.isWooCommerce = true;
     2098      }
     2099      if (document.body.classList.contains("plugin-install-php")) {
     2100        this.isPluginInstall = true;
     2101      }
     2102      this.isMac = globalThis.turboAdmin.turboAdminPalette.isMac();
    20672103      this.tableRows = this.listTable.querySelectorAll("tbody#the-list > tr");
    2068       document.addEventListener("keyup", (e) => this.handleKeyup(e));
    2069     }
    2070     handleKeyup(ev) {
    2071       if (document.activeElement.tagName !== "BODY") {
     2104      if (this.isPluginInstall) {
     2105        this.tableRows = this.listTable.querySelectorAll("#the-list .plugin-card");
     2106      }
     2107      if (document.body.classList.contains("edit-comments-php")) {
     2108        this.tableRows = this.listTable.querySelectorAll("tbody#the-comment-list > tr");
     2109      }
     2110      document.addEventListener("keydown", (e) => this.handleKey(e));
     2111      const searchInput = document.querySelector('.search-box input[type="search"], .search-form input[type="search"]');
     2112      if (searchInput) {
     2113        searchInput.addEventListener("keyup", (e) => this.handleSearchInputKey(e));
     2114      }
     2115    }
     2116    handleKey(ev) {
     2117      const isActiveElementBody = document.activeElement.tagName === "BODY";
     2118      const isActiveElementInListTable = this.listTable && this.listTable.contains(document.activeElement);
     2119      const isSearchFocussed = this.getSearchInputElement() === document.activeElement;
     2120      if (!isActiveElementBody && !isActiveElementInListTable || isSearchFocussed) {
     2121        return;
     2122      }
     2123      if (globalThis.turboAdmin.turboAdminPalette.isPaletteOpen()) {
    20722124        return;
    20732125      }
    20742126      if (ev.key === "j") {
    2075         this.tableMoveDown();
     2127        if (this.actionsOpen) {
     2128          this.actionMoveDown();
     2129        } else {
     2130          this.tableMoveDown();
     2131        }
    20762132      } else if (ev.key === "k") {
    2077         this.tableMoveUp();
     2133        if (this.actionsOpen) {
     2134          this.actionMoveUp();
     2135        } else {
     2136          this.tableMoveUp();
     2137        }
    20782138      } else if (ev.key.toLowerCase() === "enter" && this.currentRow !== null) {
    2079         this.openTableRowItem();
    2080       }
     2139        if (this.actionsOpen) {
     2140          this.openCurrentRowAction(ev);
     2141          ev.preventDefault();
     2142        } else {
     2143          this.openTableRowActions(ev);
     2144        }
     2145      } else if (ev.key === "/") {
     2146        this.focusSearch(ev);
     2147      } else if (ev.key === "f" && ev.ctrlKey) {
     2148        this.nextPage(ev);
     2149      } else if (ev.key === "b" && ev.ctrlKey) {
     2150        this.prevPage(ev);
     2151      } else if (ev.key === "ArrowDown") {
     2152        if (this.actionsOpen) {
     2153          this.actionMoveDown(ev);
     2154        }
     2155      } else if (ev.key === "ArrowUp") {
     2156        if (this.actionsOpen) {
     2157          this.actionMoveUp(ev);
     2158        }
     2159      } else if (ev.key.toLowerCase() === "escape") {
     2160        if (this.actionsOpen) {
     2161          this.closeTableRowActions(ev);
     2162        }
     2163        if (document.getElementById("post-search-input") === document.activeElement) {
     2164          document.getElementById("post-search-input").blur();
     2165        }
     2166      }
     2167    }
     2168    handleSearchInputKey(ev) {
     2169      if (ev.key.toLowerCase() === "escape") {
     2170        ev.target.blur();
     2171      }
     2172    }
     2173    getSearchInputElement() {
     2174      return document.querySelector('.search-box input[type="search"], .search-form input[type="search"]');
    20812175    }
    20822176    tableMoveDown() {
     
    21062200        this.tableRows[this.currentRowIndex].classList.add("ta-active-table-row");
    21072201      }
    2108     }
    2109     openTableRowItem() {
     2202      this.scrollIntoViewIfNeeded(this.currentRow);
     2203    }
     2204    scrollIntoViewIfNeeded(element) {
     2205      const elementRect = element.getBoundingClientRect();
     2206      const elementTop = elementRect.top;
     2207      const elementBottom = elementRect.bottom;
     2208      const viewportTop = 0;
     2209      const viewportBottom = window.innerHeight;
     2210      if (elementBottom > viewportBottom) {
     2211        element.scrollIntoView({behavior: "smooth", block: "end"});
     2212      } else if (elementTop < viewportTop) {
     2213        element.scrollIntoView({behavior: "smooth", block: "start"});
     2214      }
     2215    }
     2216    getRowActionsContainer() {
     2217      let container = this.currentRow.querySelector(".row-actions");
     2218      if (this.isPluginInstall) {
     2219        container = this.currentRow.querySelector(".plugin-action-buttons");
     2220      }
     2221      return container;
     2222    }
     2223    getRowActions() {
     2224      let rowActions = this.currentRow.querySelectorAll(".row-actions span a, .row-actions span button");
     2225      if (this.isPluginInstall) {
     2226        rowActions = this.currentRow.querySelectorAll(".plugin-action-buttons a");
     2227      }
     2228      return rowActions;
     2229    }
     2230    openTableRowActions(ev) {
    21102231      turboAdminLog(this);
    2111       const link = this.currentRow.querySelector("a.row-title");
    2112       if (link) {
    2113         link.click();
     2232      if (this.isWooCommerce) {
     2233        this.currentRow.querySelector("a.order-view").click();
     2234        return;
     2235      }
     2236      this.actionsOpen = true;
     2237      let rowActions = this.getRowActionsContainer();
     2238      if (rowActions) {
     2239        rowActions.classList.add("visible");
     2240      }
     2241      const titleElem = this.currentRow.querySelector("strong");
     2242      const titleLink = titleElem.querySelector("a");
     2243      if (titleLink) {
     2244        titleLink.classList.add("ta-active-table-row-link");
     2245        return;
     2246      }
     2247      let rowActionLinks = this.getRowActions();
     2248      if (rowActionLinks) {
     2249        rowActionLinks[0].classList.add("ta-active-table-row-link");
     2250      }
     2251    }
     2252    closeTableRowActions(ev) {
     2253      turboAdminLog(this);
     2254      const rowActions = this.currentRow.querySelector(".row-actions");
     2255      if (!document.body.classList.contains("plugins-php")) {
     2256        if (rowActions) {
     2257          rowActions.classList.remove("visible");
     2258        }
     2259      }
     2260      const activeLink = document.querySelector(".ta-active-table-row-link");
     2261      if (activeLink) {
     2262        activeLink.classList.remove("ta-active-table-row-link");
     2263      }
     2264      this.actionsOpen = false;
     2265    }
     2266    actionMoveDown(ev) {
     2267      const currentLink = document.querySelector(".ta-active-table-row-link");
     2268      if (currentLink.closest("strong")) {
     2269        const rowActions = this.getRowActions();
     2270        if (rowActions) {
     2271          rowActions[0].classList.add("ta-active-table-row-link");
     2272          currentLink.classList.remove("ta-active-table-row-link");
     2273        }
     2274        return;
     2275      }
     2276      const nextLink = currentLink.parentElement?.nextElementSibling?.querySelector("a, button");
     2277      if (nextLink) {
     2278        nextLink.classList.add("ta-active-table-row-link");
     2279        currentLink.classList.remove("ta-active-table-row-link");
     2280      }
     2281    }
     2282    actionMoveUp(ev) {
     2283      const currentLink = document.querySelector(".ta-active-table-row-link");
     2284      if (currentLink.closest("strong")) {
     2285        return;
     2286      }
     2287      const prevLink = currentLink.parentElement?.previousElementSibling?.querySelector("a, button");
     2288      if (!prevLink) {
     2289        const titleLink = this.currentRow.querySelector("strong a");
     2290        if (titleLink) {
     2291          titleLink.classList.add("ta-active-table-row-link");
     2292          currentLink.classList.remove("ta-active-table-row-link");
     2293        }
     2294        return;
     2295      }
     2296      prevLink.classList.add("ta-active-table-row-link");
     2297      currentLink.classList.remove("ta-active-table-row-link");
     2298    }
     2299    openCurrentRowAction(ev) {
     2300      const currentLink = document.querySelector(".ta-active-table-row-link");
     2301      if (currentLink) {
     2302        currentLink.click();
     2303      }
     2304    }
     2305    focusSearch(ev) {
     2306      const searchInput = this.getSearchInputElement();
     2307      if (searchInput) {
     2308        searchInput.focus();
     2309        this.scrollIntoViewIfNeeded(searchInput);
     2310        ev.preventDefault();
     2311      }
     2312    }
     2313    nextPage(ev) {
     2314      const nextPageLink = document.querySelector(".tablenav-pages .next-page");
     2315      if (nextPageLink) {
     2316        nextPageLink.click();
     2317        ev.preventDefault();
     2318      }
     2319    }
     2320    prevPage(ev) {
     2321      const prevPageLink = document.querySelector(".tablenav-pages .prev-page");
     2322      if (prevPageLink) {
     2323        prevPageLink.click();
     2324        ev.preventDefault();
    21142325      }
    21152326    }
     
    27322943          itemUrlFunction: () => {
    27332944            if (globalThis.taWp.home) {
    2734               return globalThis.taWp.siteUrl;
     2945              return globalThis.taWp.ensureTrailingSlash(globalThis.taWp.siteUrl);
    27352946            }
    27362947            return "javascript:alert('Sorry, could not detect login URL.')";
  • turbo-admin/tags/1.15.2/dist/main.min.js.map

    r2919322 r3122653  
    22  "version": 3,
    33  "sources": ["../src/fuse-6.4.6.js", "../src/class-turbo-admin-palette.js", "../src/types/class-item-definition.js", "../src/types/class-turbo-admin-menu-item.js", "../src/class-storage.js", "../src/apis/class-content-api.js", "../src/types/class-submenu-item.js", "../src/types/class-content-item.js", "../src/types/class-search-mode.js", "../src/types/class-turbo-admin-plugin.js", "../src/class-turbo-admin-wp-block-editor-fullscreen-kill.js", "../src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js", "../src/class-turbo-admin-wp-notices.js", "../src/class-list-table-shortcuts.js", "../src/plugins/class-turbo-admin-barkeeper.js", "../src/plugins/class-turbo-admin-content-search.js", "../src/plugins/class-turbo-admin-plugins.js", "../src/plugins/class-turbo-admin-users.js", "../src/plugins/class-turbo-admin-woocommerce.js", "../src/plugins/class-turbo-admin-gravity-forms.js", "../src/plugins/class-turbo-admin-mu-sites.js", "../src/plugins/class-turbo-admin-oxygen-buillder.js", "../src/class-turbo-admin.js", "../src/class-wp.js", "../src/apis/class-woocommerce-api.js", "../src/apis/class-gravity-forms-api.js", "../src/main.js"],
    4   "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item';\nimport ContentApi from './apis/class-content-api.js';\nimport SearchMode from './types/class-search-mode.js';\nimport ContentItem from './types/class-content-item.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tturboAdminLog('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));\n        /** @type {HTMLSpanElement} */\n        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));\n        /** @type {HTMLDivElement} */\n        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));\n\n\n        // Add a class if the menu needs refreshing with a visit to the Dashboard\n        if (globalThis.turboAdmin.menuNeedsRefresh) {\n            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');\n        }\n\n        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but\n        // works for now.\n        /** @type {HTMLUListElement} */\n        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        /** @type {null|String} */\n        this.profileLink = null;\n        if (this.profileLinkElem) {\n            this.profileLink = this.profileLinkElem.querySelector('a').href;\n        }\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Backup of the palette data for use when we enter a different search mode\n\t\tthis.paletteDataBackup = null;\n\t\tthis.paletteItemsBackup = null;\n        this.paletteItemIndexBackup = null;\n        this.paletteInputValueBackup = null;\n\n        // Current search modes/keyword\n        this.searchMode = null;\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n            shouldSort: true,\n            // sortFn: (a, b) => {\n            //     // Return search items first\n            //     if (a.item[0].v.startsWith('Search: ')) {\n            //         if (b.item[0].v.startsWith('Search: ')) {\n            //             return b.score - a.score;\n            //         }\n            //         return -1;\n            //     }\n            //     if (b.item[0].v.startsWith('Search: ')) {\n            //         return 1;\n            //     }\n            //     return a.score - b.score;\n            // }\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    inSearchMode() {\n        return this.searchMode !== null;\n    }\n\n\t/**\n     * This converts this.paletteData into a list of paletteListItems in this.paletteItems\n     *\n     * It also builds the itemIndex\n     */\n    buildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n            li.appendChild(a);\n            if (item.actionType === 'url') {\n                a.href = item.action;\n                let title = item.title;\n                if (item.parentTitle) {\n                    title = item.parentTitle + \": \" + title;\n                }\n                a.innerHTML = title;\n            } else if (item.actionType === 'search-mode') {\n                a.href = '#';\n                a.innerHTML = item.title;\n                li.dataset.actionType = item.actionType;\n                li.dataset.searchMode = item.action.searchMode;\n            }\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    /**\n     * Clears and sets the content items\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    setContentItems(contentItems) {\n        this.paletteItems = [];\n        this.itemIndex = [];\n        this.injectContentItems(contentItems, false);\n    }\n\n    /**\n     * Content items have:\n     *  title\n     *  subtype\n     *  url\n     *  (we should also make the sub-menu definable, but that's not done yet)\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    injectContentItems(contentItems, andRunSearch = true) {\n        turboAdminLog('Injecting items');\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(this.injectItem.bind(this));\n        }\n\n        if (andRunSearch) {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        this.updatePaletteItems();\n    }\n\n    /**\n     * Injects a single content item into the palette\n     *\n     * @param {ContentItem} item\n     */\n    injectItem(item) {\n        const itemTitle = item.title;\n        // const itemTitle = item.title.rendered;\n        const itemType = item.subtype;\n        const itemUrl = item.url;\n\n        // turboAdminLog('Adding item: ' + itemTitle);\n\n        // // Check if item already exists\n        if (this.contentItemExists(itemUrl)) {\n            turboAdminLog('Not adding duplicate');\n            return;\n        }\n\n        let title = itemTitle;\n\n        if (itemType) {\n            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;\n            title += ` (${itemTypeName})`;\n        }\n\n        const li = document.createElement('li');\n        const a = document.createElement('a');\n        let subMenu = null;\n\n        // Loop over submenu items OR add link.\n        if (item.submenuItems.length > 0) {\n\n            // Prepare the outer sub-menu elements\n            subMenu = document.createElement('div');\n            const subMenuTitle = document.createElement('div');\n            const subMenuItems = document.createElement('ul');\n            subMenu.classList.add('ta-submenu');\n            subMenuTitle.classList.add('ta-submenu-title');\n\n            subMenuTitle.textContent = this.htmlDecode(itemTitle);\n            subMenuItems.classList.add('ta-submenu-items');\n            subMenu.appendChild(subMenuTitle);\n\n            for (let i = 0; i < item.submenuItems.length; i++) {\n                const subMenuItem = item.submenuItems[i]\n                // TODO: Abstract this so sub-menus can be defined by plugins?\n                const subMenuListItem = document.createElement('li');\n                const subMenuLink = document.createElement('a');\n                subMenuLink.innerText = subMenuItem.title;\n                subMenuLink.href = subMenuItem.url;\n                for (let a = 0; a < subMenuItem.attributes.length; a++) {\n                    subMenuLink.setAttribute(\n                        subMenuItem.attributes[a].name,\n                        subMenuItem.attributes[a].value\n                    )\n                }\n                subMenuListItem.appendChild(subMenuLink);\n                subMenuItems.appendChild(subMenuListItem);\n            }\n\n            // Add the sub-menu items UL to the sub-menu element.\n            subMenu.appendChild(subMenuItems);\n\n            li.classList.add('ta-has-child-menu');\n        }\n\n        a.href = itemUrl;\n        a.innerHTML = title;\n\n        li.appendChild(a);\n        if (subMenu !== null) {\n            li.appendChild(subMenu);\n        }\n\n        this.addPaletteListItem(li);\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n            return;\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else if (this.inSearchMode()) {\n                this.leaveSearchMode();\n            } else {\n                this.hidePalette();\n            }\n            return;\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    /*\n     * Adds the tab hint for a keyword once it has been typed.\n     */\n    maybeHighlightInputKeyword(newKey) {\n        // Do nothing if we are in a search-mode\n        if (this.inSearchMode()) {\n            return;\n        }\n\n        // This is fired on \"keyDown\", so the value isn't update with the new key yet.\n        // But don't do this for special keys, and catch backspace too.\n        let newInputValue = this.paletteInputElement.value;\n        if (newKey.length === 1) {\n            newInputValue += newKey;\n        }\n        if (newKey === 'Backspace') {\n            newInputValue = newInputValue.slice(0, -1);\n        }\n        // turboAdminLog(`Checking palette input value ${newInputValue} for keyword`);\n        if (this.isKeyword(newInputValue)) {\n            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;\n            this.paletteSearchModeTabNotice.classList.add('active');\n        } else {\n            this.unhighlightInputKeyword();\n        }\n    }\n\n    unhighlightInputKeyword() {\n        this.paletteSearchModeTabNotice.classList.remove('active');\n    }\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If we're not in a search mode then search immediately\n        if (! this.inSearchMode()) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n\n        // Cancel the existing timeout\n        clearTimeout(this.debounceTimeout)\n\n        this.debounceTimeout = setTimeout(async function () {\n            // Reset timeout\n            this.debounceTimeout = null;\n\n            // Run the search function\n            await this.paletteSearchAndUpdate();\n        }.bind(this), 750);\n    }\n\n    /**\n     * Check if a string is a search mode keyword\n     *\n     * @param {string} inputString\n     * @returns {boolean}\n     */\n    isKeyword(inputString) {\n        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);\n    }\n\n    /**\n     * Show the palette notice with the specified text\n     *\n     * @param {string} text\n     */\n    showPaletteNotice(text) {\n        this.paletteNoticeElement.classList.add('active');\n        this.paletteNoticeElement.innerText = text;\n    }\n\n    /**\n     * Hide the palette notice\n     */\n    hidePaletteNotice() {\n        this.paletteNoticeElement.classList.remove('active');\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            e.preventDefault();\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n\n        /*\n         * Only the actions above can be done in sub-menus.\n         */\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\n        /*\n         * Check for a keyword being typed and add a UI hint.\n         */\n        this.maybeHighlightInputKeyword(e.key);\n\n        /*\n         * Tabbing looks for a search mode keyword.\n         */\n        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {\n            turboAdminLog('Checking for search mode');\n            let inputValue = this.paletteInputElement.value;\n            if (this.isKeyword(inputValue)) {\n                turboAdminLog('Found search mode ' + inputValue)\n                e.preventDefault();\n                await this.enterSearchMode(\n                    globalThis.turboAdmin.searchModes[inputValue]);\n                return;\n            }\n        }\n\n        /*\n         * Backspace may exit us from a search mode\n         */\n        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {\n            e.preventDefault();\n            this.leaveSearchMode();\n            return;\n        }\n\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n    /**\n     * Puts the palette into a specific search mode - used when a keyword is selected\n     *\n     * @param {SearchMode} searchMode\n     */\n    async enterSearchMode(searchMode) {\n        turboAdminLog('Entering search mode for keyword ' + searchMode.keyword);\n        this.backupPaletteData();\n\n        this.paletteData = [];\n        this.paletteItems = [];\n        this.itemIndex = [];\n\n        // Remove the notice if it's there\n        this.hidePaletteNotice();\n\n        this.searchMode = searchMode;\n        this.paletteInputElement.value = '';\n        this.addSearchModeTag(searchMode.displayName);\n        this.unhighlightInputKeyword();\n        this.updatePaletteItems();\n        // This is similar to code in paletteSearch - maybe we could extract/abstract it?\n        if (searchMode.defaultItemsCallback !== null) {\n            this.paletteInnerElement.classList.add('loading');\n            const results = await searchMode.defaultItemsCallback();\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n    }\n\n    /**\n     * Puts the palette into a specific search mode specified by a keyword\n     *\n     * @param {string} keyword\n     */\n    async enterSearchModeByKeyword(keyword) {\n        turboAdminLog('Entering search mode by keyword ' + keyword);\n        const searchMode = globalThis.turboAdmin.searchModes[keyword];\n        turboAdminLog('Search mode is ' + searchMode);\n        if (searchMode === undefined) {\n            return;\n        }\n        await this.enterSearchMode(searchMode);\n    }\n\n    /**\n     * Leaves the current search mode\n     */\n    leaveSearchMode() {\n        const searchMode = this.searchMode;\n        // It's important what we set this to - see inSearchMode()\n        this.searchMode = null;\n        this.removeSearchModeTag();\n        this.restorePaletteData();\n    }\n\n    /**\n     * Backups up the palette data and input value to local variables so that it can be\n     * restored later.\n     */\n    backupPaletteData() {\n        this.paletteDataBackup = this.paletteData;\n        this.paletteItemsBackup = this.paletteItems;\n        this.paletteItemIndexBackup = this.itemIndex;\n        this.paletteInputValueBackup = this.paletteInputElement.value;\n    }\n\n    /**\n     * Restores the save palette data - highlights and rebuilds\n     */\n    restorePaletteData() {\n        this.paletteData = this.paletteDataBackup;\n        this.paletteItems = this.paletteItemsBackup;\n        this.itemIndex = this.paletteItemIndexBackup;\n        this.paletteInputElement.value = this.paletteInputValueBackup;\n        this.maybeHighlightInputKeyword('');\n        this.paletteSearchAndUpdate();\n    }\n\n    /**\n     * Adds the search mode tag with the specified title.\n     *\n     * @param {string} title\n     */\n    addSearchModeTag(title) {\n        this.paletteSearchModeTag.classList.add('active');\n        this.paletteSearchModeTag.innerText = title;\n    }\n\n    /**\n     * Removes the search mode tag\n     */\n    removeSearchModeTag() {\n        this.paletteSearchModeTag.classList.remove('active');\n    }\n\n    isPaletteOpen() {\n        return this.paletteElement?.classList.contains('active');\n    }\n\n\tshowPalette() {\n        // Bail if already shown (this can be triggered by a focus event)\n        if (this.isPaletteOpen()) {\n            return;\n        }\n\n        this.paletteInputElement.value = '';\n\t\tthis.paletteInputElement?.focus();\n\t\tthis.paletteElement?.classList.add('active');\n        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when\n        // the palette opens.\n        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n        if (this.searchMode !== null) {\n            this.leaveSearchMode();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;\n        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + \"px\";\n        this.paletteSubmenuContainerElement.classList.add('active');\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        this.paletteSubmenuContainerElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsContainerElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n        if (this.selectedItem.dataset.actionType === 'search-mode') {\n            this.enterSearchModeByKeyword(this.selectedItem.dataset.searchMode);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        // link.href will be interpolated by the browser, so if it's empty it will be the current page\n        // use getAttribute instead to work out if its empty\n        if (link.getAttribute('href') === '') {\n            return;\n        }\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        if (! this.searchMode) {\n            this.buildPaletteItems();\n\n            if (this.paletteInputElement.value !== '') {\n                // Reset the search to work on the new items\n                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n            }\n            return;\n        }\n\n        if (this.paletteInputElement.value.length === 0) {\n            this.paletteInnerElement.classList.add('loading');\n            let results = [];\n            if (this.searchMode.defaultItemsCallback !== null) {\n                results = await this.searchMode.defaultItemsCallback();\n            }\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        } else {\n            // This is copied to enterSearchMode. Should probably be extracted.\n            this.paletteInnerElement.classList.add('loading');\n            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n\n        /**\n         * OLD CODE BELOW\n         */\n        // Content search - don't search everything!\n        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n        //     this.paletteInnerElement.classList.add('loading');\n\n        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)\n        //         .then(\n        //             results => {\n        //                     this.injectContentItems(results);\n        //                     this.paletteInnerElement.classList.remove('loading');\n        //             }\n        //         )\n        // }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "/**\n * An item definition specifies how to detect a palette item from the Dashboard's Dom\n *\n * These are all processed on initialisation to generate menu items.\n *\n * Note that a single definition may generate multiple menu items if the selectors used\n * discover multiple items.\n */\nexport default class ItemDefinition {\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuItemCallback\n    * @param {HTMLElement} element\n    * @returns {string}\n    */\n\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuActionInfoCallback\n    * @param {HTMLElement} element\n    * @returns {Object}\n    */\n\n    /**\n     * The method of detecting items. Can be:\n     *  - 'dom' for checking if a DOM element exists (requires detectSelector or detectSelectorNone)\n     *  - 'url' if the current URL is being checked (requires detectPattern)\n     *  - 'none' if no detection is required - this item will always be added\n     *\n     * @type {string}\n     */\n    detectType = 'dom';\n\n    /**\n     * [OPTIONAL] A CSS selector used to find items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelector = '';\n\n    /**\n     * [OPTIONAL] A CSS selector used to check for an absence of items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelectorNone = '';\n\n    /**\n     * [OPTIONAL] A string to find in the current URL to detect the item\n     *\n     * @type {string}\n     */\n    detectPattern = '';\n\n    /**\n     * A callback used to generate a menu item title from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemTitleFunction = null;\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     *\n     * @type {string}\n     */\n    itemActionType = 'url';\n\n    /**\n     * A callback used to generate a menu item link URL from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemUrlFunction = null;\n\n    /**\n     * A callback used to generate an object containing data used by the specified action type.\n     *\n     * For 'search-mode' the object should be like { searchMode: '<keyword>' }\n     *\n     * @type {menuActionInfoCallback|null}\n     */\n    itemActionInfoFunction = null;\n\n     /**\n      * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n      *\n      * @type {boolean}\n      */\n     noCache = false;\n}\n", "import ItemDefinition from \"./class-item-definition\";\n\n/**\n * Menu items are the items ready to appear in the palette.\n *\n * These are standard items, not content items. Though this should probably be standardised.\n */\nexport default class TurboAdminMenuItem {\n\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     */\n    actionType = 'url';\n\n    /**\n     * The action of the item is the URL to visit when the item is clicked or the action data\n     * if the action type is not 'url'\n     *\n     * @type {string|Object}\n     */\n    action = '';\n\n    /**\n     * The parent title is the title of the parent item under which the current item\n     * was found in the WordPress menu.\n     *\n     * e.g. in Posts -> Add Post, \"Posts\" is the parent item.\n     *\n     * @type {string}\n     */\n    parentTitle = '';\n\n    /**\n     * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n     *\n     * @type {boolean}\n     */\n    noCache = false;\n\n    /**\n     * Creates a new simple menu item (only works for URLs - for more complex items use fromItemDefinition)\n     *\n     * @param {string} title\n     * @param {string} action\n     * @param {string} parentTitle\n     * @param {boolean} noCache\n     */\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n        this.actionType = 'url';\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    /**\n     * Construct a new menu item from an ItemDefinition\n     *\n     * @param {ItemDefinition} item\n     * @param {HTMLElement} element\n     * @param {string} parentTitle\n     * @return {TurboAdminMenuItem}\n     */\n    static fromItemDefinition(item, element = null, parentTitle = '') {\n        const action = item.itemActionType === 'url' ?\n            item.itemUrlFunction(element) :\n            item.itemActionInfoFunction(element);\n\n        const menuItem = new TurboAdminMenuItem(\n            item.itemTitleFunction(element),\n            action,\n            parentTitle,\n            item?.noCache\n        );\n        menuItem.actionType = item.itemActionType;\n        return menuItem;\n    }\n\n    /**\n     * Compares this item to another item\n     *\n     * @param {TurboAdminMenuItem} item\n     * @returns {boolean}\n     */\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if (this.inExtension()) {\n            this.store = chrome.storage.local;\n        } else {\n            this.store = window.localStorage;\n        }\n    }\n\n    /**\n     * Returns true if we are in the extension.\n     */\n    inExtension() {\n        return window.turboAdminIsExtension();\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if (this.inExtension()) {\n            await this.store.set(dataObject);\n        } else {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if (this.inExtension()) {\n            return await this.store.get(key);\n        } else {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        }\n    }\n}\n", "import Storage from '../class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // turboAdminLog('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n        this.postTypes = [];\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        turboAdminLog('Discovering API root');\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n        // This should be very rare. I should only really see it in development.\n        turboAdminLog('API Route Discovery failed');\n        // Making best guess\n        this.apiBase = globalThis.taWp.home + '/wp-json/wp/v2/';\n        // TODO: This can't display as the palette isn't created yet.\n        // globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Can\\'t find the WP API. Try visiting the dashboard to refresh things.');\n    }\n\n    async discoverPostTypes() {\n        turboAdminLog('Discovering post types');\n        if (! this.active) {\n            turboAdminLog('Not active');\n            this.postTypes = [];\n            return;\n        }\n\n        const postTypes = await this.store.get('ta-post-types');\n\n        // Check local storage cache\n        if (postTypes && postTypes['ta-post-types'] && postTypes['ta-post-types']['expiry'] > Date.now()) {\n            turboAdminLog('Using cached post types: ', postTypes['ta-post-types']['data']);\n            this.postTypes = postTypes['ta-post-types']['data'];\n            return;\n        }\n\n        this.postTypes = await this.getPostTypes();\n        turboAdminLog('Discovered post types: ', this.postTypes);\n\n        // Cache for 10 minutes\n        const expiry = Date.now() + (10 * 60 * 1000);\n        this.store.set({\n            'ta-post-types': {\n                expiry: expiry,\n                data: this.postTypes\n            }\n        });\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    async getPostTypes() {\n        // Check the cache\n        if (undefined !== this.cache['postsTypes']) {\n            return this.cache['postTypes'];\n        }\n\n        // Fetch results\n        const response = await this.get('types');\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['postTypes'] = result;\n\n        return result;\n    }\n\n    async getPosts(searchString, postType = 'any') {\n        // Check the cache\n        const cacheKey =  `posts-${postType}-${searchString}`;\n        if (undefined !== this.cache[cacheKey]) {\n            return this.cache[cacheKey];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: postType\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[cacheKey] = result;\n\n        return result;\n    }\n\n    /**\n     * We can't use the API to get a post of any post type. So we hack this a bit.\n     *\n     * @param {number} postId\n     * @returns {Promise<any>}\n     */\n    async doesPostExist(postId) {\n        // Check the cache\n        if (undefined !== this.cache['post-' + postId]) {\n            return this.cache['post-' + postId];\n        }\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);\n\n        this.cache['post-' + postId] = response;\n\n        return response?.status === 200;\n    }\n\n    async getPlugins(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['plugins-' + searchString]) {\n            return this.cache['plugins-' + searchString];\n        }\n\n        let requestOptions = {};\n\n        if (searchString) {\n            requestOptions.search = searchString;\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"plugins\",\n            requestOptions\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['plugins-' + searchString] = result;\n\n        return result;\n    }\n\n    async getUsers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['users-' + searchString]) {\n            return this.cache['users-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"users\",\n            {\n                search: searchString,\n                per_page: 100,\n                context: 'edit' // view / embed / edit\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['users-' + searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`, init);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WordPress API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog( 'TURBO ADMIN: WordPress API Error. Try visiting the WordPress Dashboard to refresh things.' );\n            }\n        }\n\n        return response;\n    }\n\n}\n", "export default class SubmenuItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title;\n\n    /**\n     * The URL of the item\n     * @type {string}\n     */\n    url;\n\n    /**\n     * A list of attributes to go on the A tag (not the LI tag)\n     *\n     * @type {array}\n     */\n    attributes = [];\n\n    /**\n     * Create a submenu item\n     *\n     * @param {string} title The title of the item\n     * @param {string} url The URL of the item\n     */\n    constructor(title, url) {\n        this.title = title;\n        this.url = url;\n    }\n\n    /**\n     * Add an attribute\n     *\n     * @param {string} name The attribute name\n     * @param {string} value The attribute value\n     */\n    addAttribute(name, value) {\n        this.attributes.push({\n            name: name,\n            value: value\n        });\n    }\n}\n", "import SubmenuItem from \"./class-submenu-item\";\n\nexport default class ContentItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The subtype of the item. e.g. for posts, this will be the post type.\n     * Used to display extra information about the item.\n     *\n     * @type {string}\n     */\n    subtype = '';\n\n    /**\n     * The URL of the item. Leave empty if there is a sub-menu.\n     *\n     * @type {string}\n     */\n    url = '';\n\n    /**\n     * The sub-menu items, if any.\n     *\n     * This should be an empty array if the item itself has a URL\n     *\n     * @type {SubmenuItem[]}\n     */\n    submenuItems = [];\n}\n", "import ContentItem from \"./class-content-item\";\n\nexport default class SearchMode {\n    /**\n     * The keyword string used to initiate the search\n     *\n     * @type {string}\n     */\n    keyword = '';\n\n    /**\n     * The dispay name used for the search\n     *\n     * @type {string}\n     */\n    displayName = '';\n\n    /**\n     * jsDoc defintion for a `searchCallback`\n     *\n     * @callback SearchCallback\n     * @param {string} [searchString]\n     * @returns {Promise<ContentItem[]>}\n     */\n\n    /**\n     * Callback to get search items\n     *\n     * @type {SearchCallback}\n     */\n    searchCallback;\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @type {SearchCallback|null}\n     */\n    defaultItemsCallback = null;\n\n    /**\n     * Set this to false to hide the search mode from the palette - it still\n     * works with a keyword, but won't show in the palette's list of items\n     *\n     * @type {boolean}\n     */\n    showInPaletteSearch = true;\n\n    /**\n     * Constructs a new search mode\n     *\n     * @param {string} keyword\n     * @param {string} displayName\n     * @param {SearchCallback} searchCallback\n     * @param {SearchCallback} defaultItemsCallback\n     * @param {boolean} showInPaletteSearch\n     */\n    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null, showInPaletteSearch = true) {\n        this.keyword = keyword;\n        this.displayName = displayName;\n        this.searchCallback = searchCallback;\n        this.defaultItemsCallback = defaultItemsCallback;\n        this.showInPaletteSearch = showInPaletteSearch;\n    }\n}\n", "import SearchMode from \"./class-search-mode\";\nimport ItemDefinition from \"./class-item-definition\";\n\n/**\n * This is an abstract class that should be extended by plugins\n * @module TurboAdminPlugin\n */\nexport default class TurboAdminPlugin {\n    /** @type {string} */\n    name = '';\n\n    /** @type {SearchMode[]} */\n    searchModes = [];\n\n    /** @type {boolean} */\n    activated = false;\n\n    constructor(pluginName) {\n        this.name = pluginName;\n        this.registerPlugin();\n    }\n\n    /**\n     * Register the plugin with Turbo Admin\n     */\n    registerPlugin() {\n        turboAdminLog('Inside plugin - requested registration of ' + this.name);\n        globalThis.turboAdmin.registerPlugin(this);\n    }\n\n    /**\n     * Returns true if the plugin should activate\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return false;\n    }\n\n    /**\n     * Activates the plugin\n     * @return {void}\n     */\n    activate() {\n        this.activated = true;\n        this.registerSearchModes();\n    }\n\n    /**\n     * Register the search keywords with Turbo Admin - each will be registered\n     * with the whole plugin object.\n     */\n    registerSearchModes() {\n        this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);\n    }\n\n    /**\n     * Get the item definitions for search modes.\n     *\n     * Note that , at time of writing, this runs AFTER API init but before the plugin is activated.\n     * So APIs are available (and may be used in shouldActivate()) but the plugin is not yet activated.\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getSearchModeItemDefinitions() {\n        if (!this.shouldActivate()) {\n            return [];\n        }\n\n        const searchModeItems = this.searchModes.map(searchMode => {\n            // Return null if we don't want to show this search mode in the palette.\n            if (searchMode.showInPaletteSearch === false) {\n                return null;\n            }\n            const item = new ItemDefinition();\n            item.detectType = 'none';\n            item.itemTitleFunction = () => `<span style=\"font-style:italic;\">Search</span>: ${searchMode.displayName}`;\n            item.itemActionType = 'search-mode';\n            item.itemActionInfoFunction = () => { return { searchMode: searchMode.keyword } };\n            return item;\n        })\n        // Filter out the nulls.\n        return searchModeItems.filter( item => item !== null);\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getAdditionalItemDefinitions() {\n        if (!this.activated) {\n            return [];\n        }\n\n        return [];\n    }\n\n    /**\n     * Save plugin setting to persistent storage\n     */\n    saveSetting(key, value) {\n\n    }\n\n}\n", "/**\n * It's impossible to change the setting to off, because the\n * extension's content script runs in a sandbox and can't access\n * the wp object. But we can just toggle the class every time.\n */\nexport default class TurboAdminWpBlockEditorFullscreenKill {\n\n    constructor() {\n\n        // Don't run on the site editor screen\n        if (document.body.classList.contains( 'site-editor-php' )) {\n            return;\n        }\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed fullscreen\n                // if (document.body.classList.contains('turbo-admin-killed-fullscreen')) {\n                //     return;\n                // }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (mu.target.classList.contains('is-fullscreen-mode')) {\n                    this.killFullScreenEditor();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killFullScreenEditor();\n    }\n\n    killFullScreenEditor() {\n        if (! document.body.classList.contains('is-fullscreen-mode')) {\n            return;\n        }\n\n        document.body.classList.remove('is-fullscreen-mode');\n        document.body.classList.add('turbo-admin-killed-fullscreen');\n\n        const newStyles = document.createElement('style');\n        newStyles.innerHTML = \"body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }\";\n        document.body.appendChild(newStyles);\n    }\n}\n", "/**\n *\n */\nexport default class TurboAdminWpBlockEditorWelcomeGuideKill {\n\n    constructor() {\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed the modal\n                if (document.body.classList.contains('ta-killed-post-welcome-guide')) {\n                    return;\n                }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (! mu.target.classList.contains('modal-open')) {\n                    return;\n                }\n\n                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n                if (welcomeGuide) {\n                    this.killWelcomeGuide();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killWelcomeGuide();\n    }\n\n    killWelcomeGuide() {\n        const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n        if (welcomeGuide) {\n            const closeButton = welcomeGuide.querySelector('.components-modal__header button');\n            if (closeButton) {\n                closeButton.click();\n                /*\n                 * Also add a class to body so we don't do it again - subsequent modals\n                 * will need to be shown as they will have been user-initiated.\n                 */\n                document.body.classList.add('ta-killed-post-welcome-guide');\n            }\n        }\n    }\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            '.notice-success',\n            '.notice-error',\n            '.notice-failure',\n            '.updated',\n        ]\n\n        this.noticesPanelInner = null;\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nturboAdminLog('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nturboAdminLog('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice);\n            this.maybeAddMoveButtonToNotice.call(this, notice);\n        });\n\n        const noticesToHide = Array.from(notices).filter( this.noticeShouldBeHidden.bind(this) );\n\n        turboAdminLog('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        this.noticesPanelInner = document.createElement('div');\n        this.noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(this.hideNotice.bind(this));\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(this.noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n\n        // Add a mutation observer to check for notices added by JavaScript\n        // this.addObserver();\n    }\n\n    addObserver() {\n        const observer = new MutationObserver( this.handleMutations.bind(this) );\n        observer.observe(document.getElementById('wpbody-content'), {\n            childList: true,\n            subtree: true\n        });\n    }\n\n    handleMutations(mutations, observer) {\n        mutations.forEach( mutation => {\n            if (mutation.type === 'childList') {\n                mutation.addedNodes.forEach( node => {\n                    if (node.nodeType === Node.ELEMENT_NODE) {\n                        console.log('MUTATING!!!' + node.id);\n                        // this.maybeAddIdToNotice(node);\n                        // this.maybeAddMoveButtonToNotice(node);\n                        // this.maybeHideNotice(node);\n                    }\n                });\n            }\n        });\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return noticeElem.matches(this.allowedClasses.join(', '));\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    noticeShouldBeHidden(notice) {\n        if (this.rememberedNoticeIds.includes(notice.id)) {\n            return true;\n        }\n\n        if (this.keepNotice(notice)) {\n            return false;\n        }\n\n        // Invisible\n        if (\n            notice.offsetHeight === 0 ||\n            notice.offsetWidth === 0\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(noticeElem) {\n        if (noticeElem.id && noticeElem.id !== '' && noticeElem.id !=='message') {\n            return;\n        }\n\n        const classes = noticeElem.classList;\n        noticeElem.id = Array.from(noticeElem.classList).join('-');\n    }\n\n    /**\n     * Add buttons to notices that we want to be able to move to the panel\n     */\n    maybeAddMoveButtonToNotice(noticeElem) {\n        if (this.keepNotice(noticeElem)) {\n            const rememberButton = document.createElement('button');\n            rememberButton.classList.add('ta-remember-notice-button');\n            rememberButton.innerText = 'Move to panel';\n\n            const forgetButton = document.createElement('button');\n            forgetButton.classList.add('ta-forget-notice-button');\n            forgetButton.innerText = 'Move to dashboard';\n\n            noticeElem.classList.add('ta-added-pos-relative');\n\n            noticeElem.appendChild(rememberButton);\n            noticeElem.appendChild(forgetButton);\n\n            rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n            forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n        }\n    }\n\n    maybeHideNotice(noticeElem) {\n        if (this.noticeShouldBeHidden(noticeElem) && !noticeElem.classList.contains('ta-notice-hidden')) {\n            this.hideNotice(noticeElem);\n        }\n    }\n\n    hideNotice(noticeElem) {\n        noticeElem.classList.add('ta-notice-hidden');\n        // WPCore's common.js will re-add the notice below the dashboard header unless it has a .inline class.\n        // It does: $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );\n        noticeElem.classList.add('inline');\n        // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n        this.noticesPanelInner.append(noticeElem);\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        if (! this.listTable) {\n            return;\n        }\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        document.addEventListener('keyup', e => this.handleKeyup(e));\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKeyup(ev) {\n        if (document.activeElement.tagName !== 'BODY') {\n            return;\n        }\n\n        if (ev.key === 'j') {\n            this.tableMoveDown();\n        } else if (ev.key === 'k') {\n            this.tableMoveUp();\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            this.openTableRowItem();\n        }\n\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else if (this.currentRowIndex < this.tableRows.length - 1) {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n        }\n\n        this.updateTable();\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n    }\n\n    openTableRowItem() {\n        turboAdminLog(this);\n        /** @type {HTMLAnchorElement} */\n        const link = this.currentRow.querySelector('a.row-title');\n        if (link) {\n            link.click();\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\n\nexport default class TurboAdminBarkeeper extends TurboAdminPlugin {\n    constructor() {\n        super('Barkeeper');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        if (true !== globalThis.turboAdmin.options['barkeeper']) {\n            return false;\n        }\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return false;\n        }\n        // Bail if we don't have the left-hand admin bar (some users only have right-hand side)\n        if (! document.getElementById('wp-admin-bar-root-default')) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.selectorsToHide = [\n            '#wp-admin-bar-root-default > li',\n            '.monsterinsights-adminbar-menu-item',\n        ];\n\n        this.barkeeperState = this.getBarkeeperState();\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        if (! this.root) {\n            return;\n        }\n        this.itemsToHide = document.querySelectorAll( this.selectorsToHide.join(', ') );\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            this.setBarkeeperState(this.barkeeperState);\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n\n        this.setupObserver();\n    }\n\n    /**\n     * Some awkward plugins add themselves into the bar using JS\n     */\n    setupObserver() {\n        this.observer = new MutationObserver( mutations => {\n            mutations.forEach( mutation => {\n                if (mutation.type === 'childList') {\n                    mutation.addedNodes.forEach( node => {\n                        if (node.classList && node.classList.contains('ta-barkeeper-collapsable')) {\n                            return;\n                        }\n                        if (node.id && this.exclusionIds.includes(node.id)) {\n                            return;\n                        }\n                        // Check is the node matches any of the selectors\n                        if (node.matches(this.selectorsToHide.join(', '))) {\n                            node.classList.add('ta-barkeeper-collapsable');\n                            return;\n                        }\n                    });\n                }\n            });\n        });\n\n        this.observer.observe(this.root, {\n            childList: true,\n            subtree: true,\n        });\n    }\n\n    getBarkeeperState() {\n        if (window.turboAdminIsExtension()) {\n            return globalThis.turboAdmin.options['barkeeper-state'];\n        } else {\n            return window.localStorage.getItem('turbo-admin-barkeeper-state');\n        }\n    }\n\n    setBarkeeperState(state) {\n        if (window.turboAdminIsExtension()) {\n            chrome.runtime.sendMessage({\n                'action': 'barkeeperSetState',\n                'barkeeperState': this.barkeeperState,\n            });\n        } else {\n            window.localStorage.setItem('turbo-admin-barkeeper-state', state);\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminContentSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Content');\n\n        const ignoredPostTypes = [\n            'nav_menu_item',\n            'wp_block',\n            'wp_template',\n            'wp_template_part',\n            'wp_navigation',\n        ];\n\n        const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);\n\n        // Discard ignored post types\n        const filteredPostTypeKeys = postTypeKeys.filter(key => ! ignoredPostTypes.includes(key));\n\n        // Register a search mode for each post type\n        for (let i = 0; i < filteredPostTypeKeys.length; i++) {\n            const thisPostTypeKey = filteredPostTypeKeys[i];\n            const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];\n            // turboAdminLog('Adding search mode for post type', thisPostType);\n            this.searchModes.push( this.makePostTypeSearchMode(thisPostType) );\n        }\n\n        // Register ID search mode\n        this.searchModes.push( new SearchMode('id', 'Post ID', this.postById.bind(this)) );\n\n        // Register search all post types mode\n        this.searchModes.push( new SearchMode('search', 'All post types', this.contentSearch.bind(this)) );\n        // Don't show this one in the palette\n        this.searchModes.push( new SearchMode('find', 'All post types', this.contentSearch.bind(this), null, false) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * This is a generator for a post-type specific SearchMode object\n     *\n     * @param {Object} postType\n     */\n    makePostTypeSearchMode(postType) {\n        // TODO: interpret the post type name\n        return new SearchMode(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));\n    }\n\n    /**\n     * @param {string} searchString\n     * @param {string} postType This is passed to the API as a subtype. 'any' by default.\n     * @returns {Promise<ContentItem[]>}\n     */\n    async contentSearch(searchString, postType = 'any') {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPosts(searchString, postType);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = result.title;\n                            item.subtype = result.subtype;\n                            item.url = result.url;\n\n                            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item))\n\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} postId\n     * @returns {Promise<ContentItem[]>}\n     */\n    async postById(postId) {\n        if (! postId.trim().match(/^\\d+$/)) {\n            return [];\n        }\n        const postExists = await globalThis.contentApi.doesPostExist(postId);\n\n        const resultAsContentItem = new ContentItem;\n\n        if (! postExists) {\n            resultAsContentItem.title = 'Post does not exist or is not visible';\n            return [ resultAsContentItem ];\n        }\n\n        resultAsContentItem.title = `Post ID: ${postId}`;\n        resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;\n\n        resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));\n\n        return [ resultAsContentItem ];\n    }\n\n    /**\n     * Makes an array of submenu items from a content item\n     *\n     * @param {number} postId\n     * @param {ContentItem} contentItem\n     * @returns {SubmenuItem[]}\n      */\n    makeSubmenuItems(postId, contentItem) {\n        const itemsToReturn = [];\n        itemsToReturn.push(\n            new SubmenuItem(\n                'View',\n                contentItem.url\n            )\n        );\n\n        // TODO: Make a better way to detect if we are logged in.\n        if (globalThis.turboAdmin.turboAdminPalette.profileLink) {\n            // Need to get edit URL. This seems like the best way for now.\n            const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;\n            itemsToReturn.push(\n                new SubmenuItem(\n                    'Edit',\n                    editLink\n                )\n            )\n\n            // Add oxygen link if needed.\n            if (globalThis.turboAdmin.hasActivatedPlugin('OxygenBuilder')) {\n                const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;\n                itemsToReturn.push(\n                    new SubmenuItem(\n                        'Edit with Oxygen',\n                        oxygenLink\n                    )\n                );\n            }\n        }\n\n        const copyLinkItem = new SubmenuItem( 'Copy link', contentItem.url);\n        copyLinkItem.addAttribute('data-action', 'clipboard')\n        itemsToReturn.push(copyLinkItem);\n\n        return itemsToReturn;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminPluginSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Plugins');\n\n        this.searchModes.push( new SearchMode('plugin', 'Plugins', this.pluginSearch, this.defaultPluginItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultPluginItems() {\n        return await this.pluginSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async pluginSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPlugins(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            // siteUrl is at globalThis.turboAdmin.wp.siteUrl\n                            const item = new ContentItem;\n                            item.title = result.name;\n                            item.subtype = 'Plugin';\n                            // TODO: Maybe set this to be a search on the plugin screen?\n                            // Plugin \"slug\" is in result.name\n\n                            const itemViewUrlParams = new URLSearchParams();\n                            itemViewUrlParams.set('plugin_status', 'all');\n                            itemViewUrlParams.set('s', result.name);\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'View',\n                                    globalThis.taWp.siteUrl + '/plugins.php?' + itemViewUrlParams.toString()\n                                )\n                            );\n                            // Activate: /wp-admin/plugins.php?action=activate&plugin=order-simulator-woocommerce%2Fwoocommerce-order-simulator.php&plugin_status=all&paged=1&s&_wpnonce=3714a01759\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\n\nexport default class TurboAdminUserSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Users');\n\n        this.searchModes.push( new SearchMode('user', 'Users', this.userSearch, this.defaultUserItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultUserItems() {\n        return await this.userSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async userSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getUsers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            if (result.first_name && result.last_name) {\n                                item.title = `${result.first_name} ${result.last_name} - `;\n                            }\n                            item.title += result.email;\n                            item.subtype = result.roles[0];\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminWoocommerce extends TurboAdminPlugin {\n    constructor() {\n        super('WooCommerce');\n\n        this.searchModes.push( new SearchMode('order', 'Orders', this.orderSearch) );\n        this.searchModes.push( new SearchMode('customer', 'Customers', this.customerSearch) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of WooCommerce in Dashboard\n        /** @type {HTMLElement|string|Number} */\n        let woocommerceMenuElement = document.getElementById('toplevel_page_ct_dashboard_page');\n\n        // Also check for a menu bar item\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = document.getElementById('wp-admin-bar-new-shop_order');\n        }\n\n        // Check to see if WooCommerce flag is cached\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasWooCommerce = Boolean(woocommerceMenuElement);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-woocommerce', hasWooCommerce ? '1' : '0' );\n\n        return globalThis.contentApi.active && hasWooCommerce;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async orderSearch(searchString) {\n        let results;\n\n        if (searchString.trim().match(/^\\d+$/)) {\n            results = await globalThis.woocommerceApi.getOrder(searchString);\n        } else {\n            results = await globalThis.woocommerceApi.getOrders(searchString);\n        }\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `#${result.number} ${result.currency_symbol}${result.total}`;\n                            item.subtype = result.billing.email;\n                            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async customerSearch(searchString) {\n        const results = await globalThis.woocommerceApi.getCustomers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `${result.billing.first_name} ${result.billing.last_name}`;\n                            item.subtype = result.email;\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Orders',\n                                    globalThis.taWp.siteUrl + `/edit.php?post_status=all&post_type=shop_order&_customer_user=${result.id}`\n                                )\n                            )\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Profile',\n                                    globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`\n                                )\n                            )\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminGravityForms extends TurboAdminPlugin {\n    constructor() {\n        super('GravityForms');\n\n        this.searchModes.push( new SearchMode('form', 'Gravity Forms', this.formSearch, this.defaultFormsList.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return globalThis.contentApi.active &&\n               document.getElementById('wp-admin-bar-gravityforms-new-form') !== null\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultFormsList() {\n        return await this.formSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async formSearch(searchString) {\n        const resultsObject = await globalThis.gravityFormsApi.getForms(searchString);\n        // GF Results are an object rather than an array so we need to convert\n\n        // TODO: Catch the error response (do the TODO in the API class first)\n\n        const resultsArray = [];\n        const resultKeys = Object.keys(resultsObject);\n        for(let k = 0; k < resultKeys.length; k++) {\n            const result = resultsObject[resultKeys[k]];\n            const item = new ContentItem;\n            item.title = `#${result.id} ${result.title}`;\n            item.subtype = `${result.entries} entries`;\n            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Edit Form',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Entries',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_entries&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Form Settings',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=settings&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Confirmatons',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=confirmation&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Notifications',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=notification&id=${result.id}`\n                )\n            )\n\n            turboAdminLog(item);\n\n            resultsArray.push(item);\n        }\n        return resultsArray;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminMUSites extends TurboAdminPlugin {\n    constructor() {\n        super('WP Multisite Sites');\n\n        this.searchModes.push( new SearchMode('site', 'Sites', this.siteSearch.bind(this), this.defaultSiteItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return Boolean(document.querySelector('#wp-admin-bar-my-sites'));\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultSiteItems() {\n        return await this.siteSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async siteSearch(searchString) {\n        // {\n        //     'detectType': 'dom',\n        //     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n        //     'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n        //     'itemUrlFunction': (element) => element.href\n        // },\n\n        const sites = document.querySelectorAll('#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li');\n\n        if (sites.length === 0) {\n            return [];\n        }\n\n        const sitesArray = Array.from(sites);\n        const sitesLinks = sitesArray.map(site => site.querySelector('a'));\n        const filteredSites = sitesLinks.filter(site => site.innerText.toLowerCase().includes(searchString.toLowerCase()));\n\n        return filteredSites.map(site => {\n            const item = new ContentItem;\n            item.title = site.innerText;\n            item.subtype = 'Site';\n            item.url = site.href;\n\n            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));\n\n            return item;\n        });\n    }\n\n    makeSubmenuItems(siteElement) {\n        const submenuItems = [];\n\n        const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);\n        if (! submenu) {\n            return [];\n        }\n\n        const submenuLinks = submenu.querySelectorAll('a');\n        if (submenuLinks.length === 0) {\n            return [];\n        }\n\n        const submenuLinksArray = Array.from(submenuLinks);\n        submenuLinksArray.forEach(link => {\n            const submenuItem = new SubmenuItem(link.innerText, link.href);\n            submenuItems.push(submenuItem);\n        });\n\n        return submenuItems;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\nimport ItemDefinition from '../types/class-item-definition.js';\n\nexport default class TurboAdminOxygenBuilder extends TurboAdminPlugin {\n    constructor() {\n        super('OxygenBuilder');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasOxygenBuilder = Boolean(oxygenLinkElem);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', hasOxygenBuilder ? '1' : '0' );\n\n        return hasOxygenBuilder;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n     async getAdditionalItemDefinitions() {\n        const editDefinition = new ItemDefinition();\n        editDefinition.detectType = 'dom';\n        editDefinition.detectSelector = '#ct-edit-template-builder';\n        editDefinition.itemTitleFunction = () => 'Edit with Oxygen';\n        editDefinition.itemUrlFunction = (element) => element.href;\n        editDefinition.noCache = true;\n\n        // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n        // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n        // doesn't refresh the menu items.\n        const backToWpDefinition = new ItemDefinition();\n        backToWpDefinition.detectType = 'dom';\n        backToWpDefinition.detectSelector = '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)';\n        backToWpDefinition.itemTitleFunction = (element) => 'Back to WP: ' + element.textContent;\n        backToWpDefinition.itemUrlFunction = (element) => {\n            if (element.href) {\n                return element.href;\n            } else {\n                let url = new URL(window.location.href);\n                return url.origin + url.pathname;\n            }\n        };\n        backToWpDefinition.noCache = true;\n\n        return [\n            editDefinition,\n            backToWpDefinition,\n        ];\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\n\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';\nimport SearchMode from './types/class-search-mode.js';\nimport TurboAdminPlugin from './types/class-turbo-admin-plugin.js';\nimport Acf from './plugins/class-acf.js';\nimport TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\nimport TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';\nimport TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';\nimport TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';\nimport TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';\nimport TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';\nimport TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';\nimport TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';\nimport TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';\n\nexport default class TurboAdmin {\n\n    /**\n     * @param {*} options\n     * @returns {TurboAdmin}\n     */\n    constructor(options) {\n        // Sometimes we get a second copy of TA running, like if the plugin is running too.\n        // Is this case we want to skip the initialisation.\n        this.doInit = true;\n\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            this.doInit = false;\n            return globalThis.turboAdmin;\n        }\n\n        this.options = options;\n        this.plugins = {};\n\n        // TODO: Something? What should this type be?\n        this.searchModes = {};\n\n        // On the front end we set this if there is no saved menu.\n        this.menuNeedsRefresh = false;\n    }\n\n    /**\n     * Perform initialization - this is all the things that do not need APIs to\n     * get set up.\n     */\n    async init() {\n        if (! this.doInit) {\n            return;\n        }\n\n        // Register all the plugins\n        new TurboAdminBarkeeper();\n        new TurboAdminContentSearch();\n        new TurboAdminPluginSearch();\n        new TurboAdminUserSearch();\n        new TurboAdminMUSites();\n        new TurboAdminOxygenBuilder();\n\n        if (window.turboAdminIsExtension()) {\n            new TurboAdminWoocommerce();\n            new TurboAdminGravityForms();\n        }\n\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Check for .logged-in class on body - if logged in, we can use the saved menu,\n                // if it exists.\n                if (document.body.classList.contains('logged-in')) {\n                    // Get from localStorage\n                    const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                    // This attempts to see if we have cached items from the back-en\n                    if (null === savedMenu) {\n                        this.menuNeedsRefresh = true;\n                    } else {\n                        this.menu = JSON.parse(savedMenu);\n                        // Check if there is no \"Media\" item  - this should ONLY be in the back-end\n                        if (! this.menu.some(item => ( ( typeof(item.action) === 'string' ) && ( item.action.endsWith('upload.php') ) ))) {\n                            this.menuNeedsRefresh = true;\n                        }\n                        // Merge (?) the items?\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        await this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n    }\n\n    /**\n     * These are initialization steps that DO needs APIs to be set up.\n     */\n    activatePlugins() {\n        // Initialize all plugins\n        Object.keys(this.plugins).forEach( plugin => {\n            if (this.plugins[plugin].shouldActivate()) {\n                this.plugins[plugin].activate();\n            }\n        })\n\n        if (true === this.options['block-editor-fullscreen-disable']) {\n            // Initialise fullscreen kill\n            this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        }\n\n        if (true === this.options['block-editor-welcome-screen-kill']) {\n            this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    /**\n     * True if the plugin has been activated\n     *\n     * @param {string} name Name of the plugin to check for\n     * @returns {boolean}\n     */\n    hasActivatedPlugin(name) {\n        return Object.keys(this.plugins).includes(name) &&\n            this.plugins[name].activated;\n    }\n\n    /**\n     * Gather the WordPress dashboard admin (sidebar) menu items\n     *\n     * @returns { TurboAdminMenuItem[] }\n     */\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    /**\n     * Adds additional menu items passed in by configuration to the\n     * menu items list.\n     */\n    async addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.\n        let extraItems = this.options.extraItems ?? [];\n\n        // Get any extra items defined by plugins\n        const pluginKeys = Object.keys(this.plugins);\n\n        for (let i=0; i < pluginKeys.length; i++) {\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getSearchModeItemDefinitions());\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());\n        }\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                // TODO: Convert to ItemDefinition objects\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.siteUrl;\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'none') {\n                detected = true;\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = TurboAdminMenuItem.fromItemDefinition(item, element, '');\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    /**\n     * Builds the palette HTML and adds it to the DOM.\n     */\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Palette notice\n        const paletteNotice = document.createElement('div');\n        paletteNotice.id = 'ta-command-palette-notice';\n        // Tab notice\n        const tabNotice = document.createElement('div');\n        tabNotice.id = 'ta-command-palette-tab-notice';\n        // Tab notice text\n        const tabNoticeText = document.createElement('span');\n        tabNoticeText.id = 'ta-command-palette-tab-notice-text';\n        // Tab notice \"button\"\n        const tabNoticeButton = document.createElement('span');\n        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';\n        tabNoticeButton.innerText = 'Tab';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // Search mode tag\n        const searchModeTag = document.createElement('div');\n        searchModeTag.id = 'ta-command-palette-search-mode-tag';\n        // List container (needed to contain the main list and the submenu list)\n        const listContainer = document.createElement('div');\n        listContainer.id = \"ta-command-palette-items-container\";\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Sub-menu list\n        const submenuContainer = document.createElement('div');\n        submenuContainer.id = \"ta-command-palette-submenu-container\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(searchModeTag);\n        palette.appendChild(paletteNotice);\n        tabNotice.appendChild(tabNoticeText);\n        tabNotice.appendChild(tabNoticeButton);\n        palette.appendChild(tabNotice);\n        palette.appendChild(input);\n        listContainer.appendChild(list);\n        listContainer.appendChild(submenuContainer);\n        palette.appendChild(listContainer);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, listContainer );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    /**\n     * Register a plugin with Turbo Admin\n     *\n     * @param {TurboAdminPlugin} plugin\n     */\n    registerPlugin(plugin) {\n        turboAdminLog('Registering plugin ' + plugin.name);\n        this.plugins[plugin.name] = plugin;\n    }\n\n    /**\n     * Register a palette search mode and its associated plugin\n     *\n     * this is usually bound to the searchMode, so\n     *\n     * @param {SearchMode} searchMode\n     */\n    registerSearchMode(searchMode) {\n        turboAdminLog('Registering search mode with keyword ' + searchMode.keyword);\n        // Don't use `this` as we are bound!\n        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;\n    }\n\n    /**\n     * Returns a string representation of the palette's keyboard shortcut\n     *\n     * @returns { String }\n     */\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key.toUpperCase();\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n            let urlsFound = false;\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                const dashboardLink = document.getElementById('wp-admin-bar-dashboard')?.querySelector('a');\n                if (dashboardLink) {\n                    this.siteUrl = dashboardLink.href;\n                }\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    urlsFound = true;\n                } else {\n                    // We might know what the siteUrl is, so guess the home from the siteUrl\n                    if (this.siteUrl) {\n                        this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                        urlsFound = true;\n                    }\n                }\n            }\n            if (! urlsFound) {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                    urlsFound = true;\n                }\n            }\n            if (! urlsFound) {\n                // We got nothing.\n                this.home    = await this.guessHome();\n                if (this.home) {\n                    this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // turboAdminLog('siteUrl: ', this.siteUrl);\n        // turboAdminLog('home: ', this.home);\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class WoocommerceApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getOrders(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['orders-' + searchString]) {\n            return this.cache['orders-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"orders\",\n            {\n                search: searchString,\n                per_page: 100,\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['orders-' + searchString] = result;\n\n        return result;\n    }\n\n    async getOrder(orderId) {\n        // Check the cache\n        if (undefined !== this.cache['order-' + orderId]) {\n            return this.cache['order-' + orderId];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            `orders/${orderId}`\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        let resultAsArray = [ result ];\n\n        // Store in the cache\n        this.cache['order-' + orderId] = resultAsArray;\n\n        return resultAsArray;\n    }\n\n    async getCustomers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['customers-' + searchString]) {\n            return this.cache['customers-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"customers\",\n            {\n                search: searchString,\n                per_page: 100,\n                role: 'all',\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['customers-' + searchString] = result;\n\n        return result;\n    }\n\n    // TODO: Add docblock and types\n    async wooGet(path, data = {}) {\n        const wooApiBase = globalThis.contentApi.apiRoot + 'wc/v3/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${wooApiBase}${path}/?${params}`, init);\n\n        if ( response.status === 404 ) {\n            return false;\n        }\n        if ( (response.status < 200 || response.status >= 300) ) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WooCommerce API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: WooCommerce API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class GravityFormsApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getForms(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['gf-forms-' + searchString]) {\n            return this.cache['gf-forms-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.gfGet(\n            \"forms\",\n            {}\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // TODO: Trap for errors\n\n        // Filter by search string - the API doesn't do this for us\n        const searchStringLowerCase = searchString.toLowerCase();\n        const formIds = Object.keys(result);\n        for (let k = 0; k < formIds.length; k++) {\n            const thisId = formIds[k];\n            if (! result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {\n                delete result[thisId];\n            }\n        }\n\n        // Store in the cache\n        this.cache['gf-forms-' + searchString] = result;\n\n        return result;\n    }\n\n    async gfGet(path, data = {}) {\n        const gfApiBase = globalThis.contentApi.apiRoot + 'gf/v2/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${gfApiBase}${path}/?${params}`);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Gravity Forms API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: Gravity Forms API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './apis/class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport WoocommerceApi from './apis/class-woocommerce-api.js';\nimport GravityFormsApi from './apis/class-gravity-forms-api.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\nlet debugMode = false;\n\nwindow.turboAdminLog = function() {\n    if (debugMode) {\n        console.log(...arguments);\n    }\n}\n\nwindow.turboAdminIsExtension = function() {\n    return false;\n}\n\n// Use this to clear storage\n// chrome.storage.local.remove(taStorageKey).then();\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    if (typeof(globalThis.turboAdmin) !== 'undefined') {\n        // Already initialised for some reason\n        return;\n    }\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    // Set debug mode\n    debugMode = globalThis.turboAdminOptions['debug-mode'];\n\n    turboAdminLog('Preparing Turbo Admin');\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    turboAdminLog('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n    await globalThis.contentApi.discoverPostTypes();\n    globalThis.woocommerceApi = new WoocommerceApi();\n    globalThis.gravityFormsApi = new GravityFormsApi();\n\n    turboAdminLog('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n    await globalThis.turboAdmin.init();\n\n    // This needs all the APIs to be ready\n    await globalThis.turboAdmin.activatePlugins();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n        'debug-mode': globalThis.wpTurboAdmin['debugMode'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
    5   "mappings": "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",
     4  "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item';\nimport ContentApi from './apis/class-content-api.js';\nimport SearchMode from './types/class-search-mode.js';\nimport ContentItem from './types/class-content-item.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tturboAdminLog('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));\n        /** @type {HTMLSpanElement} */\n        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));\n        /** @type {HTMLDivElement} */\n        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));\n\n\n        // Add a class if the menu needs refreshing with a visit to the Dashboard\n        if (globalThis.turboAdmin.menuNeedsRefresh) {\n            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');\n        }\n\n        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but\n        // works for now.\n        /** @type {HTMLUListElement} */\n        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        /** @type {null|String} */\n        this.profileLink = null;\n        if (this.profileLinkElem) {\n            this.profileLink = this.profileLinkElem.querySelector('a').href;\n        }\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Backup of the palette data for use when we enter a different search mode\n\t\tthis.paletteDataBackup = null;\n\t\tthis.paletteItemsBackup = null;\n        this.paletteItemIndexBackup = null;\n        this.paletteInputValueBackup = null;\n\n        // Current search modes/keyword\n        this.searchMode = null;\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n            shouldSort: true,\n            // sortFn: (a, b) => {\n            //     // Return search items first\n            //     if (a.item[0].v.startsWith('Search: ')) {\n            //         if (b.item[0].v.startsWith('Search: ')) {\n            //             return b.score - a.score;\n            //         }\n            //         return -1;\n            //     }\n            //     if (b.item[0].v.startsWith('Search: ')) {\n            //         return 1;\n            //     }\n            //     return a.score - b.score;\n            // }\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    inSearchMode() {\n        return this.searchMode !== null;\n    }\n\n\t/**\n     * This converts this.paletteData into a list of paletteListItems in this.paletteItems\n     *\n     * It also builds the itemIndex\n     */\n    buildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n            li.appendChild(a);\n            if (item.actionType === 'url') {\n                a.href = item.action;\n                let title = item.title;\n                if (item.parentTitle) {\n                    title = item.parentTitle + \": \" + title;\n                }\n                a.innerHTML = title;\n            } else if (item.actionType === 'search-mode') {\n                a.href = '#';\n                a.innerHTML = item.title;\n                li.dataset.actionType = item.actionType;\n                li.dataset.searchMode = item.action.searchMode;\n            }\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    /**\n     * Clears and sets the content items\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    setContentItems(contentItems) {\n        this.paletteItems = [];\n        this.itemIndex = [];\n        this.injectContentItems(contentItems, false);\n    }\n\n    /**\n     * Content items have:\n     *  title\n     *  subtype\n     *  url\n     *  (we should also make the sub-menu definable, but that's not done yet)\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    injectContentItems(contentItems, andRunSearch = true) {\n        turboAdminLog('Injecting items');\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(this.injectItem.bind(this));\n        }\n\n        if (andRunSearch) {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        this.updatePaletteItems();\n    }\n\n    /**\n     * Injects a single content item into the palette\n     *\n     * @param {ContentItem} item\n     */\n    injectItem(item) {\n        const itemTitle = item.title;\n        // const itemTitle = item.title.rendered;\n        const itemType = item.subtype;\n        const itemUrl = item.url;\n\n        // turboAdminLog('Adding item: ' + itemTitle);\n\n        // // Check if item already exists\n        if (this.contentItemExists(itemUrl)) {\n            turboAdminLog('Not adding duplicate');\n            return;\n        }\n\n        let title = itemTitle;\n\n        if (itemType) {\n            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;\n            title += ` (${itemTypeName})`;\n        }\n\n        const li = document.createElement('li');\n        const a = document.createElement('a');\n        let subMenu = null;\n\n        // Loop over submenu items OR add link.\n        if (item.submenuItems.length > 0) {\n\n            // Prepare the outer sub-menu elements\n            subMenu = document.createElement('div');\n            const subMenuTitle = document.createElement('div');\n            const subMenuItems = document.createElement('ul');\n            subMenu.classList.add('ta-submenu');\n            subMenuTitle.classList.add('ta-submenu-title');\n\n            subMenuTitle.textContent = this.htmlDecode(itemTitle);\n            subMenuItems.classList.add('ta-submenu-items');\n            subMenu.appendChild(subMenuTitle);\n\n            for (let i = 0; i < item.submenuItems.length; i++) {\n                const subMenuItem = item.submenuItems[i]\n                // TODO: Abstract this so sub-menus can be defined by plugins?\n                const subMenuListItem = document.createElement('li');\n                const subMenuLink = document.createElement('a');\n                subMenuLink.innerText = subMenuItem.title;\n                subMenuLink.href = subMenuItem.url;\n                for (let a = 0; a < subMenuItem.attributes.length; a++) {\n                    subMenuLink.setAttribute(\n                        subMenuItem.attributes[a].name,\n                        subMenuItem.attributes[a].value\n                    )\n                }\n                subMenuListItem.appendChild(subMenuLink);\n                subMenuItems.appendChild(subMenuListItem);\n            }\n\n            // Add the sub-menu items UL to the sub-menu element.\n            subMenu.appendChild(subMenuItems);\n\n            li.classList.add('ta-has-child-menu');\n        }\n\n        a.href = itemUrl;\n        a.innerHTML = title;\n\n        li.appendChild(a);\n        if (subMenu !== null) {\n            li.appendChild(subMenu);\n        }\n\n        this.addPaletteListItem(li);\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n            return;\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else if (this.inSearchMode()) {\n                this.leaveSearchMode();\n            } else {\n                this.hidePalette();\n            }\n            return;\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    /*\n     * Adds the tab hint for a keyword once it has been typed.\n     */\n    maybeHighlightInputKeyword(newKey) {\n        // Do nothing if we are in a search-mode\n        if (this.inSearchMode()) {\n            return;\n        }\n\n        // This is fired on \"keyDown\", so the value isn't update with the new key yet.\n        // But don't do this for special keys, and catch backspace too.\n        let newInputValue = this.paletteInputElement.value;\n        if (newKey.length === 1) {\n            newInputValue += newKey;\n        }\n        if (newKey === 'Backspace') {\n            newInputValue = newInputValue.slice(0, -1);\n        }\n        // turboAdminLog(`Checking palette input value ${newInputValue} for keyword`);\n        if (this.isKeyword(newInputValue)) {\n            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;\n            this.paletteSearchModeTabNotice.classList.add('active');\n        } else {\n            this.unhighlightInputKeyword();\n        }\n    }\n\n    unhighlightInputKeyword() {\n        this.paletteSearchModeTabNotice.classList.remove('active');\n    }\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If we're not in a search mode then search immediately\n        if (! this.inSearchMode()) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n\n        // Cancel the existing timeout\n        clearTimeout(this.debounceTimeout)\n\n        this.debounceTimeout = setTimeout(async function () {\n            // Reset timeout\n            this.debounceTimeout = null;\n\n            // Run the search function\n            await this.paletteSearchAndUpdate();\n        }.bind(this), 750);\n    }\n\n    /**\n     * Check if a string is a search mode keyword\n     *\n     * @param {string} inputString\n     * @returns {boolean}\n     */\n    isKeyword(inputString) {\n        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);\n    }\n\n    /**\n     * Show the palette notice with the specified text\n     *\n     * @param {string} text\n     */\n    showPaletteNotice(text) {\n        this.paletteNoticeElement.classList.add('active');\n        this.paletteNoticeElement.innerText = text;\n    }\n\n    /**\n     * Hide the palette notice\n     */\n    hidePaletteNotice() {\n        this.paletteNoticeElement.classList.remove('active');\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n            e.stopImmediatePropagation();\n            e.stopPropagation();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n            e.stopImmediatePropagation();\n            e.stopPropagation();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            e.preventDefault();\n            e.stopImmediatePropagation();\n            e.stopPropagation();\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n\n        /*\n         * Only the actions above can be done in sub-menus.\n         */\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\n        /*\n         * Check for a keyword being typed and add a UI hint.\n         */\n        this.maybeHighlightInputKeyword(e.key);\n\n        /*\n         * Tabbing looks for a search mode keyword.\n         */\n        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {\n            turboAdminLog('Checking for search mode');\n            let inputValue = this.paletteInputElement.value;\n            if (this.isKeyword(inputValue)) {\n                turboAdminLog('Found search mode ' + inputValue)\n                e.preventDefault();\n                await this.enterSearchMode(\n                    globalThis.turboAdmin.searchModes[inputValue]);\n                return;\n            }\n        }\n\n        /*\n         * Backspace may exit us from a search mode\n         */\n        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {\n            e.preventDefault();\n            this.leaveSearchMode();\n            return;\n        }\n\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n    /**\n     * Puts the palette into a specific search mode - used when a keyword is selected\n     *\n     * @param {SearchMode} searchMode\n     */\n    async enterSearchMode(searchMode) {\n        turboAdminLog('Entering search mode for keyword ' + searchMode.keyword);\n        this.backupPaletteData();\n\n        this.paletteData = [];\n        this.paletteItems = [];\n        this.itemIndex = [];\n\n        // Remove the notice if it's there\n        this.hidePaletteNotice();\n\n        this.searchMode = searchMode;\n        this.paletteInputElement.value = '';\n        this.addSearchModeTag(searchMode.displayName);\n        this.unhighlightInputKeyword();\n        this.updatePaletteItems();\n        // This is similar to code in paletteSearch - maybe we could extract/abstract it?\n        if (searchMode.defaultItemsCallback !== null) {\n            this.paletteInnerElement.classList.add('loading');\n            const results = await searchMode.defaultItemsCallback();\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n    }\n\n    /**\n     * Puts the palette into a specific search mode specified by a keyword\n     *\n     * @param {string} keyword\n     */\n    async enterSearchModeByKeyword(keyword) {\n        turboAdminLog('Entering search mode by keyword ' + keyword);\n        const searchMode = globalThis.turboAdmin.searchModes[keyword];\n        turboAdminLog('Search mode is ' + searchMode);\n        if (searchMode === undefined) {\n            return;\n        }\n        await this.enterSearchMode(searchMode);\n    }\n\n    /**\n     * Leaves the current search mode\n     */\n    leaveSearchMode() {\n        const searchMode = this.searchMode;\n        // It's important what we set this to - see inSearchMode()\n        this.searchMode = null;\n        this.removeSearchModeTag();\n        this.restorePaletteData();\n    }\n\n    /**\n     * Backups up the palette data and input value to local variables so that it can be\n     * restored later.\n     */\n    backupPaletteData() {\n        this.paletteDataBackup = this.paletteData;\n        this.paletteItemsBackup = this.paletteItems;\n        this.paletteItemIndexBackup = this.itemIndex;\n        this.paletteInputValueBackup = this.paletteInputElement.value;\n    }\n\n    /**\n     * Restores the save palette data - highlights and rebuilds\n     */\n    restorePaletteData() {\n        this.paletteData = this.paletteDataBackup;\n        this.paletteItems = this.paletteItemsBackup;\n        this.itemIndex = this.paletteItemIndexBackup;\n        this.paletteInputElement.value = this.paletteInputValueBackup;\n        this.maybeHighlightInputKeyword('');\n        this.paletteSearchAndUpdate();\n    }\n\n    /**\n     * Adds the search mode tag with the specified title.\n     *\n     * @param {string} title\n     */\n    addSearchModeTag(title) {\n        this.paletteSearchModeTag.classList.add('active');\n        this.paletteSearchModeTag.innerText = title;\n    }\n\n    /**\n     * Removes the search mode tag\n     */\n    removeSearchModeTag() {\n        this.paletteSearchModeTag.classList.remove('active');\n    }\n\n    isPaletteOpen() {\n        return this.paletteElement?.classList.contains('active');\n    }\n\n\tshowPalette() {\n        // Bail if already shown (this can be triggered by a focus event)\n        if (this.isPaletteOpen()) {\n            return;\n        }\n\n        this.paletteInputElement.value = '';\n\t\tthis.paletteInputElement?.focus();\n\t\tthis.paletteElement?.classList.add('active');\n        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when\n        // the palette opens.\n        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n        if (this.searchMode !== null) {\n            this.leaveSearchMode();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;\n        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + \"px\";\n        this.paletteSubmenuContainerElement.classList.add('active');\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        this.paletteSubmenuContainerElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsContainerElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n        if (this.selectedItem.dataset.actionType === 'search-mode') {\n            this.enterSearchModeByKeyword(this.selectedItem.dataset.searchMode);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        // link.href will be interpolated by the browser, so if it's empty it will be the current page\n        // use getAttribute instead to work out if its empty\n        if (link.getAttribute('href') === '') {\n            return;\n        }\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        if (! this.searchMode) {\n            this.buildPaletteItems();\n\n            if (this.paletteInputElement.value !== '') {\n                // Reset the search to work on the new items\n                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n            }\n            return;\n        }\n\n        if (this.paletteInputElement.value.length === 0) {\n            this.paletteInnerElement.classList.add('loading');\n            let results = [];\n            if (this.searchMode.defaultItemsCallback !== null) {\n                results = await this.searchMode.defaultItemsCallback();\n            }\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        } else {\n            // This is copied to enterSearchMode. Should probably be extracted.\n            this.paletteInnerElement.classList.add('loading');\n            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n\n        /**\n         * OLD CODE BELOW\n         */\n        // Content search - don't search everything!\n        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n        //     this.paletteInnerElement.classList.add('loading');\n\n        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)\n        //         .then(\n        //             results => {\n        //                     this.injectContentItems(results);\n        //                     this.paletteInnerElement.classList.remove('loading');\n        //             }\n        //         )\n        // }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "/**\n * An item definition specifies how to detect a palette item from the Dashboard's Dom\n *\n * These are all processed on initialisation to generate menu items.\n *\n * Note that a single definition may generate multiple menu items if the selectors used\n * discover multiple items.\n */\nexport default class ItemDefinition {\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuItemCallback\n    * @param {HTMLElement} element\n    * @returns {string}\n    */\n\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuActionInfoCallback\n    * @param {HTMLElement} element\n    * @returns {Object}\n    */\n\n    /**\n     * The method of detecting items. Can be:\n     *  - 'dom' for checking if a DOM element exists (requires detectSelector or detectSelectorNone)\n     *  - 'url' if the current URL is being checked (requires detectPattern)\n     *  - 'none' if no detection is required - this item will always be added\n     *\n     * @type {string}\n     */\n    detectType = 'dom';\n\n    /**\n     * [OPTIONAL] A CSS selector used to find items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelector = '';\n\n    /**\n     * [OPTIONAL] A CSS selector used to check for an absence of items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelectorNone = '';\n\n    /**\n     * [OPTIONAL] A string to find in the current URL to detect the item\n     *\n     * @type {string}\n     */\n    detectPattern = '';\n\n    /**\n     * A callback used to generate a menu item title from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemTitleFunction = null;\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     *\n     * @type {string}\n     */\n    itemActionType = 'url';\n\n    /**\n     * A callback used to generate a menu item link URL from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemUrlFunction = null;\n\n    /**\n     * A callback used to generate an object containing data used by the specified action type.\n     *\n     * For 'search-mode' the object should be like { searchMode: '<keyword>' }\n     *\n     * @type {menuActionInfoCallback|null}\n     */\n    itemActionInfoFunction = null;\n\n     /**\n      * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n      *\n      * @type {boolean}\n      */\n     noCache = false;\n}\n", "import ItemDefinition from \"./class-item-definition\";\n\n/**\n * Menu items are the items ready to appear in the palette.\n *\n * These are standard items, not content items. Though this should probably be standardised.\n */\nexport default class TurboAdminMenuItem {\n\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     */\n    actionType = 'url';\n\n    /**\n     * The action of the item is the URL to visit when the item is clicked or the action data\n     * if the action type is not 'url'\n     *\n     * @type {string|Object}\n     */\n    action = '';\n\n    /**\n     * The parent title is the title of the parent item under which the current item\n     * was found in the WordPress menu.\n     *\n     * e.g. in Posts -> Add Post, \"Posts\" is the parent item.\n     *\n     * @type {string}\n     */\n    parentTitle = '';\n\n    /**\n     * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n     *\n     * @type {boolean}\n     */\n    noCache = false;\n\n    /**\n     * Creates a new simple menu item (only works for URLs - for more complex items use fromItemDefinition)\n     *\n     * @param {string} title\n     * @param {string} action\n     * @param {string} parentTitle\n     * @param {boolean} noCache\n     */\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n        this.actionType = 'url';\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    /**\n     * Construct a new menu item from an ItemDefinition\n     *\n     * @param {ItemDefinition} item\n     * @param {HTMLElement} element\n     * @param {string} parentTitle\n     * @return {TurboAdminMenuItem}\n     */\n    static fromItemDefinition(item, element = null, parentTitle = '') {\n        const action = item.itemActionType === 'url' ?\n            item.itemUrlFunction(element) :\n            item.itemActionInfoFunction(element);\n\n        const menuItem = new TurboAdminMenuItem(\n            item.itemTitleFunction(element),\n            action,\n            parentTitle,\n            item?.noCache\n        );\n        menuItem.actionType = item.itemActionType;\n        return menuItem;\n    }\n\n    /**\n     * Compares this item to another item\n     *\n     * @param {TurboAdminMenuItem} item\n     * @returns {boolean}\n     */\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if (this.inExtension()) {\n            this.store = chrome.storage.local;\n        } else {\n            this.store = window.localStorage;\n        }\n    }\n\n    /**\n     * Returns true if we are in the extension.\n     */\n    inExtension() {\n        return window.turboAdminIsExtension();\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if (this.inExtension()) {\n            await this.store.set(dataObject);\n        } else {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if (this.inExtension()) {\n            return await this.store.get(key);\n        } else {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        }\n    }\n}\n", "import Storage from '../class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // turboAdminLog('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n        this.postTypes = [];\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        turboAdminLog('Discovering API root');\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n        // This should be very rare. I should only really see it in development.\n        turboAdminLog('API Route Discovery failed');\n        // Making best guess\n        this.apiBase = globalThis.taWp.home + '/wp-json/wp/v2/';\n        // TODO: This can't display as the palette isn't created yet.\n        // globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Can\\'t find the WP API. Try visiting the dashboard to refresh things.');\n    }\n\n    async discoverPostTypes() {\n        turboAdminLog('Discovering post types');\n        if (! this.active) {\n            turboAdminLog('Not active');\n            this.postTypes = [];\n            return;\n        }\n\n        const postTypes = await this.store.get('ta-post-types');\n\n        // Check local storage cache\n        if (postTypes && postTypes['ta-post-types'] && postTypes['ta-post-types']['expiry'] > Date.now()) {\n            turboAdminLog('Using cached post types: ', postTypes['ta-post-types']['data']);\n            this.postTypes = postTypes['ta-post-types']['data'];\n            return;\n        }\n\n        this.postTypes = await this.getPostTypes();\n        turboAdminLog('Discovered post types: ', this.postTypes);\n\n        // Cache for 10 minutes\n        const expiry = Date.now() + (10 * 60 * 1000);\n        this.store.set({\n            'ta-post-types': {\n                expiry: expiry,\n                data: this.postTypes\n            }\n        });\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    async getPostTypes() {\n        // Check the cache\n        if (undefined !== this.cache['postsTypes']) {\n            return this.cache['postTypes'];\n        }\n\n        // Fetch results\n        const response = await this.get('types');\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['postTypes'] = result;\n\n        return result;\n    }\n\n    async getPosts(searchString, postType = 'any') {\n        // Check the cache\n        const cacheKey =  `posts-${postType}-${searchString}`;\n        if (undefined !== this.cache[cacheKey]) {\n            return this.cache[cacheKey];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: postType\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[cacheKey] = result;\n\n        return result;\n    }\n\n    /**\n     * We can't use the API to get a post of any post type. So we hack this a bit.\n     *\n     * @param {number} postId\n     * @returns {Promise<any>}\n     */\n    async doesPostExist(postId) {\n        // Check the cache\n        if (undefined !== this.cache['post-' + postId]) {\n            return this.cache['post-' + postId];\n        }\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);\n\n        this.cache['post-' + postId] = response;\n\n        return response?.status === 200;\n    }\n\n    async getPlugins(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['plugins-' + searchString]) {\n            return this.cache['plugins-' + searchString];\n        }\n\n        let requestOptions = {};\n\n        if (searchString) {\n            requestOptions.search = searchString;\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"plugins\",\n            requestOptions\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['plugins-' + searchString] = result;\n\n        return result;\n    }\n\n    async getUsers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['users-' + searchString]) {\n            return this.cache['users-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"users\",\n            {\n                search: searchString,\n                per_page: 100,\n                context: 'edit' // view / embed / edit\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['users-' + searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`, init);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WordPress API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog( 'TURBO ADMIN: WordPress API Error. Try visiting the WordPress Dashboard to refresh things.' );\n            }\n        }\n\n        return response;\n    }\n\n}\n", "export default class SubmenuItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title;\n\n    /**\n     * The URL of the item\n     * @type {string}\n     */\n    url;\n\n    /**\n     * A list of attributes to go on the A tag (not the LI tag)\n     *\n     * @type {array}\n     */\n    attributes = [];\n\n    /**\n     * Create a submenu item\n     *\n     * @param {string} title The title of the item\n     * @param {string} url The URL of the item\n     */\n    constructor(title, url) {\n        this.title = title;\n        this.url = url;\n    }\n\n    /**\n     * Add an attribute\n     *\n     * @param {string} name The attribute name\n     * @param {string} value The attribute value\n     */\n    addAttribute(name, value) {\n        this.attributes.push({\n            name: name,\n            value: value\n        });\n    }\n}\n", "import SubmenuItem from \"./class-submenu-item\";\n\nexport default class ContentItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The subtype of the item. e.g. for posts, this will be the post type.\n     * Used to display extra information about the item.\n     *\n     * @type {string}\n     */\n    subtype = '';\n\n    /**\n     * The URL of the item. Leave empty if there is a sub-menu.\n     *\n     * @type {string}\n     */\n    url = '';\n\n    /**\n     * The sub-menu items, if any.\n     *\n     * This should be an empty array if the item itself has a URL\n     *\n     * @type {SubmenuItem[]}\n     */\n    submenuItems = [];\n}\n", "import ContentItem from \"./class-content-item\";\n\nexport default class SearchMode {\n    /**\n     * The keyword string used to initiate the search\n     *\n     * @type {string}\n     */\n    keyword = '';\n\n    /**\n     * The dispay name used for the search\n     *\n     * @type {string}\n     */\n    displayName = '';\n\n    /**\n     * jsDoc defintion for a `searchCallback`\n     *\n     * @callback SearchCallback\n     * @param {string} [searchString]\n     * @returns {Promise<ContentItem[]>}\n     */\n\n    /**\n     * Callback to get search items\n     *\n     * @type {SearchCallback}\n     */\n    searchCallback;\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @type {SearchCallback|null}\n     */\n    defaultItemsCallback = null;\n\n    /**\n     * Set this to false to hide the search mode from the palette - it still\n     * works with a keyword, but won't show in the palette's list of items\n     *\n     * @type {boolean}\n     */\n    showInPaletteSearch = true;\n\n    /**\n     * Constructs a new search mode\n     *\n     * @param {string} keyword\n     * @param {string} displayName\n     * @param {SearchCallback} searchCallback\n     * @param {SearchCallback} defaultItemsCallback\n     * @param {boolean} showInPaletteSearch\n     */\n    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null, showInPaletteSearch = true) {\n        this.keyword = keyword;\n        this.displayName = displayName;\n        this.searchCallback = searchCallback;\n        this.defaultItemsCallback = defaultItemsCallback;\n        this.showInPaletteSearch = showInPaletteSearch;\n    }\n}\n", "import SearchMode from \"./class-search-mode\";\nimport ItemDefinition from \"./class-item-definition\";\n\n/**\n * This is an abstract class that should be extended by plugins\n * @module TurboAdminPlugin\n */\nexport default class TurboAdminPlugin {\n    /** @type {string} */\n    name = '';\n\n    /** @type {SearchMode[]} */\n    searchModes = [];\n\n    /** @type {boolean} */\n    activated = false;\n\n    constructor(pluginName) {\n        this.name = pluginName;\n        this.registerPlugin();\n    }\n\n    /**\n     * Register the plugin with Turbo Admin\n     */\n    registerPlugin() {\n        turboAdminLog('Inside plugin - requested registration of ' + this.name);\n        globalThis.turboAdmin.registerPlugin(this);\n    }\n\n    /**\n     * Returns true if the plugin should activate\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return false;\n    }\n\n    /**\n     * Activates the plugin\n     * @return {void}\n     */\n    activate() {\n        this.activated = true;\n        this.registerSearchModes();\n    }\n\n    /**\n     * Register the search keywords with Turbo Admin - each will be registered\n     * with the whole plugin object.\n     */\n    registerSearchModes() {\n        this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);\n    }\n\n    /**\n     * Get the item definitions for search modes.\n     *\n     * Note that , at time of writing, this runs AFTER API init but before the plugin is activated.\n     * So APIs are available (and may be used in shouldActivate()) but the plugin is not yet activated.\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getSearchModeItemDefinitions() {\n        if (!this.shouldActivate()) {\n            return [];\n        }\n\n        const searchModeItems = this.searchModes.map(searchMode => {\n            // Return null if we don't want to show this search mode in the palette.\n            if (searchMode.showInPaletteSearch === false) {\n                return null;\n            }\n            const item = new ItemDefinition();\n            item.detectType = 'none';\n            item.itemTitleFunction = () => `<span style=\"font-style:italic;\">Search</span>: ${searchMode.displayName}`;\n            item.itemActionType = 'search-mode';\n            item.itemActionInfoFunction = () => { return { searchMode: searchMode.keyword } };\n            return item;\n        })\n        // Filter out the nulls.\n        return searchModeItems.filter( item => item !== null);\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getAdditionalItemDefinitions() {\n        if (!this.activated) {\n            return [];\n        }\n\n        return [];\n    }\n\n    /**\n     * Save plugin setting to persistent storage\n     */\n    saveSetting(key, value) {\n\n    }\n\n}\n", "/**\n * It's impossible to change the setting to off, because the\n * extension's content script runs in a sandbox and can't access\n * the wp object. But we can just toggle the class every time.\n */\nexport default class TurboAdminWpBlockEditorFullscreenKill {\n\n    constructor() {\n\n        // Don't run on the site editor screen\n        if (document.body.classList.contains( 'site-editor-php' )) {\n            return;\n        }\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed fullscreen\n                // if (document.body.classList.contains('turbo-admin-killed-fullscreen')) {\n                //     return;\n                // }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (mu.target.classList.contains('is-fullscreen-mode')) {\n                    this.killFullScreenEditor();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killFullScreenEditor();\n    }\n\n    killFullScreenEditor() {\n        if (! document.body.classList.contains('is-fullscreen-mode')) {\n            return;\n        }\n\n        document.body.classList.remove('is-fullscreen-mode');\n        document.body.classList.add('turbo-admin-killed-fullscreen');\n\n        const newStyles = document.createElement('style');\n        newStyles.innerHTML = \"body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }\";\n        document.body.appendChild(newStyles);\n    }\n}\n", "/**\n * Kills/auto-removes:\n *  - the Welcome Guide on the post edit screen\n *  - the pattern selector modal on the post edit screen\n *  - the Welcome Panel on the dashboard on new sites\n */\nexport default class TurboAdminWpBlockEditorWelcomeGuideKill {\n\n    constructor() {\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed the modal\n                if (document.body.classList.contains('ta-killed-post-welcome-guide')) {\n                    return;\n                }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (!mu.target.classList.contains('modal-open')) {\n                    return;\n                }\n\n                console.log('Modal detected');\n                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n                const newPagePatterns = document.querySelector('.edit-post-start-page-options__modal');\n                const newPagePatterns2 = document.querySelector('.editor-start-page-options__modal-content');\n\n                if (welcomeGuide || newPagePatterns || newPagePatterns2) {\n                    this.killWelcomeGuide();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killWelcomeGuide();\n\n        // Attempt a kill of the dashboard welcome panel\n        this.killDashboardWelcomePanel();\n    }\n\n    killWelcomeGuide() {\n        // Check for welcome guide\n        let welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n        // Check for new page patterns modal (old: pre-6.6?)\n        if (!welcomeGuide) {\n            welcomeGuide = document.querySelector('.edit-post-start-page-options__modal');\n        }\n        // Check for new page patterns model (new: 6.6+)\n        if (!welcomeGuide) {\n            welcomeGuide = document.querySelector('.editor-start-page-options__modal-content');\n        }\n\n        if (welcomeGuide) {\n            const closeButton = document.querySelector('.components-modal__header button');\n            if (closeButton) {\n                closeButton.click();\n                /*\n                 * Also add a class to body so we don't do it again - subsequent modals\n                 * will need to be shown as they will have been user-initiated.\n                 */\n                document.body.classList.add('ta-killed-post-welcome-guide');\n            }\n        }\n    }\n\n    killDashboardWelcomePanel() {\n        const welcomePanel = document.getElementById('welcome-panel');\n        if (!welcomePanel) {\n            return;\n        }\n        const welcomePanelClose = welcomePanel.querySelector('.welcome-panel-close');\n        if (welcomePanelClose) {\n            welcomePanelClose.click();\n        }\n    }\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            '.notice-success',\n            '.notice-error',\n            '.notice-failure',\n            '.updated',\n        ]\n\n        this.noticesPanelInner = null;\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nturboAdminLog('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nturboAdminLog('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice);\n            this.maybeAddMoveButtonToNotice.call(this, notice);\n        });\n\n        const noticesToHide = Array.from(notices).filter( this.noticeShouldBeHidden.bind(this) );\n\n        turboAdminLog('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        this.noticesPanelInner = document.createElement('div');\n        this.noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(this.hideNotice.bind(this));\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(this.noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n\n        // Add a mutation observer to check for notices added by JavaScript\n        // this.addObserver();\n    }\n\n    addObserver() {\n        const observer = new MutationObserver( this.handleMutations.bind(this) );\n        observer.observe(document.getElementById('wpbody-content'), {\n            childList: true,\n            subtree: true\n        });\n    }\n\n    handleMutations(mutations, observer) {\n        mutations.forEach( mutation => {\n            if (mutation.type === 'childList') {\n                mutation.addedNodes.forEach( node => {\n                    if (node.nodeType === Node.ELEMENT_NODE) {\n                        console.log('MUTATING!!!' + node.id);\n                        // this.maybeAddIdToNotice(node);\n                        // this.maybeAddMoveButtonToNotice(node);\n                        // this.maybeHideNotice(node);\n                    }\n                });\n            }\n        });\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return noticeElem.matches(this.allowedClasses.join(', '));\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    noticeShouldBeHidden(notice) {\n        if (this.rememberedNoticeIds.includes(notice.id)) {\n            return true;\n        }\n\n        if (this.keepNotice(notice)) {\n            return false;\n        }\n\n        // Invisible\n        if (\n            notice.offsetHeight === 0 ||\n            notice.offsetWidth === 0\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(chrome)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(chrome)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(noticeElem) {\n        if (noticeElem.id && noticeElem.id !== '' && noticeElem.id !=='message') {\n            return;\n        }\n\n        const classes = noticeElem.classList;\n        noticeElem.id = Array.from(noticeElem.classList).join('-');\n    }\n\n    /**\n     * Add buttons to notices that we want to be able to move to the panel\n     */\n    maybeAddMoveButtonToNotice(noticeElem) {\n        if (this.keepNotice(noticeElem)) {\n            const rememberButton = document.createElement('button');\n            rememberButton.classList.add('ta-remember-notice-button');\n            rememberButton.innerText = 'Move to panel';\n\n            const forgetButton = document.createElement('button');\n            forgetButton.classList.add('ta-forget-notice-button');\n            forgetButton.innerText = 'Move to dashboard';\n\n            noticeElem.classList.add('ta-added-pos-relative');\n\n            noticeElem.appendChild(rememberButton);\n            noticeElem.appendChild(forgetButton);\n\n            rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n            forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n        }\n    }\n\n    maybeHideNotice(noticeElem) {\n        if (this.noticeShouldBeHidden(noticeElem) && !noticeElem.classList.contains('ta-notice-hidden')) {\n            this.hideNotice(noticeElem);\n        }\n    }\n\n    hideNotice(noticeElem) {\n        noticeElem.classList.add('ta-notice-hidden');\n        // WPCore's common.js will re-add the notice below the dashboard header unless it has a .inline class.\n        // It does: $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );\n        noticeElem.classList.add('inline');\n        // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n        this.noticesPanelInner.append(noticeElem);\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {boolean}\n         */\n        this.actionsOpen = false;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        /**\n         * @type {boolean}\n         */\n        this.isWooCommerce = false;\n\n        /**\n         * @type {boolean}\n         */\n        this.isPluginInstall = false;\n\n        if (!this.listTable) {\n            return;\n        }\n\n        // We make some VERY special exceptions for WooCommerce\n        if (document.body.classList.contains('woocommerce-admin-page') &&\n            document.body.classList.contains('post-type-shop_order')) {\n            this.isWooCommerce = true;\n        }\n\n        // And for the add plugins screen\n        if (document.body.classList.contains('plugin-install-php')) {\n            this.isPluginInstall = true;\n        }\n\n        /**\n         * @type {Boolean}\n         */\n        this.isMac = globalThis.turboAdmin.turboAdminPalette.isMac();\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        // Plugin install is different.\n        if (this.isPluginInstall) {\n            this.tableRows = this.listTable.querySelectorAll('#the-list .plugin-card');\n        }\n\n        // Grr... comments list is different! WHY?!\n        if (document.body.classList.contains('edit-comments-php')) {\n            this.tableRows = this.listTable.querySelectorAll('tbody#the-comment-list > tr');\n        }\n\n        document.addEventListener('keydown', e => this.handleKey(e));\n\n        // Chrome handles escape key on search input elements, so we need to\n        // intercept it here.\n        const searchInput = document.querySelector(\n            '.search-box input[type=\"search\"], .search-form input[type=\"search\"]'\n        );\n\n        if (searchInput) {\n            searchInput.addEventListener('keyup', e => this.handleSearchInputKey(e));\n        }\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKey(ev) {\n        const isActiveElementBody = document.activeElement.tagName === 'BODY';\n        const isActiveElementInListTable = this.listTable && this.listTable.contains(document.activeElement);\n        const isSearchFocussed = this.getSearchInputElement() === document.activeElement;\n        if ((!isActiveElementBody && !isActiveElementInListTable) || isSearchFocussed) {\n            return;\n        }\n        if (globalThis.turboAdmin.turboAdminPalette.isPaletteOpen()) {\n            return;\n        }\n        if (ev.key === 'j') {\n            if (this.actionsOpen) {\n                this.actionMoveDown();\n            } else {\n                this.tableMoveDown();\n            }\n        } else if (ev.key === 'k') {\n            if (this.actionsOpen) {\n                this.actionMoveUp();\n            } else {\n                this.tableMoveUp();\n            }\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            if (this.actionsOpen) {\n                this.openCurrentRowAction(ev);\n                ev.preventDefault();\n            } else {\n                this.openTableRowActions(ev);\n            }\n        } else if (ev.key === '/') {\n            this.focusSearch(ev);\n        } else if (ev.key === 'f' && ev.ctrlKey) {\n            this.nextPage(ev);\n        } else if (ev.key === 'b' && ev.ctrlKey) {\n            this.prevPage(ev);\n        } else if (ev.key === 'ArrowDown') {\n            if (this.actionsOpen) {\n                this.actionMoveDown(ev);\n            }\n        } else if (ev.key === 'ArrowUp') {\n            if (this.actionsOpen) {\n                this.actionMoveUp(ev);\n            }\n        } else if (ev.key.toLowerCase() === 'escape' /* && !document.body.classList.contains('modal-open')*/) {\n            if (this.actionsOpen) {\n                this.closeTableRowActions(ev);\n            }\n            // If the search box is focussed... Note that Chrome does its own thing with escape here.\n            if (document.getElementById('post-search-input') === document.activeElement) {\n                document.getElementById('post-search-input').blur();\n            }\n        }\n\n    }\n\n    handleSearchInputKey(ev) {\n        if (ev.key.toLowerCase() === 'escape') {\n            ev.target.blur();\n        }\n    }\n\n    getSearchInputElement() {\n        return document.querySelector('.search-box input[type=\"search\"], .search-form input[type=\"search\"]');\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else if (this.currentRowIndex < this.tableRows.length - 1) {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n        }\n\n        this.updateTable();\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (!this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n\n        this.scrollIntoViewIfNeeded(this.currentRow);\n    }\n\n    /**\n     * Scrolls the element into view if it is not already.\n     */\n    scrollIntoViewIfNeeded(element) {\n        const elementRect = element.getBoundingClientRect();\n        const elementTop = elementRect.top;\n        const elementBottom = elementRect.bottom;\n        const viewportTop = 0;\n        const viewportBottom = window.innerHeight;\n        if (elementBottom > viewportBottom) {\n            element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });\n        } else if (elementTop < viewportTop) {\n            element.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n        }\n    }\n\n    /**\n     * Gets the list table row actions container for the current row\n     */\n    getRowActionsContainer() {\n        let container = this.currentRow.querySelector('.row-actions');\n\n        if (this.isPluginInstall) {\n            container = this.currentRow.querySelector('.plugin-action-buttons');\n        }\n\n        return container;\n    }\n\n    /**\n     * Gets list table row actions for the current row\n     */\n    getRowActions() {\n        let rowActions = this.currentRow.querySelectorAll('.row-actions span a, .row-actions span button');\n\n        if (this.isPluginInstall) {\n            rowActions = this.currentRow.querySelectorAll('.plugin-action-buttons a');\n        }\n\n        return rowActions;\n    }\n\n    openTableRowActions(ev) {\n        turboAdminLog(this);\n\n        // WooCommerce doesn't have row actions, so we just find the link and visit it\n        if (this.isWooCommerce) {\n            this.currentRow.querySelector('a.order-view').click();\n            return;\n        }\n\n        this.actionsOpen = true;\n\n        let rowActions = this.getRowActionsContainer();\n\n        if (rowActions) {\n            rowActions.classList.add('visible');\n        }\n\n        const titleElem = this.currentRow.querySelector('strong');\n        const titleLink = titleElem.querySelector('a');\n\n        if (titleLink) {\n            titleLink.classList.add('ta-active-table-row-link');\n            return;\n        }\n\n        let rowActionLinks = this.getRowActions();\n\n        if (rowActionLinks) {\n            rowActionLinks[0].classList.add('ta-active-table-row-link');\n        }\n    }\n\n    closeTableRowActions(ev) {\n        turboAdminLog(this);\n        const rowActions = this.currentRow.querySelector('.row-actions');\n\n        // Don't do this on plugins screen!\n        if (!document.body.classList.contains('plugins-php')) {\n            if (rowActions) {\n                rowActions.classList.remove('visible');\n            }\n        }\n\n        const activeLink = document.querySelector('.ta-active-table-row-link');\n        if (activeLink) {\n            activeLink.classList.remove('ta-active-table-row-link');\n        }\n\n        this.actionsOpen = false;\n    }\n\n    actionMoveDown(ev) {\n        /** @type {HTMLElement} */\n        const currentLink = document.querySelector('.ta-active-table-row-link');\n\n        // Handle the case where the title link is selected\n        if (currentLink.closest('strong')) {\n            const rowActions = this.getRowActions();\n            if (rowActions) {\n                rowActions[0].classList.add('ta-active-table-row-link');\n                currentLink.classList.remove('ta-active-table-row-link');\n            }\n            return;\n        }\n\n        /** @type {HTMLElement} */\n        const nextLink = currentLink.parentElement?.nextElementSibling?.querySelector('a, button');\n        if (nextLink) {\n            nextLink.classList.add('ta-active-table-row-link');\n            currentLink.classList.remove('ta-active-table-row-link');\n        }\n    }\n\n    actionMoveUp(ev) {\n        /** @type {HTMLElement} */\n        const currentLink = document.querySelector('.ta-active-table-row-link');\n\n        // Handle the case where the title link is selected\n        if (currentLink.closest('strong')) {\n            return;\n        }\n\n        /** @type {HTMLElement} */\n        const prevLink = currentLink.parentElement?.previousElementSibling?.querySelector('a, button');\n\n        // Handle the case where the first item is selected and we need to go back to the title\n        if (!prevLink) {\n            const titleLink = this.currentRow.querySelector('strong a');\n            if (titleLink) {\n                titleLink.classList.add('ta-active-table-row-link');\n                currentLink.classList.remove('ta-active-table-row-link');\n            }\n            return;\n        }\n\n        prevLink.classList.add('ta-active-table-row-link');\n        currentLink.classList.remove('ta-active-table-row-link');\n    }\n\n    openCurrentRowAction(ev) {\n        // TODO: Open the current row action\n        /** @type {HTMLElement} */\n        const currentLink = document.querySelector('.ta-active-table-row-link');\n        // Don't do this for plugin install screen\n        if (currentLink) {\n            currentLink.click();\n        }\n    }\n\n    focusSearch(ev) {\n        /** @type {HTMLInputElement} */\n        const searchInput = this.getSearchInputElement();\n\n        if (searchInput) {\n            searchInput.focus();\n            this.scrollIntoViewIfNeeded(searchInput);\n            ev.preventDefault();\n        }\n    }\n\n    nextPage(ev) {\n        /** @type {HTMLAnchorElement} */\n        const nextPageLink = document.querySelector('.tablenav-pages .next-page');\n        if (nextPageLink) {\n            nextPageLink.click();\n            ev.preventDefault();\n        }\n    }\n\n    prevPage(ev) {\n        /** @type {HTMLAnchorElement} */\n        const prevPageLink = document.querySelector('.tablenav-pages .prev-page');\n        if (prevPageLink) {\n            prevPageLink.click();\n            ev.preventDefault();\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\n\nexport default class TurboAdminBarkeeper extends TurboAdminPlugin {\n    constructor() {\n        super('Barkeeper');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        if (true !== globalThis.turboAdmin.options['barkeeper']) {\n            return false;\n        }\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return false;\n        }\n        // Bail if we don't have the left-hand admin bar (some users only have right-hand side)\n        if (! document.getElementById('wp-admin-bar-root-default')) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.selectorsToHide = [\n            '#wp-admin-bar-root-default > li',\n            '.monsterinsights-adminbar-menu-item',\n        ];\n\n        this.barkeeperState = this.getBarkeeperState();\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        if (! this.root) {\n            return;\n        }\n        this.itemsToHide = document.querySelectorAll( this.selectorsToHide.join(', ') );\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            this.setBarkeeperState(this.barkeeperState);\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n\n        this.setupObserver();\n    }\n\n    /**\n     * Some awkward plugins add themselves into the bar using JS\n     */\n    setupObserver() {\n        this.observer = new MutationObserver( mutations => {\n            mutations.forEach( mutation => {\n                if (mutation.type === 'childList') {\n                    mutation.addedNodes.forEach( node => {\n                        if (node.classList && node.classList.contains('ta-barkeeper-collapsable')) {\n                            return;\n                        }\n                        if (node.id && this.exclusionIds.includes(node.id)) {\n                            return;\n                        }\n                        // Check is the node matches any of the selectors\n                        if (node.matches(this.selectorsToHide.join(', '))) {\n                            node.classList.add('ta-barkeeper-collapsable');\n                            return;\n                        }\n                    });\n                }\n            });\n        });\n\n        this.observer.observe(this.root, {\n            childList: true,\n            subtree: true,\n        });\n    }\n\n    getBarkeeperState() {\n        if (window.turboAdminIsExtension()) {\n            return globalThis.turboAdmin.options['barkeeper-state'];\n        } else {\n            return window.localStorage.getItem('turbo-admin-barkeeper-state');\n        }\n    }\n\n    setBarkeeperState(state) {\n        if (window.turboAdminIsExtension()) {\n            chrome.runtime.sendMessage({\n                'action': 'barkeeperSetState',\n                'barkeeperState': this.barkeeperState,\n            });\n        } else {\n            window.localStorage.setItem('turbo-admin-barkeeper-state', state);\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminContentSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Content');\n\n        const ignoredPostTypes = [\n            'nav_menu_item',\n            'wp_block',\n            'wp_template',\n            'wp_template_part',\n            'wp_navigation',\n        ];\n\n        const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);\n\n        // Discard ignored post types\n        const filteredPostTypeKeys = postTypeKeys.filter(key => ! ignoredPostTypes.includes(key));\n\n        // Register a search mode for each post type\n        for (let i = 0; i < filteredPostTypeKeys.length; i++) {\n            const thisPostTypeKey = filteredPostTypeKeys[i];\n            const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];\n            // turboAdminLog('Adding search mode for post type', thisPostType);\n            this.searchModes.push( this.makePostTypeSearchMode(thisPostType) );\n        }\n\n        // Register ID search mode\n        this.searchModes.push( new SearchMode('id', 'Post ID', this.postById.bind(this)) );\n\n        // Register search all post types mode\n        this.searchModes.push( new SearchMode('search', 'All post types', this.contentSearch.bind(this)) );\n        // Don't show this one in the palette\n        this.searchModes.push( new SearchMode('find', 'All post types', this.contentSearch.bind(this), null, false) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * This is a generator for a post-type specific SearchMode object\n     *\n     * @param {Object} postType\n     */\n    makePostTypeSearchMode(postType) {\n        // TODO: interpret the post type name\n        return new SearchMode(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));\n    }\n\n    /**\n     * @param {string} searchString\n     * @param {string} postType This is passed to the API as a subtype. 'any' by default.\n     * @returns {Promise<ContentItem[]>}\n     */\n    async contentSearch(searchString, postType = 'any') {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPosts(searchString, postType);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = result.title;\n                            item.subtype = result.subtype;\n                            item.url = result.url;\n\n                            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item))\n\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} postId\n     * @returns {Promise<ContentItem[]>}\n     */\n    async postById(postId) {\n        if (! postId.trim().match(/^\\d+$/)) {\n            return [];\n        }\n        const postExists = await globalThis.contentApi.doesPostExist(postId);\n\n        const resultAsContentItem = new ContentItem;\n\n        if (! postExists) {\n            resultAsContentItem.title = 'Post does not exist or is not visible';\n            return [ resultAsContentItem ];\n        }\n\n        resultAsContentItem.title = `Post ID: ${postId}`;\n        resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;\n\n        resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));\n\n        return [ resultAsContentItem ];\n    }\n\n    /**\n     * Makes an array of submenu items from a content item\n     *\n     * @param {number} postId\n     * @param {ContentItem} contentItem\n     * @returns {SubmenuItem[]}\n      */\n    makeSubmenuItems(postId, contentItem) {\n        const itemsToReturn = [];\n        itemsToReturn.push(\n            new SubmenuItem(\n                'View',\n                contentItem.url\n            )\n        );\n\n        // TODO: Make a better way to detect if we are logged in.\n        if (globalThis.turboAdmin.turboAdminPalette.profileLink) {\n            // Need to get edit URL. This seems like the best way for now.\n            const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;\n            itemsToReturn.push(\n                new SubmenuItem(\n                    'Edit',\n                    editLink\n                )\n            )\n\n            // Add oxygen link if needed.\n            if (globalThis.turboAdmin.hasActivatedPlugin('OxygenBuilder')) {\n                const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;\n                itemsToReturn.push(\n                    new SubmenuItem(\n                        'Edit with Oxygen',\n                        oxygenLink\n                    )\n                );\n            }\n        }\n\n        const copyLinkItem = new SubmenuItem( 'Copy link', contentItem.url);\n        copyLinkItem.addAttribute('data-action', 'clipboard')\n        itemsToReturn.push(copyLinkItem);\n\n        return itemsToReturn;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminPluginSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Plugins');\n\n        this.searchModes.push( new SearchMode('plugin', 'Plugins', this.pluginSearch, this.defaultPluginItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultPluginItems() {\n        return await this.pluginSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async pluginSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPlugins(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            // siteUrl is at globalThis.turboAdmin.wp.siteUrl\n                            const item = new ContentItem;\n                            item.title = result.name;\n                            item.subtype = 'Plugin';\n                            // TODO: Maybe set this to be a search on the plugin screen?\n                            // Plugin \"slug\" is in result.name\n\n                            const itemViewUrlParams = new URLSearchParams();\n                            itemViewUrlParams.set('plugin_status', 'all');\n                            itemViewUrlParams.set('s', result.name);\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'View',\n                                    globalThis.taWp.siteUrl + '/plugins.php?' + itemViewUrlParams.toString()\n                                )\n                            );\n                            // Activate: /wp-admin/plugins.php?action=activate&plugin=order-simulator-woocommerce%2Fwoocommerce-order-simulator.php&plugin_status=all&paged=1&s&_wpnonce=3714a01759\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\n\nexport default class TurboAdminUserSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Users');\n\n        this.searchModes.push( new SearchMode('user', 'Users', this.userSearch, this.defaultUserItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultUserItems() {\n        return await this.userSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async userSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getUsers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            if (result.first_name && result.last_name) {\n                                item.title = `${result.first_name} ${result.last_name} - `;\n                            }\n                            item.title += result.email;\n                            item.subtype = result.roles[0];\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminWoocommerce extends TurboAdminPlugin {\n    constructor() {\n        super('WooCommerce');\n\n        this.searchModes.push( new SearchMode('order', 'Orders', this.orderSearch) );\n        this.searchModes.push( new SearchMode('customer', 'Customers', this.customerSearch) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of WooCommerce in Dashboard\n        /** @type {HTMLElement|string|Number} */\n        let woocommerceMenuElement = document.getElementById('toplevel_page_ct_dashboard_page');\n\n        // Also check for a menu bar item\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = document.getElementById('wp-admin-bar-new-shop_order');\n        }\n\n        // Check to see if WooCommerce flag is cached\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasWooCommerce = Boolean(woocommerceMenuElement);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-woocommerce', hasWooCommerce ? '1' : '0' );\n\n        return globalThis.contentApi.active && hasWooCommerce;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async orderSearch(searchString) {\n        let results;\n\n        if (searchString.trim().match(/^\\d+$/)) {\n            results = await globalThis.woocommerceApi.getOrder(searchString);\n        } else {\n            results = await globalThis.woocommerceApi.getOrders(searchString);\n        }\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `#${result.number} ${result.currency_symbol}${result.total}`;\n                            item.subtype = result.billing.email;\n                            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async customerSearch(searchString) {\n        const results = await globalThis.woocommerceApi.getCustomers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `${result.billing.first_name} ${result.billing.last_name}`;\n                            item.subtype = result.email;\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Orders',\n                                    globalThis.taWp.siteUrl + `/edit.php?post_status=all&post_type=shop_order&_customer_user=${result.id}`\n                                )\n                            )\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Profile',\n                                    globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`\n                                )\n                            )\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminGravityForms extends TurboAdminPlugin {\n    constructor() {\n        super('GravityForms');\n\n        this.searchModes.push( new SearchMode('form', 'Gravity Forms', this.formSearch, this.defaultFormsList.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return globalThis.contentApi.active &&\n               document.getElementById('wp-admin-bar-gravityforms-new-form') !== null\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultFormsList() {\n        return await this.formSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async formSearch(searchString) {\n        const resultsObject = await globalThis.gravityFormsApi.getForms(searchString);\n        // GF Results are an object rather than an array so we need to convert\n\n        // TODO: Catch the error response (do the TODO in the API class first)\n\n        const resultsArray = [];\n        const resultKeys = Object.keys(resultsObject);\n        for(let k = 0; k < resultKeys.length; k++) {\n            const result = resultsObject[resultKeys[k]];\n            const item = new ContentItem;\n            item.title = `#${result.id} ${result.title}`;\n            item.subtype = `${result.entries} entries`;\n            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Edit Form',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Entries',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_entries&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Form Settings',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=settings&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Confirmatons',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=confirmation&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Notifications',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=notification&id=${result.id}`\n                )\n            )\n\n            turboAdminLog(item);\n\n            resultsArray.push(item);\n        }\n        return resultsArray;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminMUSites extends TurboAdminPlugin {\n    constructor() {\n        super('WP Multisite Sites');\n\n        this.searchModes.push( new SearchMode('site', 'Sites', this.siteSearch.bind(this), this.defaultSiteItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return Boolean(document.querySelector('#wp-admin-bar-my-sites'));\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultSiteItems() {\n        return await this.siteSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async siteSearch(searchString) {\n        // {\n        //     'detectType': 'dom',\n        //     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n        //     'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n        //     'itemUrlFunction': (element) => element.href\n        // },\n\n        const sites = document.querySelectorAll('#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li');\n\n        if (sites.length === 0) {\n            return [];\n        }\n\n        const sitesArray = Array.from(sites);\n        const sitesLinks = sitesArray.map(site => site.querySelector('a'));\n        const filteredSites = sitesLinks.filter(site => site.innerText.toLowerCase().includes(searchString.toLowerCase()));\n\n        return filteredSites.map(site => {\n            const item = new ContentItem;\n            item.title = site.innerText;\n            item.subtype = 'Site';\n            item.url = site.href;\n\n            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));\n\n            return item;\n        });\n    }\n\n    makeSubmenuItems(siteElement) {\n        const submenuItems = [];\n\n        const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);\n        if (! submenu) {\n            return [];\n        }\n\n        const submenuLinks = submenu.querySelectorAll('a');\n        if (submenuLinks.length === 0) {\n            return [];\n        }\n\n        const submenuLinksArray = Array.from(submenuLinks);\n        submenuLinksArray.forEach(link => {\n            const submenuItem = new SubmenuItem(link.innerText, link.href);\n            submenuItems.push(submenuItem);\n        });\n\n        return submenuItems;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\nimport ItemDefinition from '../types/class-item-definition.js';\n\nexport default class TurboAdminOxygenBuilder extends TurboAdminPlugin {\n    constructor() {\n        super('OxygenBuilder');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasOxygenBuilder = Boolean(oxygenLinkElem);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', hasOxygenBuilder ? '1' : '0' );\n\n        return hasOxygenBuilder;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n     async getAdditionalItemDefinitions() {\n        const editDefinition = new ItemDefinition();\n        editDefinition.detectType = 'dom';\n        editDefinition.detectSelector = '#ct-edit-template-builder';\n        editDefinition.itemTitleFunction = () => 'Edit with Oxygen';\n        editDefinition.itemUrlFunction = (element) => element.href;\n        editDefinition.noCache = true;\n\n        // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n        // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n        // doesn't refresh the menu items.\n        const backToWpDefinition = new ItemDefinition();\n        backToWpDefinition.detectType = 'dom';\n        backToWpDefinition.detectSelector = '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)';\n        backToWpDefinition.itemTitleFunction = (element) => 'Back to WP: ' + element.textContent;\n        backToWpDefinition.itemUrlFunction = (element) => {\n            if (element.href) {\n                return element.href;\n            } else {\n                let url = new URL(window.location.href);\n                return url.origin + url.pathname;\n            }\n        };\n        backToWpDefinition.noCache = true;\n\n        return [\n            editDefinition,\n            backToWpDefinition,\n        ];\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\n\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';\nimport SearchMode from './types/class-search-mode.js';\nimport TurboAdminPlugin from './types/class-turbo-admin-plugin.js';\nimport Acf from './plugins/class-acf.js';\nimport TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\nimport TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';\nimport TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';\nimport TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';\nimport TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';\nimport TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';\nimport TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';\nimport TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';\nimport TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';\n\nexport default class TurboAdmin {\n\n    /**\n     * @param {*} options\n     * @returns {TurboAdmin}\n     */\n    constructor(options) {\n        // Sometimes we get a second copy of TA running, like if the plugin is running too.\n        // Is this case we want to skip the initialisation.\n        this.doInit = true;\n\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            this.doInit = false;\n            return globalThis.turboAdmin;\n        }\n\n        this.options = options;\n        this.plugins = {};\n\n        // TODO: Something? What should this type be?\n        this.searchModes = {};\n\n        // On the front end we set this if there is no saved menu.\n        this.menuNeedsRefresh = false;\n    }\n\n    /**\n     * Perform initialization - this is all the things that do not need APIs to\n     * get set up.\n     */\n    async init() {\n        if (! this.doInit) {\n            return;\n        }\n\n        // Register all the plugins\n        new TurboAdminBarkeeper();\n        new TurboAdminContentSearch();\n        new TurboAdminPluginSearch();\n        new TurboAdminUserSearch();\n        new TurboAdminMUSites();\n        new TurboAdminOxygenBuilder();\n\n        if (window.turboAdminIsExtension()) {\n            new TurboAdminWoocommerce();\n            new TurboAdminGravityForms();\n        }\n\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Check for .logged-in class on body - if logged in, we can use the saved menu,\n                // if it exists.\n                if (document.body.classList.contains('logged-in')) {\n                    // Get from localStorage\n                    const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                    // This attempts to see if we have cached items from the back-en\n                    if (null === savedMenu) {\n                        this.menuNeedsRefresh = true;\n                    } else {\n                        this.menu = JSON.parse(savedMenu);\n                        // Check if there is no \"Media\" item  - this should ONLY be in the back-end\n                        if (! this.menu.some(item => ( ( typeof(item.action) === 'string' ) && ( item.action.endsWith('upload.php') ) ))) {\n                            this.menuNeedsRefresh = true;\n                        }\n                        // Merge (?) the items?\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        await this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n    }\n\n    /**\n     * These are initialization steps that DO needs APIs to be set up.\n     */\n    activatePlugins() {\n        // Initialize all plugins\n        Object.keys(this.plugins).forEach( plugin => {\n            if (this.plugins[plugin].shouldActivate()) {\n                this.plugins[plugin].activate();\n            }\n        })\n\n        if (true === this.options['block-editor-fullscreen-disable']) {\n            // Initialise fullscreen kill\n            this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        }\n\n        if (true === this.options['block-editor-welcome-screen-kill']) {\n            this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    /**\n     * True if the plugin has been activated\n     *\n     * @param {string} name Name of the plugin to check for\n     * @returns {boolean}\n     */\n    hasActivatedPlugin(name) {\n        return Object.keys(this.plugins).includes(name) &&\n            this.plugins[name].activated;\n    }\n\n    /**\n     * Gather the WordPress dashboard admin (sidebar) menu items\n     *\n     * @returns { TurboAdminMenuItem[] }\n     */\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    /**\n     * Adds additional menu items passed in by configuration to the\n     * menu items list.\n     */\n    async addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.\n        let extraItems = this.options.extraItems ?? [];\n\n        // Get any extra items defined by plugins\n        const pluginKeys = Object.keys(this.plugins);\n\n        for (let i=0; i < pluginKeys.length; i++) {\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getSearchModeItemDefinitions());\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());\n        }\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                // TODO: Convert to ItemDefinition objects\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.ensureTrailingSlash(globalThis.taWp.siteUrl);\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'none') {\n                detected = true;\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = TurboAdminMenuItem.fromItemDefinition(item, element, '');\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    /**\n     * Builds the palette HTML and adds it to the DOM.\n     */\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Palette notice\n        const paletteNotice = document.createElement('div');\n        paletteNotice.id = 'ta-command-palette-notice';\n        // Tab notice\n        const tabNotice = document.createElement('div');\n        tabNotice.id = 'ta-command-palette-tab-notice';\n        // Tab notice text\n        const tabNoticeText = document.createElement('span');\n        tabNoticeText.id = 'ta-command-palette-tab-notice-text';\n        // Tab notice \"button\"\n        const tabNoticeButton = document.createElement('span');\n        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';\n        tabNoticeButton.innerText = 'Tab';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // Search mode tag\n        const searchModeTag = document.createElement('div');\n        searchModeTag.id = 'ta-command-palette-search-mode-tag';\n        // List container (needed to contain the main list and the submenu list)\n        const listContainer = document.createElement('div');\n        listContainer.id = \"ta-command-palette-items-container\";\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Sub-menu list\n        const submenuContainer = document.createElement('div');\n        submenuContainer.id = \"ta-command-palette-submenu-container\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(searchModeTag);\n        palette.appendChild(paletteNotice);\n        tabNotice.appendChild(tabNoticeText);\n        tabNotice.appendChild(tabNoticeButton);\n        palette.appendChild(tabNotice);\n        palette.appendChild(input);\n        listContainer.appendChild(list);\n        listContainer.appendChild(submenuContainer);\n        palette.appendChild(listContainer);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, listContainer );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    /**\n     * Register a plugin with Turbo Admin\n     *\n     * @param {TurboAdminPlugin} plugin\n     */\n    registerPlugin(plugin) {\n        turboAdminLog('Registering plugin ' + plugin.name);\n        this.plugins[plugin.name] = plugin;\n    }\n\n    /**\n     * Register a palette search mode and its associated plugin\n     *\n     * this is usually bound to the searchMode, so\n     *\n     * @param {SearchMode} searchMode\n     */\n    registerSearchMode(searchMode) {\n        turboAdminLog('Registering search mode with keyword ' + searchMode.keyword);\n        // Don't use `this` as we are bound!\n        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;\n    }\n\n    /**\n     * Returns a string representation of the palette's keyboard shortcut\n     *\n     * @returns { String }\n     */\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key.toUpperCase();\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n            let urlsFound = false;\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                const dashboardLink = document.getElementById('wp-admin-bar-dashboard')?.querySelector('a');\n                if (dashboardLink) {\n                    this.siteUrl = dashboardLink.href;\n                }\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    urlsFound = true;\n                } else {\n                    // We might know what the siteUrl is, so guess the home from the siteUrl\n                    if (this.siteUrl) {\n                        this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                        urlsFound = true;\n                    }\n                }\n            }\n            if (! urlsFound) {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                    urlsFound = true;\n                }\n            }\n            if (! urlsFound) {\n                // We got nothing.\n                this.home    = await this.guessHome();\n                if (this.home) {\n                    this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // turboAdminLog('siteUrl: ', this.siteUrl);\n        // turboAdminLog('home: ', this.home);\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class WoocommerceApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getOrders(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['orders-' + searchString]) {\n            return this.cache['orders-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"orders\",\n            {\n                search: searchString,\n                per_page: 100,\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['orders-' + searchString] = result;\n\n        return result;\n    }\n\n    async getOrder(orderId) {\n        // Check the cache\n        if (undefined !== this.cache['order-' + orderId]) {\n            return this.cache['order-' + orderId];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            `orders/${orderId}`\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        let resultAsArray = [ result ];\n\n        // Store in the cache\n        this.cache['order-' + orderId] = resultAsArray;\n\n        return resultAsArray;\n    }\n\n    async getCustomers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['customers-' + searchString]) {\n            return this.cache['customers-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"customers\",\n            {\n                search: searchString,\n                per_page: 100,\n                role: 'all',\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['customers-' + searchString] = result;\n\n        return result;\n    }\n\n    // TODO: Add docblock and types\n    async wooGet(path, data = {}) {\n        const wooApiBase = globalThis.contentApi.apiRoot + 'wc/v3/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${wooApiBase}${path}/?${params}`, init);\n\n        if ( response.status === 404 ) {\n            return false;\n        }\n        if ( (response.status < 200 || response.status >= 300) ) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WooCommerce API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: WooCommerce API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class GravityFormsApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getForms(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['gf-forms-' + searchString]) {\n            return this.cache['gf-forms-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.gfGet(\n            \"forms\",\n            {}\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // TODO: Trap for errors\n\n        // Filter by search string - the API doesn't do this for us\n        const searchStringLowerCase = searchString.toLowerCase();\n        const formIds = Object.keys(result);\n        for (let k = 0; k < formIds.length; k++) {\n            const thisId = formIds[k];\n            if (! result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {\n                delete result[thisId];\n            }\n        }\n\n        // Store in the cache\n        this.cache['gf-forms-' + searchString] = result;\n\n        return result;\n    }\n\n    async gfGet(path, data = {}) {\n        const gfApiBase = globalThis.contentApi.apiRoot + 'gf/v2/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${gfApiBase}${path}/?${params}`);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Gravity Forms API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: Gravity Forms API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './apis/class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport WoocommerceApi from './apis/class-woocommerce-api.js';\nimport GravityFormsApi from './apis/class-gravity-forms-api.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\nlet debugMode = false;\n\nwindow.turboAdminLog = function() {\n    if (debugMode) {\n        console.log(...arguments);\n    }\n}\n\nwindow.turboAdminIsExtension = function() {\n    return false;\n}\n\n// Use this to clear storage\n// chrome.storage.local.remove(taStorageKey).then();\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    if (typeof(globalThis.turboAdmin) !== 'undefined') {\n        // Already initialised for some reason\n        return;\n    }\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    // Set debug mode\n    debugMode = globalThis.turboAdminOptions['debug-mode'];\n\n    turboAdminLog('Preparing Turbo Admin');\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    turboAdminLog('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n    await globalThis.contentApi.discoverPostTypes();\n    globalThis.woocommerceApi = new WoocommerceApi();\n    globalThis.gravityFormsApi = new GravityFormsApi();\n\n    turboAdminLog('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n    await globalThis.turboAdmin.init();\n\n    // This needs all the APIs to be ready\n    await globalThis.turboAdmin.activatePlugins();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n        'debug-mode': globalThis.wpTurboAdmin['debugMode'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
     5  "mappings": "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",
    66  "names": []
    77}
  • turbo-admin/tags/1.15.2/readme.txt

    r3013724 r3122653  
    44Tags: menu, commands, shortcuts
    55Requires at least: 4.9
    6 Tested up to: 6.4
     6Tested up to: 6.6
    77Requires PHP: 7.4
    8 Stable tag: 1.13.3
     8Stable tag: 1.15.2
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    185185== Changelog ==
    186186
     187= 1.15.2 =
     188
     189* [Enhancement] List table keyboard shortcuts now work on the "Add New Plugin" screen.
     190* [Enhancement] List table keyboard shortcuts now scroll the selected element into view.
     191
     192= 1.15.1 =
     193
     194* Incorporates all changes from  versions up to 1.15.1 of the browser extension.
     195* [Feature] The "Auto-remove block editor welcome screen" feature now hides the pattern selector on the new page screen, and the welcome page on the dashboard.
     196* [Feature] New features as part of the List table keyboard shortcuts.
     197* [Enhancement] Added stg., .wpenginepowered.com, .bigscoots-staging.com, .azurewebsites.net and localhost as dev/staging URLs.
     198* [Enhancement] Show search modes in the command palette.
     199* [Fix] Firefox bug fix in the plugin code.
     200* [Fix] Restore the input state after a search action.
     201* [Fix] Fix annoying issue with login links on LocalWP.
     202* [Fix] Fix list table keyboard shortcuts on plugins screen.
     203
    187204= 1.13.3 =
    188205
  • turbo-admin/tags/1.15.2/src/class-list-table-shortcuts.js

    r2871191 r3122653  
    1818
    1919        /**
     20         * @type {boolean}
     21         */
     22        this.actionsOpen = false;
     23
     24        /**
    2025         * @type {HTMLTableElement}
    2126         */
    2227        this.listTable = document.querySelector('.wp-list-table');
    2328
    24         if (! this.listTable) {
    25             return;
    26         }
     29        /**
     30         * @type {boolean}
     31         */
     32        this.isWooCommerce = false;
     33
     34        /**
     35         * @type {boolean}
     36         */
     37        this.isPluginInstall = false;
     38
     39        if (!this.listTable) {
     40            return;
     41        }
     42
     43        // We make some VERY special exceptions for WooCommerce
     44        if (document.body.classList.contains('woocommerce-admin-page') &&
     45            document.body.classList.contains('post-type-shop_order')) {
     46            this.isWooCommerce = true;
     47        }
     48
     49        // And for the add plugins screen
     50        if (document.body.classList.contains('plugin-install-php')) {
     51            this.isPluginInstall = true;
     52        }
     53
     54        /**
     55         * @type {Boolean}
     56         */
     57        this.isMac = globalThis.turboAdmin.turboAdminPalette.isMac();
    2758
    2859        /**
     
    3162        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');
    3263
    33         document.addEventListener('keyup', e => this.handleKeyup(e));
     64        // Plugin install is different.
     65        if (this.isPluginInstall) {
     66            this.tableRows = this.listTable.querySelectorAll('#the-list .plugin-card');
     67        }
     68
     69        // Grr... comments list is different! WHY?!
     70        if (document.body.classList.contains('edit-comments-php')) {
     71            this.tableRows = this.listTable.querySelectorAll('tbody#the-comment-list > tr');
     72        }
     73
     74        document.addEventListener('keydown', e => this.handleKey(e));
     75
     76        // Chrome handles escape key on search input elements, so we need to
     77        // intercept it here.
     78        const searchInput = document.querySelector(
     79            '.search-box input[type="search"], .search-form input[type="search"]'
     80        );
     81
     82        if (searchInput) {
     83            searchInput.addEventListener('keyup', e => this.handleSearchInputKey(e));
     84        }
    3485    }
    3586
     
    3889     * @param {KeyboardEvent} ev
    3990     */
    40     handleKeyup(ev) {
    41         if (document.activeElement.tagName !== 'BODY') {
    42             return;
    43         }
    44 
     91    handleKey(ev) {
     92        const isActiveElementBody = document.activeElement.tagName === 'BODY';
     93        const isActiveElementInListTable = this.listTable && this.listTable.contains(document.activeElement);
     94        const isSearchFocussed = this.getSearchInputElement() === document.activeElement;
     95        if ((!isActiveElementBody && !isActiveElementInListTable) || isSearchFocussed) {
     96            return;
     97        }
     98        if (globalThis.turboAdmin.turboAdminPalette.isPaletteOpen()) {
     99            return;
     100        }
    45101        if (ev.key === 'j') {
    46             this.tableMoveDown();
     102            if (this.actionsOpen) {
     103                this.actionMoveDown();
     104            } else {
     105                this.tableMoveDown();
     106            }
    47107        } else if (ev.key === 'k') {
    48             this.tableMoveUp();
     108            if (this.actionsOpen) {
     109                this.actionMoveUp();
     110            } else {
     111                this.tableMoveUp();
     112            }
    49113        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {
    50             this.openTableRowItem();
    51         }
    52 
     114            if (this.actionsOpen) {
     115                this.openCurrentRowAction(ev);
     116                ev.preventDefault();
     117            } else {
     118                this.openTableRowActions(ev);
     119            }
     120        } else if (ev.key === '/') {
     121            this.focusSearch(ev);
     122        } else if (ev.key === 'f' && ev.ctrlKey) {
     123            this.nextPage(ev);
     124        } else if (ev.key === 'b' && ev.ctrlKey) {
     125            this.prevPage(ev);
     126        } else if (ev.key === 'ArrowDown') {
     127            if (this.actionsOpen) {
     128                this.actionMoveDown(ev);
     129            }
     130        } else if (ev.key === 'ArrowUp') {
     131            if (this.actionsOpen) {
     132                this.actionMoveUp(ev);
     133            }
     134        } else if (ev.key.toLowerCase() === 'escape' /* && !document.body.classList.contains('modal-open')*/) {
     135            if (this.actionsOpen) {
     136                this.closeTableRowActions(ev);
     137            }
     138            // If the search box is focussed... Note that Chrome does its own thing with escape here.
     139            if (document.getElementById('post-search-input') === document.activeElement) {
     140                document.getElementById('post-search-input').blur();
     141            }
     142        }
     143
     144    }
     145
     146    handleSearchInputKey(ev) {
     147        if (ev.key.toLowerCase() === 'escape') {
     148            ev.target.blur();
     149        }
     150    }
     151
     152    getSearchInputElement() {
     153        return document.querySelector('.search-box input[type="search"], .search-form input[type="search"]');
    53154    }
    54155
    55156    tableMoveDown() {
    56157        this.preTableChange();
    57 
    58158        // Move down
    59159        if (this.currentRow === null) {
     
    84184        this.currentRow = this.tableRows[this.currentRowIndex];
    85185
    86         if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {
     186        if (!this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {
    87187            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');
    88188        }
    89     }
    90 
    91     openTableRowItem() {
     189
     190        this.scrollIntoViewIfNeeded(this.currentRow);
     191    }
     192
     193    /**
     194     * Scrolls the element into view if it is not already.
     195     */
     196    scrollIntoViewIfNeeded(element) {
     197        const elementRect = element.getBoundingClientRect();
     198        const elementTop = elementRect.top;
     199        const elementBottom = elementRect.bottom;
     200        const viewportTop = 0;
     201        const viewportBottom = window.innerHeight;
     202        if (elementBottom > viewportBottom) {
     203            element.scrollIntoView({ behavior: "smooth", block: "end" });
     204        } else if (elementTop < viewportTop) {
     205            element.scrollIntoView({ behavior: "smooth", block: "start" });
     206        }
     207    }
     208
     209    /**
     210     * Gets the list table row actions container for the current row
     211     */
     212    getRowActionsContainer() {
     213        let container = this.currentRow.querySelector('.row-actions');
     214
     215        if (this.isPluginInstall) {
     216            container = this.currentRow.querySelector('.plugin-action-buttons');
     217        }
     218
     219        return container;
     220    }
     221
     222    /**
     223     * Gets list table row actions for the current row
     224     */
     225    getRowActions() {
     226        let rowActions = this.currentRow.querySelectorAll('.row-actions span a, .row-actions span button');
     227
     228        if (this.isPluginInstall) {
     229            rowActions = this.currentRow.querySelectorAll('.plugin-action-buttons a');
     230        }
     231
     232        return rowActions;
     233    }
     234
     235    openTableRowActions(ev) {
    92236        turboAdminLog(this);
     237
     238        // WooCommerce doesn't have row actions, so we just find the link and visit it
     239        if (this.isWooCommerce) {
     240            this.currentRow.querySelector('a.order-view').click();
     241            return;
     242        }
     243
     244        this.actionsOpen = true;
     245
     246        let rowActions = this.getRowActionsContainer();
     247
     248        if (rowActions) {
     249            rowActions.classList.add('visible');
     250        }
     251
     252        const titleElem = this.currentRow.querySelector('strong');
     253        const titleLink = titleElem.querySelector('a');
     254
     255        if (titleLink) {
     256            titleLink.classList.add('ta-active-table-row-link');
     257            return;
     258        }
     259
     260        let rowActionLinks = this.getRowActions();
     261
     262        if (rowActionLinks) {
     263            rowActionLinks[0].classList.add('ta-active-table-row-link');
     264        }
     265    }
     266
     267    closeTableRowActions(ev) {
     268        turboAdminLog(this);
     269        const rowActions = this.currentRow.querySelector('.row-actions');
     270
     271        // Don't do this on plugins screen!
     272        if (!document.body.classList.contains('plugins-php')) {
     273            if (rowActions) {
     274                rowActions.classList.remove('visible');
     275            }
     276        }
     277
     278        const activeLink = document.querySelector('.ta-active-table-row-link');
     279        if (activeLink) {
     280            activeLink.classList.remove('ta-active-table-row-link');
     281        }
     282
     283        this.actionsOpen = false;
     284    }
     285
     286    actionMoveDown(ev) {
     287        /** @type {HTMLElement} */
     288        const currentLink = document.querySelector('.ta-active-table-row-link');
     289
     290        // Handle the case where the title link is selected
     291        if (currentLink.closest('strong')) {
     292            const rowActions = this.getRowActions();
     293            if (rowActions) {
     294                rowActions[0].classList.add('ta-active-table-row-link');
     295                currentLink.classList.remove('ta-active-table-row-link');
     296            }
     297            return;
     298        }
     299
     300        /** @type {HTMLElement} */
     301        const nextLink = currentLink.parentElement?.nextElementSibling?.querySelector('a, button');
     302        if (nextLink) {
     303            nextLink.classList.add('ta-active-table-row-link');
     304            currentLink.classList.remove('ta-active-table-row-link');
     305        }
     306    }
     307
     308    actionMoveUp(ev) {
     309        /** @type {HTMLElement} */
     310        const currentLink = document.querySelector('.ta-active-table-row-link');
     311
     312        // Handle the case where the title link is selected
     313        if (currentLink.closest('strong')) {
     314            return;
     315        }
     316
     317        /** @type {HTMLElement} */
     318        const prevLink = currentLink.parentElement?.previousElementSibling?.querySelector('a, button');
     319
     320        // Handle the case where the first item is selected and we need to go back to the title
     321        if (!prevLink) {
     322            const titleLink = this.currentRow.querySelector('strong a');
     323            if (titleLink) {
     324                titleLink.classList.add('ta-active-table-row-link');
     325                currentLink.classList.remove('ta-active-table-row-link');
     326            }
     327            return;
     328        }
     329
     330        prevLink.classList.add('ta-active-table-row-link');
     331        currentLink.classList.remove('ta-active-table-row-link');
     332    }
     333
     334    openCurrentRowAction(ev) {
     335        // TODO: Open the current row action
     336        /** @type {HTMLElement} */
     337        const currentLink = document.querySelector('.ta-active-table-row-link');
     338        // Don't do this for plugin install screen
     339        if (currentLink) {
     340            currentLink.click();
     341        }
     342    }
     343
     344    focusSearch(ev) {
     345        /** @type {HTMLInputElement} */
     346        const searchInput = this.getSearchInputElement();
     347
     348        if (searchInput) {
     349            searchInput.focus();
     350            this.scrollIntoViewIfNeeded(searchInput);
     351            ev.preventDefault();
     352        }
     353    }
     354
     355    nextPage(ev) {
    93356        /** @type {HTMLAnchorElement} */
    94         const link = this.currentRow.querySelector('a.row-title');
    95         if (link) {
    96             link.click();
     357        const nextPageLink = document.querySelector('.tablenav-pages .next-page');
     358        if (nextPageLink) {
     359            nextPageLink.click();
     360            ev.preventDefault();
     361        }
     362    }
     363
     364    prevPage(ev) {
     365        /** @type {HTMLAnchorElement} */
     366        const prevPageLink = document.querySelector('.tablenav-pages .prev-page');
     367        if (prevPageLink) {
     368            prevPageLink.click();
     369            ev.preventDefault();
    97370        }
    98371    }
  • turbo-admin/tags/1.15.2/src/class-turbo-admin-palette.js

    r2919322 r3122653  
    461461        if (e.code === 'ArrowDown' && this.paletteShown()) {
    462462            e.preventDefault();
     463            e.stopImmediatePropagation();
     464            e.stopPropagation();
    463465            this.moveDown();
    464466            return;
     
    466468        if (e.code === 'ArrowUp' && this.paletteShown()) {
    467469            e.preventDefault();
     470            e.stopImmediatePropagation();
     471            e.stopPropagation();
    468472            this.moveUp();
    469473            return;
     
    471475        if (e.code === 'Enter' && this.paletteShown()) {
    472476            e.preventDefault();
     477            e.stopImmediatePropagation();
     478            e.stopPropagation();
    473479            this.doAction(this.metaPressed(e));
    474480            return;
  • turbo-admin/tags/1.15.2/src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js

    r2702218 r3122653  
    11/**
    2  *
     2 * Kills/auto-removes:
     3 *  - the Welcome Guide on the post edit screen
     4 *  - the pattern selector modal on the post edit screen
     5 *  - the Welcome Panel on the dashboard on new sites
    36 */
    47export default class TurboAdminWpBlockEditorWelcomeGuideKill {
    58
    69    constructor() {
    7 
    810        const attrObserver = new MutationObserver((mutations) => {
    911            mutations.forEach(mu => {
     
    1719                }
    1820
    19                 if (! mu.target.classList.contains('modal-open')) {
     21                if (!mu.target.classList.contains('modal-open')) {
    2022                    return;
    2123                }
    2224
     25                console.log('Modal detected');
    2326                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');
    24                 if (welcomeGuide) {
     27                const newPagePatterns = document.querySelector('.edit-post-start-page-options__modal');
     28                const newPagePatterns2 = document.querySelector('.editor-start-page-options__modal-content');
     29
     30                if (welcomeGuide || newPagePatterns || newPagePatterns2) {
    2531                    this.killWelcomeGuide();
    2632                }
     
    3238        // Also attempt a kill now in case it's already appeared.
    3339        this.killWelcomeGuide();
     40
     41        // Attempt a kill of the dashboard welcome panel
     42        this.killDashboardWelcomePanel();
    3443    }
    3544
    3645    killWelcomeGuide() {
    37         const welcomeGuide = document.querySelector('.edit-post-welcome-guide');
     46        // Check for welcome guide
     47        let welcomeGuide = document.querySelector('.edit-post-welcome-guide');
     48        // Check for new page patterns modal (old: pre-6.6?)
     49        if (!welcomeGuide) {
     50            welcomeGuide = document.querySelector('.edit-post-start-page-options__modal');
     51        }
     52        // Check for new page patterns model (new: 6.6+)
     53        if (!welcomeGuide) {
     54            welcomeGuide = document.querySelector('.editor-start-page-options__modal-content');
     55        }
     56
    3857        if (welcomeGuide) {
    39             const closeButton = welcomeGuide.querySelector('.components-modal__header button');
     58            const closeButton = document.querySelector('.components-modal__header button');
    4059            if (closeButton) {
    4160                closeButton.click();
     
    4867        }
    4968    }
     69
     70    killDashboardWelcomePanel() {
     71        const welcomePanel = document.getElementById('welcome-panel');
     72        if (!welcomePanel) {
     73            return;
     74        }
     75        const welcomePanelClose = welcomePanel.querySelector('.welcome-panel-close');
     76        if (welcomePanelClose) {
     77            welcomePanelClose.click();
     78        }
     79    }
    5080}
  • turbo-admin/tags/1.15.2/src/class-turbo-admin-wp-notices.js

    r2871191 r3122653  
    217217        this.rememberedNoticeIds.push(noticeId);
    218218
    219         if ('object' === typeof(browser)) {
     219        if ('object' === typeof(chrome)) {
    220220            chrome.runtime.sendMessage({
    221221                'action': 'rememberNotice',
     
    260260        this.rememberedNoticeIds.push(noticeId);
    261261
    262         if ('object' === typeof(browser)) {
     262        if ('object' === typeof(chrome)) {
    263263            chrome.runtime.sendMessage({
    264264                'action': 'rememberNotice',
  • turbo-admin/tags/1.15.2/src/class-turbo-admin.js

    r2919322 r3122653  
    360360                    'itemUrlFunction': () => {
    361361                        if (globalThis.taWp.home) {
    362                             return globalThis.taWp.siteUrl;
     362                            return globalThis.taWp.ensureTrailingSlash(globalThis.taWp.siteUrl);
    363363                        }
    364364                        // Try getting wp-admin
  • turbo-admin/tags/1.15.2/turbo-admin.css

    r2871191 r3122653  
    584584}
    585585
     586.has-row-actions .ta-active-table-row-link,
     587.plugin-title .ta-active-table-row-link,
     588.plugin-card .name .ta-active-table-row-link,
     589.plugin-action-buttons .ta-active-table-row-link {
     590    text-decoration: underline !important;
     591}
     592
    586593/**
    587594 * Barkeeper
  • turbo-admin/tags/1.15.2/turbo-admin.php

    r2919322 r3122653  
    33/**
    44 * Plugin Name:     Turbo Admin
    5  * Plugin URI:      https://oikos.digital/turbo-admin
     5 * Plugin URI:      https://turbo-admin.com/
    66 * Description:     The command palette that gives super fast access to your WordPress Dashboard.
    77 * Author:          Ross Wintle
     
    99 * Text Domain:     turbo-admin
    1010 * Domain Path:     /languages
    11  * Version:         1.13.3
     11 * Version:         1.15.2
    1212 *
    13  * @package         Turbo_Admin
     13 * @package Turbo_Admin
    1414 */
    1515
     
    4141function add_admin_scripts()
    4242{
    43     if (is_user_logged_in()) {
    44         $userShortcutKeys   = userShortcutKeys();
    45         $hideNotices        = get_user_meta( get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true );
    46         $adminBarSearch     = get_user_meta( get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true );
    47         $barkeeper          = get_user_meta( get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true );
    48         $listTableShortcuts = get_user_meta( get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true );
    49         $debugMode          = get_user_meta( get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true );
    50 
    51         // We will pass an array of shortcut key objects into the JS
    52         $shortcutKeys = [
    53             $userShortcutKeys
    54         ];
    55 
    56         wp_enqueue_script('turbo-admin-scripts', plugin_dir_url(__FILE__) . 'dist/main.min.js', [], null, true);
    57         wp_enqueue_style('turbo-admin-styles', plugin_dir_url(__FILE__) . 'turbo-admin.css', []);
    58 
    59         wp_localize_script( 'turbo-admin-scripts', 'wpTurboAdmin', [
    60             'keys'               => $shortcutKeys,
    61             'hideNotices'        => intval( $hideNotices ) === 1,
    62             'adminBarSearch'     => intval( $adminBarSearch ) === 1,
    63             'barkeeper'          => intval( $barkeeper ) === 1,
    64             'listTableShortcuts' => intval( $listTableShortcuts ) === 1,
    65             'debugMode'          => intval( $debugMode ) === 1,
    66         ] );
    67     }
     43    if (is_user_logged_in()) {
     44        $userShortcutKeys   = userShortcutKeys();
     45        $hideNotices        = get_user_meta(get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true);
     46        $adminBarSearch     = get_user_meta(get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true);
     47        $barkeeper          = get_user_meta(get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true);
     48        $listTableShortcuts = get_user_meta(get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true);
     49        $debugMode          = get_user_meta(get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true);
     50
     51        // We will pass an array of shortcut key objects into the JS
     52        $shortcutKeys = [
     53        $userShortcutKeys
     54        ];
     55
     56        wp_enqueue_script('turbo-admin-scripts', plugin_dir_url(__FILE__) . 'dist/main.min.js', [], null, true);
     57        wp_enqueue_style('turbo-admin-styles', plugin_dir_url(__FILE__) . 'turbo-admin.css', []);
     58
     59        wp_localize_script(
     60            'turbo-admin-scripts', 'wpTurboAdmin', [
     61            'keys'               => $shortcutKeys,
     62            'hideNotices'        => intval($hideNotices) === 1,
     63            'adminBarSearch'     => intval($adminBarSearch) === 1,
     64            'barkeeper'          => intval($barkeeper) === 1,
     65            'listTableShortcuts' => intval($listTableShortcuts) === 1,
     66            'debugMode'          => intval($debugMode) === 1,
     67            ]
     68        );
     69    }
    6870}
    6971
     
    7577    }
    7678
    77     $userShortcutKeys = userShortcutKeys();
    78 
    79     $keysTextArray = [];
    80 
    81     if ($userShortcutKeys['meta']) {
    82         $keysTextArray[] = 'Cmd';
    83     }
    84     if ($userShortcutKeys['alt']) {
    85         $keysTextArray[] = 'Alt';
    86     }
    87     if ($userShortcutKeys['ctrl']) {
    88         $keysTextArray[] = 'Ctrl';
    89     }
    90     if ($userShortcutKeys['shift']) {
    91         $keysTextArray[] = 'Shift';
    92     }
    93     $keysTextArray[] = $userShortcutKeys['key'] === ' ' ? 'Space' : strtoupper($userShortcutKeys['key']);
    94 
    95     $keysText = implode('-', $keysTextArray);
    96 
    97     $admin_bar->add_menu(array(
    98         'id'    => 'turbo-admin',
    99         'parent' => null,
    100         'group'  => null,
    101         'title' => '<span class="ab-icon" style="margin-right: 0;"><img src="' . plugin_dir_url(__FILE__) . '/images/snail.svg' . '" style="display: block; width: 24px; height: 24px;"></span>',
    102         'href'  => null,
    103         'meta' => [
    104             'title' => sprintf(__('Turbo admin is installed! Use %s to open the command palette.', 'turbo-admin'), $keysText), //This title will show on hover
    105         ]
    106     ));
     79    $userShortcutKeys = userShortcutKeys();
     80
     81    $keysTextArray = [];
     82
     83    if ($userShortcutKeys['meta']) {
     84        $keysTextArray[] = 'Cmd';
     85    }
     86    if ($userShortcutKeys['alt']) {
     87        $keysTextArray[] = 'Alt';
     88    }
     89    if ($userShortcutKeys['ctrl']) {
     90        $keysTextArray[] = 'Ctrl';
     91    }
     92    if ($userShortcutKeys['shift']) {
     93        $keysTextArray[] = 'Shift';
     94    }
     95    $keysTextArray[] = $userShortcutKeys['key'] === ' ' ? 'Space' : strtoupper($userShortcutKeys['key']);
     96
     97    $keysText = implode('-', $keysTextArray);
     98
     99    $admin_bar->add_menu(
     100        array(
     101        'id'    => 'turbo-admin',
     102        'parent' => null,
     103        'group'  => null,
     104        'title' => '<span class="ab-icon" style="margin-right: 0;"><img src="' . plugin_dir_url(__FILE__) . '/images/snail.svg' . '" style="display: block; width: 24px; height: 24px;"></span>',
     105        'href'  => null,
     106        'meta' => [
     107        'title' => sprintf(__('Turbo admin is installed! Use %s to open the command palette.', 'turbo-admin'), $keysText), //This title will show on hover
     108        ]
     109        )
     110    );
    107111}
    108112
     
    110114add_action('edit_user_profile', 'TurboAdmin\show_profile_fields');
    111115
    112 function get_hide_icon($user_id) {
     116function get_hide_icon($user_id)
     117{
    113118    $hideIcon = get_user_meta($user_id, TURBO_ADMIN_HIDE_ICON_META_NAME, true);
    114119
     
    122127function show_profile_fields($user)
    123128{
    124     $shortcut = get_user_meta($user->ID, TURBO_ADMIN_SHORTCUT_META_NAME, true);
    125     if (empty($shortcut)) {
    126         $shortcut = defaultShortcutKeys();
    127     }
     129    $shortcut = get_user_meta($user->ID, TURBO_ADMIN_SHORTCUT_META_NAME, true);
     130    if (empty($shortcut)) {
     131        $shortcut = defaultShortcutKeys();
     132    }
    128133    $hideIcon = get_hide_icon($user->ID);
    129     $hideNotices        = get_user_meta( get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true );
    130     $adminBarSearch     = get_user_meta( get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true );
    131     $barkeeper          = get_user_meta( get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true );
    132     $listTableShortcuts = get_user_meta( get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true );
    133     $debugMode          = get_user_meta( get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true );
    134 ?>
    135     <h3><?php _e('Turbo Admin settings', 'turbo_admin') ?></h3>
    136     <table class="form-table">
    137         <tr>
    138             <th><label for="turbo-admin-shortcut"><?php _e('Keyboard shortcut', 'turbo_admin') ?></label></th>
    139             <td>
    140                 <label style="margin-right: 18px;">
    141                     <input type="checkbox" name="turbo-admin-meta-key" <?php checked($shortcut['meta']) ?>></input>
    142                     <?php _e('Cmd (Mac only)', 'turbo_admin') ?>
    143                 </label>
    144                 <label style="margin-right: 18px;">
    145                     <input type="checkbox" name="turbo-admin-alt-key" <?php checked($shortcut['alt']) ?>></input>
    146                     <?php _e('Alt/option', 'turbo_admin') ?>
    147                 </label>
    148                 <label style="margin-right: 18px;">
    149                     <input type="checkbox" name="turbo-admin-ctrl-key" <?php checked($shortcut['ctrl']) ?>></input>
    150                     <?php _e('Ctrl', 'turbo_admin') ?>
    151                 </label>
    152                 <label style="margin-right: 18px;">
    153                     <input type="checkbox" name="turbo-admin-shift-key" <?php checked($shortcut['shift']) ?>></input>
    154                     <?php _e('Shift', 'turbo_admin') ?>
    155                 </label>
    156                 <input type="text" required name="turbo-admin-shortcut" id="turbo-admin-shortcut" minLength="1" maxLength="1" value="<?php echo esc_attr($shortcut['key']); ?>" class="regular-text" /><br />
    157                 <span class="description"><?php _e('Please enter the keyboard shortcut you want to use to activate the Turbo Admin command palette.<br>
    158                 Do not choose a keyboard combination that your browser already uses.', 'turbo_admin') ?></span>
    159             </td>
    160         </tr>
    161         <tr>
    162             <th><label for="turbo-admin-hide-icon"><?php _e('Hide admin bar icon', 'turbo_admin') ?></label></th>
    163             <td>
    164                 <label style="margin-right: 18px;">
    165                     <input type="radio" name="turbo-admin-hide-icon" value="1" <?php checked($hideIcon, 1) ?>></input>
    166                     <?php _e('Hide icon', 'turbo_admin') ?>
    167                 </label>
    168                 <label style="margin-right: 18px;">
    169                     <input type="radio" name="turbo-admin-hide-icon" value="0" <?php checked($hideIcon, 0) ?>></input>
    170                     <?php _e('Show icon', 'turbo_admin') ?>
    171                 </label>
    172             </td>
    173         </tr>
     134    $hideNotices        = get_user_meta(get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true);
     135    $adminBarSearch     = get_user_meta(get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true);
     136    $barkeeper          = get_user_meta(get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true);
     137    $listTableShortcuts = get_user_meta(get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true);
     138    $debugMode          = get_user_meta(get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true);
     139    ?>
     140    <h3><?php _e('Turbo Admin settings', 'turbo_admin') ?></h3>
     141    <table class="form-table">
    174142        <tr>
    175             <th>
     143            <th><label for="turbo-admin-shortcut"><?php _e('Keyboard shortcut', 'turbo_admin') ?></label></th>
     144            <td>
     145                <label style="margin-right: 18px;">
     146                    <input type="checkbox" name="turbo-admin-meta-key" <?php checked($shortcut['meta']) ?>></input>
     147                    <?php _e('Cmd (Mac only)', 'turbo_admin') ?>
     148                </label>
     149                <label style="margin-right: 18px;">
     150                    <input type="checkbox" name="turbo-admin-alt-key" <?php checked($shortcut['alt']) ?>></input>
     151                    <?php _e('Alt/option', 'turbo_admin') ?>
     152                </label>
     153                <label style="margin-right: 18px;">
     154                    <input type="checkbox" name="turbo-admin-ctrl-key" <?php checked($shortcut['ctrl']) ?>></input>
     155                    <?php _e('Ctrl', 'turbo_admin') ?>
     156                </label>
     157                <label style="margin-right: 18px;">
     158                    <input type="checkbox" name="turbo-admin-shift-key" <?php checked($shortcut['shift']) ?>></input>
     159                    <?php _e('Shift', 'turbo_admin') ?>
     160                </label>
     161                <input type="text" required name="turbo-admin-shortcut" id="turbo-admin-shortcut" minLength="1" maxLength="1" value="<?php echo esc_attr($shortcut['key']); ?>" class="regular-text" /><br />
     162                <span class="description"><?php _e(
     163                    'Please enter the keyboard shortcut you want to use to activate the Turbo Admin command palette.<br>
     164                Do not choose a keyboard combination that your browser already uses.', 'turbo_admin'
     165                ) ?></span>
     166            </td>
     167        </tr>
     168        <tr>
     169            <th><label for="turbo-admin-hide-icon"><?php _e('Hide admin bar icon', 'turbo_admin') ?></label></th>
     170            <td>
     171                <label style="margin-right: 18px;">
     172                    <input type="radio" name="turbo-admin-hide-icon" value="1" <?php checked($hideIcon, 1) ?>></input>
     173                    <?php _e('Hide icon', 'turbo_admin') ?>
     174                </label>
     175                <label style="margin-right: 18px;">
     176                    <input type="radio" name="turbo-admin-hide-icon" value="0" <?php checked($hideIcon, 0) ?>></input>
     177                    <?php _e('Show icon', 'turbo_admin') ?>
     178                </label>
     179            </td>
     180        </tr>
     181        <tr>
     182            <th>
    176183                <label for="turbo-admin-additional-features"><?php _e('Additional features', 'turbo_admin') ?></label>
    177184            </th>
    178             <td>
     185            <td>
    179186                <label for="turbo-admin-hide-notices">
    180                     <input name="turbo-admin-hide-notices" type="checkbox" id="turbo-admin-hide-notices" value="1" <?php checked($hideNotices) ?>>
    181                     Hide notices (experimental)
     187                    <input name="turbo-admin-hide-notices" type="checkbox" id="turbo-admin-hide-notices" value="1" <?php checked($hideNotices) ?>>
     188                    Hide notices (experimental)
    182189                </label>
    183190                <br>
     
    203210            </td>
    204211        </tr>
    205     </table>
    206 
    207 <?php
     212    </table>
     213
     214    <?php
    208215}
    209216
     
    214221{
    215222
    216     if (!current_user_can('edit_user', $user_id)) {
    217         return false;
    218     }
    219 
    220     $shortcut = [];
    221 
    222     $shortcut['meta'] = isset($_POST['turbo-admin-meta-key']);
    223     $shortcut['alt'] = isset($_POST['turbo-admin-alt-key']);
    224     $shortcut['ctrl'] = isset($_POST['turbo-admin-ctrl-key']);
    225     $shortcut['shift'] = isset($_POST['turbo-admin-shift-key']);
    226     $shortcut['key'] = isset($_POST['turbo-admin-shortcut']) ? esc_attr($_POST['turbo-admin-shortcut']) : 'P';
    227 
    228     update_user_meta($user_id, TURBO_ADMIN_SHORTCUT_META_NAME, $shortcut);
     223    if (!current_user_can('edit_user', $user_id)) {
     224        return false;
     225    }
     226
     227    $shortcut = [];
     228
     229    $shortcut['meta'] = isset($_POST['turbo-admin-meta-key']);
     230    $shortcut['alt'] = isset($_POST['turbo-admin-alt-key']);
     231    $shortcut['ctrl'] = isset($_POST['turbo-admin-ctrl-key']);
     232    $shortcut['shift'] = isset($_POST['turbo-admin-shift-key']);
     233    $shortcut['key'] = isset($_POST['turbo-admin-shortcut']) ? esc_attr($_POST['turbo-admin-shortcut']) : 'P';
     234
     235    update_user_meta($user_id, TURBO_ADMIN_SHORTCUT_META_NAME, $shortcut);
    229236
    230237    if (isset($_POST['turbo-admin-hide-icon']) && in_array(intval($_POST['turbo-admin-hide-icon']), [0, 1], true) ) {
     
    261268 * This returns the user-specified key combo if set, or the default one if not
    262269 */
    263 function userShortcutKeys() {
    264     $userShortcutKeys = get_user_meta(get_current_user_id(), TURBO_ADMIN_SHORTCUT_META_NAME, true);
    265 
    266     if (! $userShortcutKeys) {
    267         return defaultShortcutKeys();
    268     }
    269 
    270     return $userShortcutKeys;
    271 }
    272 
    273 function defaultShortcutKeys() {
    274     $shortcut = [
    275         'meta' => false,
    276         'alt' => true,
    277         'ctrl' => true,
    278         'shift' => true,
    279         'key' => 'P',
    280     ];
    281     if (isUserOnMacOs()) {
    282         $shortcut['meta'] = true;
    283         $shortcut['ctrl'] = false;
    284     }
    285     return $shortcut;
    286 }
    287 
    288 function isUserOnMacOs() {
    289     return strpos($_SERVER['HTTP_USER_AGENT'], "Mac") !== false;
    290 }
     270function userShortcutKeys()
     271{
     272    $userShortcutKeys = get_user_meta(get_current_user_id(), TURBO_ADMIN_SHORTCUT_META_NAME, true);
     273
     274    if (! $userShortcutKeys) {
     275        return defaultShortcutKeys();
     276    }
     277
     278    return $userShortcutKeys;
     279}
     280
     281function defaultShortcutKeys()
     282{
     283    $shortcut = [
     284    'meta' => false,
     285    'alt' => true,
     286    'ctrl' => true,
     287    'shift' => true,
     288    'key' => 'P',
     289    ];
     290    if (isUserOnMacOs()) {
     291        $shortcut['meta'] = true;
     292        $shortcut['ctrl'] = false;
     293    }
     294    return $shortcut;
     295}
     296
     297function isUserOnMacOs()
     298{
     299    return strpos($_SERVER['HTTP_USER_AGENT'], "Mac") !== false;
     300}
  • turbo-admin/trunk/dist/main.min.js

    r2919322 r3122653  
    13711371      if (e.code === "ArrowDown" && this.paletteShown()) {
    13721372        e.preventDefault();
     1373        e.stopImmediatePropagation();
     1374        e.stopPropagation();
    13731375        this.moveDown();
    13741376        return;
     
    13761378      if (e.code === "ArrowUp" && this.paletteShown()) {
    13771379        e.preventDefault();
     1380        e.stopImmediatePropagation();
     1381        e.stopPropagation();
    13781382        this.moveUp();
    13791383        return;
     
    13811385      if (e.code === "Enter" && this.paletteShown()) {
    13821386        e.preventDefault();
     1387        e.stopImmediatePropagation();
     1388        e.stopPropagation();
    13831389        this.doAction(this.metaPressed(e));
    13841390        return;
     
    17731779            return;
    17741780          }
     1781          console.log("Modal detected");
    17751782          const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
    1776           if (welcomeGuide) {
     1783          const newPagePatterns = document.querySelector(".edit-post-start-page-options__modal");
     1784          const newPagePatterns2 = document.querySelector(".editor-start-page-options__modal-content");
     1785          if (welcomeGuide || newPagePatterns || newPagePatterns2) {
    17771786            this.killWelcomeGuide();
    17781787          }
     
    17811790      attrObserver.observe(document.body, {attributes: true});
    17821791      this.killWelcomeGuide();
     1792      this.killDashboardWelcomePanel();
    17831793    }
    17841794    killWelcomeGuide() {
    1785       const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
     1795      let welcomeGuide = document.querySelector(".edit-post-welcome-guide");
     1796      if (!welcomeGuide) {
     1797        welcomeGuide = document.querySelector(".edit-post-start-page-options__modal");
     1798      }
     1799      if (!welcomeGuide) {
     1800        welcomeGuide = document.querySelector(".editor-start-page-options__modal-content");
     1801      }
    17861802      if (welcomeGuide) {
    1787         const closeButton = welcomeGuide.querySelector(".components-modal__header button");
     1803        const closeButton = document.querySelector(".components-modal__header button");
    17881804        if (closeButton) {
    17891805          closeButton.click();
    17901806          document.body.classList.add("ta-killed-post-welcome-guide");
    17911807        }
     1808      }
     1809    }
     1810    killDashboardWelcomePanel() {
     1811      const welcomePanel = document.getElementById("welcome-panel");
     1812      if (!welcomePanel) {
     1813        return;
     1814      }
     1815      const welcomePanelClose = welcomePanel.querySelector(".welcome-panel-close");
     1816      if (welcomePanelClose) {
     1817        welcomePanelClose.click();
    17921818      }
    17931819    }
     
    19271953    saveRememberedNotice(noticeId) {
    19281954      this.rememberedNoticeIds.push(noticeId);
    1929       if (typeof browser === "object") {
     1955      if (typeof chrome === "object") {
    19301956        chrome.runtime.sendMessage({
    19311957          action: "rememberNotice",
     
    19571983    saveForgottenNotice(noticeId) {
    19581984      this.rememberedNoticeIds.push(noticeId);
    1959       if (typeof browser === "object") {
     1985      if (typeof chrome === "object") {
    19601986        chrome.runtime.sendMessage({
    19611987          action: "rememberNotice",
     
    20612087      this.currentRow = null;
    20622088      this.currentRowIndex = 0;
     2089      this.actionsOpen = false;
    20632090      this.listTable = document.querySelector(".wp-list-table");
     2091      this.isWooCommerce = false;
     2092      this.isPluginInstall = false;
    20642093      if (!this.listTable) {
    20652094        return;
    20662095      }
     2096      if (document.body.classList.contains("woocommerce-admin-page") && document.body.classList.contains("post-type-shop_order")) {
     2097        this.isWooCommerce = true;
     2098      }
     2099      if (document.body.classList.contains("plugin-install-php")) {
     2100        this.isPluginInstall = true;
     2101      }
     2102      this.isMac = globalThis.turboAdmin.turboAdminPalette.isMac();
    20672103      this.tableRows = this.listTable.querySelectorAll("tbody#the-list > tr");
    2068       document.addEventListener("keyup", (e) => this.handleKeyup(e));
    2069     }
    2070     handleKeyup(ev) {
    2071       if (document.activeElement.tagName !== "BODY") {
     2104      if (this.isPluginInstall) {
     2105        this.tableRows = this.listTable.querySelectorAll("#the-list .plugin-card");
     2106      }
     2107      if (document.body.classList.contains("edit-comments-php")) {
     2108        this.tableRows = this.listTable.querySelectorAll("tbody#the-comment-list > tr");
     2109      }
     2110      document.addEventListener("keydown", (e) => this.handleKey(e));
     2111      const searchInput = document.querySelector('.search-box input[type="search"], .search-form input[type="search"]');
     2112      if (searchInput) {
     2113        searchInput.addEventListener("keyup", (e) => this.handleSearchInputKey(e));
     2114      }
     2115    }
     2116    handleKey(ev) {
     2117      const isActiveElementBody = document.activeElement.tagName === "BODY";
     2118      const isActiveElementInListTable = this.listTable && this.listTable.contains(document.activeElement);
     2119      const isSearchFocussed = this.getSearchInputElement() === document.activeElement;
     2120      if (!isActiveElementBody && !isActiveElementInListTable || isSearchFocussed) {
     2121        return;
     2122      }
     2123      if (globalThis.turboAdmin.turboAdminPalette.isPaletteOpen()) {
    20722124        return;
    20732125      }
    20742126      if (ev.key === "j") {
    2075         this.tableMoveDown();
     2127        if (this.actionsOpen) {
     2128          this.actionMoveDown();
     2129        } else {
     2130          this.tableMoveDown();
     2131        }
    20762132      } else if (ev.key === "k") {
    2077         this.tableMoveUp();
     2133        if (this.actionsOpen) {
     2134          this.actionMoveUp();
     2135        } else {
     2136          this.tableMoveUp();
     2137        }
    20782138      } else if (ev.key.toLowerCase() === "enter" && this.currentRow !== null) {
    2079         this.openTableRowItem();
    2080       }
     2139        if (this.actionsOpen) {
     2140          this.openCurrentRowAction(ev);
     2141          ev.preventDefault();
     2142        } else {
     2143          this.openTableRowActions(ev);
     2144        }
     2145      } else if (ev.key === "/") {
     2146        this.focusSearch(ev);
     2147      } else if (ev.key === "f" && ev.ctrlKey) {
     2148        this.nextPage(ev);
     2149      } else if (ev.key === "b" && ev.ctrlKey) {
     2150        this.prevPage(ev);
     2151      } else if (ev.key === "ArrowDown") {
     2152        if (this.actionsOpen) {
     2153          this.actionMoveDown(ev);
     2154        }
     2155      } else if (ev.key === "ArrowUp") {
     2156        if (this.actionsOpen) {
     2157          this.actionMoveUp(ev);
     2158        }
     2159      } else if (ev.key.toLowerCase() === "escape") {
     2160        if (this.actionsOpen) {
     2161          this.closeTableRowActions(ev);
     2162        }
     2163        if (document.getElementById("post-search-input") === document.activeElement) {
     2164          document.getElementById("post-search-input").blur();
     2165        }
     2166      }
     2167    }
     2168    handleSearchInputKey(ev) {
     2169      if (ev.key.toLowerCase() === "escape") {
     2170        ev.target.blur();
     2171      }
     2172    }
     2173    getSearchInputElement() {
     2174      return document.querySelector('.search-box input[type="search"], .search-form input[type="search"]');
    20812175    }
    20822176    tableMoveDown() {
     
    21062200        this.tableRows[this.currentRowIndex].classList.add("ta-active-table-row");
    21072201      }
    2108     }
    2109     openTableRowItem() {
     2202      this.scrollIntoViewIfNeeded(this.currentRow);
     2203    }
     2204    scrollIntoViewIfNeeded(element) {
     2205      const elementRect = element.getBoundingClientRect();
     2206      const elementTop = elementRect.top;
     2207      const elementBottom = elementRect.bottom;
     2208      const viewportTop = 0;
     2209      const viewportBottom = window.innerHeight;
     2210      if (elementBottom > viewportBottom) {
     2211        element.scrollIntoView({behavior: "smooth", block: "end"});
     2212      } else if (elementTop < viewportTop) {
     2213        element.scrollIntoView({behavior: "smooth", block: "start"});
     2214      }
     2215    }
     2216    getRowActionsContainer() {
     2217      let container = this.currentRow.querySelector(".row-actions");
     2218      if (this.isPluginInstall) {
     2219        container = this.currentRow.querySelector(".plugin-action-buttons");
     2220      }
     2221      return container;
     2222    }
     2223    getRowActions() {
     2224      let rowActions = this.currentRow.querySelectorAll(".row-actions span a, .row-actions span button");
     2225      if (this.isPluginInstall) {
     2226        rowActions = this.currentRow.querySelectorAll(".plugin-action-buttons a");
     2227      }
     2228      return rowActions;
     2229    }
     2230    openTableRowActions(ev) {
    21102231      turboAdminLog(this);
    2111       const link = this.currentRow.querySelector("a.row-title");
    2112       if (link) {
    2113         link.click();
     2232      if (this.isWooCommerce) {
     2233        this.currentRow.querySelector("a.order-view").click();
     2234        return;
     2235      }
     2236      this.actionsOpen = true;
     2237      let rowActions = this.getRowActionsContainer();
     2238      if (rowActions) {
     2239        rowActions.classList.add("visible");
     2240      }
     2241      const titleElem = this.currentRow.querySelector("strong");
     2242      const titleLink = titleElem.querySelector("a");
     2243      if (titleLink) {
     2244        titleLink.classList.add("ta-active-table-row-link");
     2245        return;
     2246      }
     2247      let rowActionLinks = this.getRowActions();
     2248      if (rowActionLinks) {
     2249        rowActionLinks[0].classList.add("ta-active-table-row-link");
     2250      }
     2251    }
     2252    closeTableRowActions(ev) {
     2253      turboAdminLog(this);
     2254      const rowActions = this.currentRow.querySelector(".row-actions");
     2255      if (!document.body.classList.contains("plugins-php")) {
     2256        if (rowActions) {
     2257          rowActions.classList.remove("visible");
     2258        }
     2259      }
     2260      const activeLink = document.querySelector(".ta-active-table-row-link");
     2261      if (activeLink) {
     2262        activeLink.classList.remove("ta-active-table-row-link");
     2263      }
     2264      this.actionsOpen = false;
     2265    }
     2266    actionMoveDown(ev) {
     2267      const currentLink = document.querySelector(".ta-active-table-row-link");
     2268      if (currentLink.closest("strong")) {
     2269        const rowActions = this.getRowActions();
     2270        if (rowActions) {
     2271          rowActions[0].classList.add("ta-active-table-row-link");
     2272          currentLink.classList.remove("ta-active-table-row-link");
     2273        }
     2274        return;
     2275      }
     2276      const nextLink = currentLink.parentElement?.nextElementSibling?.querySelector("a, button");
     2277      if (nextLink) {
     2278        nextLink.classList.add("ta-active-table-row-link");
     2279        currentLink.classList.remove("ta-active-table-row-link");
     2280      }
     2281    }
     2282    actionMoveUp(ev) {
     2283      const currentLink = document.querySelector(".ta-active-table-row-link");
     2284      if (currentLink.closest("strong")) {
     2285        return;
     2286      }
     2287      const prevLink = currentLink.parentElement?.previousElementSibling?.querySelector("a, button");
     2288      if (!prevLink) {
     2289        const titleLink = this.currentRow.querySelector("strong a");
     2290        if (titleLink) {
     2291          titleLink.classList.add("ta-active-table-row-link");
     2292          currentLink.classList.remove("ta-active-table-row-link");
     2293        }
     2294        return;
     2295      }
     2296      prevLink.classList.add("ta-active-table-row-link");
     2297      currentLink.classList.remove("ta-active-table-row-link");
     2298    }
     2299    openCurrentRowAction(ev) {
     2300      const currentLink = document.querySelector(".ta-active-table-row-link");
     2301      if (currentLink) {
     2302        currentLink.click();
     2303      }
     2304    }
     2305    focusSearch(ev) {
     2306      const searchInput = this.getSearchInputElement();
     2307      if (searchInput) {
     2308        searchInput.focus();
     2309        this.scrollIntoViewIfNeeded(searchInput);
     2310        ev.preventDefault();
     2311      }
     2312    }
     2313    nextPage(ev) {
     2314      const nextPageLink = document.querySelector(".tablenav-pages .next-page");
     2315      if (nextPageLink) {
     2316        nextPageLink.click();
     2317        ev.preventDefault();
     2318      }
     2319    }
     2320    prevPage(ev) {
     2321      const prevPageLink = document.querySelector(".tablenav-pages .prev-page");
     2322      if (prevPageLink) {
     2323        prevPageLink.click();
     2324        ev.preventDefault();
    21142325      }
    21152326    }
     
    27322943          itemUrlFunction: () => {
    27332944            if (globalThis.taWp.home) {
    2734               return globalThis.taWp.siteUrl;
     2945              return globalThis.taWp.ensureTrailingSlash(globalThis.taWp.siteUrl);
    27352946            }
    27362947            return "javascript:alert('Sorry, could not detect login URL.')";
  • turbo-admin/trunk/dist/main.min.js.map

    r2919322 r3122653  
    22  "version": 3,
    33  "sources": ["../src/fuse-6.4.6.js", "../src/class-turbo-admin-palette.js", "../src/types/class-item-definition.js", "../src/types/class-turbo-admin-menu-item.js", "../src/class-storage.js", "../src/apis/class-content-api.js", "../src/types/class-submenu-item.js", "../src/types/class-content-item.js", "../src/types/class-search-mode.js", "../src/types/class-turbo-admin-plugin.js", "../src/class-turbo-admin-wp-block-editor-fullscreen-kill.js", "../src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js", "../src/class-turbo-admin-wp-notices.js", "../src/class-list-table-shortcuts.js", "../src/plugins/class-turbo-admin-barkeeper.js", "../src/plugins/class-turbo-admin-content-search.js", "../src/plugins/class-turbo-admin-plugins.js", "../src/plugins/class-turbo-admin-users.js", "../src/plugins/class-turbo-admin-woocommerce.js", "../src/plugins/class-turbo-admin-gravity-forms.js", "../src/plugins/class-turbo-admin-mu-sites.js", "../src/plugins/class-turbo-admin-oxygen-buillder.js", "../src/class-turbo-admin.js", "../src/class-wp.js", "../src/apis/class-woocommerce-api.js", "../src/apis/class-gravity-forms-api.js", "../src/main.js"],
    4   "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item';\nimport ContentApi from './apis/class-content-api.js';\nimport SearchMode from './types/class-search-mode.js';\nimport ContentItem from './types/class-content-item.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tturboAdminLog('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));\n        /** @type {HTMLSpanElement} */\n        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));\n        /** @type {HTMLDivElement} */\n        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));\n\n\n        // Add a class if the menu needs refreshing with a visit to the Dashboard\n        if (globalThis.turboAdmin.menuNeedsRefresh) {\n            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');\n        }\n\n        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but\n        // works for now.\n        /** @type {HTMLUListElement} */\n        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        /** @type {null|String} */\n        this.profileLink = null;\n        if (this.profileLinkElem) {\n            this.profileLink = this.profileLinkElem.querySelector('a').href;\n        }\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Backup of the palette data for use when we enter a different search mode\n\t\tthis.paletteDataBackup = null;\n\t\tthis.paletteItemsBackup = null;\n        this.paletteItemIndexBackup = null;\n        this.paletteInputValueBackup = null;\n\n        // Current search modes/keyword\n        this.searchMode = null;\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n            shouldSort: true,\n            // sortFn: (a, b) => {\n            //     // Return search items first\n            //     if (a.item[0].v.startsWith('Search: ')) {\n            //         if (b.item[0].v.startsWith('Search: ')) {\n            //             return b.score - a.score;\n            //         }\n            //         return -1;\n            //     }\n            //     if (b.item[0].v.startsWith('Search: ')) {\n            //         return 1;\n            //     }\n            //     return a.score - b.score;\n            // }\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    inSearchMode() {\n        return this.searchMode !== null;\n    }\n\n\t/**\n     * This converts this.paletteData into a list of paletteListItems in this.paletteItems\n     *\n     * It also builds the itemIndex\n     */\n    buildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n            li.appendChild(a);\n            if (item.actionType === 'url') {\n                a.href = item.action;\n                let title = item.title;\n                if (item.parentTitle) {\n                    title = item.parentTitle + \": \" + title;\n                }\n                a.innerHTML = title;\n            } else if (item.actionType === 'search-mode') {\n                a.href = '#';\n                a.innerHTML = item.title;\n                li.dataset.actionType = item.actionType;\n                li.dataset.searchMode = item.action.searchMode;\n            }\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    /**\n     * Clears and sets the content items\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    setContentItems(contentItems) {\n        this.paletteItems = [];\n        this.itemIndex = [];\n        this.injectContentItems(contentItems, false);\n    }\n\n    /**\n     * Content items have:\n     *  title\n     *  subtype\n     *  url\n     *  (we should also make the sub-menu definable, but that's not done yet)\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    injectContentItems(contentItems, andRunSearch = true) {\n        turboAdminLog('Injecting items');\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(this.injectItem.bind(this));\n        }\n\n        if (andRunSearch) {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        this.updatePaletteItems();\n    }\n\n    /**\n     * Injects a single content item into the palette\n     *\n     * @param {ContentItem} item\n     */\n    injectItem(item) {\n        const itemTitle = item.title;\n        // const itemTitle = item.title.rendered;\n        const itemType = item.subtype;\n        const itemUrl = item.url;\n\n        // turboAdminLog('Adding item: ' + itemTitle);\n\n        // // Check if item already exists\n        if (this.contentItemExists(itemUrl)) {\n            turboAdminLog('Not adding duplicate');\n            return;\n        }\n\n        let title = itemTitle;\n\n        if (itemType) {\n            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;\n            title += ` (${itemTypeName})`;\n        }\n\n        const li = document.createElement('li');\n        const a = document.createElement('a');\n        let subMenu = null;\n\n        // Loop over submenu items OR add link.\n        if (item.submenuItems.length > 0) {\n\n            // Prepare the outer sub-menu elements\n            subMenu = document.createElement('div');\n            const subMenuTitle = document.createElement('div');\n            const subMenuItems = document.createElement('ul');\n            subMenu.classList.add('ta-submenu');\n            subMenuTitle.classList.add('ta-submenu-title');\n\n            subMenuTitle.textContent = this.htmlDecode(itemTitle);\n            subMenuItems.classList.add('ta-submenu-items');\n            subMenu.appendChild(subMenuTitle);\n\n            for (let i = 0; i < item.submenuItems.length; i++) {\n                const subMenuItem = item.submenuItems[i]\n                // TODO: Abstract this so sub-menus can be defined by plugins?\n                const subMenuListItem = document.createElement('li');\n                const subMenuLink = document.createElement('a');\n                subMenuLink.innerText = subMenuItem.title;\n                subMenuLink.href = subMenuItem.url;\n                for (let a = 0; a < subMenuItem.attributes.length; a++) {\n                    subMenuLink.setAttribute(\n                        subMenuItem.attributes[a].name,\n                        subMenuItem.attributes[a].value\n                    )\n                }\n                subMenuListItem.appendChild(subMenuLink);\n                subMenuItems.appendChild(subMenuListItem);\n            }\n\n            // Add the sub-menu items UL to the sub-menu element.\n            subMenu.appendChild(subMenuItems);\n\n            li.classList.add('ta-has-child-menu');\n        }\n\n        a.href = itemUrl;\n        a.innerHTML = title;\n\n        li.appendChild(a);\n        if (subMenu !== null) {\n            li.appendChild(subMenu);\n        }\n\n        this.addPaletteListItem(li);\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n            return;\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else if (this.inSearchMode()) {\n                this.leaveSearchMode();\n            } else {\n                this.hidePalette();\n            }\n            return;\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    /*\n     * Adds the tab hint for a keyword once it has been typed.\n     */\n    maybeHighlightInputKeyword(newKey) {\n        // Do nothing if we are in a search-mode\n        if (this.inSearchMode()) {\n            return;\n        }\n\n        // This is fired on \"keyDown\", so the value isn't update with the new key yet.\n        // But don't do this for special keys, and catch backspace too.\n        let newInputValue = this.paletteInputElement.value;\n        if (newKey.length === 1) {\n            newInputValue += newKey;\n        }\n        if (newKey === 'Backspace') {\n            newInputValue = newInputValue.slice(0, -1);\n        }\n        // turboAdminLog(`Checking palette input value ${newInputValue} for keyword`);\n        if (this.isKeyword(newInputValue)) {\n            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;\n            this.paletteSearchModeTabNotice.classList.add('active');\n        } else {\n            this.unhighlightInputKeyword();\n        }\n    }\n\n    unhighlightInputKeyword() {\n        this.paletteSearchModeTabNotice.classList.remove('active');\n    }\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If we're not in a search mode then search immediately\n        if (! this.inSearchMode()) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n\n        // Cancel the existing timeout\n        clearTimeout(this.debounceTimeout)\n\n        this.debounceTimeout = setTimeout(async function () {\n            // Reset timeout\n            this.debounceTimeout = null;\n\n            // Run the search function\n            await this.paletteSearchAndUpdate();\n        }.bind(this), 750);\n    }\n\n    /**\n     * Check if a string is a search mode keyword\n     *\n     * @param {string} inputString\n     * @returns {boolean}\n     */\n    isKeyword(inputString) {\n        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);\n    }\n\n    /**\n     * Show the palette notice with the specified text\n     *\n     * @param {string} text\n     */\n    showPaletteNotice(text) {\n        this.paletteNoticeElement.classList.add('active');\n        this.paletteNoticeElement.innerText = text;\n    }\n\n    /**\n     * Hide the palette notice\n     */\n    hidePaletteNotice() {\n        this.paletteNoticeElement.classList.remove('active');\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            e.preventDefault();\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n\n        /*\n         * Only the actions above can be done in sub-menus.\n         */\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\n        /*\n         * Check for a keyword being typed and add a UI hint.\n         */\n        this.maybeHighlightInputKeyword(e.key);\n\n        /*\n         * Tabbing looks for a search mode keyword.\n         */\n        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {\n            turboAdminLog('Checking for search mode');\n            let inputValue = this.paletteInputElement.value;\n            if (this.isKeyword(inputValue)) {\n                turboAdminLog('Found search mode ' + inputValue)\n                e.preventDefault();\n                await this.enterSearchMode(\n                    globalThis.turboAdmin.searchModes[inputValue]);\n                return;\n            }\n        }\n\n        /*\n         * Backspace may exit us from a search mode\n         */\n        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {\n            e.preventDefault();\n            this.leaveSearchMode();\n            return;\n        }\n\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n    /**\n     * Puts the palette into a specific search mode - used when a keyword is selected\n     *\n     * @param {SearchMode} searchMode\n     */\n    async enterSearchMode(searchMode) {\n        turboAdminLog('Entering search mode for keyword ' + searchMode.keyword);\n        this.backupPaletteData();\n\n        this.paletteData = [];\n        this.paletteItems = [];\n        this.itemIndex = [];\n\n        // Remove the notice if it's there\n        this.hidePaletteNotice();\n\n        this.searchMode = searchMode;\n        this.paletteInputElement.value = '';\n        this.addSearchModeTag(searchMode.displayName);\n        this.unhighlightInputKeyword();\n        this.updatePaletteItems();\n        // This is similar to code in paletteSearch - maybe we could extract/abstract it?\n        if (searchMode.defaultItemsCallback !== null) {\n            this.paletteInnerElement.classList.add('loading');\n            const results = await searchMode.defaultItemsCallback();\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n    }\n\n    /**\n     * Puts the palette into a specific search mode specified by a keyword\n     *\n     * @param {string} keyword\n     */\n    async enterSearchModeByKeyword(keyword) {\n        turboAdminLog('Entering search mode by keyword ' + keyword);\n        const searchMode = globalThis.turboAdmin.searchModes[keyword];\n        turboAdminLog('Search mode is ' + searchMode);\n        if (searchMode === undefined) {\n            return;\n        }\n        await this.enterSearchMode(searchMode);\n    }\n\n    /**\n     * Leaves the current search mode\n     */\n    leaveSearchMode() {\n        const searchMode = this.searchMode;\n        // It's important what we set this to - see inSearchMode()\n        this.searchMode = null;\n        this.removeSearchModeTag();\n        this.restorePaletteData();\n    }\n\n    /**\n     * Backups up the palette data and input value to local variables so that it can be\n     * restored later.\n     */\n    backupPaletteData() {\n        this.paletteDataBackup = this.paletteData;\n        this.paletteItemsBackup = this.paletteItems;\n        this.paletteItemIndexBackup = this.itemIndex;\n        this.paletteInputValueBackup = this.paletteInputElement.value;\n    }\n\n    /**\n     * Restores the save palette data - highlights and rebuilds\n     */\n    restorePaletteData() {\n        this.paletteData = this.paletteDataBackup;\n        this.paletteItems = this.paletteItemsBackup;\n        this.itemIndex = this.paletteItemIndexBackup;\n        this.paletteInputElement.value = this.paletteInputValueBackup;\n        this.maybeHighlightInputKeyword('');\n        this.paletteSearchAndUpdate();\n    }\n\n    /**\n     * Adds the search mode tag with the specified title.\n     *\n     * @param {string} title\n     */\n    addSearchModeTag(title) {\n        this.paletteSearchModeTag.classList.add('active');\n        this.paletteSearchModeTag.innerText = title;\n    }\n\n    /**\n     * Removes the search mode tag\n     */\n    removeSearchModeTag() {\n        this.paletteSearchModeTag.classList.remove('active');\n    }\n\n    isPaletteOpen() {\n        return this.paletteElement?.classList.contains('active');\n    }\n\n\tshowPalette() {\n        // Bail if already shown (this can be triggered by a focus event)\n        if (this.isPaletteOpen()) {\n            return;\n        }\n\n        this.paletteInputElement.value = '';\n\t\tthis.paletteInputElement?.focus();\n\t\tthis.paletteElement?.classList.add('active');\n        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when\n        // the palette opens.\n        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n        if (this.searchMode !== null) {\n            this.leaveSearchMode();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;\n        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + \"px\";\n        this.paletteSubmenuContainerElement.classList.add('active');\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        this.paletteSubmenuContainerElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsContainerElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n        if (this.selectedItem.dataset.actionType === 'search-mode') {\n            this.enterSearchModeByKeyword(this.selectedItem.dataset.searchMode);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        // link.href will be interpolated by the browser, so if it's empty it will be the current page\n        // use getAttribute instead to work out if its empty\n        if (link.getAttribute('href') === '') {\n            return;\n        }\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        if (! this.searchMode) {\n            this.buildPaletteItems();\n\n            if (this.paletteInputElement.value !== '') {\n                // Reset the search to work on the new items\n                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n            }\n            return;\n        }\n\n        if (this.paletteInputElement.value.length === 0) {\n            this.paletteInnerElement.classList.add('loading');\n            let results = [];\n            if (this.searchMode.defaultItemsCallback !== null) {\n                results = await this.searchMode.defaultItemsCallback();\n            }\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        } else {\n            // This is copied to enterSearchMode. Should probably be extracted.\n            this.paletteInnerElement.classList.add('loading');\n            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n\n        /**\n         * OLD CODE BELOW\n         */\n        // Content search - don't search everything!\n        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n        //     this.paletteInnerElement.classList.add('loading');\n\n        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)\n        //         .then(\n        //             results => {\n        //                     this.injectContentItems(results);\n        //                     this.paletteInnerElement.classList.remove('loading');\n        //             }\n        //         )\n        // }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "/**\n * An item definition specifies how to detect a palette item from the Dashboard's Dom\n *\n * These are all processed on initialisation to generate menu items.\n *\n * Note that a single definition may generate multiple menu items if the selectors used\n * discover multiple items.\n */\nexport default class ItemDefinition {\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuItemCallback\n    * @param {HTMLElement} element\n    * @returns {string}\n    */\n\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuActionInfoCallback\n    * @param {HTMLElement} element\n    * @returns {Object}\n    */\n\n    /**\n     * The method of detecting items. Can be:\n     *  - 'dom' for checking if a DOM element exists (requires detectSelector or detectSelectorNone)\n     *  - 'url' if the current URL is being checked (requires detectPattern)\n     *  - 'none' if no detection is required - this item will always be added\n     *\n     * @type {string}\n     */\n    detectType = 'dom';\n\n    /**\n     * [OPTIONAL] A CSS selector used to find items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelector = '';\n\n    /**\n     * [OPTIONAL] A CSS selector used to check for an absence of items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelectorNone = '';\n\n    /**\n     * [OPTIONAL] A string to find in the current URL to detect the item\n     *\n     * @type {string}\n     */\n    detectPattern = '';\n\n    /**\n     * A callback used to generate a menu item title from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemTitleFunction = null;\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     *\n     * @type {string}\n     */\n    itemActionType = 'url';\n\n    /**\n     * A callback used to generate a menu item link URL from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemUrlFunction = null;\n\n    /**\n     * A callback used to generate an object containing data used by the specified action type.\n     *\n     * For 'search-mode' the object should be like { searchMode: '<keyword>' }\n     *\n     * @type {menuActionInfoCallback|null}\n     */\n    itemActionInfoFunction = null;\n\n     /**\n      * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n      *\n      * @type {boolean}\n      */\n     noCache = false;\n}\n", "import ItemDefinition from \"./class-item-definition\";\n\n/**\n * Menu items are the items ready to appear in the palette.\n *\n * These are standard items, not content items. Though this should probably be standardised.\n */\nexport default class TurboAdminMenuItem {\n\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     */\n    actionType = 'url';\n\n    /**\n     * The action of the item is the URL to visit when the item is clicked or the action data\n     * if the action type is not 'url'\n     *\n     * @type {string|Object}\n     */\n    action = '';\n\n    /**\n     * The parent title is the title of the parent item under which the current item\n     * was found in the WordPress menu.\n     *\n     * e.g. in Posts -> Add Post, \"Posts\" is the parent item.\n     *\n     * @type {string}\n     */\n    parentTitle = '';\n\n    /**\n     * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n     *\n     * @type {boolean}\n     */\n    noCache = false;\n\n    /**\n     * Creates a new simple menu item (only works for URLs - for more complex items use fromItemDefinition)\n     *\n     * @param {string} title\n     * @param {string} action\n     * @param {string} parentTitle\n     * @param {boolean} noCache\n     */\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n        this.actionType = 'url';\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    /**\n     * Construct a new menu item from an ItemDefinition\n     *\n     * @param {ItemDefinition} item\n     * @param {HTMLElement} element\n     * @param {string} parentTitle\n     * @return {TurboAdminMenuItem}\n     */\n    static fromItemDefinition(item, element = null, parentTitle = '') {\n        const action = item.itemActionType === 'url' ?\n            item.itemUrlFunction(element) :\n            item.itemActionInfoFunction(element);\n\n        const menuItem = new TurboAdminMenuItem(\n            item.itemTitleFunction(element),\n            action,\n            parentTitle,\n            item?.noCache\n        );\n        menuItem.actionType = item.itemActionType;\n        return menuItem;\n    }\n\n    /**\n     * Compares this item to another item\n     *\n     * @param {TurboAdminMenuItem} item\n     * @returns {boolean}\n     */\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if (this.inExtension()) {\n            this.store = chrome.storage.local;\n        } else {\n            this.store = window.localStorage;\n        }\n    }\n\n    /**\n     * Returns true if we are in the extension.\n     */\n    inExtension() {\n        return window.turboAdminIsExtension();\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if (this.inExtension()) {\n            await this.store.set(dataObject);\n        } else {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if (this.inExtension()) {\n            return await this.store.get(key);\n        } else {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        }\n    }\n}\n", "import Storage from '../class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // turboAdminLog('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n        this.postTypes = [];\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        turboAdminLog('Discovering API root');\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n        // This should be very rare. I should only really see it in development.\n        turboAdminLog('API Route Discovery failed');\n        // Making best guess\n        this.apiBase = globalThis.taWp.home + '/wp-json/wp/v2/';\n        // TODO: This can't display as the palette isn't created yet.\n        // globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Can\\'t find the WP API. Try visiting the dashboard to refresh things.');\n    }\n\n    async discoverPostTypes() {\n        turboAdminLog('Discovering post types');\n        if (! this.active) {\n            turboAdminLog('Not active');\n            this.postTypes = [];\n            return;\n        }\n\n        const postTypes = await this.store.get('ta-post-types');\n\n        // Check local storage cache\n        if (postTypes && postTypes['ta-post-types'] && postTypes['ta-post-types']['expiry'] > Date.now()) {\n            turboAdminLog('Using cached post types: ', postTypes['ta-post-types']['data']);\n            this.postTypes = postTypes['ta-post-types']['data'];\n            return;\n        }\n\n        this.postTypes = await this.getPostTypes();\n        turboAdminLog('Discovered post types: ', this.postTypes);\n\n        // Cache for 10 minutes\n        const expiry = Date.now() + (10 * 60 * 1000);\n        this.store.set({\n            'ta-post-types': {\n                expiry: expiry,\n                data: this.postTypes\n            }\n        });\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    async getPostTypes() {\n        // Check the cache\n        if (undefined !== this.cache['postsTypes']) {\n            return this.cache['postTypes'];\n        }\n\n        // Fetch results\n        const response = await this.get('types');\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['postTypes'] = result;\n\n        return result;\n    }\n\n    async getPosts(searchString, postType = 'any') {\n        // Check the cache\n        const cacheKey =  `posts-${postType}-${searchString}`;\n        if (undefined !== this.cache[cacheKey]) {\n            return this.cache[cacheKey];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: postType\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[cacheKey] = result;\n\n        return result;\n    }\n\n    /**\n     * We can't use the API to get a post of any post type. So we hack this a bit.\n     *\n     * @param {number} postId\n     * @returns {Promise<any>}\n     */\n    async doesPostExist(postId) {\n        // Check the cache\n        if (undefined !== this.cache['post-' + postId]) {\n            return this.cache['post-' + postId];\n        }\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);\n\n        this.cache['post-' + postId] = response;\n\n        return response?.status === 200;\n    }\n\n    async getPlugins(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['plugins-' + searchString]) {\n            return this.cache['plugins-' + searchString];\n        }\n\n        let requestOptions = {};\n\n        if (searchString) {\n            requestOptions.search = searchString;\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"plugins\",\n            requestOptions\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['plugins-' + searchString] = result;\n\n        return result;\n    }\n\n    async getUsers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['users-' + searchString]) {\n            return this.cache['users-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"users\",\n            {\n                search: searchString,\n                per_page: 100,\n                context: 'edit' // view / embed / edit\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['users-' + searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`, init);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WordPress API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog( 'TURBO ADMIN: WordPress API Error. Try visiting the WordPress Dashboard to refresh things.' );\n            }\n        }\n\n        return response;\n    }\n\n}\n", "export default class SubmenuItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title;\n\n    /**\n     * The URL of the item\n     * @type {string}\n     */\n    url;\n\n    /**\n     * A list of attributes to go on the A tag (not the LI tag)\n     *\n     * @type {array}\n     */\n    attributes = [];\n\n    /**\n     * Create a submenu item\n     *\n     * @param {string} title The title of the item\n     * @param {string} url The URL of the item\n     */\n    constructor(title, url) {\n        this.title = title;\n        this.url = url;\n    }\n\n    /**\n     * Add an attribute\n     *\n     * @param {string} name The attribute name\n     * @param {string} value The attribute value\n     */\n    addAttribute(name, value) {\n        this.attributes.push({\n            name: name,\n            value: value\n        });\n    }\n}\n", "import SubmenuItem from \"./class-submenu-item\";\n\nexport default class ContentItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The subtype of the item. e.g. for posts, this will be the post type.\n     * Used to display extra information about the item.\n     *\n     * @type {string}\n     */\n    subtype = '';\n\n    /**\n     * The URL of the item. Leave empty if there is a sub-menu.\n     *\n     * @type {string}\n     */\n    url = '';\n\n    /**\n     * The sub-menu items, if any.\n     *\n     * This should be an empty array if the item itself has a URL\n     *\n     * @type {SubmenuItem[]}\n     */\n    submenuItems = [];\n}\n", "import ContentItem from \"./class-content-item\";\n\nexport default class SearchMode {\n    /**\n     * The keyword string used to initiate the search\n     *\n     * @type {string}\n     */\n    keyword = '';\n\n    /**\n     * The dispay name used for the search\n     *\n     * @type {string}\n     */\n    displayName = '';\n\n    /**\n     * jsDoc defintion for a `searchCallback`\n     *\n     * @callback SearchCallback\n     * @param {string} [searchString]\n     * @returns {Promise<ContentItem[]>}\n     */\n\n    /**\n     * Callback to get search items\n     *\n     * @type {SearchCallback}\n     */\n    searchCallback;\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @type {SearchCallback|null}\n     */\n    defaultItemsCallback = null;\n\n    /**\n     * Set this to false to hide the search mode from the palette - it still\n     * works with a keyword, but won't show in the palette's list of items\n     *\n     * @type {boolean}\n     */\n    showInPaletteSearch = true;\n\n    /**\n     * Constructs a new search mode\n     *\n     * @param {string} keyword\n     * @param {string} displayName\n     * @param {SearchCallback} searchCallback\n     * @param {SearchCallback} defaultItemsCallback\n     * @param {boolean} showInPaletteSearch\n     */\n    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null, showInPaletteSearch = true) {\n        this.keyword = keyword;\n        this.displayName = displayName;\n        this.searchCallback = searchCallback;\n        this.defaultItemsCallback = defaultItemsCallback;\n        this.showInPaletteSearch = showInPaletteSearch;\n    }\n}\n", "import SearchMode from \"./class-search-mode\";\nimport ItemDefinition from \"./class-item-definition\";\n\n/**\n * This is an abstract class that should be extended by plugins\n * @module TurboAdminPlugin\n */\nexport default class TurboAdminPlugin {\n    /** @type {string} */\n    name = '';\n\n    /** @type {SearchMode[]} */\n    searchModes = [];\n\n    /** @type {boolean} */\n    activated = false;\n\n    constructor(pluginName) {\n        this.name = pluginName;\n        this.registerPlugin();\n    }\n\n    /**\n     * Register the plugin with Turbo Admin\n     */\n    registerPlugin() {\n        turboAdminLog('Inside plugin - requested registration of ' + this.name);\n        globalThis.turboAdmin.registerPlugin(this);\n    }\n\n    /**\n     * Returns true if the plugin should activate\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return false;\n    }\n\n    /**\n     * Activates the plugin\n     * @return {void}\n     */\n    activate() {\n        this.activated = true;\n        this.registerSearchModes();\n    }\n\n    /**\n     * Register the search keywords with Turbo Admin - each will be registered\n     * with the whole plugin object.\n     */\n    registerSearchModes() {\n        this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);\n    }\n\n    /**\n     * Get the item definitions for search modes.\n     *\n     * Note that , at time of writing, this runs AFTER API init but before the plugin is activated.\n     * So APIs are available (and may be used in shouldActivate()) but the plugin is not yet activated.\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getSearchModeItemDefinitions() {\n        if (!this.shouldActivate()) {\n            return [];\n        }\n\n        const searchModeItems = this.searchModes.map(searchMode => {\n            // Return null if we don't want to show this search mode in the palette.\n            if (searchMode.showInPaletteSearch === false) {\n                return null;\n            }\n            const item = new ItemDefinition();\n            item.detectType = 'none';\n            item.itemTitleFunction = () => `<span style=\"font-style:italic;\">Search</span>: ${searchMode.displayName}`;\n            item.itemActionType = 'search-mode';\n            item.itemActionInfoFunction = () => { return { searchMode: searchMode.keyword } };\n            return item;\n        })\n        // Filter out the nulls.\n        return searchModeItems.filter( item => item !== null);\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getAdditionalItemDefinitions() {\n        if (!this.activated) {\n            return [];\n        }\n\n        return [];\n    }\n\n    /**\n     * Save plugin setting to persistent storage\n     */\n    saveSetting(key, value) {\n\n    }\n\n}\n", "/**\n * It's impossible to change the setting to off, because the\n * extension's content script runs in a sandbox and can't access\n * the wp object. But we can just toggle the class every time.\n */\nexport default class TurboAdminWpBlockEditorFullscreenKill {\n\n    constructor() {\n\n        // Don't run on the site editor screen\n        if (document.body.classList.contains( 'site-editor-php' )) {\n            return;\n        }\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed fullscreen\n                // if (document.body.classList.contains('turbo-admin-killed-fullscreen')) {\n                //     return;\n                // }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (mu.target.classList.contains('is-fullscreen-mode')) {\n                    this.killFullScreenEditor();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killFullScreenEditor();\n    }\n\n    killFullScreenEditor() {\n        if (! document.body.classList.contains('is-fullscreen-mode')) {\n            return;\n        }\n\n        document.body.classList.remove('is-fullscreen-mode');\n        document.body.classList.add('turbo-admin-killed-fullscreen');\n\n        const newStyles = document.createElement('style');\n        newStyles.innerHTML = \"body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }\";\n        document.body.appendChild(newStyles);\n    }\n}\n", "/**\n *\n */\nexport default class TurboAdminWpBlockEditorWelcomeGuideKill {\n\n    constructor() {\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed the modal\n                if (document.body.classList.contains('ta-killed-post-welcome-guide')) {\n                    return;\n                }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (! mu.target.classList.contains('modal-open')) {\n                    return;\n                }\n\n                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n                if (welcomeGuide) {\n                    this.killWelcomeGuide();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killWelcomeGuide();\n    }\n\n    killWelcomeGuide() {\n        const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n        if (welcomeGuide) {\n            const closeButton = welcomeGuide.querySelector('.components-modal__header button');\n            if (closeButton) {\n                closeButton.click();\n                /*\n                 * Also add a class to body so we don't do it again - subsequent modals\n                 * will need to be shown as they will have been user-initiated.\n                 */\n                document.body.classList.add('ta-killed-post-welcome-guide');\n            }\n        }\n    }\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            '.notice-success',\n            '.notice-error',\n            '.notice-failure',\n            '.updated',\n        ]\n\n        this.noticesPanelInner = null;\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nturboAdminLog('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nturboAdminLog('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice);\n            this.maybeAddMoveButtonToNotice.call(this, notice);\n        });\n\n        const noticesToHide = Array.from(notices).filter( this.noticeShouldBeHidden.bind(this) );\n\n        turboAdminLog('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        this.noticesPanelInner = document.createElement('div');\n        this.noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(this.hideNotice.bind(this));\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(this.noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n\n        // Add a mutation observer to check for notices added by JavaScript\n        // this.addObserver();\n    }\n\n    addObserver() {\n        const observer = new MutationObserver( this.handleMutations.bind(this) );\n        observer.observe(document.getElementById('wpbody-content'), {\n            childList: true,\n            subtree: true\n        });\n    }\n\n    handleMutations(mutations, observer) {\n        mutations.forEach( mutation => {\n            if (mutation.type === 'childList') {\n                mutation.addedNodes.forEach( node => {\n                    if (node.nodeType === Node.ELEMENT_NODE) {\n                        console.log('MUTATING!!!' + node.id);\n                        // this.maybeAddIdToNotice(node);\n                        // this.maybeAddMoveButtonToNotice(node);\n                        // this.maybeHideNotice(node);\n                    }\n                });\n            }\n        });\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return noticeElem.matches(this.allowedClasses.join(', '));\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    noticeShouldBeHidden(notice) {\n        if (this.rememberedNoticeIds.includes(notice.id)) {\n            return true;\n        }\n\n        if (this.keepNotice(notice)) {\n            return false;\n        }\n\n        // Invisible\n        if (\n            notice.offsetHeight === 0 ||\n            notice.offsetWidth === 0\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(noticeElem) {\n        if (noticeElem.id && noticeElem.id !== '' && noticeElem.id !=='message') {\n            return;\n        }\n\n        const classes = noticeElem.classList;\n        noticeElem.id = Array.from(noticeElem.classList).join('-');\n    }\n\n    /**\n     * Add buttons to notices that we want to be able to move to the panel\n     */\n    maybeAddMoveButtonToNotice(noticeElem) {\n        if (this.keepNotice(noticeElem)) {\n            const rememberButton = document.createElement('button');\n            rememberButton.classList.add('ta-remember-notice-button');\n            rememberButton.innerText = 'Move to panel';\n\n            const forgetButton = document.createElement('button');\n            forgetButton.classList.add('ta-forget-notice-button');\n            forgetButton.innerText = 'Move to dashboard';\n\n            noticeElem.classList.add('ta-added-pos-relative');\n\n            noticeElem.appendChild(rememberButton);\n            noticeElem.appendChild(forgetButton);\n\n            rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n            forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n        }\n    }\n\n    maybeHideNotice(noticeElem) {\n        if (this.noticeShouldBeHidden(noticeElem) && !noticeElem.classList.contains('ta-notice-hidden')) {\n            this.hideNotice(noticeElem);\n        }\n    }\n\n    hideNotice(noticeElem) {\n        noticeElem.classList.add('ta-notice-hidden');\n        // WPCore's common.js will re-add the notice below the dashboard header unless it has a .inline class.\n        // It does: $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );\n        noticeElem.classList.add('inline');\n        // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n        this.noticesPanelInner.append(noticeElem);\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        if (! this.listTable) {\n            return;\n        }\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        document.addEventListener('keyup', e => this.handleKeyup(e));\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKeyup(ev) {\n        if (document.activeElement.tagName !== 'BODY') {\n            return;\n        }\n\n        if (ev.key === 'j') {\n            this.tableMoveDown();\n        } else if (ev.key === 'k') {\n            this.tableMoveUp();\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            this.openTableRowItem();\n        }\n\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else if (this.currentRowIndex < this.tableRows.length - 1) {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n        }\n\n        this.updateTable();\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n    }\n\n    openTableRowItem() {\n        turboAdminLog(this);\n        /** @type {HTMLAnchorElement} */\n        const link = this.currentRow.querySelector('a.row-title');\n        if (link) {\n            link.click();\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\n\nexport default class TurboAdminBarkeeper extends TurboAdminPlugin {\n    constructor() {\n        super('Barkeeper');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        if (true !== globalThis.turboAdmin.options['barkeeper']) {\n            return false;\n        }\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return false;\n        }\n        // Bail if we don't have the left-hand admin bar (some users only have right-hand side)\n        if (! document.getElementById('wp-admin-bar-root-default')) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.selectorsToHide = [\n            '#wp-admin-bar-root-default > li',\n            '.monsterinsights-adminbar-menu-item',\n        ];\n\n        this.barkeeperState = this.getBarkeeperState();\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        if (! this.root) {\n            return;\n        }\n        this.itemsToHide = document.querySelectorAll( this.selectorsToHide.join(', ') );\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            this.setBarkeeperState(this.barkeeperState);\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n\n        this.setupObserver();\n    }\n\n    /**\n     * Some awkward plugins add themselves into the bar using JS\n     */\n    setupObserver() {\n        this.observer = new MutationObserver( mutations => {\n            mutations.forEach( mutation => {\n                if (mutation.type === 'childList') {\n                    mutation.addedNodes.forEach( node => {\n                        if (node.classList && node.classList.contains('ta-barkeeper-collapsable')) {\n                            return;\n                        }\n                        if (node.id && this.exclusionIds.includes(node.id)) {\n                            return;\n                        }\n                        // Check is the node matches any of the selectors\n                        if (node.matches(this.selectorsToHide.join(', '))) {\n                            node.classList.add('ta-barkeeper-collapsable');\n                            return;\n                        }\n                    });\n                }\n            });\n        });\n\n        this.observer.observe(this.root, {\n            childList: true,\n            subtree: true,\n        });\n    }\n\n    getBarkeeperState() {\n        if (window.turboAdminIsExtension()) {\n            return globalThis.turboAdmin.options['barkeeper-state'];\n        } else {\n            return window.localStorage.getItem('turbo-admin-barkeeper-state');\n        }\n    }\n\n    setBarkeeperState(state) {\n        if (window.turboAdminIsExtension()) {\n            chrome.runtime.sendMessage({\n                'action': 'barkeeperSetState',\n                'barkeeperState': this.barkeeperState,\n            });\n        } else {\n            window.localStorage.setItem('turbo-admin-barkeeper-state', state);\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminContentSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Content');\n\n        const ignoredPostTypes = [\n            'nav_menu_item',\n            'wp_block',\n            'wp_template',\n            'wp_template_part',\n            'wp_navigation',\n        ];\n\n        const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);\n\n        // Discard ignored post types\n        const filteredPostTypeKeys = postTypeKeys.filter(key => ! ignoredPostTypes.includes(key));\n\n        // Register a search mode for each post type\n        for (let i = 0; i < filteredPostTypeKeys.length; i++) {\n            const thisPostTypeKey = filteredPostTypeKeys[i];\n            const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];\n            // turboAdminLog('Adding search mode for post type', thisPostType);\n            this.searchModes.push( this.makePostTypeSearchMode(thisPostType) );\n        }\n\n        // Register ID search mode\n        this.searchModes.push( new SearchMode('id', 'Post ID', this.postById.bind(this)) );\n\n        // Register search all post types mode\n        this.searchModes.push( new SearchMode('search', 'All post types', this.contentSearch.bind(this)) );\n        // Don't show this one in the palette\n        this.searchModes.push( new SearchMode('find', 'All post types', this.contentSearch.bind(this), null, false) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * This is a generator for a post-type specific SearchMode object\n     *\n     * @param {Object} postType\n     */\n    makePostTypeSearchMode(postType) {\n        // TODO: interpret the post type name\n        return new SearchMode(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));\n    }\n\n    /**\n     * @param {string} searchString\n     * @param {string} postType This is passed to the API as a subtype. 'any' by default.\n     * @returns {Promise<ContentItem[]>}\n     */\n    async contentSearch(searchString, postType = 'any') {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPosts(searchString, postType);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = result.title;\n                            item.subtype = result.subtype;\n                            item.url = result.url;\n\n                            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item))\n\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} postId\n     * @returns {Promise<ContentItem[]>}\n     */\n    async postById(postId) {\n        if (! postId.trim().match(/^\\d+$/)) {\n            return [];\n        }\n        const postExists = await globalThis.contentApi.doesPostExist(postId);\n\n        const resultAsContentItem = new ContentItem;\n\n        if (! postExists) {\n            resultAsContentItem.title = 'Post does not exist or is not visible';\n            return [ resultAsContentItem ];\n        }\n\n        resultAsContentItem.title = `Post ID: ${postId}`;\n        resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;\n\n        resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));\n\n        return [ resultAsContentItem ];\n    }\n\n    /**\n     * Makes an array of submenu items from a content item\n     *\n     * @param {number} postId\n     * @param {ContentItem} contentItem\n     * @returns {SubmenuItem[]}\n      */\n    makeSubmenuItems(postId, contentItem) {\n        const itemsToReturn = [];\n        itemsToReturn.push(\n            new SubmenuItem(\n                'View',\n                contentItem.url\n            )\n        );\n\n        // TODO: Make a better way to detect if we are logged in.\n        if (globalThis.turboAdmin.turboAdminPalette.profileLink) {\n            // Need to get edit URL. This seems like the best way for now.\n            const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;\n            itemsToReturn.push(\n                new SubmenuItem(\n                    'Edit',\n                    editLink\n                )\n            )\n\n            // Add oxygen link if needed.\n            if (globalThis.turboAdmin.hasActivatedPlugin('OxygenBuilder')) {\n                const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;\n                itemsToReturn.push(\n                    new SubmenuItem(\n                        'Edit with Oxygen',\n                        oxygenLink\n                    )\n                );\n            }\n        }\n\n        const copyLinkItem = new SubmenuItem( 'Copy link', contentItem.url);\n        copyLinkItem.addAttribute('data-action', 'clipboard')\n        itemsToReturn.push(copyLinkItem);\n\n        return itemsToReturn;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminPluginSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Plugins');\n\n        this.searchModes.push( new SearchMode('plugin', 'Plugins', this.pluginSearch, this.defaultPluginItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultPluginItems() {\n        return await this.pluginSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async pluginSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPlugins(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            // siteUrl is at globalThis.turboAdmin.wp.siteUrl\n                            const item = new ContentItem;\n                            item.title = result.name;\n                            item.subtype = 'Plugin';\n                            // TODO: Maybe set this to be a search on the plugin screen?\n                            // Plugin \"slug\" is in result.name\n\n                            const itemViewUrlParams = new URLSearchParams();\n                            itemViewUrlParams.set('plugin_status', 'all');\n                            itemViewUrlParams.set('s', result.name);\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'View',\n                                    globalThis.taWp.siteUrl + '/plugins.php?' + itemViewUrlParams.toString()\n                                )\n                            );\n                            // Activate: /wp-admin/plugins.php?action=activate&plugin=order-simulator-woocommerce%2Fwoocommerce-order-simulator.php&plugin_status=all&paged=1&s&_wpnonce=3714a01759\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\n\nexport default class TurboAdminUserSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Users');\n\n        this.searchModes.push( new SearchMode('user', 'Users', this.userSearch, this.defaultUserItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultUserItems() {\n        return await this.userSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async userSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getUsers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            if (result.first_name && result.last_name) {\n                                item.title = `${result.first_name} ${result.last_name} - `;\n                            }\n                            item.title += result.email;\n                            item.subtype = result.roles[0];\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminWoocommerce extends TurboAdminPlugin {\n    constructor() {\n        super('WooCommerce');\n\n        this.searchModes.push( new SearchMode('order', 'Orders', this.orderSearch) );\n        this.searchModes.push( new SearchMode('customer', 'Customers', this.customerSearch) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of WooCommerce in Dashboard\n        /** @type {HTMLElement|string|Number} */\n        let woocommerceMenuElement = document.getElementById('toplevel_page_ct_dashboard_page');\n\n        // Also check for a menu bar item\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = document.getElementById('wp-admin-bar-new-shop_order');\n        }\n\n        // Check to see if WooCommerce flag is cached\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasWooCommerce = Boolean(woocommerceMenuElement);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-woocommerce', hasWooCommerce ? '1' : '0' );\n\n        return globalThis.contentApi.active && hasWooCommerce;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async orderSearch(searchString) {\n        let results;\n\n        if (searchString.trim().match(/^\\d+$/)) {\n            results = await globalThis.woocommerceApi.getOrder(searchString);\n        } else {\n            results = await globalThis.woocommerceApi.getOrders(searchString);\n        }\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `#${result.number} ${result.currency_symbol}${result.total}`;\n                            item.subtype = result.billing.email;\n                            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async customerSearch(searchString) {\n        const results = await globalThis.woocommerceApi.getCustomers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `${result.billing.first_name} ${result.billing.last_name}`;\n                            item.subtype = result.email;\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Orders',\n                                    globalThis.taWp.siteUrl + `/edit.php?post_status=all&post_type=shop_order&_customer_user=${result.id}`\n                                )\n                            )\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Profile',\n                                    globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`\n                                )\n                            )\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminGravityForms extends TurboAdminPlugin {\n    constructor() {\n        super('GravityForms');\n\n        this.searchModes.push( new SearchMode('form', 'Gravity Forms', this.formSearch, this.defaultFormsList.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return globalThis.contentApi.active &&\n               document.getElementById('wp-admin-bar-gravityforms-new-form') !== null\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultFormsList() {\n        return await this.formSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async formSearch(searchString) {\n        const resultsObject = await globalThis.gravityFormsApi.getForms(searchString);\n        // GF Results are an object rather than an array so we need to convert\n\n        // TODO: Catch the error response (do the TODO in the API class first)\n\n        const resultsArray = [];\n        const resultKeys = Object.keys(resultsObject);\n        for(let k = 0; k < resultKeys.length; k++) {\n            const result = resultsObject[resultKeys[k]];\n            const item = new ContentItem;\n            item.title = `#${result.id} ${result.title}`;\n            item.subtype = `${result.entries} entries`;\n            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Edit Form',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Entries',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_entries&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Form Settings',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=settings&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Confirmatons',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=confirmation&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Notifications',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=notification&id=${result.id}`\n                )\n            )\n\n            turboAdminLog(item);\n\n            resultsArray.push(item);\n        }\n        return resultsArray;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminMUSites extends TurboAdminPlugin {\n    constructor() {\n        super('WP Multisite Sites');\n\n        this.searchModes.push( new SearchMode('site', 'Sites', this.siteSearch.bind(this), this.defaultSiteItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return Boolean(document.querySelector('#wp-admin-bar-my-sites'));\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultSiteItems() {\n        return await this.siteSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async siteSearch(searchString) {\n        // {\n        //     'detectType': 'dom',\n        //     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n        //     'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n        //     'itemUrlFunction': (element) => element.href\n        // },\n\n        const sites = document.querySelectorAll('#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li');\n\n        if (sites.length === 0) {\n            return [];\n        }\n\n        const sitesArray = Array.from(sites);\n        const sitesLinks = sitesArray.map(site => site.querySelector('a'));\n        const filteredSites = sitesLinks.filter(site => site.innerText.toLowerCase().includes(searchString.toLowerCase()));\n\n        return filteredSites.map(site => {\n            const item = new ContentItem;\n            item.title = site.innerText;\n            item.subtype = 'Site';\n            item.url = site.href;\n\n            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));\n\n            return item;\n        });\n    }\n\n    makeSubmenuItems(siteElement) {\n        const submenuItems = [];\n\n        const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);\n        if (! submenu) {\n            return [];\n        }\n\n        const submenuLinks = submenu.querySelectorAll('a');\n        if (submenuLinks.length === 0) {\n            return [];\n        }\n\n        const submenuLinksArray = Array.from(submenuLinks);\n        submenuLinksArray.forEach(link => {\n            const submenuItem = new SubmenuItem(link.innerText, link.href);\n            submenuItems.push(submenuItem);\n        });\n\n        return submenuItems;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\nimport ItemDefinition from '../types/class-item-definition.js';\n\nexport default class TurboAdminOxygenBuilder extends TurboAdminPlugin {\n    constructor() {\n        super('OxygenBuilder');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasOxygenBuilder = Boolean(oxygenLinkElem);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', hasOxygenBuilder ? '1' : '0' );\n\n        return hasOxygenBuilder;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n     async getAdditionalItemDefinitions() {\n        const editDefinition = new ItemDefinition();\n        editDefinition.detectType = 'dom';\n        editDefinition.detectSelector = '#ct-edit-template-builder';\n        editDefinition.itemTitleFunction = () => 'Edit with Oxygen';\n        editDefinition.itemUrlFunction = (element) => element.href;\n        editDefinition.noCache = true;\n\n        // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n        // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n        // doesn't refresh the menu items.\n        const backToWpDefinition = new ItemDefinition();\n        backToWpDefinition.detectType = 'dom';\n        backToWpDefinition.detectSelector = '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)';\n        backToWpDefinition.itemTitleFunction = (element) => 'Back to WP: ' + element.textContent;\n        backToWpDefinition.itemUrlFunction = (element) => {\n            if (element.href) {\n                return element.href;\n            } else {\n                let url = new URL(window.location.href);\n                return url.origin + url.pathname;\n            }\n        };\n        backToWpDefinition.noCache = true;\n\n        return [\n            editDefinition,\n            backToWpDefinition,\n        ];\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\n\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';\nimport SearchMode from './types/class-search-mode.js';\nimport TurboAdminPlugin from './types/class-turbo-admin-plugin.js';\nimport Acf from './plugins/class-acf.js';\nimport TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\nimport TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';\nimport TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';\nimport TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';\nimport TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';\nimport TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';\nimport TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';\nimport TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';\nimport TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';\n\nexport default class TurboAdmin {\n\n    /**\n     * @param {*} options\n     * @returns {TurboAdmin}\n     */\n    constructor(options) {\n        // Sometimes we get a second copy of TA running, like if the plugin is running too.\n        // Is this case we want to skip the initialisation.\n        this.doInit = true;\n\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            this.doInit = false;\n            return globalThis.turboAdmin;\n        }\n\n        this.options = options;\n        this.plugins = {};\n\n        // TODO: Something? What should this type be?\n        this.searchModes = {};\n\n        // On the front end we set this if there is no saved menu.\n        this.menuNeedsRefresh = false;\n    }\n\n    /**\n     * Perform initialization - this is all the things that do not need APIs to\n     * get set up.\n     */\n    async init() {\n        if (! this.doInit) {\n            return;\n        }\n\n        // Register all the plugins\n        new TurboAdminBarkeeper();\n        new TurboAdminContentSearch();\n        new TurboAdminPluginSearch();\n        new TurboAdminUserSearch();\n        new TurboAdminMUSites();\n        new TurboAdminOxygenBuilder();\n\n        if (window.turboAdminIsExtension()) {\n            new TurboAdminWoocommerce();\n            new TurboAdminGravityForms();\n        }\n\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Check for .logged-in class on body - if logged in, we can use the saved menu,\n                // if it exists.\n                if (document.body.classList.contains('logged-in')) {\n                    // Get from localStorage\n                    const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                    // This attempts to see if we have cached items from the back-en\n                    if (null === savedMenu) {\n                        this.menuNeedsRefresh = true;\n                    } else {\n                        this.menu = JSON.parse(savedMenu);\n                        // Check if there is no \"Media\" item  - this should ONLY be in the back-end\n                        if (! this.menu.some(item => ( ( typeof(item.action) === 'string' ) && ( item.action.endsWith('upload.php') ) ))) {\n                            this.menuNeedsRefresh = true;\n                        }\n                        // Merge (?) the items?\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        await this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n    }\n\n    /**\n     * These are initialization steps that DO needs APIs to be set up.\n     */\n    activatePlugins() {\n        // Initialize all plugins\n        Object.keys(this.plugins).forEach( plugin => {\n            if (this.plugins[plugin].shouldActivate()) {\n                this.plugins[plugin].activate();\n            }\n        })\n\n        if (true === this.options['block-editor-fullscreen-disable']) {\n            // Initialise fullscreen kill\n            this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        }\n\n        if (true === this.options['block-editor-welcome-screen-kill']) {\n            this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    /**\n     * True if the plugin has been activated\n     *\n     * @param {string} name Name of the plugin to check for\n     * @returns {boolean}\n     */\n    hasActivatedPlugin(name) {\n        return Object.keys(this.plugins).includes(name) &&\n            this.plugins[name].activated;\n    }\n\n    /**\n     * Gather the WordPress dashboard admin (sidebar) menu items\n     *\n     * @returns { TurboAdminMenuItem[] }\n     */\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    /**\n     * Adds additional menu items passed in by configuration to the\n     * menu items list.\n     */\n    async addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.\n        let extraItems = this.options.extraItems ?? [];\n\n        // Get any extra items defined by plugins\n        const pluginKeys = Object.keys(this.plugins);\n\n        for (let i=0; i < pluginKeys.length; i++) {\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getSearchModeItemDefinitions());\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());\n        }\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                // TODO: Convert to ItemDefinition objects\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.siteUrl;\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'none') {\n                detected = true;\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = TurboAdminMenuItem.fromItemDefinition(item, element, '');\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    /**\n     * Builds the palette HTML and adds it to the DOM.\n     */\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Palette notice\n        const paletteNotice = document.createElement('div');\n        paletteNotice.id = 'ta-command-palette-notice';\n        // Tab notice\n        const tabNotice = document.createElement('div');\n        tabNotice.id = 'ta-command-palette-tab-notice';\n        // Tab notice text\n        const tabNoticeText = document.createElement('span');\n        tabNoticeText.id = 'ta-command-palette-tab-notice-text';\n        // Tab notice \"button\"\n        const tabNoticeButton = document.createElement('span');\n        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';\n        tabNoticeButton.innerText = 'Tab';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // Search mode tag\n        const searchModeTag = document.createElement('div');\n        searchModeTag.id = 'ta-command-palette-search-mode-tag';\n        // List container (needed to contain the main list and the submenu list)\n        const listContainer = document.createElement('div');\n        listContainer.id = \"ta-command-palette-items-container\";\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Sub-menu list\n        const submenuContainer = document.createElement('div');\n        submenuContainer.id = \"ta-command-palette-submenu-container\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(searchModeTag);\n        palette.appendChild(paletteNotice);\n        tabNotice.appendChild(tabNoticeText);\n        tabNotice.appendChild(tabNoticeButton);\n        palette.appendChild(tabNotice);\n        palette.appendChild(input);\n        listContainer.appendChild(list);\n        listContainer.appendChild(submenuContainer);\n        palette.appendChild(listContainer);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, listContainer );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    /**\n     * Register a plugin with Turbo Admin\n     *\n     * @param {TurboAdminPlugin} plugin\n     */\n    registerPlugin(plugin) {\n        turboAdminLog('Registering plugin ' + plugin.name);\n        this.plugins[plugin.name] = plugin;\n    }\n\n    /**\n     * Register a palette search mode and its associated plugin\n     *\n     * this is usually bound to the searchMode, so\n     *\n     * @param {SearchMode} searchMode\n     */\n    registerSearchMode(searchMode) {\n        turboAdminLog('Registering search mode with keyword ' + searchMode.keyword);\n        // Don't use `this` as we are bound!\n        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;\n    }\n\n    /**\n     * Returns a string representation of the palette's keyboard shortcut\n     *\n     * @returns { String }\n     */\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key.toUpperCase();\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n            let urlsFound = false;\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                const dashboardLink = document.getElementById('wp-admin-bar-dashboard')?.querySelector('a');\n                if (dashboardLink) {\n                    this.siteUrl = dashboardLink.href;\n                }\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    urlsFound = true;\n                } else {\n                    // We might know what the siteUrl is, so guess the home from the siteUrl\n                    if (this.siteUrl) {\n                        this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                        urlsFound = true;\n                    }\n                }\n            }\n            if (! urlsFound) {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                    urlsFound = true;\n                }\n            }\n            if (! urlsFound) {\n                // We got nothing.\n                this.home    = await this.guessHome();\n                if (this.home) {\n                    this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // turboAdminLog('siteUrl: ', this.siteUrl);\n        // turboAdminLog('home: ', this.home);\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class WoocommerceApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getOrders(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['orders-' + searchString]) {\n            return this.cache['orders-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"orders\",\n            {\n                search: searchString,\n                per_page: 100,\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['orders-' + searchString] = result;\n\n        return result;\n    }\n\n    async getOrder(orderId) {\n        // Check the cache\n        if (undefined !== this.cache['order-' + orderId]) {\n            return this.cache['order-' + orderId];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            `orders/${orderId}`\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        let resultAsArray = [ result ];\n\n        // Store in the cache\n        this.cache['order-' + orderId] = resultAsArray;\n\n        return resultAsArray;\n    }\n\n    async getCustomers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['customers-' + searchString]) {\n            return this.cache['customers-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"customers\",\n            {\n                search: searchString,\n                per_page: 100,\n                role: 'all',\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['customers-' + searchString] = result;\n\n        return result;\n    }\n\n    // TODO: Add docblock and types\n    async wooGet(path, data = {}) {\n        const wooApiBase = globalThis.contentApi.apiRoot + 'wc/v3/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${wooApiBase}${path}/?${params}`, init);\n\n        if ( response.status === 404 ) {\n            return false;\n        }\n        if ( (response.status < 200 || response.status >= 300) ) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WooCommerce API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: WooCommerce API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class GravityFormsApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getForms(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['gf-forms-' + searchString]) {\n            return this.cache['gf-forms-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.gfGet(\n            \"forms\",\n            {}\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // TODO: Trap for errors\n\n        // Filter by search string - the API doesn't do this for us\n        const searchStringLowerCase = searchString.toLowerCase();\n        const formIds = Object.keys(result);\n        for (let k = 0; k < formIds.length; k++) {\n            const thisId = formIds[k];\n            if (! result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {\n                delete result[thisId];\n            }\n        }\n\n        // Store in the cache\n        this.cache['gf-forms-' + searchString] = result;\n\n        return result;\n    }\n\n    async gfGet(path, data = {}) {\n        const gfApiBase = globalThis.contentApi.apiRoot + 'gf/v2/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${gfApiBase}${path}/?${params}`);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Gravity Forms API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: Gravity Forms API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './apis/class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport WoocommerceApi from './apis/class-woocommerce-api.js';\nimport GravityFormsApi from './apis/class-gravity-forms-api.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\nlet debugMode = false;\n\nwindow.turboAdminLog = function() {\n    if (debugMode) {\n        console.log(...arguments);\n    }\n}\n\nwindow.turboAdminIsExtension = function() {\n    return false;\n}\n\n// Use this to clear storage\n// chrome.storage.local.remove(taStorageKey).then();\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    if (typeof(globalThis.turboAdmin) !== 'undefined') {\n        // Already initialised for some reason\n        return;\n    }\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    // Set debug mode\n    debugMode = globalThis.turboAdminOptions['debug-mode'];\n\n    turboAdminLog('Preparing Turbo Admin');\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    turboAdminLog('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n    await globalThis.contentApi.discoverPostTypes();\n    globalThis.woocommerceApi = new WoocommerceApi();\n    globalThis.gravityFormsApi = new GravityFormsApi();\n\n    turboAdminLog('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n    await globalThis.turboAdmin.init();\n\n    // This needs all the APIs to be ready\n    await globalThis.turboAdmin.activatePlugins();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n        'debug-mode': globalThis.wpTurboAdmin['debugMode'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
    5   "mappings": "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",
     4  "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item';\nimport ContentApi from './apis/class-content-api.js';\nimport SearchMode from './types/class-search-mode.js';\nimport ContentItem from './types/class-content-item.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tturboAdminLog('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));\n        /** @type {HTMLSpanElement} */\n        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));\n        /** @type {HTMLDivElement} */\n        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));\n\n\n        // Add a class if the menu needs refreshing with a visit to the Dashboard\n        if (globalThis.turboAdmin.menuNeedsRefresh) {\n            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');\n        }\n\n        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but\n        // works for now.\n        /** @type {HTMLUListElement} */\n        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        /** @type {null|String} */\n        this.profileLink = null;\n        if (this.profileLinkElem) {\n            this.profileLink = this.profileLinkElem.querySelector('a').href;\n        }\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Backup of the palette data for use when we enter a different search mode\n\t\tthis.paletteDataBackup = null;\n\t\tthis.paletteItemsBackup = null;\n        this.paletteItemIndexBackup = null;\n        this.paletteInputValueBackup = null;\n\n        // Current search modes/keyword\n        this.searchMode = null;\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n            shouldSort: true,\n            // sortFn: (a, b) => {\n            //     // Return search items first\n            //     if (a.item[0].v.startsWith('Search: ')) {\n            //         if (b.item[0].v.startsWith('Search: ')) {\n            //             return b.score - a.score;\n            //         }\n            //         return -1;\n            //     }\n            //     if (b.item[0].v.startsWith('Search: ')) {\n            //         return 1;\n            //     }\n            //     return a.score - b.score;\n            // }\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    inSearchMode() {\n        return this.searchMode !== null;\n    }\n\n\t/**\n     * This converts this.paletteData into a list of paletteListItems in this.paletteItems\n     *\n     * It also builds the itemIndex\n     */\n    buildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n            li.appendChild(a);\n            if (item.actionType === 'url') {\n                a.href = item.action;\n                let title = item.title;\n                if (item.parentTitle) {\n                    title = item.parentTitle + \": \" + title;\n                }\n                a.innerHTML = title;\n            } else if (item.actionType === 'search-mode') {\n                a.href = '#';\n                a.innerHTML = item.title;\n                li.dataset.actionType = item.actionType;\n                li.dataset.searchMode = item.action.searchMode;\n            }\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    /**\n     * Clears and sets the content items\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    setContentItems(contentItems) {\n        this.paletteItems = [];\n        this.itemIndex = [];\n        this.injectContentItems(contentItems, false);\n    }\n\n    /**\n     * Content items have:\n     *  title\n     *  subtype\n     *  url\n     *  (we should also make the sub-menu definable, but that's not done yet)\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    injectContentItems(contentItems, andRunSearch = true) {\n        turboAdminLog('Injecting items');\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(this.injectItem.bind(this));\n        }\n\n        if (andRunSearch) {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        this.updatePaletteItems();\n    }\n\n    /**\n     * Injects a single content item into the palette\n     *\n     * @param {ContentItem} item\n     */\n    injectItem(item) {\n        const itemTitle = item.title;\n        // const itemTitle = item.title.rendered;\n        const itemType = item.subtype;\n        const itemUrl = item.url;\n\n        // turboAdminLog('Adding item: ' + itemTitle);\n\n        // // Check if item already exists\n        if (this.contentItemExists(itemUrl)) {\n            turboAdminLog('Not adding duplicate');\n            return;\n        }\n\n        let title = itemTitle;\n\n        if (itemType) {\n            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;\n            title += ` (${itemTypeName})`;\n        }\n\n        const li = document.createElement('li');\n        const a = document.createElement('a');\n        let subMenu = null;\n\n        // Loop over submenu items OR add link.\n        if (item.submenuItems.length > 0) {\n\n            // Prepare the outer sub-menu elements\n            subMenu = document.createElement('div');\n            const subMenuTitle = document.createElement('div');\n            const subMenuItems = document.createElement('ul');\n            subMenu.classList.add('ta-submenu');\n            subMenuTitle.classList.add('ta-submenu-title');\n\n            subMenuTitle.textContent = this.htmlDecode(itemTitle);\n            subMenuItems.classList.add('ta-submenu-items');\n            subMenu.appendChild(subMenuTitle);\n\n            for (let i = 0; i < item.submenuItems.length; i++) {\n                const subMenuItem = item.submenuItems[i]\n                // TODO: Abstract this so sub-menus can be defined by plugins?\n                const subMenuListItem = document.createElement('li');\n                const subMenuLink = document.createElement('a');\n                subMenuLink.innerText = subMenuItem.title;\n                subMenuLink.href = subMenuItem.url;\n                for (let a = 0; a < subMenuItem.attributes.length; a++) {\n                    subMenuLink.setAttribute(\n                        subMenuItem.attributes[a].name,\n                        subMenuItem.attributes[a].value\n                    )\n                }\n                subMenuListItem.appendChild(subMenuLink);\n                subMenuItems.appendChild(subMenuListItem);\n            }\n\n            // Add the sub-menu items UL to the sub-menu element.\n            subMenu.appendChild(subMenuItems);\n\n            li.classList.add('ta-has-child-menu');\n        }\n\n        a.href = itemUrl;\n        a.innerHTML = title;\n\n        li.appendChild(a);\n        if (subMenu !== null) {\n            li.appendChild(subMenu);\n        }\n\n        this.addPaletteListItem(li);\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n            return;\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else if (this.inSearchMode()) {\n                this.leaveSearchMode();\n            } else {\n                this.hidePalette();\n            }\n            return;\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    /*\n     * Adds the tab hint for a keyword once it has been typed.\n     */\n    maybeHighlightInputKeyword(newKey) {\n        // Do nothing if we are in a search-mode\n        if (this.inSearchMode()) {\n            return;\n        }\n\n        // This is fired on \"keyDown\", so the value isn't update with the new key yet.\n        // But don't do this for special keys, and catch backspace too.\n        let newInputValue = this.paletteInputElement.value;\n        if (newKey.length === 1) {\n            newInputValue += newKey;\n        }\n        if (newKey === 'Backspace') {\n            newInputValue = newInputValue.slice(0, -1);\n        }\n        // turboAdminLog(`Checking palette input value ${newInputValue} for keyword`);\n        if (this.isKeyword(newInputValue)) {\n            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;\n            this.paletteSearchModeTabNotice.classList.add('active');\n        } else {\n            this.unhighlightInputKeyword();\n        }\n    }\n\n    unhighlightInputKeyword() {\n        this.paletteSearchModeTabNotice.classList.remove('active');\n    }\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If we're not in a search mode then search immediately\n        if (! this.inSearchMode()) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n\n        // Cancel the existing timeout\n        clearTimeout(this.debounceTimeout)\n\n        this.debounceTimeout = setTimeout(async function () {\n            // Reset timeout\n            this.debounceTimeout = null;\n\n            // Run the search function\n            await this.paletteSearchAndUpdate();\n        }.bind(this), 750);\n    }\n\n    /**\n     * Check if a string is a search mode keyword\n     *\n     * @param {string} inputString\n     * @returns {boolean}\n     */\n    isKeyword(inputString) {\n        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);\n    }\n\n    /**\n     * Show the palette notice with the specified text\n     *\n     * @param {string} text\n     */\n    showPaletteNotice(text) {\n        this.paletteNoticeElement.classList.add('active');\n        this.paletteNoticeElement.innerText = text;\n    }\n\n    /**\n     * Hide the palette notice\n     */\n    hidePaletteNotice() {\n        this.paletteNoticeElement.classList.remove('active');\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n            e.stopImmediatePropagation();\n            e.stopPropagation();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n            e.stopImmediatePropagation();\n            e.stopPropagation();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            e.preventDefault();\n            e.stopImmediatePropagation();\n            e.stopPropagation();\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n\n        /*\n         * Only the actions above can be done in sub-menus.\n         */\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\n        /*\n         * Check for a keyword being typed and add a UI hint.\n         */\n        this.maybeHighlightInputKeyword(e.key);\n\n        /*\n         * Tabbing looks for a search mode keyword.\n         */\n        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {\n            turboAdminLog('Checking for search mode');\n            let inputValue = this.paletteInputElement.value;\n            if (this.isKeyword(inputValue)) {\n                turboAdminLog('Found search mode ' + inputValue)\n                e.preventDefault();\n                await this.enterSearchMode(\n                    globalThis.turboAdmin.searchModes[inputValue]);\n                return;\n            }\n        }\n\n        /*\n         * Backspace may exit us from a search mode\n         */\n        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {\n            e.preventDefault();\n            this.leaveSearchMode();\n            return;\n        }\n\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n    /**\n     * Puts the palette into a specific search mode - used when a keyword is selected\n     *\n     * @param {SearchMode} searchMode\n     */\n    async enterSearchMode(searchMode) {\n        turboAdminLog('Entering search mode for keyword ' + searchMode.keyword);\n        this.backupPaletteData();\n\n        this.paletteData = [];\n        this.paletteItems = [];\n        this.itemIndex = [];\n\n        // Remove the notice if it's there\n        this.hidePaletteNotice();\n\n        this.searchMode = searchMode;\n        this.paletteInputElement.value = '';\n        this.addSearchModeTag(searchMode.displayName);\n        this.unhighlightInputKeyword();\n        this.updatePaletteItems();\n        // This is similar to code in paletteSearch - maybe we could extract/abstract it?\n        if (searchMode.defaultItemsCallback !== null) {\n            this.paletteInnerElement.classList.add('loading');\n            const results = await searchMode.defaultItemsCallback();\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n    }\n\n    /**\n     * Puts the palette into a specific search mode specified by a keyword\n     *\n     * @param {string} keyword\n     */\n    async enterSearchModeByKeyword(keyword) {\n        turboAdminLog('Entering search mode by keyword ' + keyword);\n        const searchMode = globalThis.turboAdmin.searchModes[keyword];\n        turboAdminLog('Search mode is ' + searchMode);\n        if (searchMode === undefined) {\n            return;\n        }\n        await this.enterSearchMode(searchMode);\n    }\n\n    /**\n     * Leaves the current search mode\n     */\n    leaveSearchMode() {\n        const searchMode = this.searchMode;\n        // It's important what we set this to - see inSearchMode()\n        this.searchMode = null;\n        this.removeSearchModeTag();\n        this.restorePaletteData();\n    }\n\n    /**\n     * Backups up the palette data and input value to local variables so that it can be\n     * restored later.\n     */\n    backupPaletteData() {\n        this.paletteDataBackup = this.paletteData;\n        this.paletteItemsBackup = this.paletteItems;\n        this.paletteItemIndexBackup = this.itemIndex;\n        this.paletteInputValueBackup = this.paletteInputElement.value;\n    }\n\n    /**\n     * Restores the save palette data - highlights and rebuilds\n     */\n    restorePaletteData() {\n        this.paletteData = this.paletteDataBackup;\n        this.paletteItems = this.paletteItemsBackup;\n        this.itemIndex = this.paletteItemIndexBackup;\n        this.paletteInputElement.value = this.paletteInputValueBackup;\n        this.maybeHighlightInputKeyword('');\n        this.paletteSearchAndUpdate();\n    }\n\n    /**\n     * Adds the search mode tag with the specified title.\n     *\n     * @param {string} title\n     */\n    addSearchModeTag(title) {\n        this.paletteSearchModeTag.classList.add('active');\n        this.paletteSearchModeTag.innerText = title;\n    }\n\n    /**\n     * Removes the search mode tag\n     */\n    removeSearchModeTag() {\n        this.paletteSearchModeTag.classList.remove('active');\n    }\n\n    isPaletteOpen() {\n        return this.paletteElement?.classList.contains('active');\n    }\n\n\tshowPalette() {\n        // Bail if already shown (this can be triggered by a focus event)\n        if (this.isPaletteOpen()) {\n            return;\n        }\n\n        this.paletteInputElement.value = '';\n\t\tthis.paletteInputElement?.focus();\n\t\tthis.paletteElement?.classList.add('active');\n        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when\n        // the palette opens.\n        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n        if (this.searchMode !== null) {\n            this.leaveSearchMode();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;\n        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + \"px\";\n        this.paletteSubmenuContainerElement.classList.add('active');\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        this.paletteSubmenuContainerElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsContainerElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n        if (this.selectedItem.dataset.actionType === 'search-mode') {\n            this.enterSearchModeByKeyword(this.selectedItem.dataset.searchMode);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        // link.href will be interpolated by the browser, so if it's empty it will be the current page\n        // use getAttribute instead to work out if its empty\n        if (link.getAttribute('href') === '') {\n            return;\n        }\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        if (! this.searchMode) {\n            this.buildPaletteItems();\n\n            if (this.paletteInputElement.value !== '') {\n                // Reset the search to work on the new items\n                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n            }\n            return;\n        }\n\n        if (this.paletteInputElement.value.length === 0) {\n            this.paletteInnerElement.classList.add('loading');\n            let results = [];\n            if (this.searchMode.defaultItemsCallback !== null) {\n                results = await this.searchMode.defaultItemsCallback();\n            }\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        } else {\n            // This is copied to enterSearchMode. Should probably be extracted.\n            this.paletteInnerElement.classList.add('loading');\n            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n\n        /**\n         * OLD CODE BELOW\n         */\n        // Content search - don't search everything!\n        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n        //     this.paletteInnerElement.classList.add('loading');\n\n        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)\n        //         .then(\n        //             results => {\n        //                     this.injectContentItems(results);\n        //                     this.paletteInnerElement.classList.remove('loading');\n        //             }\n        //         )\n        // }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "/**\n * An item definition specifies how to detect a palette item from the Dashboard's Dom\n *\n * These are all processed on initialisation to generate menu items.\n *\n * Note that a single definition may generate multiple menu items if the selectors used\n * discover multiple items.\n */\nexport default class ItemDefinition {\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuItemCallback\n    * @param {HTMLElement} element\n    * @returns {string}\n    */\n\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuActionInfoCallback\n    * @param {HTMLElement} element\n    * @returns {Object}\n    */\n\n    /**\n     * The method of detecting items. Can be:\n     *  - 'dom' for checking if a DOM element exists (requires detectSelector or detectSelectorNone)\n     *  - 'url' if the current URL is being checked (requires detectPattern)\n     *  - 'none' if no detection is required - this item will always be added\n     *\n     * @type {string}\n     */\n    detectType = 'dom';\n\n    /**\n     * [OPTIONAL] A CSS selector used to find items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelector = '';\n\n    /**\n     * [OPTIONAL] A CSS selector used to check for an absence of items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelectorNone = '';\n\n    /**\n     * [OPTIONAL] A string to find in the current URL to detect the item\n     *\n     * @type {string}\n     */\n    detectPattern = '';\n\n    /**\n     * A callback used to generate a menu item title from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemTitleFunction = null;\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     *\n     * @type {string}\n     */\n    itemActionType = 'url';\n\n    /**\n     * A callback used to generate a menu item link URL from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemUrlFunction = null;\n\n    /**\n     * A callback used to generate an object containing data used by the specified action type.\n     *\n     * For 'search-mode' the object should be like { searchMode: '<keyword>' }\n     *\n     * @type {menuActionInfoCallback|null}\n     */\n    itemActionInfoFunction = null;\n\n     /**\n      * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n      *\n      * @type {boolean}\n      */\n     noCache = false;\n}\n", "import ItemDefinition from \"./class-item-definition\";\n\n/**\n * Menu items are the items ready to appear in the palette.\n *\n * These are standard items, not content items. Though this should probably be standardised.\n */\nexport default class TurboAdminMenuItem {\n\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The type of action to take when the item is clicked. Can be:\n     * - 'url' to visit a URL (default)\n     * - 'search-mode' to enter a search mode\n     */\n    actionType = 'url';\n\n    /**\n     * The action of the item is the URL to visit when the item is clicked or the action data\n     * if the action type is not 'url'\n     *\n     * @type {string|Object}\n     */\n    action = '';\n\n    /**\n     * The parent title is the title of the parent item under which the current item\n     * was found in the WordPress menu.\n     *\n     * e.g. in Posts -> Add Post, \"Posts\" is the parent item.\n     *\n     * @type {string}\n     */\n    parentTitle = '';\n\n    /**\n     * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n     *\n     * @type {boolean}\n     */\n    noCache = false;\n\n    /**\n     * Creates a new simple menu item (only works for URLs - for more complex items use fromItemDefinition)\n     *\n     * @param {string} title\n     * @param {string} action\n     * @param {string} parentTitle\n     * @param {boolean} noCache\n     */\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n        this.actionType = 'url';\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    /**\n     * Construct a new menu item from an ItemDefinition\n     *\n     * @param {ItemDefinition} item\n     * @param {HTMLElement} element\n     * @param {string} parentTitle\n     * @return {TurboAdminMenuItem}\n     */\n    static fromItemDefinition(item, element = null, parentTitle = '') {\n        const action = item.itemActionType === 'url' ?\n            item.itemUrlFunction(element) :\n            item.itemActionInfoFunction(element);\n\n        const menuItem = new TurboAdminMenuItem(\n            item.itemTitleFunction(element),\n            action,\n            parentTitle,\n            item?.noCache\n        );\n        menuItem.actionType = item.itemActionType;\n        return menuItem;\n    }\n\n    /**\n     * Compares this item to another item\n     *\n     * @param {TurboAdminMenuItem} item\n     * @returns {boolean}\n     */\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if (this.inExtension()) {\n            this.store = chrome.storage.local;\n        } else {\n            this.store = window.localStorage;\n        }\n    }\n\n    /**\n     * Returns true if we are in the extension.\n     */\n    inExtension() {\n        return window.turboAdminIsExtension();\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if (this.inExtension()) {\n            await this.store.set(dataObject);\n        } else {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if (this.inExtension()) {\n            return await this.store.get(key);\n        } else {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        }\n    }\n}\n", "import Storage from '../class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // turboAdminLog('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n        this.postTypes = [];\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        turboAdminLog('Discovering API root');\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n        // This should be very rare. I should only really see it in development.\n        turboAdminLog('API Route Discovery failed');\n        // Making best guess\n        this.apiBase = globalThis.taWp.home + '/wp-json/wp/v2/';\n        // TODO: This can't display as the palette isn't created yet.\n        // globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Can\\'t find the WP API. Try visiting the dashboard to refresh things.');\n    }\n\n    async discoverPostTypes() {\n        turboAdminLog('Discovering post types');\n        if (! this.active) {\n            turboAdminLog('Not active');\n            this.postTypes = [];\n            return;\n        }\n\n        const postTypes = await this.store.get('ta-post-types');\n\n        // Check local storage cache\n        if (postTypes && postTypes['ta-post-types'] && postTypes['ta-post-types']['expiry'] > Date.now()) {\n            turboAdminLog('Using cached post types: ', postTypes['ta-post-types']['data']);\n            this.postTypes = postTypes['ta-post-types']['data'];\n            return;\n        }\n\n        this.postTypes = await this.getPostTypes();\n        turboAdminLog('Discovered post types: ', this.postTypes);\n\n        // Cache for 10 minutes\n        const expiry = Date.now() + (10 * 60 * 1000);\n        this.store.set({\n            'ta-post-types': {\n                expiry: expiry,\n                data: this.postTypes\n            }\n        });\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    async getPostTypes() {\n        // Check the cache\n        if (undefined !== this.cache['postsTypes']) {\n            return this.cache['postTypes'];\n        }\n\n        // Fetch results\n        const response = await this.get('types');\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['postTypes'] = result;\n\n        return result;\n    }\n\n    async getPosts(searchString, postType = 'any') {\n        // Check the cache\n        const cacheKey =  `posts-${postType}-${searchString}`;\n        if (undefined !== this.cache[cacheKey]) {\n            return this.cache[cacheKey];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: postType\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[cacheKey] = result;\n\n        return result;\n    }\n\n    /**\n     * We can't use the API to get a post of any post type. So we hack this a bit.\n     *\n     * @param {number} postId\n     * @returns {Promise<any>}\n     */\n    async doesPostExist(postId) {\n        // Check the cache\n        if (undefined !== this.cache['post-' + postId]) {\n            return this.cache['post-' + postId];\n        }\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);\n\n        this.cache['post-' + postId] = response;\n\n        return response?.status === 200;\n    }\n\n    async getPlugins(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['plugins-' + searchString]) {\n            return this.cache['plugins-' + searchString];\n        }\n\n        let requestOptions = {};\n\n        if (searchString) {\n            requestOptions.search = searchString;\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"plugins\",\n            requestOptions\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['plugins-' + searchString] = result;\n\n        return result;\n    }\n\n    async getUsers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['users-' + searchString]) {\n            return this.cache['users-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"users\",\n            {\n                search: searchString,\n                per_page: 100,\n                context: 'edit' // view / embed / edit\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['users-' + searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`, init);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WordPress API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog( 'TURBO ADMIN: WordPress API Error. Try visiting the WordPress Dashboard to refresh things.' );\n            }\n        }\n\n        return response;\n    }\n\n}\n", "export default class SubmenuItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title;\n\n    /**\n     * The URL of the item\n     * @type {string}\n     */\n    url;\n\n    /**\n     * A list of attributes to go on the A tag (not the LI tag)\n     *\n     * @type {array}\n     */\n    attributes = [];\n\n    /**\n     * Create a submenu item\n     *\n     * @param {string} title The title of the item\n     * @param {string} url The URL of the item\n     */\n    constructor(title, url) {\n        this.title = title;\n        this.url = url;\n    }\n\n    /**\n     * Add an attribute\n     *\n     * @param {string} name The attribute name\n     * @param {string} value The attribute value\n     */\n    addAttribute(name, value) {\n        this.attributes.push({\n            name: name,\n            value: value\n        });\n    }\n}\n", "import SubmenuItem from \"./class-submenu-item\";\n\nexport default class ContentItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The subtype of the item. e.g. for posts, this will be the post type.\n     * Used to display extra information about the item.\n     *\n     * @type {string}\n     */\n    subtype = '';\n\n    /**\n     * The URL of the item. Leave empty if there is a sub-menu.\n     *\n     * @type {string}\n     */\n    url = '';\n\n    /**\n     * The sub-menu items, if any.\n     *\n     * This should be an empty array if the item itself has a URL\n     *\n     * @type {SubmenuItem[]}\n     */\n    submenuItems = [];\n}\n", "import ContentItem from \"./class-content-item\";\n\nexport default class SearchMode {\n    /**\n     * The keyword string used to initiate the search\n     *\n     * @type {string}\n     */\n    keyword = '';\n\n    /**\n     * The dispay name used for the search\n     *\n     * @type {string}\n     */\n    displayName = '';\n\n    /**\n     * jsDoc defintion for a `searchCallback`\n     *\n     * @callback SearchCallback\n     * @param {string} [searchString]\n     * @returns {Promise<ContentItem[]>}\n     */\n\n    /**\n     * Callback to get search items\n     *\n     * @type {SearchCallback}\n     */\n    searchCallback;\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @type {SearchCallback|null}\n     */\n    defaultItemsCallback = null;\n\n    /**\n     * Set this to false to hide the search mode from the palette - it still\n     * works with a keyword, but won't show in the palette's list of items\n     *\n     * @type {boolean}\n     */\n    showInPaletteSearch = true;\n\n    /**\n     * Constructs a new search mode\n     *\n     * @param {string} keyword\n     * @param {string} displayName\n     * @param {SearchCallback} searchCallback\n     * @param {SearchCallback} defaultItemsCallback\n     * @param {boolean} showInPaletteSearch\n     */\n    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null, showInPaletteSearch = true) {\n        this.keyword = keyword;\n        this.displayName = displayName;\n        this.searchCallback = searchCallback;\n        this.defaultItemsCallback = defaultItemsCallback;\n        this.showInPaletteSearch = showInPaletteSearch;\n    }\n}\n", "import SearchMode from \"./class-search-mode\";\nimport ItemDefinition from \"./class-item-definition\";\n\n/**\n * This is an abstract class that should be extended by plugins\n * @module TurboAdminPlugin\n */\nexport default class TurboAdminPlugin {\n    /** @type {string} */\n    name = '';\n\n    /** @type {SearchMode[]} */\n    searchModes = [];\n\n    /** @type {boolean} */\n    activated = false;\n\n    constructor(pluginName) {\n        this.name = pluginName;\n        this.registerPlugin();\n    }\n\n    /**\n     * Register the plugin with Turbo Admin\n     */\n    registerPlugin() {\n        turboAdminLog('Inside plugin - requested registration of ' + this.name);\n        globalThis.turboAdmin.registerPlugin(this);\n    }\n\n    /**\n     * Returns true if the plugin should activate\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return false;\n    }\n\n    /**\n     * Activates the plugin\n     * @return {void}\n     */\n    activate() {\n        this.activated = true;\n        this.registerSearchModes();\n    }\n\n    /**\n     * Register the search keywords with Turbo Admin - each will be registered\n     * with the whole plugin object.\n     */\n    registerSearchModes() {\n        this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);\n    }\n\n    /**\n     * Get the item definitions for search modes.\n     *\n     * Note that , at time of writing, this runs AFTER API init but before the plugin is activated.\n     * So APIs are available (and may be used in shouldActivate()) but the plugin is not yet activated.\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getSearchModeItemDefinitions() {\n        if (!this.shouldActivate()) {\n            return [];\n        }\n\n        const searchModeItems = this.searchModes.map(searchMode => {\n            // Return null if we don't want to show this search mode in the palette.\n            if (searchMode.showInPaletteSearch === false) {\n                return null;\n            }\n            const item = new ItemDefinition();\n            item.detectType = 'none';\n            item.itemTitleFunction = () => `<span style=\"font-style:italic;\">Search</span>: ${searchMode.displayName}`;\n            item.itemActionType = 'search-mode';\n            item.itemActionInfoFunction = () => { return { searchMode: searchMode.keyword } };\n            return item;\n        })\n        // Filter out the nulls.\n        return searchModeItems.filter( item => item !== null);\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n    async getAdditionalItemDefinitions() {\n        if (!this.activated) {\n            return [];\n        }\n\n        return [];\n    }\n\n    /**\n     * Save plugin setting to persistent storage\n     */\n    saveSetting(key, value) {\n\n    }\n\n}\n", "/**\n * It's impossible to change the setting to off, because the\n * extension's content script runs in a sandbox and can't access\n * the wp object. But we can just toggle the class every time.\n */\nexport default class TurboAdminWpBlockEditorFullscreenKill {\n\n    constructor() {\n\n        // Don't run on the site editor screen\n        if (document.body.classList.contains( 'site-editor-php' )) {\n            return;\n        }\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed fullscreen\n                // if (document.body.classList.contains('turbo-admin-killed-fullscreen')) {\n                //     return;\n                // }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (mu.target.classList.contains('is-fullscreen-mode')) {\n                    this.killFullScreenEditor();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killFullScreenEditor();\n    }\n\n    killFullScreenEditor() {\n        if (! document.body.classList.contains('is-fullscreen-mode')) {\n            return;\n        }\n\n        document.body.classList.remove('is-fullscreen-mode');\n        document.body.classList.add('turbo-admin-killed-fullscreen');\n\n        const newStyles = document.createElement('style');\n        newStyles.innerHTML = \"body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }\";\n        document.body.appendChild(newStyles);\n    }\n}\n", "/**\n * Kills/auto-removes:\n *  - the Welcome Guide on the post edit screen\n *  - the pattern selector modal on the post edit screen\n *  - the Welcome Panel on the dashboard on new sites\n */\nexport default class TurboAdminWpBlockEditorWelcomeGuideKill {\n\n    constructor() {\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed the modal\n                if (document.body.classList.contains('ta-killed-post-welcome-guide')) {\n                    return;\n                }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (!mu.target.classList.contains('modal-open')) {\n                    return;\n                }\n\n                console.log('Modal detected');\n                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n                const newPagePatterns = document.querySelector('.edit-post-start-page-options__modal');\n                const newPagePatterns2 = document.querySelector('.editor-start-page-options__modal-content');\n\n                if (welcomeGuide || newPagePatterns || newPagePatterns2) {\n                    this.killWelcomeGuide();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killWelcomeGuide();\n\n        // Attempt a kill of the dashboard welcome panel\n        this.killDashboardWelcomePanel();\n    }\n\n    killWelcomeGuide() {\n        // Check for welcome guide\n        let welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n        // Check for new page patterns modal (old: pre-6.6?)\n        if (!welcomeGuide) {\n            welcomeGuide = document.querySelector('.edit-post-start-page-options__modal');\n        }\n        // Check for new page patterns model (new: 6.6+)\n        if (!welcomeGuide) {\n            welcomeGuide = document.querySelector('.editor-start-page-options__modal-content');\n        }\n\n        if (welcomeGuide) {\n            const closeButton = document.querySelector('.components-modal__header button');\n            if (closeButton) {\n                closeButton.click();\n                /*\n                 * Also add a class to body so we don't do it again - subsequent modals\n                 * will need to be shown as they will have been user-initiated.\n                 */\n                document.body.classList.add('ta-killed-post-welcome-guide');\n            }\n        }\n    }\n\n    killDashboardWelcomePanel() {\n        const welcomePanel = document.getElementById('welcome-panel');\n        if (!welcomePanel) {\n            return;\n        }\n        const welcomePanelClose = welcomePanel.querySelector('.welcome-panel-close');\n        if (welcomePanelClose) {\n            welcomePanelClose.click();\n        }\n    }\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            '.notice-success',\n            '.notice-error',\n            '.notice-failure',\n            '.updated',\n        ]\n\n        this.noticesPanelInner = null;\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nturboAdminLog('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nturboAdminLog('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice);\n            this.maybeAddMoveButtonToNotice.call(this, notice);\n        });\n\n        const noticesToHide = Array.from(notices).filter( this.noticeShouldBeHidden.bind(this) );\n\n        turboAdminLog('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        this.noticesPanelInner = document.createElement('div');\n        this.noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(this.hideNotice.bind(this));\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(this.noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n\n        // Add a mutation observer to check for notices added by JavaScript\n        // this.addObserver();\n    }\n\n    addObserver() {\n        const observer = new MutationObserver( this.handleMutations.bind(this) );\n        observer.observe(document.getElementById('wpbody-content'), {\n            childList: true,\n            subtree: true\n        });\n    }\n\n    handleMutations(mutations, observer) {\n        mutations.forEach( mutation => {\n            if (mutation.type === 'childList') {\n                mutation.addedNodes.forEach( node => {\n                    if (node.nodeType === Node.ELEMENT_NODE) {\n                        console.log('MUTATING!!!' + node.id);\n                        // this.maybeAddIdToNotice(node);\n                        // this.maybeAddMoveButtonToNotice(node);\n                        // this.maybeHideNotice(node);\n                    }\n                });\n            }\n        });\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return noticeElem.matches(this.allowedClasses.join(', '));\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    noticeShouldBeHidden(notice) {\n        if (this.rememberedNoticeIds.includes(notice.id)) {\n            return true;\n        }\n\n        if (this.keepNotice(notice)) {\n            return false;\n        }\n\n        // Invisible\n        if (\n            notice.offsetHeight === 0 ||\n            notice.offsetWidth === 0\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(chrome)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        turboAdminLog(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(chrome)) {\n            chrome.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(noticeElem) {\n        if (noticeElem.id && noticeElem.id !== '' && noticeElem.id !=='message') {\n            return;\n        }\n\n        const classes = noticeElem.classList;\n        noticeElem.id = Array.from(noticeElem.classList).join('-');\n    }\n\n    /**\n     * Add buttons to notices that we want to be able to move to the panel\n     */\n    maybeAddMoveButtonToNotice(noticeElem) {\n        if (this.keepNotice(noticeElem)) {\n            const rememberButton = document.createElement('button');\n            rememberButton.classList.add('ta-remember-notice-button');\n            rememberButton.innerText = 'Move to panel';\n\n            const forgetButton = document.createElement('button');\n            forgetButton.classList.add('ta-forget-notice-button');\n            forgetButton.innerText = 'Move to dashboard';\n\n            noticeElem.classList.add('ta-added-pos-relative');\n\n            noticeElem.appendChild(rememberButton);\n            noticeElem.appendChild(forgetButton);\n\n            rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n            forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n        }\n    }\n\n    maybeHideNotice(noticeElem) {\n        if (this.noticeShouldBeHidden(noticeElem) && !noticeElem.classList.contains('ta-notice-hidden')) {\n            this.hideNotice(noticeElem);\n        }\n    }\n\n    hideNotice(noticeElem) {\n        noticeElem.classList.add('ta-notice-hidden');\n        // WPCore's common.js will re-add the notice below the dashboard header unless it has a .inline class.\n        // It does: $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );\n        noticeElem.classList.add('inline');\n        // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n        this.noticesPanelInner.append(noticeElem);\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {boolean}\n         */\n        this.actionsOpen = false;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        /**\n         * @type {boolean}\n         */\n        this.isWooCommerce = false;\n\n        /**\n         * @type {boolean}\n         */\n        this.isPluginInstall = false;\n\n        if (!this.listTable) {\n            return;\n        }\n\n        // We make some VERY special exceptions for WooCommerce\n        if (document.body.classList.contains('woocommerce-admin-page') &&\n            document.body.classList.contains('post-type-shop_order')) {\n            this.isWooCommerce = true;\n        }\n\n        // And for the add plugins screen\n        if (document.body.classList.contains('plugin-install-php')) {\n            this.isPluginInstall = true;\n        }\n\n        /**\n         * @type {Boolean}\n         */\n        this.isMac = globalThis.turboAdmin.turboAdminPalette.isMac();\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        // Plugin install is different.\n        if (this.isPluginInstall) {\n            this.tableRows = this.listTable.querySelectorAll('#the-list .plugin-card');\n        }\n\n        // Grr... comments list is different! WHY?!\n        if (document.body.classList.contains('edit-comments-php')) {\n            this.tableRows = this.listTable.querySelectorAll('tbody#the-comment-list > tr');\n        }\n\n        document.addEventListener('keydown', e => this.handleKey(e));\n\n        // Chrome handles escape key on search input elements, so we need to\n        // intercept it here.\n        const searchInput = document.querySelector(\n            '.search-box input[type=\"search\"], .search-form input[type=\"search\"]'\n        );\n\n        if (searchInput) {\n            searchInput.addEventListener('keyup', e => this.handleSearchInputKey(e));\n        }\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKey(ev) {\n        const isActiveElementBody = document.activeElement.tagName === 'BODY';\n        const isActiveElementInListTable = this.listTable && this.listTable.contains(document.activeElement);\n        const isSearchFocussed = this.getSearchInputElement() === document.activeElement;\n        if ((!isActiveElementBody && !isActiveElementInListTable) || isSearchFocussed) {\n            return;\n        }\n        if (globalThis.turboAdmin.turboAdminPalette.isPaletteOpen()) {\n            return;\n        }\n        if (ev.key === 'j') {\n            if (this.actionsOpen) {\n                this.actionMoveDown();\n            } else {\n                this.tableMoveDown();\n            }\n        } else if (ev.key === 'k') {\n            if (this.actionsOpen) {\n                this.actionMoveUp();\n            } else {\n                this.tableMoveUp();\n            }\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            if (this.actionsOpen) {\n                this.openCurrentRowAction(ev);\n                ev.preventDefault();\n            } else {\n                this.openTableRowActions(ev);\n            }\n        } else if (ev.key === '/') {\n            this.focusSearch(ev);\n        } else if (ev.key === 'f' && ev.ctrlKey) {\n            this.nextPage(ev);\n        } else if (ev.key === 'b' && ev.ctrlKey) {\n            this.prevPage(ev);\n        } else if (ev.key === 'ArrowDown') {\n            if (this.actionsOpen) {\n                this.actionMoveDown(ev);\n            }\n        } else if (ev.key === 'ArrowUp') {\n            if (this.actionsOpen) {\n                this.actionMoveUp(ev);\n            }\n        } else if (ev.key.toLowerCase() === 'escape' /* && !document.body.classList.contains('modal-open')*/) {\n            if (this.actionsOpen) {\n                this.closeTableRowActions(ev);\n            }\n            // If the search box is focussed... Note that Chrome does its own thing with escape here.\n            if (document.getElementById('post-search-input') === document.activeElement) {\n                document.getElementById('post-search-input').blur();\n            }\n        }\n\n    }\n\n    handleSearchInputKey(ev) {\n        if (ev.key.toLowerCase() === 'escape') {\n            ev.target.blur();\n        }\n    }\n\n    getSearchInputElement() {\n        return document.querySelector('.search-box input[type=\"search\"], .search-form input[type=\"search\"]');\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else if (this.currentRowIndex < this.tableRows.length - 1) {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n        }\n\n        this.updateTable();\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (!this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n\n        this.scrollIntoViewIfNeeded(this.currentRow);\n    }\n\n    /**\n     * Scrolls the element into view if it is not already.\n     */\n    scrollIntoViewIfNeeded(element) {\n        const elementRect = element.getBoundingClientRect();\n        const elementTop = elementRect.top;\n        const elementBottom = elementRect.bottom;\n        const viewportTop = 0;\n        const viewportBottom = window.innerHeight;\n        if (elementBottom > viewportBottom) {\n            element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });\n        } else if (elementTop < viewportTop) {\n            element.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n        }\n    }\n\n    /**\n     * Gets the list table row actions container for the current row\n     */\n    getRowActionsContainer() {\n        let container = this.currentRow.querySelector('.row-actions');\n\n        if (this.isPluginInstall) {\n            container = this.currentRow.querySelector('.plugin-action-buttons');\n        }\n\n        return container;\n    }\n\n    /**\n     * Gets list table row actions for the current row\n     */\n    getRowActions() {\n        let rowActions = this.currentRow.querySelectorAll('.row-actions span a, .row-actions span button');\n\n        if (this.isPluginInstall) {\n            rowActions = this.currentRow.querySelectorAll('.plugin-action-buttons a');\n        }\n\n        return rowActions;\n    }\n\n    openTableRowActions(ev) {\n        turboAdminLog(this);\n\n        // WooCommerce doesn't have row actions, so we just find the link and visit it\n        if (this.isWooCommerce) {\n            this.currentRow.querySelector('a.order-view').click();\n            return;\n        }\n\n        this.actionsOpen = true;\n\n        let rowActions = this.getRowActionsContainer();\n\n        if (rowActions) {\n            rowActions.classList.add('visible');\n        }\n\n        const titleElem = this.currentRow.querySelector('strong');\n        const titleLink = titleElem.querySelector('a');\n\n        if (titleLink) {\n            titleLink.classList.add('ta-active-table-row-link');\n            return;\n        }\n\n        let rowActionLinks = this.getRowActions();\n\n        if (rowActionLinks) {\n            rowActionLinks[0].classList.add('ta-active-table-row-link');\n        }\n    }\n\n    closeTableRowActions(ev) {\n        turboAdminLog(this);\n        const rowActions = this.currentRow.querySelector('.row-actions');\n\n        // Don't do this on plugins screen!\n        if (!document.body.classList.contains('plugins-php')) {\n            if (rowActions) {\n                rowActions.classList.remove('visible');\n            }\n        }\n\n        const activeLink = document.querySelector('.ta-active-table-row-link');\n        if (activeLink) {\n            activeLink.classList.remove('ta-active-table-row-link');\n        }\n\n        this.actionsOpen = false;\n    }\n\n    actionMoveDown(ev) {\n        /** @type {HTMLElement} */\n        const currentLink = document.querySelector('.ta-active-table-row-link');\n\n        // Handle the case where the title link is selected\n        if (currentLink.closest('strong')) {\n            const rowActions = this.getRowActions();\n            if (rowActions) {\n                rowActions[0].classList.add('ta-active-table-row-link');\n                currentLink.classList.remove('ta-active-table-row-link');\n            }\n            return;\n        }\n\n        /** @type {HTMLElement} */\n        const nextLink = currentLink.parentElement?.nextElementSibling?.querySelector('a, button');\n        if (nextLink) {\n            nextLink.classList.add('ta-active-table-row-link');\n            currentLink.classList.remove('ta-active-table-row-link');\n        }\n    }\n\n    actionMoveUp(ev) {\n        /** @type {HTMLElement} */\n        const currentLink = document.querySelector('.ta-active-table-row-link');\n\n        // Handle the case where the title link is selected\n        if (currentLink.closest('strong')) {\n            return;\n        }\n\n        /** @type {HTMLElement} */\n        const prevLink = currentLink.parentElement?.previousElementSibling?.querySelector('a, button');\n\n        // Handle the case where the first item is selected and we need to go back to the title\n        if (!prevLink) {\n            const titleLink = this.currentRow.querySelector('strong a');\n            if (titleLink) {\n                titleLink.classList.add('ta-active-table-row-link');\n                currentLink.classList.remove('ta-active-table-row-link');\n            }\n            return;\n        }\n\n        prevLink.classList.add('ta-active-table-row-link');\n        currentLink.classList.remove('ta-active-table-row-link');\n    }\n\n    openCurrentRowAction(ev) {\n        // TODO: Open the current row action\n        /** @type {HTMLElement} */\n        const currentLink = document.querySelector('.ta-active-table-row-link');\n        // Don't do this for plugin install screen\n        if (currentLink) {\n            currentLink.click();\n        }\n    }\n\n    focusSearch(ev) {\n        /** @type {HTMLInputElement} */\n        const searchInput = this.getSearchInputElement();\n\n        if (searchInput) {\n            searchInput.focus();\n            this.scrollIntoViewIfNeeded(searchInput);\n            ev.preventDefault();\n        }\n    }\n\n    nextPage(ev) {\n        /** @type {HTMLAnchorElement} */\n        const nextPageLink = document.querySelector('.tablenav-pages .next-page');\n        if (nextPageLink) {\n            nextPageLink.click();\n            ev.preventDefault();\n        }\n    }\n\n    prevPage(ev) {\n        /** @type {HTMLAnchorElement} */\n        const prevPageLink = document.querySelector('.tablenav-pages .prev-page');\n        if (prevPageLink) {\n            prevPageLink.click();\n            ev.preventDefault();\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\n\nexport default class TurboAdminBarkeeper extends TurboAdminPlugin {\n    constructor() {\n        super('Barkeeper');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        if (true !== globalThis.turboAdmin.options['barkeeper']) {\n            return false;\n        }\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return false;\n        }\n        // Bail if we don't have the left-hand admin bar (some users only have right-hand side)\n        if (! document.getElementById('wp-admin-bar-root-default')) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.selectorsToHide = [\n            '#wp-admin-bar-root-default > li',\n            '.monsterinsights-adminbar-menu-item',\n        ];\n\n        this.barkeeperState = this.getBarkeeperState();\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        if (! this.root) {\n            return;\n        }\n        this.itemsToHide = document.querySelectorAll( this.selectorsToHide.join(', ') );\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            this.setBarkeeperState(this.barkeeperState);\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n\n        this.setupObserver();\n    }\n\n    /**\n     * Some awkward plugins add themselves into the bar using JS\n     */\n    setupObserver() {\n        this.observer = new MutationObserver( mutations => {\n            mutations.forEach( mutation => {\n                if (mutation.type === 'childList') {\n                    mutation.addedNodes.forEach( node => {\n                        if (node.classList && node.classList.contains('ta-barkeeper-collapsable')) {\n                            return;\n                        }\n                        if (node.id && this.exclusionIds.includes(node.id)) {\n                            return;\n                        }\n                        // Check is the node matches any of the selectors\n                        if (node.matches(this.selectorsToHide.join(', '))) {\n                            node.classList.add('ta-barkeeper-collapsable');\n                            return;\n                        }\n                    });\n                }\n            });\n        });\n\n        this.observer.observe(this.root, {\n            childList: true,\n            subtree: true,\n        });\n    }\n\n    getBarkeeperState() {\n        if (window.turboAdminIsExtension()) {\n            return globalThis.turboAdmin.options['barkeeper-state'];\n        } else {\n            return window.localStorage.getItem('turbo-admin-barkeeper-state');\n        }\n    }\n\n    setBarkeeperState(state) {\n        if (window.turboAdminIsExtension()) {\n            chrome.runtime.sendMessage({\n                'action': 'barkeeperSetState',\n                'barkeeperState': this.barkeeperState,\n            });\n        } else {\n            window.localStorage.setItem('turbo-admin-barkeeper-state', state);\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminContentSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Content');\n\n        const ignoredPostTypes = [\n            'nav_menu_item',\n            'wp_block',\n            'wp_template',\n            'wp_template_part',\n            'wp_navigation',\n        ];\n\n        const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);\n\n        // Discard ignored post types\n        const filteredPostTypeKeys = postTypeKeys.filter(key => ! ignoredPostTypes.includes(key));\n\n        // Register a search mode for each post type\n        for (let i = 0; i < filteredPostTypeKeys.length; i++) {\n            const thisPostTypeKey = filteredPostTypeKeys[i];\n            const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];\n            // turboAdminLog('Adding search mode for post type', thisPostType);\n            this.searchModes.push( this.makePostTypeSearchMode(thisPostType) );\n        }\n\n        // Register ID search mode\n        this.searchModes.push( new SearchMode('id', 'Post ID', this.postById.bind(this)) );\n\n        // Register search all post types mode\n        this.searchModes.push( new SearchMode('search', 'All post types', this.contentSearch.bind(this)) );\n        // Don't show this one in the palette\n        this.searchModes.push( new SearchMode('find', 'All post types', this.contentSearch.bind(this), null, false) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * This is a generator for a post-type specific SearchMode object\n     *\n     * @param {Object} postType\n     */\n    makePostTypeSearchMode(postType) {\n        // TODO: interpret the post type name\n        return new SearchMode(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));\n    }\n\n    /**\n     * @param {string} searchString\n     * @param {string} postType This is passed to the API as a subtype. 'any' by default.\n     * @returns {Promise<ContentItem[]>}\n     */\n    async contentSearch(searchString, postType = 'any') {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPosts(searchString, postType);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = result.title;\n                            item.subtype = result.subtype;\n                            item.url = result.url;\n\n                            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item))\n\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} postId\n     * @returns {Promise<ContentItem[]>}\n     */\n    async postById(postId) {\n        if (! postId.trim().match(/^\\d+$/)) {\n            return [];\n        }\n        const postExists = await globalThis.contentApi.doesPostExist(postId);\n\n        const resultAsContentItem = new ContentItem;\n\n        if (! postExists) {\n            resultAsContentItem.title = 'Post does not exist or is not visible';\n            return [ resultAsContentItem ];\n        }\n\n        resultAsContentItem.title = `Post ID: ${postId}`;\n        resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;\n\n        resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));\n\n        return [ resultAsContentItem ];\n    }\n\n    /**\n     * Makes an array of submenu items from a content item\n     *\n     * @param {number} postId\n     * @param {ContentItem} contentItem\n     * @returns {SubmenuItem[]}\n      */\n    makeSubmenuItems(postId, contentItem) {\n        const itemsToReturn = [];\n        itemsToReturn.push(\n            new SubmenuItem(\n                'View',\n                contentItem.url\n            )\n        );\n\n        // TODO: Make a better way to detect if we are logged in.\n        if (globalThis.turboAdmin.turboAdminPalette.profileLink) {\n            // Need to get edit URL. This seems like the best way for now.\n            const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;\n            itemsToReturn.push(\n                new SubmenuItem(\n                    'Edit',\n                    editLink\n                )\n            )\n\n            // Add oxygen link if needed.\n            if (globalThis.turboAdmin.hasActivatedPlugin('OxygenBuilder')) {\n                const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;\n                itemsToReturn.push(\n                    new SubmenuItem(\n                        'Edit with Oxygen',\n                        oxygenLink\n                    )\n                );\n            }\n        }\n\n        const copyLinkItem = new SubmenuItem( 'Copy link', contentItem.url);\n        copyLinkItem.addAttribute('data-action', 'clipboard')\n        itemsToReturn.push(copyLinkItem);\n\n        return itemsToReturn;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminPluginSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Plugins');\n\n        this.searchModes.push( new SearchMode('plugin', 'Plugins', this.pluginSearch, this.defaultPluginItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultPluginItems() {\n        return await this.pluginSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async pluginSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPlugins(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            // siteUrl is at globalThis.turboAdmin.wp.siteUrl\n                            const item = new ContentItem;\n                            item.title = result.name;\n                            item.subtype = 'Plugin';\n                            // TODO: Maybe set this to be a search on the plugin screen?\n                            // Plugin \"slug\" is in result.name\n\n                            const itemViewUrlParams = new URLSearchParams();\n                            itemViewUrlParams.set('plugin_status', 'all');\n                            itemViewUrlParams.set('s', result.name);\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'View',\n                                    globalThis.taWp.siteUrl + '/plugins.php?' + itemViewUrlParams.toString()\n                                )\n                            );\n                            // Activate: /wp-admin/plugins.php?action=activate&plugin=order-simulator-woocommerce%2Fwoocommerce-order-simulator.php&plugin_status=all&paged=1&s&_wpnonce=3714a01759\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\n\nexport default class TurboAdminUserSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Users');\n\n        this.searchModes.push( new SearchMode('user', 'Users', this.userSearch, this.defaultUserItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultUserItems() {\n        return await this.userSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async userSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getUsers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            if (result.first_name && result.last_name) {\n                                item.title = `${result.first_name} ${result.last_name} - `;\n                            }\n                            item.title += result.email;\n                            item.subtype = result.roles[0];\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminWoocommerce extends TurboAdminPlugin {\n    constructor() {\n        super('WooCommerce');\n\n        this.searchModes.push( new SearchMode('order', 'Orders', this.orderSearch) );\n        this.searchModes.push( new SearchMode('customer', 'Customers', this.customerSearch) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of WooCommerce in Dashboard\n        /** @type {HTMLElement|string|Number} */\n        let woocommerceMenuElement = document.getElementById('toplevel_page_ct_dashboard_page');\n\n        // Also check for a menu bar item\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = document.getElementById('wp-admin-bar-new-shop_order');\n        }\n\n        // Check to see if WooCommerce flag is cached\n        if (! woocommerceMenuElement) {\n            woocommerceMenuElement = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasWooCommerce = Boolean(woocommerceMenuElement);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-woocommerce', hasWooCommerce ? '1' : '0' );\n\n        return globalThis.contentApi.active && hasWooCommerce;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async orderSearch(searchString) {\n        let results;\n\n        if (searchString.trim().match(/^\\d+$/)) {\n            results = await globalThis.woocommerceApi.getOrder(searchString);\n        } else {\n            results = await globalThis.woocommerceApi.getOrders(searchString);\n        }\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `#${result.number} ${result.currency_symbol}${result.total}`;\n                            item.subtype = result.billing.email;\n                            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async customerSearch(searchString) {\n        const results = await globalThis.woocommerceApi.getCustomers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = `${result.billing.first_name} ${result.billing.last_name}`;\n                            item.subtype = result.email;\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Orders',\n                                    globalThis.taWp.siteUrl + `/edit.php?post_status=all&post_type=shop_order&_customer_user=${result.id}`\n                                )\n                            )\n\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'Profile',\n                                    globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`\n                                )\n                            )\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminGravityForms extends TurboAdminPlugin {\n    constructor() {\n        super('GravityForms');\n\n        this.searchModes.push( new SearchMode('form', 'Gravity Forms', this.formSearch, this.defaultFormsList.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return globalThis.contentApi.active &&\n               document.getElementById('wp-admin-bar-gravityforms-new-form') !== null\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultFormsList() {\n        return await this.formSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async formSearch(searchString) {\n        const resultsObject = await globalThis.gravityFormsApi.getForms(searchString);\n        // GF Results are an object rather than an array so we need to convert\n\n        // TODO: Catch the error response (do the TODO in the API class first)\n\n        const resultsArray = [];\n        const resultKeys = Object.keys(resultsObject);\n        for(let k = 0; k < resultKeys.length; k++) {\n            const result = resultsObject[resultKeys[k]];\n            const item = new ContentItem;\n            item.title = `#${result.id} ${result.title}`;\n            item.subtype = `${result.entries} entries`;\n            item.url = globalThis.taWp.siteUrl + `/post.php?post=${result.id}&action=edit`;\n\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Edit Form',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Entries',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_entries&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Form Settings',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=settings&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Confirmatons',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=confirmation&id=${result.id}`\n                )\n            )\n            item.submenuItems.push(\n                new SubmenuItem(\n                    'Notifications',\n                    globalThis.taWp.siteUrl + `/admin.php?page=gf_edit_forms&view=settings&subview=notification&id=${result.id}`\n                )\n            )\n\n            turboAdminLog(item);\n\n            resultsArray.push(item);\n        }\n        return resultsArray;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminMUSites extends TurboAdminPlugin {\n    constructor() {\n        super('WP Multisite Sites');\n\n        this.searchModes.push( new SearchMode('site', 'Sites', this.siteSearch.bind(this), this.defaultSiteItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return Boolean(document.querySelector('#wp-admin-bar-my-sites'));\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultSiteItems() {\n        return await this.siteSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async siteSearch(searchString) {\n        // {\n        //     'detectType': 'dom',\n        //     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n        //     'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n        //     'itemUrlFunction': (element) => element.href\n        // },\n\n        const sites = document.querySelectorAll('#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li');\n\n        if (sites.length === 0) {\n            return [];\n        }\n\n        const sitesArray = Array.from(sites);\n        const sitesLinks = sitesArray.map(site => site.querySelector('a'));\n        const filteredSites = sitesLinks.filter(site => site.innerText.toLowerCase().includes(searchString.toLowerCase()));\n\n        return filteredSites.map(site => {\n            const item = new ContentItem;\n            item.title = site.innerText;\n            item.subtype = 'Site';\n            item.url = site.href;\n\n            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));\n\n            return item;\n        });\n    }\n\n    makeSubmenuItems(siteElement) {\n        const submenuItems = [];\n\n        const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);\n        if (! submenu) {\n            return [];\n        }\n\n        const submenuLinks = submenu.querySelectorAll('a');\n        if (submenuLinks.length === 0) {\n            return [];\n        }\n\n        const submenuLinksArray = Array.from(submenuLinks);\n        submenuLinksArray.forEach(link => {\n            const submenuItem = new SubmenuItem(link.innerText, link.href);\n            submenuItems.push(submenuItem);\n        });\n\n        return submenuItems;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\nimport ItemDefinition from '../types/class-item-definition.js';\n\nexport default class TurboAdminOxygenBuilder extends TurboAdminPlugin {\n    constructor() {\n        super('OxygenBuilder');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasOxygenBuilder = Boolean(oxygenLinkElem);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', hasOxygenBuilder ? '1' : '0' );\n\n        return hasOxygenBuilder;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {Promise<ItemDefinition[]>}\n     */\n     async getAdditionalItemDefinitions() {\n        const editDefinition = new ItemDefinition();\n        editDefinition.detectType = 'dom';\n        editDefinition.detectSelector = '#ct-edit-template-builder';\n        editDefinition.itemTitleFunction = () => 'Edit with Oxygen';\n        editDefinition.itemUrlFunction = (element) => element.href;\n        editDefinition.noCache = true;\n\n        // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n        // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n        // doesn't refresh the menu items.\n        const backToWpDefinition = new ItemDefinition();\n        backToWpDefinition.detectType = 'dom';\n        backToWpDefinition.detectSelector = '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)';\n        backToWpDefinition.itemTitleFunction = (element) => 'Back to WP: ' + element.textContent;\n        backToWpDefinition.itemUrlFunction = (element) => {\n            if (element.href) {\n                return element.href;\n            } else {\n                let url = new URL(window.location.href);\n                return url.origin + url.pathname;\n            }\n        };\n        backToWpDefinition.noCache = true;\n\n        return [\n            editDefinition,\n            backToWpDefinition,\n        ];\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\n\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';\nimport SearchMode from './types/class-search-mode.js';\nimport TurboAdminPlugin from './types/class-turbo-admin-plugin.js';\nimport Acf from './plugins/class-acf.js';\nimport TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\nimport TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';\nimport TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';\nimport TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';\nimport TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';\nimport TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';\nimport TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';\nimport TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';\nimport TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';\n\nexport default class TurboAdmin {\n\n    /**\n     * @param {*} options\n     * @returns {TurboAdmin}\n     */\n    constructor(options) {\n        // Sometimes we get a second copy of TA running, like if the plugin is running too.\n        // Is this case we want to skip the initialisation.\n        this.doInit = true;\n\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            this.doInit = false;\n            return globalThis.turboAdmin;\n        }\n\n        this.options = options;\n        this.plugins = {};\n\n        // TODO: Something? What should this type be?\n        this.searchModes = {};\n\n        // On the front end we set this if there is no saved menu.\n        this.menuNeedsRefresh = false;\n    }\n\n    /**\n     * Perform initialization - this is all the things that do not need APIs to\n     * get set up.\n     */\n    async init() {\n        if (! this.doInit) {\n            return;\n        }\n\n        // Register all the plugins\n        new TurboAdminBarkeeper();\n        new TurboAdminContentSearch();\n        new TurboAdminPluginSearch();\n        new TurboAdminUserSearch();\n        new TurboAdminMUSites();\n        new TurboAdminOxygenBuilder();\n\n        if (window.turboAdminIsExtension()) {\n            new TurboAdminWoocommerce();\n            new TurboAdminGravityForms();\n        }\n\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Check for .logged-in class on body - if logged in, we can use the saved menu,\n                // if it exists.\n                if (document.body.classList.contains('logged-in')) {\n                    // Get from localStorage\n                    const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                    // This attempts to see if we have cached items from the back-en\n                    if (null === savedMenu) {\n                        this.menuNeedsRefresh = true;\n                    } else {\n                        this.menu = JSON.parse(savedMenu);\n                        // Check if there is no \"Media\" item  - this should ONLY be in the back-end\n                        if (! this.menu.some(item => ( ( typeof(item.action) === 'string' ) && ( item.action.endsWith('upload.php') ) ))) {\n                            this.menuNeedsRefresh = true;\n                        }\n                        // Merge (?) the items?\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        await this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n    }\n\n    /**\n     * These are initialization steps that DO needs APIs to be set up.\n     */\n    activatePlugins() {\n        // Initialize all plugins\n        Object.keys(this.plugins).forEach( plugin => {\n            if (this.plugins[plugin].shouldActivate()) {\n                this.plugins[plugin].activate();\n            }\n        })\n\n        if (true === this.options['block-editor-fullscreen-disable']) {\n            // Initialise fullscreen kill\n            this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        }\n\n        if (true === this.options['block-editor-welcome-screen-kill']) {\n            this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    /**\n     * True if the plugin has been activated\n     *\n     * @param {string} name Name of the plugin to check for\n     * @returns {boolean}\n     */\n    hasActivatedPlugin(name) {\n        return Object.keys(this.plugins).includes(name) &&\n            this.plugins[name].activated;\n    }\n\n    /**\n     * Gather the WordPress dashboard admin (sidebar) menu items\n     *\n     * @returns { TurboAdminMenuItem[] }\n     */\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    /**\n     * Adds additional menu items passed in by configuration to the\n     * menu items list.\n     */\n    async addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.\n        let extraItems = this.options.extraItems ?? [];\n\n        // Get any extra items defined by plugins\n        const pluginKeys = Object.keys(this.plugins);\n\n        for (let i=0; i < pluginKeys.length; i++) {\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getSearchModeItemDefinitions());\n            extraItems = extraItems.concat(await this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());\n        }\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                // TODO: Convert to ItemDefinition objects\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.ensureTrailingSlash(globalThis.taWp.siteUrl);\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemActionType': 'url',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'none') {\n                detected = true;\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n                // Just grab any old element. We shouldn't need it.\n                elements = document.querySelectorAll('body');\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = TurboAdminMenuItem.fromItemDefinition(item, element, '');\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    /**\n     * Builds the palette HTML and adds it to the DOM.\n     */\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Palette notice\n        const paletteNotice = document.createElement('div');\n        paletteNotice.id = 'ta-command-palette-notice';\n        // Tab notice\n        const tabNotice = document.createElement('div');\n        tabNotice.id = 'ta-command-palette-tab-notice';\n        // Tab notice text\n        const tabNoticeText = document.createElement('span');\n        tabNoticeText.id = 'ta-command-palette-tab-notice-text';\n        // Tab notice \"button\"\n        const tabNoticeButton = document.createElement('span');\n        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';\n        tabNoticeButton.innerText = 'Tab';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // Search mode tag\n        const searchModeTag = document.createElement('div');\n        searchModeTag.id = 'ta-command-palette-search-mode-tag';\n        // List container (needed to contain the main list and the submenu list)\n        const listContainer = document.createElement('div');\n        listContainer.id = \"ta-command-palette-items-container\";\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Sub-menu list\n        const submenuContainer = document.createElement('div');\n        submenuContainer.id = \"ta-command-palette-submenu-container\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(searchModeTag);\n        palette.appendChild(paletteNotice);\n        tabNotice.appendChild(tabNoticeText);\n        tabNotice.appendChild(tabNoticeButton);\n        palette.appendChild(tabNotice);\n        palette.appendChild(input);\n        listContainer.appendChild(list);\n        listContainer.appendChild(submenuContainer);\n        palette.appendChild(listContainer);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, listContainer );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    /**\n     * Register a plugin with Turbo Admin\n     *\n     * @param {TurboAdminPlugin} plugin\n     */\n    registerPlugin(plugin) {\n        turboAdminLog('Registering plugin ' + plugin.name);\n        this.plugins[plugin.name] = plugin;\n    }\n\n    /**\n     * Register a palette search mode and its associated plugin\n     *\n     * this is usually bound to the searchMode, so\n     *\n     * @param {SearchMode} searchMode\n     */\n    registerSearchMode(searchMode) {\n        turboAdminLog('Registering search mode with keyword ' + searchMode.keyword);\n        // Don't use `this` as we are bound!\n        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;\n    }\n\n    /**\n     * Returns a string representation of the palette's keyboard shortcut\n     *\n     * @returns { String }\n     */\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key.toUpperCase();\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n            let urlsFound = false;\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                const dashboardLink = document.getElementById('wp-admin-bar-dashboard')?.querySelector('a');\n                if (dashboardLink) {\n                    this.siteUrl = dashboardLink.href;\n                }\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    urlsFound = true;\n                } else {\n                    // We might know what the siteUrl is, so guess the home from the siteUrl\n                    if (this.siteUrl) {\n                        this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                        urlsFound = true;\n                    }\n                }\n            }\n            if (! urlsFound) {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                    urlsFound = true;\n                }\n            }\n            if (! urlsFound) {\n                // We got nothing.\n                this.home    = await this.guessHome();\n                if (this.home) {\n                    this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // turboAdminLog('siteUrl: ', this.siteUrl);\n        // turboAdminLog('home: ', this.home);\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class WoocommerceApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getOrders(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['orders-' + searchString]) {\n            return this.cache['orders-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"orders\",\n            {\n                search: searchString,\n                per_page: 100,\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['orders-' + searchString] = result;\n\n        return result;\n    }\n\n    async getOrder(orderId) {\n        // Check the cache\n        if (undefined !== this.cache['order-' + orderId]) {\n            return this.cache['order-' + orderId];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            `orders/${orderId}`\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        let resultAsArray = [ result ];\n\n        // Store in the cache\n        this.cache['order-' + orderId] = resultAsArray;\n\n        return resultAsArray;\n    }\n\n    async getCustomers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['customers-' + searchString]) {\n            return this.cache['customers-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"customers\",\n            {\n                search: searchString,\n                per_page: 100,\n                role: 'all',\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['customers-' + searchString] = result;\n\n        return result;\n    }\n\n    // TODO: Add docblock and types\n    async wooGet(path, data = {}) {\n        const wooApiBase = globalThis.contentApi.apiRoot + 'wc/v3/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${wooApiBase}${path}/?${params}`, init);\n\n        if ( response.status === 404 ) {\n            return false;\n        }\n        if ( (response.status < 200 || response.status >= 300) ) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WooCommerce API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: WooCommerce API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class GravityFormsApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getForms(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['gf-forms-' + searchString]) {\n            return this.cache['gf-forms-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.gfGet(\n            \"forms\",\n            {}\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // TODO: Trap for errors\n\n        // Filter by search string - the API doesn't do this for us\n        const searchStringLowerCase = searchString.toLowerCase();\n        const formIds = Object.keys(result);\n        for (let k = 0; k < formIds.length; k++) {\n            const thisId = formIds[k];\n            if (! result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {\n                delete result[thisId];\n            }\n        }\n\n        // Store in the cache\n        this.cache['gf-forms-' + searchString] = result;\n\n        return result;\n    }\n\n    async gfGet(path, data = {}) {\n        const gfApiBase = globalThis.contentApi.apiRoot + 'gf/v2/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${gfApiBase}${path}/?${params}`);\n\n        if (response.status < 200 || response.status >= 300) {\n            // TODO: Set a \"deferred\" notice to show when the palette is created?\n            if (globalThis.turboAdmin && globalThis.turboAdmin.turboAdminPalette) {\n                globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Gravity Forms API Error. Try visiting the dashboard to refresh things.');\n            } else {\n                // Always log this as people may look\n                turboAdminLog('TURBO ADMIN: Gravity Forms API Error. Try visiting the WordPress Dashboard to refresh things.');\n            }\n        }\n\n        return response;\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './apis/class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport WoocommerceApi from './apis/class-woocommerce-api.js';\nimport GravityFormsApi from './apis/class-gravity-forms-api.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\nlet debugMode = false;\n\nwindow.turboAdminLog = function() {\n    if (debugMode) {\n        console.log(...arguments);\n    }\n}\n\nwindow.turboAdminIsExtension = function() {\n    return false;\n}\n\n// Use this to clear storage\n// chrome.storage.local.remove(taStorageKey).then();\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    if (typeof(globalThis.turboAdmin) !== 'undefined') {\n        // Already initialised for some reason\n        return;\n    }\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    // Set debug mode\n    debugMode = globalThis.turboAdminOptions['debug-mode'];\n\n    turboAdminLog('Preparing Turbo Admin');\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    turboAdminLog('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n    await globalThis.contentApi.discoverPostTypes();\n    globalThis.woocommerceApi = new WoocommerceApi();\n    globalThis.gravityFormsApi = new GravityFormsApi();\n\n    turboAdminLog('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n    await globalThis.turboAdmin.init();\n\n    // This needs all the APIs to be ready\n    await globalThis.turboAdmin.activatePlugins();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n        'debug-mode': globalThis.wpTurboAdmin['debugMode'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
     5  "mappings": "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",
    66  "names": []
    77}
  • turbo-admin/trunk/readme.txt

    r3013724 r3122653  
    44Tags: menu, commands, shortcuts
    55Requires at least: 4.9
    6 Tested up to: 6.4
     6Tested up to: 6.6
    77Requires PHP: 7.4
    8 Stable tag: 1.13.3
     8Stable tag: 1.15.2
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    185185== Changelog ==
    186186
     187= 1.15.2 =
     188
     189* [Enhancement] List table keyboard shortcuts now work on the "Add New Plugin" screen.
     190* [Enhancement] List table keyboard shortcuts now scroll the selected element into view.
     191
     192= 1.15.1 =
     193
     194* Incorporates all changes from  versions up to 1.15.1 of the browser extension.
     195* [Feature] The "Auto-remove block editor welcome screen" feature now hides the pattern selector on the new page screen, and the welcome page on the dashboard.
     196* [Feature] New features as part of the List table keyboard shortcuts.
     197* [Enhancement] Added stg., .wpenginepowered.com, .bigscoots-staging.com, .azurewebsites.net and localhost as dev/staging URLs.
     198* [Enhancement] Show search modes in the command palette.
     199* [Fix] Firefox bug fix in the plugin code.
     200* [Fix] Restore the input state after a search action.
     201* [Fix] Fix annoying issue with login links on LocalWP.
     202* [Fix] Fix list table keyboard shortcuts on plugins screen.
     203
    187204= 1.13.3 =
    188205
  • turbo-admin/trunk/src/class-list-table-shortcuts.js

    r2871191 r3122653  
    1818
    1919        /**
     20         * @type {boolean}
     21         */
     22        this.actionsOpen = false;
     23
     24        /**
    2025         * @type {HTMLTableElement}
    2126         */
    2227        this.listTable = document.querySelector('.wp-list-table');
    2328
    24         if (! this.listTable) {
    25             return;
    26         }
     29        /**
     30         * @type {boolean}
     31         */
     32        this.isWooCommerce = false;
     33
     34        /**
     35         * @type {boolean}
     36         */
     37        this.isPluginInstall = false;
     38
     39        if (!this.listTable) {
     40            return;
     41        }
     42
     43        // We make some VERY special exceptions for WooCommerce
     44        if (document.body.classList.contains('woocommerce-admin-page') &&
     45            document.body.classList.contains('post-type-shop_order')) {
     46            this.isWooCommerce = true;
     47        }
     48
     49        // And for the add plugins screen
     50        if (document.body.classList.contains('plugin-install-php')) {
     51            this.isPluginInstall = true;
     52        }
     53
     54        /**
     55         * @type {Boolean}
     56         */
     57        this.isMac = globalThis.turboAdmin.turboAdminPalette.isMac();
    2758
    2859        /**
     
    3162        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');
    3263
    33         document.addEventListener('keyup', e => this.handleKeyup(e));
     64        // Plugin install is different.
     65        if (this.isPluginInstall) {
     66            this.tableRows = this.listTable.querySelectorAll('#the-list .plugin-card');
     67        }
     68
     69        // Grr... comments list is different! WHY?!
     70        if (document.body.classList.contains('edit-comments-php')) {
     71            this.tableRows = this.listTable.querySelectorAll('tbody#the-comment-list > tr');
     72        }
     73
     74        document.addEventListener('keydown', e => this.handleKey(e));
     75
     76        // Chrome handles escape key on search input elements, so we need to
     77        // intercept it here.
     78        const searchInput = document.querySelector(
     79            '.search-box input[type="search"], .search-form input[type="search"]'
     80        );
     81
     82        if (searchInput) {
     83            searchInput.addEventListener('keyup', e => this.handleSearchInputKey(e));
     84        }
    3485    }
    3586
     
    3889     * @param {KeyboardEvent} ev
    3990     */
    40     handleKeyup(ev) {
    41         if (document.activeElement.tagName !== 'BODY') {
    42             return;
    43         }
    44 
     91    handleKey(ev) {
     92        const isActiveElementBody = document.activeElement.tagName === 'BODY';
     93        const isActiveElementInListTable = this.listTable && this.listTable.contains(document.activeElement);
     94        const isSearchFocussed = this.getSearchInputElement() === document.activeElement;
     95        if ((!isActiveElementBody && !isActiveElementInListTable) || isSearchFocussed) {
     96            return;
     97        }
     98        if (globalThis.turboAdmin.turboAdminPalette.isPaletteOpen()) {
     99            return;
     100        }
    45101        if (ev.key === 'j') {
    46             this.tableMoveDown();
     102            if (this.actionsOpen) {
     103                this.actionMoveDown();
     104            } else {
     105                this.tableMoveDown();
     106            }
    47107        } else if (ev.key === 'k') {
    48             this.tableMoveUp();
     108            if (this.actionsOpen) {
     109                this.actionMoveUp();
     110            } else {
     111                this.tableMoveUp();
     112            }
    49113        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {
    50             this.openTableRowItem();
    51         }
    52 
     114            if (this.actionsOpen) {
     115                this.openCurrentRowAction(ev);
     116                ev.preventDefault();
     117            } else {
     118                this.openTableRowActions(ev);
     119            }
     120        } else if (ev.key === '/') {
     121            this.focusSearch(ev);
     122        } else if (ev.key === 'f' && ev.ctrlKey) {
     123            this.nextPage(ev);
     124        } else if (ev.key === 'b' && ev.ctrlKey) {
     125            this.prevPage(ev);
     126        } else if (ev.key === 'ArrowDown') {
     127            if (this.actionsOpen) {
     128                this.actionMoveDown(ev);
     129            }
     130        } else if (ev.key === 'ArrowUp') {
     131            if (this.actionsOpen) {
     132                this.actionMoveUp(ev);
     133            }
     134        } else if (ev.key.toLowerCase() === 'escape' /* && !document.body.classList.contains('modal-open')*/) {
     135            if (this.actionsOpen) {
     136                this.closeTableRowActions(ev);
     137            }
     138            // If the search box is focussed... Note that Chrome does its own thing with escape here.
     139            if (document.getElementById('post-search-input') === document.activeElement) {
     140                document.getElementById('post-search-input').blur();
     141            }
     142        }
     143
     144    }
     145
     146    handleSearchInputKey(ev) {
     147        if (ev.key.toLowerCase() === 'escape') {
     148            ev.target.blur();
     149        }
     150    }
     151
     152    getSearchInputElement() {
     153        return document.querySelector('.search-box input[type="search"], .search-form input[type="search"]');
    53154    }
    54155
    55156    tableMoveDown() {
    56157        this.preTableChange();
    57 
    58158        // Move down
    59159        if (this.currentRow === null) {
     
    84184        this.currentRow = this.tableRows[this.currentRowIndex];
    85185
    86         if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {
     186        if (!this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {
    87187            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');
    88188        }
    89     }
    90 
    91     openTableRowItem() {
     189
     190        this.scrollIntoViewIfNeeded(this.currentRow);
     191    }
     192
     193    /**
     194     * Scrolls the element into view if it is not already.
     195     */
     196    scrollIntoViewIfNeeded(element) {
     197        const elementRect = element.getBoundingClientRect();
     198        const elementTop = elementRect.top;
     199        const elementBottom = elementRect.bottom;
     200        const viewportTop = 0;
     201        const viewportBottom = window.innerHeight;
     202        if (elementBottom > viewportBottom) {
     203            element.scrollIntoView({ behavior: "smooth", block: "end" });
     204        } else if (elementTop < viewportTop) {
     205            element.scrollIntoView({ behavior: "smooth", block: "start" });
     206        }
     207    }
     208
     209    /**
     210     * Gets the list table row actions container for the current row
     211     */
     212    getRowActionsContainer() {
     213        let container = this.currentRow.querySelector('.row-actions');
     214
     215        if (this.isPluginInstall) {
     216            container = this.currentRow.querySelector('.plugin-action-buttons');
     217        }
     218
     219        return container;
     220    }
     221
     222    /**
     223     * Gets list table row actions for the current row
     224     */
     225    getRowActions() {
     226        let rowActions = this.currentRow.querySelectorAll('.row-actions span a, .row-actions span button');
     227
     228        if (this.isPluginInstall) {
     229            rowActions = this.currentRow.querySelectorAll('.plugin-action-buttons a');
     230        }
     231
     232        return rowActions;
     233    }
     234
     235    openTableRowActions(ev) {
    92236        turboAdminLog(this);
     237
     238        // WooCommerce doesn't have row actions, so we just find the link and visit it
     239        if (this.isWooCommerce) {
     240            this.currentRow.querySelector('a.order-view').click();
     241            return;
     242        }
     243
     244        this.actionsOpen = true;
     245
     246        let rowActions = this.getRowActionsContainer();
     247
     248        if (rowActions) {
     249            rowActions.classList.add('visible');
     250        }
     251
     252        const titleElem = this.currentRow.querySelector('strong');
     253        const titleLink = titleElem.querySelector('a');
     254
     255        if (titleLink) {
     256            titleLink.classList.add('ta-active-table-row-link');
     257            return;
     258        }
     259
     260        let rowActionLinks = this.getRowActions();
     261
     262        if (rowActionLinks) {
     263            rowActionLinks[0].classList.add('ta-active-table-row-link');
     264        }
     265    }
     266
     267    closeTableRowActions(ev) {
     268        turboAdminLog(this);
     269        const rowActions = this.currentRow.querySelector('.row-actions');
     270
     271        // Don't do this on plugins screen!
     272        if (!document.body.classList.contains('plugins-php')) {
     273            if (rowActions) {
     274                rowActions.classList.remove('visible');
     275            }
     276        }
     277
     278        const activeLink = document.querySelector('.ta-active-table-row-link');
     279        if (activeLink) {
     280            activeLink.classList.remove('ta-active-table-row-link');
     281        }
     282
     283        this.actionsOpen = false;
     284    }
     285
     286    actionMoveDown(ev) {
     287        /** @type {HTMLElement} */
     288        const currentLink = document.querySelector('.ta-active-table-row-link');
     289
     290        // Handle the case where the title link is selected
     291        if (currentLink.closest('strong')) {
     292            const rowActions = this.getRowActions();
     293            if (rowActions) {
     294                rowActions[0].classList.add('ta-active-table-row-link');
     295                currentLink.classList.remove('ta-active-table-row-link');
     296            }
     297            return;
     298        }
     299
     300        /** @type {HTMLElement} */
     301        const nextLink = currentLink.parentElement?.nextElementSibling?.querySelector('a, button');
     302        if (nextLink) {
     303            nextLink.classList.add('ta-active-table-row-link');
     304            currentLink.classList.remove('ta-active-table-row-link');
     305        }
     306    }
     307
     308    actionMoveUp(ev) {
     309        /** @type {HTMLElement} */
     310        const currentLink = document.querySelector('.ta-active-table-row-link');
     311
     312        // Handle the case where the title link is selected
     313        if (currentLink.closest('strong')) {
     314            return;
     315        }
     316
     317        /** @type {HTMLElement} */
     318        const prevLink = currentLink.parentElement?.previousElementSibling?.querySelector('a, button');
     319
     320        // Handle the case where the first item is selected and we need to go back to the title
     321        if (!prevLink) {
     322            const titleLink = this.currentRow.querySelector('strong a');
     323            if (titleLink) {
     324                titleLink.classList.add('ta-active-table-row-link');
     325                currentLink.classList.remove('ta-active-table-row-link');
     326            }
     327            return;
     328        }
     329
     330        prevLink.classList.add('ta-active-table-row-link');
     331        currentLink.classList.remove('ta-active-table-row-link');
     332    }
     333
     334    openCurrentRowAction(ev) {
     335        // TODO: Open the current row action
     336        /** @type {HTMLElement} */
     337        const currentLink = document.querySelector('.ta-active-table-row-link');
     338        // Don't do this for plugin install screen
     339        if (currentLink) {
     340            currentLink.click();
     341        }
     342    }
     343
     344    focusSearch(ev) {
     345        /** @type {HTMLInputElement} */
     346        const searchInput = this.getSearchInputElement();
     347
     348        if (searchInput) {
     349            searchInput.focus();
     350            this.scrollIntoViewIfNeeded(searchInput);
     351            ev.preventDefault();
     352        }
     353    }
     354
     355    nextPage(ev) {
    93356        /** @type {HTMLAnchorElement} */
    94         const link = this.currentRow.querySelector('a.row-title');
    95         if (link) {
    96             link.click();
     357        const nextPageLink = document.querySelector('.tablenav-pages .next-page');
     358        if (nextPageLink) {
     359            nextPageLink.click();
     360            ev.preventDefault();
     361        }
     362    }
     363
     364    prevPage(ev) {
     365        /** @type {HTMLAnchorElement} */
     366        const prevPageLink = document.querySelector('.tablenav-pages .prev-page');
     367        if (prevPageLink) {
     368            prevPageLink.click();
     369            ev.preventDefault();
    97370        }
    98371    }
  • turbo-admin/trunk/src/class-turbo-admin-palette.js

    r2919322 r3122653  
    461461        if (e.code === 'ArrowDown' && this.paletteShown()) {
    462462            e.preventDefault();
     463            e.stopImmediatePropagation();
     464            e.stopPropagation();
    463465            this.moveDown();
    464466            return;
     
    466468        if (e.code === 'ArrowUp' && this.paletteShown()) {
    467469            e.preventDefault();
     470            e.stopImmediatePropagation();
     471            e.stopPropagation();
    468472            this.moveUp();
    469473            return;
     
    471475        if (e.code === 'Enter' && this.paletteShown()) {
    472476            e.preventDefault();
     477            e.stopImmediatePropagation();
     478            e.stopPropagation();
    473479            this.doAction(this.metaPressed(e));
    474480            return;
  • turbo-admin/trunk/src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js

    r2702218 r3122653  
    11/**
    2  *
     2 * Kills/auto-removes:
     3 *  - the Welcome Guide on the post edit screen
     4 *  - the pattern selector modal on the post edit screen
     5 *  - the Welcome Panel on the dashboard on new sites
    36 */
    47export default class TurboAdminWpBlockEditorWelcomeGuideKill {
    58
    69    constructor() {
    7 
    810        const attrObserver = new MutationObserver((mutations) => {
    911            mutations.forEach(mu => {
     
    1719                }
    1820
    19                 if (! mu.target.classList.contains('modal-open')) {
     21                if (!mu.target.classList.contains('modal-open')) {
    2022                    return;
    2123                }
    2224
     25                console.log('Modal detected');
    2326                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');
    24                 if (welcomeGuide) {
     27                const newPagePatterns = document.querySelector('.edit-post-start-page-options__modal');
     28                const newPagePatterns2 = document.querySelector('.editor-start-page-options__modal-content');
     29
     30                if (welcomeGuide || newPagePatterns || newPagePatterns2) {
    2531                    this.killWelcomeGuide();
    2632                }
     
    3238        // Also attempt a kill now in case it's already appeared.
    3339        this.killWelcomeGuide();
     40
     41        // Attempt a kill of the dashboard welcome panel
     42        this.killDashboardWelcomePanel();
    3443    }
    3544
    3645    killWelcomeGuide() {
    37         const welcomeGuide = document.querySelector('.edit-post-welcome-guide');
     46        // Check for welcome guide
     47        let welcomeGuide = document.querySelector('.edit-post-welcome-guide');
     48        // Check for new page patterns modal (old: pre-6.6?)
     49        if (!welcomeGuide) {
     50            welcomeGuide = document.querySelector('.edit-post-start-page-options__modal');
     51        }
     52        // Check for new page patterns model (new: 6.6+)
     53        if (!welcomeGuide) {
     54            welcomeGuide = document.querySelector('.editor-start-page-options__modal-content');
     55        }
     56
    3857        if (welcomeGuide) {
    39             const closeButton = welcomeGuide.querySelector('.components-modal__header button');
     58            const closeButton = document.querySelector('.components-modal__header button');
    4059            if (closeButton) {
    4160                closeButton.click();
     
    4867        }
    4968    }
     69
     70    killDashboardWelcomePanel() {
     71        const welcomePanel = document.getElementById('welcome-panel');
     72        if (!welcomePanel) {
     73            return;
     74        }
     75        const welcomePanelClose = welcomePanel.querySelector('.welcome-panel-close');
     76        if (welcomePanelClose) {
     77            welcomePanelClose.click();
     78        }
     79    }
    5080}
  • turbo-admin/trunk/src/class-turbo-admin-wp-notices.js

    r2871191 r3122653  
    217217        this.rememberedNoticeIds.push(noticeId);
    218218
    219         if ('object' === typeof(browser)) {
     219        if ('object' === typeof(chrome)) {
    220220            chrome.runtime.sendMessage({
    221221                'action': 'rememberNotice',
     
    260260        this.rememberedNoticeIds.push(noticeId);
    261261
    262         if ('object' === typeof(browser)) {
     262        if ('object' === typeof(chrome)) {
    263263            chrome.runtime.sendMessage({
    264264                'action': 'rememberNotice',
  • turbo-admin/trunk/src/class-turbo-admin.js

    r2919322 r3122653  
    360360                    'itemUrlFunction': () => {
    361361                        if (globalThis.taWp.home) {
    362                             return globalThis.taWp.siteUrl;
     362                            return globalThis.taWp.ensureTrailingSlash(globalThis.taWp.siteUrl);
    363363                        }
    364364                        // Try getting wp-admin
  • turbo-admin/trunk/turbo-admin.css

    r2871191 r3122653  
    584584}
    585585
     586.has-row-actions .ta-active-table-row-link,
     587.plugin-title .ta-active-table-row-link,
     588.plugin-card .name .ta-active-table-row-link,
     589.plugin-action-buttons .ta-active-table-row-link {
     590    text-decoration: underline !important;
     591}
     592
    586593/**
    587594 * Barkeeper
  • turbo-admin/trunk/turbo-admin.php

    r2919322 r3122653  
    33/**
    44 * Plugin Name:     Turbo Admin
    5  * Plugin URI:      https://oikos.digital/turbo-admin
     5 * Plugin URI:      https://turbo-admin.com/
    66 * Description:     The command palette that gives super fast access to your WordPress Dashboard.
    77 * Author:          Ross Wintle
     
    99 * Text Domain:     turbo-admin
    1010 * Domain Path:     /languages
    11  * Version:         1.13.3
     11 * Version:         1.15.2
    1212 *
    13  * @package         Turbo_Admin
     13 * @package Turbo_Admin
    1414 */
    1515
     
    4141function add_admin_scripts()
    4242{
    43     if (is_user_logged_in()) {
    44         $userShortcutKeys   = userShortcutKeys();
    45         $hideNotices        = get_user_meta( get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true );
    46         $adminBarSearch     = get_user_meta( get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true );
    47         $barkeeper          = get_user_meta( get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true );
    48         $listTableShortcuts = get_user_meta( get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true );
    49         $debugMode          = get_user_meta( get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true );
    50 
    51         // We will pass an array of shortcut key objects into the JS
    52         $shortcutKeys = [
    53             $userShortcutKeys
    54         ];
    55 
    56         wp_enqueue_script('turbo-admin-scripts', plugin_dir_url(__FILE__) . 'dist/main.min.js', [], null, true);
    57         wp_enqueue_style('turbo-admin-styles', plugin_dir_url(__FILE__) . 'turbo-admin.css', []);
    58 
    59         wp_localize_script( 'turbo-admin-scripts', 'wpTurboAdmin', [
    60             'keys'               => $shortcutKeys,
    61             'hideNotices'        => intval( $hideNotices ) === 1,
    62             'adminBarSearch'     => intval( $adminBarSearch ) === 1,
    63             'barkeeper'          => intval( $barkeeper ) === 1,
    64             'listTableShortcuts' => intval( $listTableShortcuts ) === 1,
    65             'debugMode'          => intval( $debugMode ) === 1,
    66         ] );
    67     }
     43    if (is_user_logged_in()) {
     44        $userShortcutKeys   = userShortcutKeys();
     45        $hideNotices        = get_user_meta(get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true);
     46        $adminBarSearch     = get_user_meta(get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true);
     47        $barkeeper          = get_user_meta(get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true);
     48        $listTableShortcuts = get_user_meta(get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true);
     49        $debugMode          = get_user_meta(get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true);
     50
     51        // We will pass an array of shortcut key objects into the JS
     52        $shortcutKeys = [
     53        $userShortcutKeys
     54        ];
     55
     56        wp_enqueue_script('turbo-admin-scripts', plugin_dir_url(__FILE__) . 'dist/main.min.js', [], null, true);
     57        wp_enqueue_style('turbo-admin-styles', plugin_dir_url(__FILE__) . 'turbo-admin.css', []);
     58
     59        wp_localize_script(
     60            'turbo-admin-scripts', 'wpTurboAdmin', [
     61            'keys'               => $shortcutKeys,
     62            'hideNotices'        => intval($hideNotices) === 1,
     63            'adminBarSearch'     => intval($adminBarSearch) === 1,
     64            'barkeeper'          => intval($barkeeper) === 1,
     65            'listTableShortcuts' => intval($listTableShortcuts) === 1,
     66            'debugMode'          => intval($debugMode) === 1,
     67            ]
     68        );
     69    }
    6870}
    6971
     
    7577    }
    7678
    77     $userShortcutKeys = userShortcutKeys();
    78 
    79     $keysTextArray = [];
    80 
    81     if ($userShortcutKeys['meta']) {
    82         $keysTextArray[] = 'Cmd';
    83     }
    84     if ($userShortcutKeys['alt']) {
    85         $keysTextArray[] = 'Alt';
    86     }
    87     if ($userShortcutKeys['ctrl']) {
    88         $keysTextArray[] = 'Ctrl';
    89     }
    90     if ($userShortcutKeys['shift']) {
    91         $keysTextArray[] = 'Shift';
    92     }
    93     $keysTextArray[] = $userShortcutKeys['key'] === ' ' ? 'Space' : strtoupper($userShortcutKeys['key']);
    94 
    95     $keysText = implode('-', $keysTextArray);
    96 
    97     $admin_bar->add_menu(array(
    98         'id'    => 'turbo-admin',
    99         'parent' => null,
    100         'group'  => null,
    101         'title' => '<span class="ab-icon" style="margin-right: 0;"><img src="' . plugin_dir_url(__FILE__) . '/images/snail.svg' . '" style="display: block; width: 24px; height: 24px;"></span>',
    102         'href'  => null,
    103         'meta' => [
    104             'title' => sprintf(__('Turbo admin is installed! Use %s to open the command palette.', 'turbo-admin'), $keysText), //This title will show on hover
    105         ]
    106     ));
     79    $userShortcutKeys = userShortcutKeys();
     80
     81    $keysTextArray = [];
     82
     83    if ($userShortcutKeys['meta']) {
     84        $keysTextArray[] = 'Cmd';
     85    }
     86    if ($userShortcutKeys['alt']) {
     87        $keysTextArray[] = 'Alt';
     88    }
     89    if ($userShortcutKeys['ctrl']) {
     90        $keysTextArray[] = 'Ctrl';
     91    }
     92    if ($userShortcutKeys['shift']) {
     93        $keysTextArray[] = 'Shift';
     94    }
     95    $keysTextArray[] = $userShortcutKeys['key'] === ' ' ? 'Space' : strtoupper($userShortcutKeys['key']);
     96
     97    $keysText = implode('-', $keysTextArray);
     98
     99    $admin_bar->add_menu(
     100        array(
     101        'id'    => 'turbo-admin',
     102        'parent' => null,
     103        'group'  => null,
     104        'title' => '<span class="ab-icon" style="margin-right: 0;"><img src="' . plugin_dir_url(__FILE__) . '/images/snail.svg' . '" style="display: block; width: 24px; height: 24px;"></span>',
     105        'href'  => null,
     106        'meta' => [
     107        'title' => sprintf(__('Turbo admin is installed! Use %s to open the command palette.', 'turbo-admin'), $keysText), //This title will show on hover
     108        ]
     109        )
     110    );
    107111}
    108112
     
    110114add_action('edit_user_profile', 'TurboAdmin\show_profile_fields');
    111115
    112 function get_hide_icon($user_id) {
     116function get_hide_icon($user_id)
     117{
    113118    $hideIcon = get_user_meta($user_id, TURBO_ADMIN_HIDE_ICON_META_NAME, true);
    114119
     
    122127function show_profile_fields($user)
    123128{
    124     $shortcut = get_user_meta($user->ID, TURBO_ADMIN_SHORTCUT_META_NAME, true);
    125     if (empty($shortcut)) {
    126         $shortcut = defaultShortcutKeys();
    127     }
     129    $shortcut = get_user_meta($user->ID, TURBO_ADMIN_SHORTCUT_META_NAME, true);
     130    if (empty($shortcut)) {
     131        $shortcut = defaultShortcutKeys();
     132    }
    128133    $hideIcon = get_hide_icon($user->ID);
    129     $hideNotices        = get_user_meta( get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true );
    130     $adminBarSearch     = get_user_meta( get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true );
    131     $barkeeper          = get_user_meta( get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true );
    132     $listTableShortcuts = get_user_meta( get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true );
    133     $debugMode          = get_user_meta( get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true );
    134 ?>
    135     <h3><?php _e('Turbo Admin settings', 'turbo_admin') ?></h3>
    136     <table class="form-table">
    137         <tr>
    138             <th><label for="turbo-admin-shortcut"><?php _e('Keyboard shortcut', 'turbo_admin') ?></label></th>
    139             <td>
    140                 <label style="margin-right: 18px;">
    141                     <input type="checkbox" name="turbo-admin-meta-key" <?php checked($shortcut['meta']) ?>></input>
    142                     <?php _e('Cmd (Mac only)', 'turbo_admin') ?>
    143                 </label>
    144                 <label style="margin-right: 18px;">
    145                     <input type="checkbox" name="turbo-admin-alt-key" <?php checked($shortcut['alt']) ?>></input>
    146                     <?php _e('Alt/option', 'turbo_admin') ?>
    147                 </label>
    148                 <label style="margin-right: 18px;">
    149                     <input type="checkbox" name="turbo-admin-ctrl-key" <?php checked($shortcut['ctrl']) ?>></input>
    150                     <?php _e('Ctrl', 'turbo_admin') ?>
    151                 </label>
    152                 <label style="margin-right: 18px;">
    153                     <input type="checkbox" name="turbo-admin-shift-key" <?php checked($shortcut['shift']) ?>></input>
    154                     <?php _e('Shift', 'turbo_admin') ?>
    155                 </label>
    156                 <input type="text" required name="turbo-admin-shortcut" id="turbo-admin-shortcut" minLength="1" maxLength="1" value="<?php echo esc_attr($shortcut['key']); ?>" class="regular-text" /><br />
    157                 <span class="description"><?php _e('Please enter the keyboard shortcut you want to use to activate the Turbo Admin command palette.<br>
    158                 Do not choose a keyboard combination that your browser already uses.', 'turbo_admin') ?></span>
    159             </td>
    160         </tr>
    161         <tr>
    162             <th><label for="turbo-admin-hide-icon"><?php _e('Hide admin bar icon', 'turbo_admin') ?></label></th>
    163             <td>
    164                 <label style="margin-right: 18px;">
    165                     <input type="radio" name="turbo-admin-hide-icon" value="1" <?php checked($hideIcon, 1) ?>></input>
    166                     <?php _e('Hide icon', 'turbo_admin') ?>
    167                 </label>
    168                 <label style="margin-right: 18px;">
    169                     <input type="radio" name="turbo-admin-hide-icon" value="0" <?php checked($hideIcon, 0) ?>></input>
    170                     <?php _e('Show icon', 'turbo_admin') ?>
    171                 </label>
    172             </td>
    173         </tr>
     134    $hideNotices        = get_user_meta(get_current_user_id(), TURBO_ADMIN_HIDE_NOTICES_META_NAME, true);
     135    $adminBarSearch     = get_user_meta(get_current_user_id(), TURBO_ADMIN_ADMIN_BAR_SEARCH_META_NAME, true);
     136    $barkeeper          = get_user_meta(get_current_user_id(), TURBO_ADMIN_BARKEEPER_META_NAME, true);
     137    $listTableShortcuts = get_user_meta(get_current_user_id(), TURBO_ADMIN_LIST_TABLE_SHORTCUTS_NAME, true);
     138    $debugMode          = get_user_meta(get_current_user_id(), TURBO_ADMIN_DEBUG_MODE_NAME, true);
     139    ?>
     140    <h3><?php _e('Turbo Admin settings', 'turbo_admin') ?></h3>
     141    <table class="form-table">
    174142        <tr>
    175             <th>
     143            <th><label for="turbo-admin-shortcut"><?php _e('Keyboard shortcut', 'turbo_admin') ?></label></th>
     144            <td>
     145                <label style="margin-right: 18px;">
     146                    <input type="checkbox" name="turbo-admin-meta-key" <?php checked($shortcut['meta']) ?>></input>
     147                    <?php _e('Cmd (Mac only)', 'turbo_admin') ?>
     148                </label>
     149                <label style="margin-right: 18px;">
     150                    <input type="checkbox" name="turbo-admin-alt-key" <?php checked($shortcut['alt']) ?>></input>
     151                    <?php _e('Alt/option', 'turbo_admin') ?>
     152                </label>
     153                <label style="margin-right: 18px;">
     154                    <input type="checkbox" name="turbo-admin-ctrl-key" <?php checked($shortcut['ctrl']) ?>></input>
     155                    <?php _e('Ctrl', 'turbo_admin') ?>
     156                </label>
     157                <label style="margin-right: 18px;">
     158                    <input type="checkbox" name="turbo-admin-shift-key" <?php checked($shortcut['shift']) ?>></input>
     159                    <?php _e('Shift', 'turbo_admin') ?>
     160                </label>
     161                <input type="text" required name="turbo-admin-shortcut" id="turbo-admin-shortcut" minLength="1" maxLength="1" value="<?php echo esc_attr($shortcut['key']); ?>" class="regular-text" /><br />
     162                <span class="description"><?php _e(
     163                    'Please enter the keyboard shortcut you want to use to activate the Turbo Admin command palette.<br>
     164                Do not choose a keyboard combination that your browser already uses.', 'turbo_admin'
     165                ) ?></span>
     166            </td>
     167        </tr>
     168        <tr>
     169            <th><label for="turbo-admin-hide-icon"><?php _e('Hide admin bar icon', 'turbo_admin') ?></label></th>
     170            <td>
     171                <label style="margin-right: 18px;">
     172                    <input type="radio" name="turbo-admin-hide-icon" value="1" <?php checked($hideIcon, 1) ?>></input>
     173                    <?php _e('Hide icon', 'turbo_admin') ?>
     174                </label>
     175                <label style="margin-right: 18px;">
     176                    <input type="radio" name="turbo-admin-hide-icon" value="0" <?php checked($hideIcon, 0) ?>></input>
     177                    <?php _e('Show icon', 'turbo_admin') ?>
     178                </label>
     179            </td>
     180        </tr>
     181        <tr>
     182            <th>
    176183                <label for="turbo-admin-additional-features"><?php _e('Additional features', 'turbo_admin') ?></label>
    177184            </th>
    178             <td>
     185            <td>
    179186                <label for="turbo-admin-hide-notices">
    180                     <input name="turbo-admin-hide-notices" type="checkbox" id="turbo-admin-hide-notices" value="1" <?php checked($hideNotices) ?>>
    181                     Hide notices (experimental)
     187                    <input name="turbo-admin-hide-notices" type="checkbox" id="turbo-admin-hide-notices" value="1" <?php checked($hideNotices) ?>>
     188                    Hide notices (experimental)
    182189                </label>
    183190                <br>
     
    203210            </td>
    204211        </tr>
    205     </table>
    206 
    207 <?php
     212    </table>
     213
     214    <?php
    208215}
    209216
     
    214221{
    215222
    216     if (!current_user_can('edit_user', $user_id)) {
    217         return false;
    218     }
    219 
    220     $shortcut = [];
    221 
    222     $shortcut['meta'] = isset($_POST['turbo-admin-meta-key']);
    223     $shortcut['alt'] = isset($_POST['turbo-admin-alt-key']);
    224     $shortcut['ctrl'] = isset($_POST['turbo-admin-ctrl-key']);
    225     $shortcut['shift'] = isset($_POST['turbo-admin-shift-key']);
    226     $shortcut['key'] = isset($_POST['turbo-admin-shortcut']) ? esc_attr($_POST['turbo-admin-shortcut']) : 'P';
    227 
    228     update_user_meta($user_id, TURBO_ADMIN_SHORTCUT_META_NAME, $shortcut);
     223    if (!current_user_can('edit_user', $user_id)) {
     224        return false;
     225    }
     226
     227    $shortcut = [];
     228
     229    $shortcut['meta'] = isset($_POST['turbo-admin-meta-key']);
     230    $shortcut['alt'] = isset($_POST['turbo-admin-alt-key']);
     231    $shortcut['ctrl'] = isset($_POST['turbo-admin-ctrl-key']);
     232    $shortcut['shift'] = isset($_POST['turbo-admin-shift-key']);
     233    $shortcut['key'] = isset($_POST['turbo-admin-shortcut']) ? esc_attr($_POST['turbo-admin-shortcut']) : 'P';
     234
     235    update_user_meta($user_id, TURBO_ADMIN_SHORTCUT_META_NAME, $shortcut);
    229236
    230237    if (isset($_POST['turbo-admin-hide-icon']) && in_array(intval($_POST['turbo-admin-hide-icon']), [0, 1], true) ) {
     
    261268 * This returns the user-specified key combo if set, or the default one if not
    262269 */
    263 function userShortcutKeys() {
    264     $userShortcutKeys = get_user_meta(get_current_user_id(), TURBO_ADMIN_SHORTCUT_META_NAME, true);
    265 
    266     if (! $userShortcutKeys) {
    267         return defaultShortcutKeys();
    268     }
    269 
    270     return $userShortcutKeys;
    271 }
    272 
    273 function defaultShortcutKeys() {
    274     $shortcut = [
    275         'meta' => false,
    276         'alt' => true,
    277         'ctrl' => true,
    278         'shift' => true,
    279         'key' => 'P',
    280     ];
    281     if (isUserOnMacOs()) {
    282         $shortcut['meta'] = true;
    283         $shortcut['ctrl'] = false;
    284     }
    285     return $shortcut;
    286 }
    287 
    288 function isUserOnMacOs() {
    289     return strpos($_SERVER['HTTP_USER_AGENT'], "Mac") !== false;
    290 }
     270function userShortcutKeys()
     271{
     272    $userShortcutKeys = get_user_meta(get_current_user_id(), TURBO_ADMIN_SHORTCUT_META_NAME, true);
     273
     274    if (! $userShortcutKeys) {
     275        return defaultShortcutKeys();
     276    }
     277
     278    return $userShortcutKeys;
     279}
     280
     281function defaultShortcutKeys()
     282{
     283    $shortcut = [
     284    'meta' => false,
     285    'alt' => true,
     286    'ctrl' => true,
     287    'shift' => true,
     288    'key' => 'P',
     289    ];
     290    if (isUserOnMacOs()) {
     291        $shortcut['meta'] = true;
     292        $shortcut['ctrl'] = false;
     293    }
     294    return $shortcut;
     295}
     296
     297function isUserOnMacOs()
     298{
     299    return strpos($_SERVER['HTTP_USER_AGENT'], "Mac") !== false;
     300}
Note: See TracChangeset for help on using the changeset viewer.