diff --git a/src/Modal.test.tsx b/src/Modal.test.tsx
index bb6fb0f7..6368c7d9 100644
--- a/src/Modal.test.tsx
+++ b/src/Modal.test.tsx
@@ -5,10 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/
-import { expect, test } from "vitest";
+import { expect, test, afterEach } from "vitest";
import { render } from "@testing-library/react";
import { type ReactNode, useState } from "react";
-import { afterEach } from "node:test";
import userEvent from "@testing-library/user-event";
import { Modal } from "./Modal";
diff --git a/src/room/CallEventAudioRenderer.test.tsx b/src/room/CallEventAudioRenderer.test.tsx
index 106cdad1..10fcbecf 100644
--- a/src/room/CallEventAudioRenderer.test.tsx
+++ b/src/room/CallEventAudioRenderer.test.tsx
@@ -13,8 +13,8 @@ import {
type MockedFunction,
test,
vitest,
+ afterEach,
} from "vitest";
-import { afterEach } from "node:test";
import { act } from "react";
import { type CallMembership } from "matrix-js-sdk/src/matrixrtc";
diff --git a/src/room/ReactionAudioRenderer.test.tsx b/src/room/ReactionAudioRenderer.test.tsx
index e8a41d7b..9f1f4efb 100644
--- a/src/room/ReactionAudioRenderer.test.tsx
+++ b/src/room/ReactionAudioRenderer.test.tsx
@@ -8,6 +8,7 @@ Please see LICENSE in the repository root for full details.
import { render } from "@testing-library/react";
import {
afterAll,
+ afterEach,
beforeEach,
expect,
test,
@@ -17,7 +18,6 @@ import {
} from "vitest";
import { TooltipProvider } from "@vector-im/compound-web";
import { act, type ReactNode } from "react";
-import { afterEach } from "node:test";
import { ReactionsAudioRenderer } from "./ReactionAudioRenderer";
import {
diff --git a/src/room/ReactionsOverlay.test.tsx b/src/room/ReactionsOverlay.test.tsx
index f1401132..77ec77f8 100644
--- a/src/room/ReactionsOverlay.test.tsx
+++ b/src/room/ReactionsOverlay.test.tsx
@@ -6,9 +6,8 @@ Please see LICENSE in the repository root for full details.
*/
import { render } from "@testing-library/react";
-import { expect, test } from "vitest";
+import { expect, test, afterEach } from "vitest";
import { act } from "react";
-import { afterEach } from "node:test";
import { showReactions } from "../settings/settings";
import { ReactionsOverlay } from "./ReactionsOverlay";
@@ -42,7 +41,10 @@ test("shows a reaction when sent", () => {
const reaction = ReactionSet[0];
act(() => {
reactionsSubject$.next({
- [aliceRtcMember.deviceId]: { reactionOption: reaction, expireAfter: 0 },
+ [aliceRtcMember.deviceId]: {
+ reactionOption: reaction,
+ expireAfter: new Date(0),
+ },
});
});
const span = getByRole("presentation");
@@ -60,8 +62,14 @@ test("shows two of the same reaction when sent", () => {
const { getAllByRole } = render();
act(() => {
reactionsSubject$.next({
- [aliceRtcMember.deviceId]: { reactionOption: reaction, expireAfter: 0 },
- [bobRtcMember.deviceId]: { reactionOption: reaction, expireAfter: 0 },
+ [aliceRtcMember.deviceId]: {
+ reactionOption: reaction,
+ expireAfter: new Date(0),
+ },
+ [bobRtcMember.deviceId]: {
+ reactionOption: reaction,
+ expireAfter: new Date(0),
+ },
});
});
expect(getAllByRole("presentation")).toHaveLength(2);
@@ -77,8 +85,14 @@ test("shows two different reactions when sent", () => {
const { getAllByRole } = render();
act(() => {
reactionsSubject$.next({
- [aliceRtcMember.deviceId]: { reactionOption: reactionA, expireAfter: 0 },
- [bobRtcMember.deviceId]: { reactionOption: reactionB, expireAfter: 0 },
+ [aliceRtcMember.deviceId]: {
+ reactionOption: reactionA,
+ expireAfter: new Date(0),
+ },
+ [bobRtcMember.deviceId]: {
+ reactionOption: reactionB,
+ expireAfter: new Date(0),
+ },
});
});
const [reactionElementA, reactionElementB] = getAllByRole("presentation");
@@ -96,7 +110,10 @@ test("hides reactions when reaction animations are disabled", () => {
const { container } = render();
act(() => {
reactionsSubject$.next({
- [aliceRtcMember.deviceId]: { reactionOption: reaction, expireAfter: 0 },
+ [aliceRtcMember.deviceId]: {
+ reactionOption: reaction,
+ expireAfter: new Date(0),
+ },
});
});
expect(container.getElementsByTagName("span")).toHaveLength(0);
diff --git a/src/useAudioContext.test.tsx b/src/useAudioContext.test.tsx
index 2fda4add..9f97f1b6 100644
--- a/src/useAudioContext.test.tsx
+++ b/src/useAudioContext.test.tsx
@@ -5,10 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/
-import { expect, test, vitest } from "vitest";
+import { expect, test, vitest, afterEach } from "vitest";
import { type FC } from "react";
import { render } from "@testing-library/react";
-import { afterEach } from "node:test";
import userEvent from "@testing-library/user-event";
import { deviceStub, MediaDevicesContext } from "./livekit/MediaDevicesContext";
diff --git a/vitest.config.js.timestamp-1734431318010-5e75ad3d9ffe3.mjs b/vitest.config.js.timestamp-1734431318010-5e75ad3d9ffe3.mjs
new file mode 100644
index 00000000..7283b6fb
--- /dev/null
+++ b/vitest.config.js.timestamp-1734431318010-5e75ad3d9ffe3.mjs
@@ -0,0 +1,131 @@
+// vitest.config.js
+import {
+ defineConfig as defineConfig2,
+ mergeConfig,
+} from "file:///home/will/git/element-call/node_modules/vitest/dist/config.js";
+
+// vite.config.js
+import {
+ defineConfig,
+ loadEnv,
+} from "file:///home/will/git/element-call/node_modules/vite/dist/node/index.js";
+import { compression } from "file:///home/will/git/element-call/node_modules/vite-plugin-compression2/dist/index.mjs";
+import svgrPlugin from "file:///home/will/git/element-call/node_modules/vite-plugin-svgr/dist/index.js";
+import htmlTemplate from "file:///home/will/git/element-call/node_modules/vite-plugin-html-template/dist/index.js";
+import { codecovVitePlugin } from "file:///home/will/git/element-call/node_modules/@codecov/vite-plugin/dist/index.mjs";
+import { sentryVitePlugin } from "file:///home/will/git/element-call/node_modules/@sentry/vite-plugin/dist/esm/index.mjs";
+import react from "file:///home/will/git/element-call/node_modules/@vitejs/plugin-react/dist/index.mjs";
+import basicSsl from "file:///home/will/git/element-call/node_modules/@vitejs/plugin-basic-ssl/dist/index.mjs";
+var vite_config_default = defineConfig(({ mode }) => {
+ const env = loadEnv(mode, process.cwd());
+ const plugins = [
+ react(),
+ basicSsl(),
+ svgrPlugin({
+ svgrOptions: {
+ // This enables ref forwarding on SVGR components, which is needed, for
+ // example, to make tooltips on icons work
+ ref: true,
+ },
+ }),
+ htmlTemplate.default({
+ data: {
+ title: env.VITE_PRODUCT_NAME || "Element Call",
+ },
+ }),
+ codecovVitePlugin({
+ enableBundleAnalysis: process.env.CODECOV_TOKEN !== void 0,
+ bundleName: "element-call",
+ uploadToken: process.env.CODECOV_TOKEN,
+ }),
+ compression({
+ exclude: [/config.json/],
+ }),
+ ];
+ if (
+ process.env.SENTRY_ORG &&
+ process.env.SENTRY_PROJECT &&
+ process.env.SENTRY_AUTH_TOKEN &&
+ process.env.SENTRY_URL
+ ) {
+ plugins.push(
+ sentryVitePlugin({
+ include: "./dist",
+ release: process.env.VITE_APP_VERSION,
+ }),
+ );
+ }
+ return {
+ server: {
+ port: 3e3,
+ },
+ build: {
+ sourcemap: true,
+ rollupOptions: {
+ output: {
+ assetFileNames: ({ originalFileNames }) => {
+ if (originalFileNames) {
+ for (const name of originalFileNames) {
+ const match = name.match(/locales\/([^/]+)\/(.+)\.json$/);
+ if (match) {
+ const [, locale, filename] = match;
+ return `assets/${locale}-${filename}-[hash].json`;
+ }
+ }
+ }
+ return "assets/[name]-[hash][extname]";
+ },
+ manualChunks: {
+ // we should be able to remove this one https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/167 lands
+ "matrix-sdk-crypto-wasm": ["@matrix-org/matrix-sdk-crypto-wasm"],
+ },
+ },
+ },
+ },
+ plugins,
+ resolve: {
+ alias: {
+ // matrix-widget-api has its transpiled lib/index.js as its entry point,
+ // which Vite for some reason refuses to work with, so we point it to
+ // src/index.ts instead
+ "matrix-widget-api": "matrix-widget-api/src/index.ts",
+ },
+ dedupe: [
+ "react",
+ "react-dom",
+ "matrix-js-sdk",
+ "react-use-measure",
+ // These packages modify the document based on some module-level global
+ // state, and don't play nicely with duplicate copies of themselves
+ // https://github.com/radix-ui/primitives/issues/1241#issuecomment-1847837850
+ "@radix-ui/react-focus-guards",
+ "@radix-ui/react-dismissable-layer",
+ ],
+ },
+ };
+});
+
+// vitest.config.js
+var vitest_config_default = defineConfig2((configEnv) =>
+ mergeConfig(
+ vite_config_default(configEnv),
+ defineConfig2({
+ test: {
+ environment: "jsdom",
+ css: {
+ modules: {
+ classNameStrategy: "non-scoped",
+ },
+ },
+ setupFiles: ["src/vitest.setup.ts"],
+ coverage: {
+ reporter: ["html", "json"],
+ include: ["src/"],
+ exclude: ["src/**/*.{d,test}.{ts,tsx}", "src/utils/test.ts"],
+ },
+ },
+ }),
+ ),
+);
+export { vitest_config_default as default };
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZXN0LmNvbmZpZy5qcyIsICJ2aXRlLmNvbmZpZy5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIi9ob21lL3dpbGwvZ2l0L2VsZW1lbnQtY2FsbFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL2hvbWUvd2lsbC9naXQvZWxlbWVudC1jYWxsL3ZpdGVzdC5jb25maWcuanNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL2hvbWUvd2lsbC9naXQvZWxlbWVudC1jYWxsL3ZpdGVzdC5jb25maWcuanNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcsIG1lcmdlQ29uZmlnIH0gZnJvbSBcInZpdGVzdC9jb25maWdcIjtcbmltcG9ydCB2aXRlQ29uZmlnIGZyb20gXCIuL3ZpdGUuY29uZmlnLmpzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZygoY29uZmlnRW52KSA9PlxuICBtZXJnZUNvbmZpZyhcbiAgICB2aXRlQ29uZmlnKGNvbmZpZ0VudiksXG4gICAgZGVmaW5lQ29uZmlnKHtcbiAgICAgIHRlc3Q6IHtcbiAgICAgICAgZW52aXJvbm1lbnQ6IFwianNkb21cIixcbiAgICAgICAgY3NzOiB7XG4gICAgICAgICAgbW9kdWxlczoge1xuICAgICAgICAgICAgY2xhc3NOYW1lU3RyYXRlZ3k6IFwibm9uLXNjb3BlZFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHNldHVwRmlsZXM6IFtcInNyYy92aXRlc3Quc2V0dXAudHNcIl0sXG4gICAgICAgIGNvdmVyYWdlOiB7XG4gICAgICAgICAgcmVwb3J0ZXI6IFtcImh0bWxcIiwgXCJqc29uXCJdLFxuICAgICAgICAgIGluY2x1ZGU6IFtcInNyYy9cIl0sXG4gICAgICAgICAgZXhjbHVkZTogW1wic3JjLyoqLyoue2QsdGVzdH0ue3RzLHRzeH1cIiwgXCJzcmMvdXRpbHMvdGVzdC50c1wiXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSksXG4gICksXG4pO1xuIiwgImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvaG9tZS93aWxsL2dpdC9lbGVtZW50LWNhbGxcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9ob21lL3dpbGwvZ2l0L2VsZW1lbnQtY2FsbC92aXRlLmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vaG9tZS93aWxsL2dpdC9lbGVtZW50LWNhbGwvdml0ZS5jb25maWcuanNcIjsvKlxuQ29weXJpZ2h0IDIwMjEtMjAyNCBOZXcgVmVjdG9yIEx0ZC5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgeyBkZWZpbmVDb25maWcsIGxvYWRFbnYgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHsgY29tcHJlc3Npb24gfSBmcm9tIFwidml0ZS1wbHVnaW4tY29tcHJlc3Npb24yXCI7XG5pbXBvcnQgc3ZnclBsdWdpbiBmcm9tIFwidml0ZS1wbHVnaW4tc3ZnclwiO1xuaW1wb3J0IGh0bWxUZW1wbGF0ZSBmcm9tIFwidml0ZS1wbHVnaW4taHRtbC10ZW1wbGF0ZVwiO1xuaW1wb3J0IHsgY29kZWNvdlZpdGVQbHVnaW4gfSBmcm9tIFwiQGNvZGVjb3Yvdml0ZS1wbHVnaW5cIjtcbmltcG9ydCB7IHNlbnRyeVZpdGVQbHVnaW4gfSBmcm9tIFwiQHNlbnRyeS92aXRlLXBsdWdpblwiO1xuaW1wb3J0IHJlYWN0IGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdFwiO1xuaW1wb3J0IGJhc2ljU3NsIGZyb20gXCJAdml0ZWpzL3BsdWdpbi1iYXNpYy1zc2xcIjtcblxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZygoeyBtb2RlIH0pID0+IHtcbiAgY29uc3QgZW52ID0gbG9hZEVudihtb2RlLCBwcm9jZXNzLmN3ZCgpKTtcblxuICBjb25zdCBwbHVnaW5zID0gW1xuICAgIHJlYWN0KCksXG4gICAgYmFzaWNTc2woKSxcbiAgICBzdmdyUGx1Z2luKHtcbiAgICAgIHN2Z3JPcHRpb25zOiB7XG4gICAgICAgIC8vIFRoaXMgZW5hYmxlcyByZWYgZm9yd2FyZGluZyBvbiBTVkdSIGNvbXBvbmVudHMsIHdoaWNoIGlzIG5lZWRlZCwgZm9yXG4gICAgICAgIC8vIGV4YW1wbGUsIHRvIG1ha2UgdG9vbHRpcHMgb24gaWNvbnMgd29ya1xuICAgICAgICByZWY6IHRydWUsXG4gICAgICB9LFxuICAgIH0pLFxuICAgIGh0bWxUZW1wbGF0ZS5kZWZhdWx0KHtcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgdGl0bGU6IGVudi5WSVRFX1BST0RVQ1RfTkFNRSB8fCBcIkVsZW1lbnQgQ2FsbFwiLFxuICAgICAgfSxcbiAgICB9KSxcblxuICAgIGNvZGVjb3ZWaXRlUGx1Z2luKHtcbiAgICAgIGVuYWJsZUJ1bmRsZUFuYWx5c2lzOiBwcm9jZXNzLmVudi5DT0RFQ09WX1RPS0VOICE9PSB1bmRlZmluZWQsXG4gICAgICBidW5kbGVOYW1lOiBcImVsZW1lbnQtY2FsbFwiLFxuICAgICAgdXBsb2FkVG9rZW46IHByb2Nlc3MuZW52LkNPREVDT1ZfVE9LRU4sXG4gICAgfSksXG5cbiAgICBjb21wcmVzc2lvbih7XG4gICAgICBleGNsdWRlOiBbL2NvbmZpZy5qc29uL10sXG4gICAgfSksXG4gIF07XG5cbiAgaWYgKFxuICAgIHByb2Nlc3MuZW52LlNFTlRSWV9PUkcgJiZcbiAgICBwcm9jZXNzLmVudi5TRU5UUllfUFJPSkVDVCAmJlxuICAgIHByb2Nlc3MuZW52LlNFTlRSWV9BVVRIX1RPS0VOICYmXG4gICAgcHJvY2Vzcy5lbnYuU0VOVFJZX1VSTFxuICApIHtcbiAgICBwbHVnaW5zLnB1c2goXG4gICAgICBzZW50cnlWaXRlUGx1Z2luKHtcbiAgICAgICAgaW5jbHVkZTogXCIuL2Rpc3RcIixcbiAgICAgICAgcmVsZWFzZTogcHJvY2Vzcy5lbnYuVklURV9BUFBfVkVSU0lPTixcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHNlcnZlcjoge1xuICAgICAgcG9ydDogMzAwMCxcbiAgICB9LFxuICAgIGJ1aWxkOiB7XG4gICAgICBzb3VyY2VtYXA6IHRydWUsXG4gICAgICByb2xsdXBPcHRpb25zOiB7XG4gICAgICAgIG91dHB1dDoge1xuICAgICAgICAgIGFzc2V0RmlsZU5hbWVzOiAoeyBvcmlnaW5hbEZpbGVOYW1lcyB9KSA9PiB7XG4gICAgICAgICAgICBpZiAob3JpZ2luYWxGaWxlTmFtZXMpIHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIG9yaWdpbmFsRmlsZU5hbWVzKSB7XG4gICAgICAgICAgICAgICAgLy8gQ3VzdG9tIGFzc2V0IG5hbWUgZm9yIGxvY2FsZXMgdG8gaW5jbHVkZSB0aGUgbG9jYWxlIGNvZGUgaW4gdGhlIGZpbGVuYW1lXG4gICAgICAgICAgICAgICAgY29uc3QgbWF0Y2ggPSBuYW1lLm1hdGNoKC9sb2NhbGVzXFwvKFteL10rKVxcLyguKylcXC5qc29uJC8pO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgWywgbG9jYWxlLCBmaWxlbmFtZV0gPSBtYXRjaDtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgYXNzZXRzLyR7bG9jYWxlfS0ke2ZpbGVuYW1lfS1baGFzaF0uanNvbmA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERlZmF1bHQgbmFtaW5nIGZhbGxiYWNrXG4gICAgICAgICAgICByZXR1cm4gXCJhc3NldHMvW25hbWVdLVtoYXNoXVtleHRuYW1lXVwiO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgbWFudWFsQ2h1bmtzOiB7XG4gICAgICAgICAgICAvLyB3ZSBzaG91bGQgYmUgYWJsZSB0byByZW1vdmUgdGhpcyBvbmUgaHR0cHM6Ly9naXRodWIuY29tL21hdHJpeC1vcmcvbWF0cml4LXJ1c3Qtc2RrLWNyeXB0by13YXNtL3B1bGwvMTY3IGxhbmRzXG4gICAgICAgICAgICBcIm1hdHJpeC1zZGstY3J5cHRvLXdhc21cIjogW1wiQG1hdHJpeC1vcmcvbWF0cml4LXNkay1jcnlwdG8td2FzbVwiXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICAgIHBsdWdpbnMsXG4gICAgcmVzb2x2ZToge1xuICAgICAgYWxpYXM6IHtcbiAgICAgICAgLy8gbWF0cml4LXdpZGdldC1hcGkgaGFzIGl0cyB0cmFuc3BpbGVkIGxpYi9pbmRleC5qcyBhcyBpdHMgZW50cnkgcG9pbnQsXG4gICAgICAgIC8vIHdoaWNoIFZpdGUgZm9yIHNvbWUgcmVhc29uIHJlZnVzZXMgdG8gd29yayB3aXRoLCBzbyB3ZSBwb2ludCBpdCB0b1xuICAgICAgICAvLyBzcmMvaW5kZXgudHMgaW5zdGVhZFxuICAgICAgICBcIm1hdHJpeC13aWRnZXQtYXBpXCI6IFwibWF0cml4LXdpZGdldC1hcGkvc3JjL2luZGV4LnRzXCIsXG4gICAgICB9LFxuICAgICAgZGVkdXBlOiBbXG4gICAgICAgIFwicmVhY3RcIixcbiAgICAgICAgXCJyZWFjdC1kb21cIixcbiAgICAgICAgXCJtYXRyaXgtanMtc2RrXCIsXG4gICAgICAgIFwicmVhY3QtdXNlLW1lYXN1cmVcIixcbiAgICAgICAgLy8gVGhlc2UgcGFja2FnZXMgbW9kaWZ5IHRoZSBkb2N1bWVudCBiYXNlZCBvbiBzb21lIG1vZHVsZS1sZXZlbCBnbG9iYWxcbiAgICAgICAgLy8gc3RhdGUsIGFuZCBkb24ndCBwbGF5IG5pY2VseSB3aXRoIGR1cGxpY2F0ZSBjb3BpZXMgb2YgdGhlbXNlbHZlc1xuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcmFkaXgtdWkvcHJpbWl0aXZlcy9pc3N1ZXMvMTI0MSNpc3N1ZWNvbW1lbnQtMTg0NzgzNzg1MFxuICAgICAgICBcIkByYWRpeC11aS9yZWFjdC1mb2N1cy1ndWFyZHNcIixcbiAgICAgICAgXCJAcmFkaXgtdWkvcmVhY3QtZGlzbWlzc2FibGUtbGF5ZXJcIixcbiAgICAgIF0sXG4gICAgfSxcbiAgfTtcbn0pO1xuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUF1USxTQUFTLGdCQUFBQSxlQUFjLG1CQUFtQjs7O0FDT2pULFNBQVMsY0FBYyxlQUFlO0FBQ3RDLFNBQVMsbUJBQW1CO0FBQzVCLE9BQU8sZ0JBQWdCO0FBQ3ZCLE9BQU8sa0JBQWtCO0FBQ3pCLFNBQVMseUJBQXlCO0FBQ2xDLFNBQVMsd0JBQXdCO0FBQ2pDLE9BQU8sV0FBVztBQUNsQixPQUFPLGNBQWM7QUFHckIsSUFBTyxzQkFBUSxhQUFhLENBQUMsRUFBRSxLQUFLLE1BQU07QUFDeEMsUUFBTSxNQUFNLFFBQVEsTUFBTSxRQUFRLElBQUksQ0FBQztBQUV2QyxRQUFNLFVBQVU7QUFBQSxJQUNkLE1BQU07QUFBQSxJQUNOLFNBQVM7QUFBQSxJQUNULFdBQVc7QUFBQSxNQUNULGFBQWE7QUFBQTtBQUFBO0FBQUEsUUFHWCxLQUFLO0FBQUEsTUFDUDtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0QsYUFBYSxRQUFRO0FBQUEsTUFDbkIsTUFBTTtBQUFBLFFBQ0osT0FBTyxJQUFJLHFCQUFxQjtBQUFBLE1BQ2xDO0FBQUEsSUFDRixDQUFDO0FBQUEsSUFFRCxrQkFBa0I7QUFBQSxNQUNoQixzQkFBc0IsUUFBUSxJQUFJLGtCQUFrQjtBQUFBLE1BQ3BELFlBQVk7QUFBQSxNQUNaLGFBQWEsUUFBUSxJQUFJO0FBQUEsSUFDM0IsQ0FBQztBQUFBLElBRUQsWUFBWTtBQUFBLE1BQ1YsU0FBUyxDQUFDLGFBQWE7QUFBQSxJQUN6QixDQUFDO0FBQUEsRUFDSDtBQUVBLE1BQ0UsUUFBUSxJQUFJLGNBQ1osUUFBUSxJQUFJLGtCQUNaLFFBQVEsSUFBSSxxQkFDWixRQUFRLElBQUksWUFDWjtBQUNBLFlBQVE7QUFBQSxNQUNOLGlCQUFpQjtBQUFBLFFBQ2YsU0FBUztBQUFBLFFBQ1QsU0FBUyxRQUFRLElBQUk7QUFBQSxNQUN2QixDQUFDO0FBQUEsSUFDSDtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQUEsSUFDTCxRQUFRO0FBQUEsTUFDTixNQUFNO0FBQUEsSUFDUjtBQUFBLElBQ0EsT0FBTztBQUFBLE1BQ0wsV0FBVztBQUFBLE1BQ1gsZUFBZTtBQUFBLFFBQ2IsUUFBUTtBQUFBLFVBQ04sZ0JBQWdCLENBQUMsRUFBRSxrQkFBa0IsTUFBTTtBQUN6QyxnQkFBSSxtQkFBbUI7QUFDckIseUJBQVcsUUFBUSxtQkFBbUI7QUFFcEMsc0JBQU0sUUFBUSxLQUFLLE1BQU0sK0JBQStCO0FBQ3hELG9CQUFJLE9BQU87QUFDVCx3QkFBTSxDQUFDLEVBQUUsUUFBUSxRQUFRLElBQUk7QUFDN0IseUJBQU8sVUFBVSxNQUFNLElBQUksUUFBUTtBQUFBLGdCQUNyQztBQUFBLGNBQ0Y7QUFBQSxZQUNGO0FBR0EsbUJBQU87QUFBQSxVQUNUO0FBQUEsVUFDQSxjQUFjO0FBQUE7QUFBQSxZQUVaLDBCQUEwQixDQUFDLG9DQUFvQztBQUFBLFVBQ2pFO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsSUFDQTtBQUFBLElBQ0EsU0FBUztBQUFBLE1BQ1AsT0FBTztBQUFBO0FBQUE7QUFBQTtBQUFBLFFBSUwscUJBQXFCO0FBQUEsTUFDdkI7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNOO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUEsUUFJQTtBQUFBLFFBQ0E7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRixDQUFDOzs7QUQ3R0QsSUFBTyx3QkFBUUM7QUFBQSxFQUFhLENBQUMsY0FDM0I7QUFBQSxJQUNFLG9CQUFXLFNBQVM7QUFBQSxJQUNwQkEsY0FBYTtBQUFBLE1BQ1gsTUFBTTtBQUFBLFFBQ0osYUFBYTtBQUFBLFFBQ2IsS0FBSztBQUFBLFVBQ0gsU0FBUztBQUFBLFlBQ1AsbUJBQW1CO0FBQUEsVUFDckI7QUFBQSxRQUNGO0FBQUEsUUFDQSxZQUFZLENBQUMscUJBQXFCO0FBQUEsUUFDbEMsVUFBVTtBQUFBLFVBQ1IsVUFBVSxDQUFDLFFBQVEsTUFBTTtBQUFBLFVBQ3pCLFNBQVMsQ0FBQyxNQUFNO0FBQUEsVUFDaEIsU0FBUyxDQUFDLDhCQUE4QixtQkFBbUI7QUFBQSxRQUM3RDtBQUFBLE1BQ0Y7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBQ0Y7IiwKICAibmFtZXMiOiBbImRlZmluZUNvbmZpZyIsICJkZWZpbmVDb25maWciXQp9Cg==