// This file runs in the browser.
window.process = window.process || {};
window.process.env = window.process.env || {};
window.process.env.NODE_ENV = __MODE__;
const defines = __DEFINES__;
Object.keys(defines).forEach((key) => {
    const segs = key.split('.');
    let target = window;
    for (let i = 0; i < segs.length; i++) {
        const seg = segs[i];
        if (i === segs.length - 1) {
            target[seg] = defines[key];
        }
        else {
            target = target[seg] || (target[seg] = {});
        }
    }
});
console.log('[vite] connecting...');
// use server configuration, then fallback to inference
const socketProtocol = __HMR_PROTOCOL__ || (location.protocol === 'https:' ? 'wss' : 'ws');
const socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`;
const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr');
function warnFailedFetch(err, path) {
    if (!err.message.match('fetch')) {
        console.error(err);
    }
    console.error(`[hmr] Failed to reload ${path}. ` +
        `This could be due to syntax errors or importing non-existent ` +
        `modules. (see errors above)`);
}
// Listen for messages
socket.addEventListener('message', async ({ data }) => {
    const payload = JSON.parse(data);
    if (payload.type === 'multi') {
        payload.updates.forEach(handleMessage);
    }
    else {
        handleMessage(payload);
    }
});
async function handleMessage(payload) {
    const { path, changeSrcPath, timestamp } = payload;
    switch (payload.type) {
        case 'connected':
            console.log(`[vite] connected.`);
            break;
        case 'vue-reload':
            queueUpdate(import(`${path}?t=${timestamp}`)
                .catch((err) => warnFailedFetch(err, path))
                .then((m) => () => {
                __VUE_HMR_RUNTIME__.reload(path, m.default);
                console.log(`[vite] ${path} reloaded.`);
            }));
            break;
        case 'vue-rerender':
            const templatePath = `${path}?type=template`;
            import(`${templatePath}&t=${timestamp}`).then((m) => {
                __VUE_HMR_RUNTIME__.rerender(path, m.render);
                console.log(`[vite] ${path} template updated.`);
            });
            break;
        case 'style-update':
            // check if this is referenced in html via <link>
            const el = document.querySelector(`link[href*='${path}']`);
            if (el) {
                el.setAttribute('href', `${path}${path.includes('?') ? '&' : '?'}t=${timestamp}`);
                break;
            }
            // imported CSS
            const importQuery = path.includes('?') ? '&import' : '?import';
            await import(`${path}${importQuery}&t=${timestamp}`);
            console.log(`[vite] ${path} updated.`);
            break;
        case 'style-remove':
            removeStyle(payload.id);
            break;
        case 'js-update':
            queueUpdate(updateModule(path, changeSrcPath, timestamp));
            break;
        case 'custom':
            const cbs = customUpdateMap.get(payload.id);
            if (cbs) {
                cbs.forEach((cb) => cb(payload.customData));
            }
            break;
        case 'full-reload':
            if (path.endsWith('.html')) {
                // if html file is edited, only reload the page if the browser is
                // currently on that page.
                const pagePath = location.pathname;
                if (pagePath === path ||
                    (pagePath.endsWith('/') && pagePath + 'index.html' === path)) {
                    location.reload();
                }
                return;
            }
            else {
                location.reload();
            }
    }
}
let pending = false;
let queued = [];
/**
 * 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 function queueUpdate(p) {
    queued.push(p);
    if (!pending) {
        pending = true;
        await Promise.resolve();
        pending = false;
        const loading = [...queued];
        queued = [];
        (await Promise.all(loading)).forEach((fn) => fn && fn());
    }
}
// ping server
socket.addEventListener('close', () => {
    console.log(`[vite] server connection lost. polling for restart...`);
    setInterval(() => {
        fetch('/')
            .then(() => {
            location.reload();
        })
            .catch((e) => {
            /* ignore */
        });
    }, 1000);
});
// https://wicg.github.io/construct-stylesheets
const supportsConstructedSheet = (() => {
    try {
        new CSSStyleSheet();
        return true;
    }
    catch (e) { }
    return false;
})();
const sheetsMap = new Map();
export function updateStyle(id, content) {
    let style = sheetsMap.get(id);
    if (supportsConstructedSheet && !content.includes('@import')) {
        if (style && !(style instanceof CSSStyleSheet)) {
            removeStyle(id);
            style = undefined;
        }
        if (!style) {
            style = new CSSStyleSheet();
            style.replaceSync(content);
            // @ts-ignore
            document.adoptedStyleSheets = [...document.adoptedStyleSheets, style];
        }
        else {
            style.replaceSync(content);
        }
    }
    else {
        if (style && !(style instanceof HTMLStyleElement)) {
            removeStyle(id);
            style = undefined;
        }
        if (!style) {
            style = document.createElement('style');
            style.setAttribute('type', 'text/css');
            style.innerHTML = content;
            document.head.appendChild(style);
        }
        else {
            style.innerHTML = content;
        }
    }
    sheetsMap.set(id, style);
}
function removeStyle(id) {
    let style = sheetsMap.get(id);
    if (style) {
        if (style instanceof CSSStyleSheet) {
            // @ts-ignore
            const index = document.adoptedStyleSheets.indexOf(style);
            // @ts-ignore
            document.adoptedStyleSheets = document.adoptedStyleSheets.filter((s) => s !== style);
        }
        else {
            document.head.removeChild(style);
        }
        sheetsMap.delete(id);
    }
}
async function updateModule(id, changedPath, timestamp) {
    const mod = hotModulesMap.get(id);
    if (!mod) {
        // In a code-spliting project,
        // it is common that the hot-updating module is not loaded yet.
        // https://github.com/vitejs/vite/issues/721
        return;
    }
    const moduleMap = new Map();
    const isSelfUpdate = id === changedPath;
    // make sure we only import each dep once
    const modulesToUpdate = new Set();
    if (isSelfUpdate) {
        // self update - only update self
        modulesToUpdate.add(id);
    }
    else {
        // dep update
        for (const { deps } of mod.callbacks) {
            if (Array.isArray(deps)) {
                deps.forEach((dep) => modulesToUpdate.add(dep));
            }
            else {
                modulesToUpdate.add(deps);
            }
        }
    }
    // determine the qualified callbacks before we re-import the modules
    const callbacks = mod.callbacks.filter(({ deps }) => {
        return Array.isArray(deps)
            ? deps.some((dep) => modulesToUpdate.has(dep))
            : modulesToUpdate.has(deps);
    });
    await Promise.all(Array.from(modulesToUpdate).map(async (dep) => {
        const disposer = disposeMap.get(dep);
        if (disposer)
            await disposer(dataMap.get(dep));
        try {
            const newMod = await import(dep + (dep.includes('?') ? '&' : '?') + `t=${timestamp}`);
            moduleMap.set(dep, newMod);
        }
        catch (e) {
            warnFailedFetch(e, dep);
        }
    }));
    return () => {
        for (const { deps, fn } of callbacks) {
            if (Array.isArray(deps)) {
                fn(deps.map((dep) => moduleMap.get(dep)));
            }
            else {
                fn(moduleMap.get(deps));
            }
        }
        console.log(`[vite]: js module hot updated: `, id);
    };
}
const hotModulesMap = new Map();
const disposeMap = new Map();
const dataMap = new Map();
const customUpdateMap = new Map();
export const createHotContext = (id) => {
    if (!dataMap.has(id)) {
        dataMap.set(id, {});
    }
    // when a file is hot updated, a new context is created
    // clear its stale callbacks
    const mod = hotModulesMap.get(id);
    if (mod) {
        mod.callbacks = [];
    }
    const hot = {
        get data() {
            return dataMap.get(id);
        },
        accept(callback = () => { }) {
            hot.acceptDeps(id, callback);
        },
        acceptDeps(deps, callback = () => { }) {
            const mod = hotModulesMap.get(id) || {
                id,
                callbacks: []
            };
            mod.callbacks.push({
                deps: deps,
                fn: callback
            });
            hotModulesMap.set(id, mod);
        },
        dispose(cb) {
            disposeMap.set(id, cb);
        },
        // noop, used for static analysis only
        decline() { },
        invalidate() {
            location.reload();
        },
        // custom events
        on(event, cb) {
            const existing = customUpdateMap.get(event) || [];
            existing.push(cb);
            customUpdateMap.set(event, existing);
        }
    };
    return hot;
};
