830 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			830 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import '@vite/env';
 | 
						|
 | 
						|
class HMRContext {
 | 
						|
  constructor(hmrClient, ownerPath) {
 | 
						|
    this.hmrClient = hmrClient;
 | 
						|
    this.ownerPath = ownerPath;
 | 
						|
    if (!hmrClient.dataMap.has(ownerPath)) {
 | 
						|
      hmrClient.dataMap.set(ownerPath, {});
 | 
						|
    }
 | 
						|
    const mod = hmrClient.hotModulesMap.get(ownerPath);
 | 
						|
    if (mod) {
 | 
						|
      mod.callbacks = [];
 | 
						|
    }
 | 
						|
    const staleListeners = hmrClient.ctxToListenersMap.get(ownerPath);
 | 
						|
    if (staleListeners) {
 | 
						|
      for (const [event, staleFns] of staleListeners) {
 | 
						|
        const listeners = hmrClient.customListenersMap.get(event);
 | 
						|
        if (listeners) {
 | 
						|
          hmrClient.customListenersMap.set(
 | 
						|
            event,
 | 
						|
            listeners.filter((l) => !staleFns.includes(l))
 | 
						|
          );
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    this.newListeners = /* @__PURE__ */ new Map();
 | 
						|
    hmrClient.ctxToListenersMap.set(ownerPath, this.newListeners);
 | 
						|
  }
 | 
						|
  get data() {
 | 
						|
    return this.hmrClient.dataMap.get(this.ownerPath);
 | 
						|
  }
 | 
						|
  accept(deps, callback) {
 | 
						|
    if (typeof deps === "function" || !deps) {
 | 
						|
      this.acceptDeps([this.ownerPath], ([mod]) => deps?.(mod));
 | 
						|
    } else if (typeof deps === "string") {
 | 
						|
      this.acceptDeps([deps], ([mod]) => callback?.(mod));
 | 
						|
    } else if (Array.isArray(deps)) {
 | 
						|
      this.acceptDeps(deps, callback);
 | 
						|
    } else {
 | 
						|
      throw new Error(`invalid hot.accept() usage.`);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  // export names (first arg) are irrelevant on the client side, they're
 | 
						|
  // extracted in the server for propagation
 | 
						|
  acceptExports(_, callback) {
 | 
						|
    this.acceptDeps([this.ownerPath], ([mod]) => callback?.(mod));
 | 
						|
  }
 | 
						|
  dispose(cb) {
 | 
						|
    this.hmrClient.disposeMap.set(this.ownerPath, cb);
 | 
						|
  }
 | 
						|
  prune(cb) {
 | 
						|
    this.hmrClient.pruneMap.set(this.ownerPath, cb);
 | 
						|
  }
 | 
						|
  // Kept for backward compatibility (#11036)
 | 
						|
  // eslint-disable-next-line @typescript-eslint/no-empty-function
 | 
						|
  decline() {
 | 
						|
  }
 | 
						|
  invalidate(message) {
 | 
						|
    this.hmrClient.notifyListeners("vite:invalidate", {
 | 
						|
      path: this.ownerPath,
 | 
						|
      message
 | 
						|
    });
 | 
						|
    this.send("vite:invalidate", { path: this.ownerPath, message });
 | 
						|
    this.hmrClient.logger.debug(
 | 
						|
      `[vite] invalidate ${this.ownerPath}${message ? `: ${message}` : ""}`
 | 
						|
    );
 | 
						|
  }
 | 
						|
  on(event, cb) {
 | 
						|
    const addToMap = (map) => {
 | 
						|
      const existing = map.get(event) || [];
 | 
						|
      existing.push(cb);
 | 
						|
      map.set(event, existing);
 | 
						|
    };
 | 
						|
    addToMap(this.hmrClient.customListenersMap);
 | 
						|
    addToMap(this.newListeners);
 | 
						|
  }
 | 
						|
  off(event, cb) {
 | 
						|
    const removeFromMap = (map) => {
 | 
						|
      const existing = map.get(event);
 | 
						|
      if (existing === void 0) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      const pruned = existing.filter((l) => l !== cb);
 | 
						|
      if (pruned.length === 0) {
 | 
						|
        map.delete(event);
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      map.set(event, pruned);
 | 
						|
    };
 | 
						|
    removeFromMap(this.hmrClient.customListenersMap);
 | 
						|
    removeFromMap(this.newListeners);
 | 
						|
  }
 | 
						|
  send(event, data) {
 | 
						|
    this.hmrClient.messenger.send(
 | 
						|
      JSON.stringify({ type: "custom", event, data })
 | 
						|
    );
 | 
						|
  }
 | 
						|
  acceptDeps(deps, callback = () => {
 | 
						|
  }) {
 | 
						|
    const mod = this.hmrClient.hotModulesMap.get(this.ownerPath) || {
 | 
						|
      id: this.ownerPath,
 | 
						|
      callbacks: []
 | 
						|
    };
 | 
						|
    mod.callbacks.push({
 | 
						|
      deps,
 | 
						|
      fn: callback
 | 
						|
    });
 | 
						|
    this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
 | 
						|
  }
 | 
						|
}
 | 
						|
class HMRMessenger {
 | 
						|
  constructor(connection) {
 | 
						|
    this.connection = connection;
 | 
						|
    this.queue = [];
 | 
						|
  }
 | 
						|
  send(message) {
 | 
						|
    this.queue.push(message);
 | 
						|
    this.flush();
 | 
						|
  }
 | 
						|
  flush() {
 | 
						|
    if (this.connection.isReady()) {
 | 
						|
      this.queue.forEach((msg) => this.connection.send(msg));
 | 
						|
      this.queue = [];
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
class HMRClient {
 | 
						|
  constructor(logger, connection, importUpdatedModule) {
 | 
						|
    this.logger = logger;
 | 
						|
    this.importUpdatedModule = importUpdatedModule;
 | 
						|
    this.hotModulesMap = /* @__PURE__ */ new Map();
 | 
						|
    this.disposeMap = /* @__PURE__ */ new Map();
 | 
						|
    this.pruneMap = /* @__PURE__ */ new Map();
 | 
						|
    this.dataMap = /* @__PURE__ */ new Map();
 | 
						|
    this.customListenersMap = /* @__PURE__ */ new Map();
 | 
						|
    this.ctxToListenersMap = /* @__PURE__ */ new Map();
 | 
						|
    this.updateQueue = [];
 | 
						|
    this.pendingUpdateQueue = false;
 | 
						|
    this.messenger = new HMRMessenger(connection);
 | 
						|
  }
 | 
						|
  async notifyListeners(event, data) {
 | 
						|
    const cbs = this.customListenersMap.get(event);
 | 
						|
    if (cbs) {
 | 
						|
      await Promise.allSettled(cbs.map((cb) => cb(data)));
 | 
						|
    }
 | 
						|
  }
 | 
						|
  clear() {
 | 
						|
    this.hotModulesMap.clear();
 | 
						|
    this.disposeMap.clear();
 | 
						|
    this.pruneMap.clear();
 | 
						|
    this.dataMap.clear();
 | 
						|
    this.customListenersMap.clear();
 | 
						|
    this.ctxToListenersMap.clear();
 | 
						|
  }
 | 
						|
  // After an HMR update, some modules are no longer imported on the page
 | 
						|
  // but they may have left behind side effects that need to be cleaned up
 | 
						|
  // (.e.g style injections)
 | 
						|
  async prunePaths(paths) {
 | 
						|
    await Promise.all(
 | 
						|
      paths.map((path) => {
 | 
						|
        const disposer = this.disposeMap.get(path);
 | 
						|
        if (disposer) return disposer(this.dataMap.get(path));
 | 
						|
      })
 | 
						|
    );
 | 
						|
    paths.forEach((path) => {
 | 
						|
      const fn = this.pruneMap.get(path);
 | 
						|
      if (fn) {
 | 
						|
        fn(this.dataMap.get(path));
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
  warnFailedUpdate(err, path) {
 | 
						|
    if (!err.message.includes("fetch")) {
 | 
						|
      this.logger.error(err);
 | 
						|
    }
 | 
						|
    this.logger.error(
 | 
						|
      `[hmr] Failed to reload ${path}. This could be due to syntax errors or importing non-existent modules. (see errors above)`
 | 
						|
    );
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * buffer multiple hot updates triggered by the same src change
 | 
						|
   * so that they are invoked in the same order they were sent.
 | 
						|
   * (otherwise the order may be inconsistent because of the http request round trip)
 | 
						|
   */
 | 
						|
  async queueUpdate(payload) {
 | 
						|
    this.updateQueue.push(this.fetchUpdate(payload));
 | 
						|
    if (!this.pendingUpdateQueue) {
 | 
						|
      this.pendingUpdateQueue = true;
 | 
						|
      await Promise.resolve();
 | 
						|
      this.pendingUpdateQueue = false;
 | 
						|
      const loading = [...this.updateQueue];
 | 
						|
      this.updateQueue = [];
 | 
						|
      (await Promise.all(loading)).forEach((fn) => fn && fn());
 | 
						|
    }
 | 
						|
  }
 | 
						|
  async fetchUpdate(update) {
 | 
						|
    const { path, acceptedPath } = update;
 | 
						|
    const mod = this.hotModulesMap.get(path);
 | 
						|
    if (!mod) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    let fetchedModule;
 | 
						|
    const isSelfUpdate = path === acceptedPath;
 | 
						|
    const qualifiedCallbacks = mod.callbacks.filter(
 | 
						|
      ({ deps }) => deps.includes(acceptedPath)
 | 
						|
    );
 | 
						|
    if (isSelfUpdate || qualifiedCallbacks.length > 0) {
 | 
						|
      const disposer = this.disposeMap.get(acceptedPath);
 | 
						|
      if (disposer) await disposer(this.dataMap.get(acceptedPath));
 | 
						|
      try {
 | 
						|
        fetchedModule = await this.importUpdatedModule(update);
 | 
						|
      } catch (e) {
 | 
						|
        this.warnFailedUpdate(e, acceptedPath);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return () => {
 | 
						|
      for (const { deps, fn } of qualifiedCallbacks) {
 | 
						|
        fn(
 | 
						|
          deps.map((dep) => dep === acceptedPath ? fetchedModule : void 0)
 | 
						|
        );
 | 
						|
      }
 | 
						|
      const loggedPath = isSelfUpdate ? path : `${acceptedPath} via ${path}`;
 | 
						|
      this.logger.debug(`[vite] hot updated: ${loggedPath}`);
 | 
						|
    };
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const hmrConfigName = __HMR_CONFIG_NAME__;
 | 
						|
const base$1 = __BASE__ || "/";
 | 
						|
function h(e, attrs = {}, ...children) {
 | 
						|
  const elem = document.createElement(e);
 | 
						|
  for (const [k, v] of Object.entries(attrs)) {
 | 
						|
    elem.setAttribute(k, v);
 | 
						|
  }
 | 
						|
  elem.append(...children);
 | 
						|
  return elem;
 | 
						|
}
 | 
						|
const templateStyle = (
 | 
						|
  /*css*/
 | 
						|
  `
 | 
						|
:host {
 | 
						|
  position: fixed;
 | 
						|
  top: 0;
 | 
						|
  left: 0;
 | 
						|
  width: 100%;
 | 
						|
  height: 100%;
 | 
						|
  z-index: 99999;
 | 
						|
  --monospace: 'SFMono-Regular', Consolas,
 | 
						|
  'Liberation Mono', Menlo, Courier, monospace;
 | 
						|
  --red: #ff5555;
 | 
						|
  --yellow: #e2aa53;
 | 
						|
  --purple: #cfa4ff;
 | 
						|
  --cyan: #2dd9da;
 | 
						|
  --dim: #c9c9c9;
 | 
						|
 | 
						|
  --window-background: #181818;
 | 
						|
  --window-color: #d8d8d8;
 | 
						|
}
 | 
						|
 | 
						|
.backdrop {
 | 
						|
  position: fixed;
 | 
						|
  z-index: 99999;
 | 
						|
  top: 0;
 | 
						|
  left: 0;
 | 
						|
  width: 100%;
 | 
						|
  height: 100%;
 | 
						|
  overflow-y: scroll;
 | 
						|
  margin: 0;
 | 
						|
  background: rgba(0, 0, 0, 0.66);
 | 
						|
}
 | 
						|
 | 
						|
.window {
 | 
						|
  font-family: var(--monospace);
 | 
						|
  line-height: 1.5;
 | 
						|
  max-width: 80vw;
 | 
						|
  color: var(--window-color);
 | 
						|
  box-sizing: border-box;
 | 
						|
  margin: 30px auto;
 | 
						|
  padding: 2.5vh 4vw;
 | 
						|
  position: relative;
 | 
						|
  background: var(--window-background);
 | 
						|
  border-radius: 6px 6px 8px 8px;
 | 
						|
  box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
 | 
						|
  overflow: hidden;
 | 
						|
  border-top: 8px solid var(--red);
 | 
						|
  direction: ltr;
 | 
						|
  text-align: left;
 | 
						|
}
 | 
						|
 | 
						|
pre {
 | 
						|
  font-family: var(--monospace);
 | 
						|
  font-size: 16px;
 | 
						|
  margin-top: 0;
 | 
						|
  margin-bottom: 1em;
 | 
						|
  overflow-x: scroll;
 | 
						|
  scrollbar-width: none;
 | 
						|
}
 | 
						|
 | 
						|
pre::-webkit-scrollbar {
 | 
						|
  display: none;
 | 
						|
}
 | 
						|
 | 
						|
pre.frame::-webkit-scrollbar {
 | 
						|
  display: block;
 | 
						|
  height: 5px;
 | 
						|
}
 | 
						|
 | 
						|
pre.frame::-webkit-scrollbar-thumb {
 | 
						|
  background: #999;
 | 
						|
  border-radius: 5px;
 | 
						|
}
 | 
						|
 | 
						|
pre.frame {
 | 
						|
  scrollbar-width: thin;
 | 
						|
}
 | 
						|
 | 
						|
.message {
 | 
						|
  line-height: 1.3;
 | 
						|
  font-weight: 600;
 | 
						|
  white-space: pre-wrap;
 | 
						|
}
 | 
						|
 | 
						|
.message-body {
 | 
						|
  color: var(--red);
 | 
						|
}
 | 
						|
 | 
						|
.plugin {
 | 
						|
  color: var(--purple);
 | 
						|
}
 | 
						|
 | 
						|
.file {
 | 
						|
  color: var(--cyan);
 | 
						|
  margin-bottom: 0;
 | 
						|
  white-space: pre-wrap;
 | 
						|
  word-break: break-all;
 | 
						|
}
 | 
						|
 | 
						|
.frame {
 | 
						|
  color: var(--yellow);
 | 
						|
}
 | 
						|
 | 
						|
.stack {
 | 
						|
  font-size: 13px;
 | 
						|
  color: var(--dim);
 | 
						|
}
 | 
						|
 | 
						|
.tip {
 | 
						|
  font-size: 13px;
 | 
						|
  color: #999;
 | 
						|
  border-top: 1px dotted #999;
 | 
						|
  padding-top: 13px;
 | 
						|
  line-height: 1.8;
 | 
						|
}
 | 
						|
 | 
						|
code {
 | 
						|
  font-size: 13px;
 | 
						|
  font-family: var(--monospace);
 | 
						|
  color: var(--yellow);
 | 
						|
}
 | 
						|
 | 
						|
.file-link {
 | 
						|
  text-decoration: underline;
 | 
						|
  cursor: pointer;
 | 
						|
}
 | 
						|
 | 
						|
kbd {
 | 
						|
  line-height: 1.5;
 | 
						|
  font-family: ui-monospace, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
 | 
						|
  font-size: 0.75rem;
 | 
						|
  font-weight: 700;
 | 
						|
  background-color: rgb(38, 40, 44);
 | 
						|
  color: rgb(166, 167, 171);
 | 
						|
  padding: 0.15rem 0.3rem;
 | 
						|
  border-radius: 0.25rem;
 | 
						|
  border-width: 0.0625rem 0.0625rem 0.1875rem;
 | 
						|
  border-style: solid;
 | 
						|
  border-color: rgb(54, 57, 64);
 | 
						|
  border-image: initial;
 | 
						|
}
 | 
						|
`
 | 
						|
);
 | 
						|
const createTemplate = () => h(
 | 
						|
  "div",
 | 
						|
  { class: "backdrop", part: "backdrop" },
 | 
						|
  h(
 | 
						|
    "div",
 | 
						|
    { class: "window", part: "window" },
 | 
						|
    h(
 | 
						|
      "pre",
 | 
						|
      { class: "message", part: "message" },
 | 
						|
      h("span", { class: "plugin", part: "plugin" }),
 | 
						|
      h("span", { class: "message-body", part: "message-body" })
 | 
						|
    ),
 | 
						|
    h("pre", { class: "file", part: "file" }),
 | 
						|
    h("pre", { class: "frame", part: "frame" }),
 | 
						|
    h("pre", { class: "stack", part: "stack" }),
 | 
						|
    h(
 | 
						|
      "div",
 | 
						|
      { class: "tip", part: "tip" },
 | 
						|
      "Click outside, press ",
 | 
						|
      h("kbd", {}, "Esc"),
 | 
						|
      " key, or fix the code to dismiss.",
 | 
						|
      h("br"),
 | 
						|
      "You can also disable this overlay by setting ",
 | 
						|
      h("code", { part: "config-option-name" }, "server.hmr.overlay"),
 | 
						|
      " to ",
 | 
						|
      h("code", { part: "config-option-value" }, "false"),
 | 
						|
      " in ",
 | 
						|
      h("code", { part: "config-file-name" }, hmrConfigName),
 | 
						|
      "."
 | 
						|
    )
 | 
						|
  ),
 | 
						|
  h("style", {}, templateStyle)
 | 
						|
);
 | 
						|
const fileRE = /(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g;
 | 
						|
const codeframeRE = /^(?:>?\s*\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm;
 | 
						|
const { HTMLElement = class {
 | 
						|
} } = globalThis;
 | 
						|
class ErrorOverlay extends HTMLElement {
 | 
						|
  constructor(err, links = true) {
 | 
						|
    super();
 | 
						|
    this.root = this.attachShadow({ mode: "open" });
 | 
						|
    this.root.appendChild(createTemplate());
 | 
						|
    codeframeRE.lastIndex = 0;
 | 
						|
    const hasFrame = err.frame && codeframeRE.test(err.frame);
 | 
						|
    const message = hasFrame ? err.message.replace(codeframeRE, "") : err.message;
 | 
						|
    if (err.plugin) {
 | 
						|
      this.text(".plugin", `[plugin:${err.plugin}] `);
 | 
						|
    }
 | 
						|
    this.text(".message-body", message.trim());
 | 
						|
    const [file] = (err.loc?.file || err.id || "unknown file").split(`?`);
 | 
						|
    if (err.loc) {
 | 
						|
      this.text(".file", `${file}:${err.loc.line}:${err.loc.column}`, links);
 | 
						|
    } else if (err.id) {
 | 
						|
      this.text(".file", file);
 | 
						|
    }
 | 
						|
    if (hasFrame) {
 | 
						|
      this.text(".frame", err.frame.trim());
 | 
						|
    }
 | 
						|
    this.text(".stack", err.stack, links);
 | 
						|
    this.root.querySelector(".window").addEventListener("click", (e) => {
 | 
						|
      e.stopPropagation();
 | 
						|
    });
 | 
						|
    this.addEventListener("click", () => {
 | 
						|
      this.close();
 | 
						|
    });
 | 
						|
    this.closeOnEsc = (e) => {
 | 
						|
      if (e.key === "Escape" || e.code === "Escape") {
 | 
						|
        this.close();
 | 
						|
      }
 | 
						|
    };
 | 
						|
    document.addEventListener("keydown", this.closeOnEsc);
 | 
						|
  }
 | 
						|
  text(selector, text, linkFiles = false) {
 | 
						|
    const el = this.root.querySelector(selector);
 | 
						|
    if (!linkFiles) {
 | 
						|
      el.textContent = text;
 | 
						|
    } else {
 | 
						|
      let curIndex = 0;
 | 
						|
      let match;
 | 
						|
      fileRE.lastIndex = 0;
 | 
						|
      while (match = fileRE.exec(text)) {
 | 
						|
        const { 0: file, index } = match;
 | 
						|
        if (index != null) {
 | 
						|
          const frag = text.slice(curIndex, index);
 | 
						|
          el.appendChild(document.createTextNode(frag));
 | 
						|
          const link = document.createElement("a");
 | 
						|
          link.textContent = file;
 | 
						|
          link.className = "file-link";
 | 
						|
          link.onclick = () => {
 | 
						|
            fetch(
 | 
						|
              new URL(
 | 
						|
                `${base$1}__open-in-editor?file=${encodeURIComponent(file)}`,
 | 
						|
                import.meta.url
 | 
						|
              )
 | 
						|
            );
 | 
						|
          };
 | 
						|
          el.appendChild(link);
 | 
						|
          curIndex += frag.length + file.length;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  close() {
 | 
						|
    this.parentNode?.removeChild(this);
 | 
						|
    document.removeEventListener("keydown", this.closeOnEsc);
 | 
						|
  }
 | 
						|
}
 | 
						|
const overlayId = "vite-error-overlay";
 | 
						|
const { customElements } = globalThis;
 | 
						|
if (customElements && !customElements.get(overlayId)) {
 | 
						|
  customElements.define(overlayId, ErrorOverlay);
 | 
						|
}
 | 
						|
 | 
						|
console.debug("[vite] connecting...");
 | 
						|
const importMetaUrl = new URL(import.meta.url);
 | 
						|
const serverHost = __SERVER_HOST__;
 | 
						|
const socketProtocol = __HMR_PROTOCOL__ || (importMetaUrl.protocol === "https:" ? "wss" : "ws");
 | 
						|
const hmrPort = __HMR_PORT__;
 | 
						|
const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
 | 
						|
const directSocketHost = __HMR_DIRECT_TARGET__;
 | 
						|
const base = __BASE__ || "/";
 | 
						|
const wsToken = __WS_TOKEN__;
 | 
						|
let socket;
 | 
						|
try {
 | 
						|
  let fallback;
 | 
						|
  if (!hmrPort) {
 | 
						|
    fallback = () => {
 | 
						|
      socket = setupWebSocket(socketProtocol, directSocketHost, () => {
 | 
						|
        const currentScriptHostURL = new URL(import.meta.url);
 | 
						|
        const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
 | 
						|
        console.error(
 | 
						|
          `[vite] failed to connect to websocket.
 | 
						|
your current setup:
 | 
						|
  (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)
 | 
						|
  (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)
 | 
						|
Check out your Vite / network configuration and https://vite.dev/config/server-options.html#server-hmr .`
 | 
						|
        );
 | 
						|
      });
 | 
						|
      socket.addEventListener(
 | 
						|
        "open",
 | 
						|
        () => {
 | 
						|
          console.info(
 | 
						|
            "[vite] Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-hmr to remove the previous connection error."
 | 
						|
          );
 | 
						|
        },
 | 
						|
        { once: true }
 | 
						|
      );
 | 
						|
    };
 | 
						|
  }
 | 
						|
  socket = setupWebSocket(socketProtocol, socketHost, fallback);
 | 
						|
} catch (error) {
 | 
						|
  console.error(`[vite] failed to connect to websocket (${error}). `);
 | 
						|
}
 | 
						|
function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {
 | 
						|
  const socket2 = new WebSocket(
 | 
						|
    `${protocol}://${hostAndPath}?token=${wsToken}`,
 | 
						|
    "vite-hmr"
 | 
						|
  );
 | 
						|
  let isOpened = false;
 | 
						|
  socket2.addEventListener(
 | 
						|
    "open",
 | 
						|
    () => {
 | 
						|
      isOpened = true;
 | 
						|
      notifyListeners("vite:ws:connect", { webSocket: socket2 });
 | 
						|
    },
 | 
						|
    { once: true }
 | 
						|
  );
 | 
						|
  socket2.addEventListener("message", async ({ data }) => {
 | 
						|
    handleMessage(JSON.parse(data));
 | 
						|
  });
 | 
						|
  socket2.addEventListener("close", async ({ wasClean }) => {
 | 
						|
    if (wasClean) return;
 | 
						|
    if (!isOpened && onCloseWithoutOpen) {
 | 
						|
      onCloseWithoutOpen();
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    notifyListeners("vite:ws:disconnect", { webSocket: socket2 });
 | 
						|
    if (hasDocument) {
 | 
						|
      console.log(`[vite] server connection lost. Polling for restart...`);
 | 
						|
      await waitForSuccessfulPing(protocol, hostAndPath);
 | 
						|
      location.reload();
 | 
						|
    }
 | 
						|
  });
 | 
						|
  return socket2;
 | 
						|
}
 | 
						|
function cleanUrl(pathname) {
 | 
						|
  const url = new URL(pathname, "http://vite.dev");
 | 
						|
  url.searchParams.delete("direct");
 | 
						|
  return url.pathname + url.search;
 | 
						|
}
 | 
						|
let isFirstUpdate = true;
 | 
						|
const outdatedLinkTags = /* @__PURE__ */ new WeakSet();
 | 
						|
const debounceReload = (time) => {
 | 
						|
  let timer;
 | 
						|
  return () => {
 | 
						|
    if (timer) {
 | 
						|
      clearTimeout(timer);
 | 
						|
      timer = null;
 | 
						|
    }
 | 
						|
    timer = setTimeout(() => {
 | 
						|
      location.reload();
 | 
						|
    }, time);
 | 
						|
  };
 | 
						|
};
 | 
						|
const pageReload = debounceReload(50);
 | 
						|
const hmrClient = new HMRClient(
 | 
						|
  console,
 | 
						|
  {
 | 
						|
    isReady: () => socket && socket.readyState === 1,
 | 
						|
    send: (message) => socket.send(message)
 | 
						|
  },
 | 
						|
  async function importUpdatedModule({
 | 
						|
    acceptedPath,
 | 
						|
    timestamp,
 | 
						|
    explicitImportRequired,
 | 
						|
    isWithinCircularImport
 | 
						|
  }) {
 | 
						|
    const [acceptedPathWithoutQuery, query] = acceptedPath.split(`?`);
 | 
						|
    const importPromise = import(
 | 
						|
      /* @vite-ignore */
 | 
						|
      base + acceptedPathWithoutQuery.slice(1) + `?${explicitImportRequired ? "import&" : ""}t=${timestamp}${query ? `&${query}` : ""}`
 | 
						|
    );
 | 
						|
    if (isWithinCircularImport) {
 | 
						|
      importPromise.catch(() => {
 | 
						|
        console.info(
 | 
						|
          `[hmr] ${acceptedPath} failed to apply HMR as it's within a circular import. Reloading page to reset the execution order. To debug and break the circular import, you can run \`vite --debug hmr\` to log the circular dependency path if a file change triggered it.`
 | 
						|
        );
 | 
						|
        pageReload();
 | 
						|
      });
 | 
						|
    }
 | 
						|
    return await importPromise;
 | 
						|
  }
 | 
						|
);
 | 
						|
async function handleMessage(payload) {
 | 
						|
  switch (payload.type) {
 | 
						|
    case "connected":
 | 
						|
      console.debug(`[vite] connected.`);
 | 
						|
      hmrClient.messenger.flush();
 | 
						|
      setInterval(() => {
 | 
						|
        if (socket.readyState === socket.OPEN) {
 | 
						|
          socket.send('{"type":"ping"}');
 | 
						|
        }
 | 
						|
      }, __HMR_TIMEOUT__);
 | 
						|
      break;
 | 
						|
    case "update":
 | 
						|
      notifyListeners("vite:beforeUpdate", payload);
 | 
						|
      if (hasDocument) {
 | 
						|
        if (isFirstUpdate && hasErrorOverlay()) {
 | 
						|
          location.reload();
 | 
						|
          return;
 | 
						|
        } else {
 | 
						|
          if (enableOverlay) {
 | 
						|
            clearErrorOverlay();
 | 
						|
          }
 | 
						|
          isFirstUpdate = false;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      await Promise.all(
 | 
						|
        payload.updates.map(async (update) => {
 | 
						|
          if (update.type === "js-update") {
 | 
						|
            return hmrClient.queueUpdate(update);
 | 
						|
          }
 | 
						|
          const { path, timestamp } = update;
 | 
						|
          const searchUrl = cleanUrl(path);
 | 
						|
          const el = Array.from(
 | 
						|
            document.querySelectorAll("link")
 | 
						|
          ).find(
 | 
						|
            (e) => !outdatedLinkTags.has(e) && cleanUrl(e.href).includes(searchUrl)
 | 
						|
          );
 | 
						|
          if (!el) {
 | 
						|
            return;
 | 
						|
          }
 | 
						|
          const newPath = `${base}${searchUrl.slice(1)}${searchUrl.includes("?") ? "&" : "?"}t=${timestamp}`;
 | 
						|
          return new Promise((resolve) => {
 | 
						|
            const newLinkTag = el.cloneNode();
 | 
						|
            newLinkTag.href = new URL(newPath, el.href).href;
 | 
						|
            const removeOldEl = () => {
 | 
						|
              el.remove();
 | 
						|
              console.debug(`[vite] css hot updated: ${searchUrl}`);
 | 
						|
              resolve();
 | 
						|
            };
 | 
						|
            newLinkTag.addEventListener("load", removeOldEl);
 | 
						|
            newLinkTag.addEventListener("error", removeOldEl);
 | 
						|
            outdatedLinkTags.add(el);
 | 
						|
            el.after(newLinkTag);
 | 
						|
          });
 | 
						|
        })
 | 
						|
      );
 | 
						|
      notifyListeners("vite:afterUpdate", payload);
 | 
						|
      break;
 | 
						|
    case "custom": {
 | 
						|
      notifyListeners(payload.event, payload.data);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    case "full-reload":
 | 
						|
      notifyListeners("vite:beforeFullReload", payload);
 | 
						|
      if (hasDocument) {
 | 
						|
        if (payload.path && payload.path.endsWith(".html")) {
 | 
						|
          const pagePath = decodeURI(location.pathname);
 | 
						|
          const payloadPath = base + payload.path.slice(1);
 | 
						|
          if (pagePath === payloadPath || payload.path === "/index.html" || pagePath.endsWith("/") && pagePath + "index.html" === payloadPath) {
 | 
						|
            pageReload();
 | 
						|
          }
 | 
						|
          return;
 | 
						|
        } else {
 | 
						|
          pageReload();
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case "prune":
 | 
						|
      notifyListeners("vite:beforePrune", payload);
 | 
						|
      await hmrClient.prunePaths(payload.paths);
 | 
						|
      break;
 | 
						|
    case "error": {
 | 
						|
      notifyListeners("vite:error", payload);
 | 
						|
      if (hasDocument) {
 | 
						|
        const err = payload.err;
 | 
						|
        if (enableOverlay) {
 | 
						|
          createErrorOverlay(err);
 | 
						|
        } else {
 | 
						|
          console.error(
 | 
						|
            `[vite] Internal Server Error
 | 
						|
${err.message}
 | 
						|
${err.stack}`
 | 
						|
          );
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    default: {
 | 
						|
      const check = payload;
 | 
						|
      return check;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
function notifyListeners(event, data) {
 | 
						|
  hmrClient.notifyListeners(event, data);
 | 
						|
}
 | 
						|
const enableOverlay = __HMR_ENABLE_OVERLAY__;
 | 
						|
const hasDocument = "document" in globalThis;
 | 
						|
function createErrorOverlay(err) {
 | 
						|
  clearErrorOverlay();
 | 
						|
  document.body.appendChild(new ErrorOverlay(err));
 | 
						|
}
 | 
						|
function clearErrorOverlay() {
 | 
						|
  document.querySelectorAll(overlayId).forEach((n) => n.close());
 | 
						|
}
 | 
						|
function hasErrorOverlay() {
 | 
						|
  return document.querySelectorAll(overlayId).length;
 | 
						|
}
 | 
						|
async function waitForSuccessfulPing(socketProtocol2, hostAndPath, ms = 1e3) {
 | 
						|
  const pingHostProtocol = socketProtocol2 === "wss" ? "https" : "http";
 | 
						|
  const ping = async () => {
 | 
						|
    try {
 | 
						|
      await fetch(`${pingHostProtocol}://${hostAndPath}`, {
 | 
						|
        mode: "no-cors",
 | 
						|
        headers: {
 | 
						|
          // Custom headers won't be included in a request with no-cors so (ab)use one of the
 | 
						|
          // safelisted headers to identify the ping request
 | 
						|
          Accept: "text/x-vite-ping"
 | 
						|
        }
 | 
						|
      });
 | 
						|
      return true;
 | 
						|
    } catch {
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  };
 | 
						|
  if (await ping()) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  await wait(ms);
 | 
						|
  while (true) {
 | 
						|
    if (document.visibilityState === "visible") {
 | 
						|
      if (await ping()) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      await wait(ms);
 | 
						|
    } else {
 | 
						|
      await waitForWindowShow();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
function wait(ms) {
 | 
						|
  return new Promise((resolve) => setTimeout(resolve, ms));
 | 
						|
}
 | 
						|
function waitForWindowShow() {
 | 
						|
  return new Promise((resolve) => {
 | 
						|
    const onChange = async () => {
 | 
						|
      if (document.visibilityState === "visible") {
 | 
						|
        resolve();
 | 
						|
        document.removeEventListener("visibilitychange", onChange);
 | 
						|
      }
 | 
						|
    };
 | 
						|
    document.addEventListener("visibilitychange", onChange);
 | 
						|
  });
 | 
						|
}
 | 
						|
const sheetsMap = /* @__PURE__ */ new Map();
 | 
						|
if ("document" in globalThis) {
 | 
						|
  document.querySelectorAll("style[data-vite-dev-id]").forEach((el) => {
 | 
						|
    sheetsMap.set(el.getAttribute("data-vite-dev-id"), el);
 | 
						|
  });
 | 
						|
}
 | 
						|
const cspNonce = "document" in globalThis ? document.querySelector("meta[property=csp-nonce]")?.nonce : void 0;
 | 
						|
let lastInsertedStyle;
 | 
						|
function updateStyle(id, content) {
 | 
						|
  let style = sheetsMap.get(id);
 | 
						|
  if (!style) {
 | 
						|
    style = document.createElement("style");
 | 
						|
    style.setAttribute("type", "text/css");
 | 
						|
    style.setAttribute("data-vite-dev-id", id);
 | 
						|
    style.textContent = content;
 | 
						|
    if (cspNonce) {
 | 
						|
      style.setAttribute("nonce", cspNonce);
 | 
						|
    }
 | 
						|
    if (!lastInsertedStyle) {
 | 
						|
      document.head.appendChild(style);
 | 
						|
      setTimeout(() => {
 | 
						|
        lastInsertedStyle = void 0;
 | 
						|
      }, 0);
 | 
						|
    } else {
 | 
						|
      lastInsertedStyle.insertAdjacentElement("afterend", style);
 | 
						|
    }
 | 
						|
    lastInsertedStyle = style;
 | 
						|
  } else {
 | 
						|
    style.textContent = content;
 | 
						|
  }
 | 
						|
  sheetsMap.set(id, style);
 | 
						|
}
 | 
						|
function removeStyle(id) {
 | 
						|
  const style = sheetsMap.get(id);
 | 
						|
  if (style) {
 | 
						|
    document.head.removeChild(style);
 | 
						|
    sheetsMap.delete(id);
 | 
						|
  }
 | 
						|
}
 | 
						|
function createHotContext(ownerPath) {
 | 
						|
  return new HMRContext(hmrClient, ownerPath);
 | 
						|
}
 | 
						|
function injectQuery(url, queryToInject) {
 | 
						|
  if (url[0] !== "." && url[0] !== "/") {
 | 
						|
    return url;
 | 
						|
  }
 | 
						|
  const pathname = url.replace(/[?#].*$/, "");
 | 
						|
  const { search, hash } = new URL(url, "http://vite.dev");
 | 
						|
  return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ""}${hash || ""}`;
 | 
						|
}
 | 
						|
 | 
						|
export { ErrorOverlay, createHotContext, injectQuery, removeStyle, updateStyle };
 |