summaryrefslogtreecommitdiff
path: root/frontend-old/node_modules/web-vitals/dist
diff options
context:
space:
mode:
Diffstat (limited to 'frontend-old/node_modules/web-vitals/dist')
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts7
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.js22
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/index.d.ts12
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/index.js27
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts23
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.js74
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts8
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.js57
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts11
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.js46
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts30
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.js256
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts13
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.js83
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts17
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.js76
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/deprecated.d.ts5
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/deprecated.js20
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/index.d.ts7
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/index.js22
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts6
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.js25
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts26
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.js45
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.js18
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts6
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js23
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.js20
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts2
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.js47
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js32
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.js48
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts3
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js80
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts21
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.js48
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.d.ts31
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.js107
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/observe.d.ts20
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/observe.js46
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.js22
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts7
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js147
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js25
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts14
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js50
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.js24
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.js23
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts5
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.js36
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onCLS.d.ts25
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onCLS.js108
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onFCP.d.ts10
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onFCP.js71
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onFID.d.ts13
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onFID.js70
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onINP.d.ts31
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onINP.js111
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onLCP.d.ts15
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onLCP.js106
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onTTFB.d.ts19
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/onTTFB.js79
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types.d.ts54
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types.js23
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/base.d.ts101
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/base.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/cls.d.ts55
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/cls.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/fcp.d.ts46
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/fcp.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/fid.d.ts46
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/fid.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/inp.d.ts103
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/inp.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/lcp.d.ts69
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/lcp.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.d.ts4
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.d.ts59
-rw-r--r--frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.js16
-rw-r--r--frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.iife.js1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.js1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.umd.cjs1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/web-vitals.iife.js1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/web-vitals.js1
-rw-r--r--frontend-old/node_modules/web-vitals/dist/web-vitals.umd.cjs1
94 files changed, 3183 insertions, 0 deletions
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts
new file mode 100644
index 0000000..e29b6dc
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.d.ts
@@ -0,0 +1,7 @@
+export {
+/**
+ * @deprecated Use `onINP()` instead.
+ */
+onFID, } from './onFID.js';
+export { FIDThresholds } from '../onFID.js';
+export * from '../types.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.js
new file mode 100644
index 0000000..2132ab4
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/deprecated.js
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {
+/**
+ * @deprecated Use `onINP()` instead.
+ */
+onFID, } from './onFID.js';
+export { FIDThresholds } from '../onFID.js';
+export * from '../types.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.d.ts
new file mode 100644
index 0000000..8513e3f
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.d.ts
@@ -0,0 +1,12 @@
+export { onCLS } from './onCLS.js';
+export { onFCP } from './onFCP.js';
+export { onINP } from './onINP.js';
+export { onLCP } from './onLCP.js';
+export { onTTFB } from './onTTFB.js';
+export { CLSThresholds } from '../onCLS.js';
+export { FCPThresholds } from '../onFCP.js';
+export { INPThresholds } from '../onINP.js';
+export { LCPThresholds } from '../onLCP.js';
+export { TTFBThresholds } from '../onTTFB.js';
+export * from './deprecated.js';
+export * from '../types.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.js
new file mode 100644
index 0000000..03702fc
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/index.js
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export { onCLS } from './onCLS.js';
+export { onFCP } from './onFCP.js';
+export { onINP } from './onINP.js';
+export { onLCP } from './onLCP.js';
+export { onTTFB } from './onTTFB.js';
+export { CLSThresholds } from '../onCLS.js';
+export { FCPThresholds } from '../onFCP.js';
+export { INPThresholds } from '../onINP.js';
+export { LCPThresholds } from '../onLCP.js';
+export { TTFBThresholds } from '../onTTFB.js';
+export * from './deprecated.js';
+export * from '../types.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts
new file mode 100644
index 0000000..65e1ca9
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.d.ts
@@ -0,0 +1,23 @@
+import { CLSMetricWithAttribution, ReportOpts } from '../types.js';
+/**
+ * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
+ * calls the `callback` function once the value is ready to be reported, along
+ * with all `layout-shift` performance entries that were used in the metric
+ * value calculation. The reported value is a `double` (corresponding to a
+ * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** CLS should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export declare const onCLS: (onReport: (metric: CLSMetricWithAttribution) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.js
new file mode 100644
index 0000000..78221fa
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onCLS.js
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getLoadState } from '../lib/getLoadState.js';
+import { getSelector } from '../lib/getSelector.js';
+import { onCLS as unattributedOnCLS } from '../onCLS.js';
+const getLargestLayoutShiftEntry = (entries) => {
+ return entries.reduce((a, b) => (a && a.value > b.value ? a : b));
+};
+const getLargestLayoutShiftSource = (sources) => {
+ return sources.find((s) => s.node && s.node.nodeType === 1) || sources[0];
+};
+const attributeCLS = (metric) => {
+ // Use an empty object if no other attribution has been set.
+ let attribution = {};
+ if (metric.entries.length) {
+ const largestEntry = getLargestLayoutShiftEntry(metric.entries);
+ if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
+ const largestSource = getLargestLayoutShiftSource(largestEntry.sources);
+ if (largestSource) {
+ attribution = {
+ largestShiftTarget: getSelector(largestSource.node),
+ largestShiftTime: largestEntry.startTime,
+ largestShiftValue: largestEntry.value,
+ largestShiftSource: largestSource,
+ largestShiftEntry: largestEntry,
+ loadState: getLoadState(largestEntry.startTime),
+ };
+ }
+ }
+ }
+ // Use Object.assign to set property to keep tsc happy.
+ const metricWithAttribution = Object.assign(metric, { attribution });
+ return metricWithAttribution;
+};
+/**
+ * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
+ * calls the `callback` function once the value is ready to be reported, along
+ * with all `layout-shift` performance entries that were used in the metric
+ * value calculation. The reported value is a `double` (corresponding to a
+ * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** CLS should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export const onCLS = (onReport, opts) => {
+ unattributedOnCLS((metric) => {
+ const metricWithAttribution = attributeCLS(metric);
+ onReport(metricWithAttribution);
+ }, opts);
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts
new file mode 100644
index 0000000..b0b7f37
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.d.ts
@@ -0,0 +1,8 @@
+import { FCPMetricWithAttribution, ReportOpts } from '../types.js';
+/**
+ * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `paint` performance entry used to determine the value. The reported
+ * value is a `DOMHighResTimeStamp`.
+ */
+export declare const onFCP: (onReport: (metric: FCPMetricWithAttribution) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.js
new file mode 100644
index 0000000..06e87f6
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFCP.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getBFCacheRestoreTime } from '../lib/bfcache.js';
+import { getLoadState } from '../lib/getLoadState.js';
+import { getNavigationEntry } from '../lib/getNavigationEntry.js';
+import { onFCP as unattributedOnFCP } from '../onFCP.js';
+const attributeFCP = (metric) => {
+ // Use a default object if no other attribution has been set.
+ let attribution = {
+ timeToFirstByte: 0,
+ firstByteToFCP: metric.value,
+ loadState: getLoadState(getBFCacheRestoreTime()),
+ };
+ if (metric.entries.length) {
+ const navigationEntry = getNavigationEntry();
+ const fcpEntry = metric.entries[metric.entries.length - 1];
+ if (navigationEntry) {
+ const activationStart = navigationEntry.activationStart || 0;
+ const ttfb = Math.max(0, navigationEntry.responseStart - activationStart);
+ attribution = {
+ timeToFirstByte: ttfb,
+ firstByteToFCP: metric.value - ttfb,
+ loadState: getLoadState(metric.entries[0].startTime),
+ navigationEntry,
+ fcpEntry,
+ };
+ }
+ }
+ // Use Object.assign to set property to keep tsc happy.
+ const metricWithAttribution = Object.assign(metric, { attribution });
+ return metricWithAttribution;
+};
+/**
+ * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `paint` performance entry used to determine the value. The reported
+ * value is a `DOMHighResTimeStamp`.
+ */
+export const onFCP = (onReport, opts) => {
+ unattributedOnFCP((metric) => {
+ const metricWithAttribution = attributeFCP(metric);
+ onReport(metricWithAttribution);
+ }, opts);
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts
new file mode 100644
index 0000000..b910f15
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.d.ts
@@ -0,0 +1,11 @@
+import { FIDMetricWithAttribution, ReportOpts } from '../types.js';
+/**
+ * Calculates the [FID](https://web.dev/articles/fid) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `first-input` performance entry used to determine the value. The
+ * reported value is a `DOMHighResTimeStamp`.
+ *
+ * _**Important:** since FID is only reported after the user interacts with the
+ * page, it's possible that it will not be reported for some page loads._
+ */
+export declare const onFID: (onReport: (metric: FIDMetricWithAttribution) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.js
new file mode 100644
index 0000000..52f1ddc
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onFID.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getLoadState } from '../lib/getLoadState.js';
+import { getSelector } from '../lib/getSelector.js';
+import { onFID as unattributedOnFID } from '../onFID.js';
+const attributeFID = (metric) => {
+ const fidEntry = metric.entries[0];
+ const attribution = {
+ eventTarget: getSelector(fidEntry.target),
+ eventType: fidEntry.name,
+ eventTime: fidEntry.startTime,
+ eventEntry: fidEntry,
+ loadState: getLoadState(fidEntry.startTime),
+ };
+ // Use Object.assign to set property to keep tsc happy.
+ const metricWithAttribution = Object.assign(metric, { attribution });
+ return metricWithAttribution;
+};
+/**
+ * Calculates the [FID](https://web.dev/articles/fid) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `first-input` performance entry used to determine the value. The
+ * reported value is a `DOMHighResTimeStamp`.
+ *
+ * _**Important:** since FID is only reported after the user interacts with the
+ * page, it's possible that it will not be reported for some page loads._
+ */
+export const onFID = (onReport, opts) => {
+ unattributedOnFID((metric) => {
+ const metricWithAttribution = attributeFID(metric);
+ onReport(metricWithAttribution);
+ }, opts);
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts
new file mode 100644
index 0000000..217faa0
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.d.ts
@@ -0,0 +1,30 @@
+import { INPMetricWithAttribution, ReportOpts } from '../types.js';
+export declare const interactionTargetMap: Map<number, Node>;
+/**
+ * Calculates the [INP](https://web.dev/articles/inp) value for the current
+ * page and calls the `callback` function once the value is ready, along with
+ * the `event` performance entries reported for that interaction. The reported
+ * value is a `DOMHighResTimeStamp`.
+ *
+ * A custom `durationThreshold` configuration option can optionally be passed to
+ * control what `event-timing` entries are considered for INP reporting. The
+ * default threshold is `40`, which means INP scores of less than 40 are
+ * reported as 0. Note that this will not affect your 75th percentile INP value
+ * unless that value is also less than 40 (well below the recommended
+ * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** INP should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export declare const onINP: (onReport: (metric: INPMetricWithAttribution) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.js
new file mode 100644
index 0000000..51df8e3
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onINP.js
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getLoadState } from '../lib/getLoadState.js';
+import { getSelector } from '../lib/getSelector.js';
+import { longestInteractionList, entryPreProcessingCallbacks, longestInteractionMap, } from '../lib/interactions.js';
+import { observe } from '../lib/observe.js';
+import { whenIdle } from '../lib/whenIdle.js';
+import { onINP as unattributedOnINP } from '../onINP.js';
+// The maximum number of previous frames for which data is kept.
+// Storing data about previous frames is necessary to handle cases where event
+// and LoAF entries are dispatched out of order, and so a buffer of previous
+// frame data is needed to determine various bits of INP attribution once all
+// the frame-related data has come in.
+// In most cases this out-of-order data is only off by a frame or two, so
+// keeping the most recent 50 should be more than sufficient.
+const MAX_PREVIOUS_FRAMES = 50;
+// A PerformanceObserver, observing new `long-animation-frame` entries.
+// If this variable is defined it means the browser supports LoAF.
+let loafObserver;
+// A list of LoAF entries that have been dispatched and could potentially
+// intersect with the INP candidate interaction. Note that periodically this
+// list is cleaned up and entries that are known to not match INP are removed.
+let pendingLoAFs = [];
+// An array of groups of all the event timing entries that occurred within a
+// particular frame. Note that periodically this array is cleaned up and entries
+// that are known to not match INP are removed.
+let pendingEntriesGroups = [];
+// The `processingEnd` time of most recently-processed event, chronologically.
+let latestProcessingEnd = 0;
+// A WeakMap to look up the event-timing-entries group of a given entry.
+// Note that this only maps from "important" entries: either the first input or
+// those with an `interactionId`.
+const entryToEntriesGroupMap = new WeakMap();
+// A mapping of interactionIds to the target Node.
+export const interactionTargetMap = new Map();
+// A reference to the idle task used to clean up entries from the above
+// variables. If the value is -1 it means no task is queue, and if it's
+// greater than -1 the value corresponds to the idle callback handle.
+let idleHandle = -1;
+/**
+ * Adds new LoAF entries to the `pendingLoAFs` list.
+ */
+const handleLoAFEntries = (entries) => {
+ pendingLoAFs = pendingLoAFs.concat(entries);
+ queueCleanup();
+};
+// Get a reference to the interaction target element in case it's removed
+// from the DOM later.
+const saveInteractionTarget = (entry) => {
+ if (entry.interactionId &&
+ entry.target &&
+ !interactionTargetMap.has(entry.interactionId)) {
+ interactionTargetMap.set(entry.interactionId, entry.target);
+ }
+};
+/**
+ * Groups entries that were presented within the same animation frame by
+ * a common `renderTime`. This function works by referencing
+ * `pendingEntriesGroups` and using an existing render time if one is found
+ * (otherwise creating a new one). This function also adds all interaction
+ * entries to an `entryToRenderTimeMap` WeakMap so that the "grouped" entries
+ * can be looked up later.
+ */
+const groupEntriesByRenderTime = (entry) => {
+ const renderTime = entry.startTime + entry.duration;
+ let group;
+ latestProcessingEnd = Math.max(latestProcessingEnd, entry.processingEnd);
+ // Iterate over all previous render times in reverse order to find a match.
+ // Go in reverse since the most likely match will be at the end.
+ for (let i = pendingEntriesGroups.length - 1; i >= 0; i--) {
+ const potentialGroup = pendingEntriesGroups[i];
+ // If a group's render time is within 8ms of the entry's render time,
+ // assume they were part of the same frame and add it to the group.
+ if (Math.abs(renderTime - potentialGroup.renderTime) <= 8) {
+ group = potentialGroup;
+ group.startTime = Math.min(entry.startTime, group.startTime);
+ group.processingStart = Math.min(entry.processingStart, group.processingStart);
+ group.processingEnd = Math.max(entry.processingEnd, group.processingEnd);
+ group.entries.push(entry);
+ break;
+ }
+ }
+ // If there was no matching group, assume this is a new frame.
+ if (!group) {
+ group = {
+ startTime: entry.startTime,
+ processingStart: entry.processingStart,
+ processingEnd: entry.processingEnd,
+ renderTime,
+ entries: [entry],
+ };
+ pendingEntriesGroups.push(group);
+ }
+ // Store the grouped render time for this entry for reference later.
+ if (entry.interactionId || entry.entryType === 'first-input') {
+ entryToEntriesGroupMap.set(entry, group);
+ }
+ queueCleanup();
+};
+const queueCleanup = () => {
+ // Queue cleanup of entries that are not part of any INP candidates.
+ if (idleHandle < 0) {
+ idleHandle = whenIdle(cleanupEntries);
+ }
+};
+const cleanupEntries = () => {
+ // Delete any stored interaction target elements if they're not part of one
+ // of the 10 longest interactions.
+ if (interactionTargetMap.size > 10) {
+ interactionTargetMap.forEach((_, key) => {
+ if (!longestInteractionMap.has(key)) {
+ interactionTargetMap.delete(key);
+ }
+ });
+ }
+ // Keep all render times that are part of a pending INP candidate or
+ // that occurred within the 50 most recently-dispatched groups of events.
+ const longestInteractionGroups = longestInteractionList.map((i) => {
+ return entryToEntriesGroupMap.get(i.entries[0]);
+ });
+ const minIndex = pendingEntriesGroups.length - MAX_PREVIOUS_FRAMES;
+ pendingEntriesGroups = pendingEntriesGroups.filter((group, index) => {
+ if (index >= minIndex)
+ return true;
+ return longestInteractionGroups.includes(group);
+ });
+ // Keep all pending LoAF entries that either:
+ // 1) intersect with entries in the newly cleaned up `pendingEntriesGroups`
+ // 2) occur after the most recently-processed event entry (for up to MAX_PREVIOUS_FRAMES)
+ const loafsToKeep = new Set();
+ for (let i = 0; i < pendingEntriesGroups.length; i++) {
+ const group = pendingEntriesGroups[i];
+ getIntersectingLoAFs(group.startTime, group.processingEnd).forEach((loaf) => {
+ loafsToKeep.add(loaf);
+ });
+ }
+ const prevFrameIndexCutoff = pendingLoAFs.length - 1 - MAX_PREVIOUS_FRAMES;
+ // Filter `pendingLoAFs` to preserve LoAF order.
+ pendingLoAFs = pendingLoAFs.filter((loaf, index) => {
+ if (loaf.startTime > latestProcessingEnd && index > prevFrameIndexCutoff) {
+ return true;
+ }
+ return loafsToKeep.has(loaf);
+ });
+ // Reset the idle callback handle so it can be queued again.
+ idleHandle = -1;
+};
+entryPreProcessingCallbacks.push(saveInteractionTarget, groupEntriesByRenderTime);
+const getIntersectingLoAFs = (start, end) => {
+ const intersectingLoAFs = [];
+ for (let i = 0, loaf; (loaf = pendingLoAFs[i]); i++) {
+ // If the LoAF ends before the given start time, ignore it.
+ if (loaf.startTime + loaf.duration < start)
+ continue;
+ // If the LoAF starts after the given end time, ignore it and all
+ // subsequent pending LoAFs (because they're in time order).
+ if (loaf.startTime > end)
+ break;
+ // Still here? If so this LoAF intersects with the interaction.
+ intersectingLoAFs.push(loaf);
+ }
+ return intersectingLoAFs;
+};
+const attributeINP = (metric) => {
+ const firstEntry = metric.entries[0];
+ const group = entryToEntriesGroupMap.get(firstEntry);
+ const processingStart = firstEntry.processingStart;
+ const processingEnd = group.processingEnd;
+ // Sort the entries in processing time order.
+ const processedEventEntries = group.entries.sort((a, b) => {
+ return a.processingStart - b.processingStart;
+ });
+ const longAnimationFrameEntries = getIntersectingLoAFs(firstEntry.startTime, processingEnd);
+ // The first interaction entry may not have a target defined, so use the
+ // first one found in the entry list.
+ // TODO: when the following bug is fixed just use `firstInteractionEntry`.
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=1367329
+ // As a fallback, also check the interactionTargetMap (to account for
+ // cases where the element is removed from the DOM before reporting happens).
+ const firstEntryWithTarget = metric.entries.find((entry) => entry.target);
+ const interactionTargetElement = (firstEntryWithTarget && firstEntryWithTarget.target) ||
+ interactionTargetMap.get(firstEntry.interactionId);
+ // Since entry durations are rounded to the nearest 8ms, we need to clamp
+ // the `nextPaintTime` value to be higher than the `processingEnd` or
+ // end time of any LoAF entry.
+ const nextPaintTimeCandidates = [
+ firstEntry.startTime + firstEntry.duration,
+ processingEnd,
+ ].concat(longAnimationFrameEntries.map((loaf) => loaf.startTime + loaf.duration));
+ const nextPaintTime = Math.max.apply(Math, nextPaintTimeCandidates);
+ const attribution = {
+ interactionTarget: getSelector(interactionTargetElement),
+ interactionTargetElement: interactionTargetElement,
+ interactionType: firstEntry.name.startsWith('key') ? 'keyboard' : 'pointer',
+ interactionTime: firstEntry.startTime,
+ nextPaintTime: nextPaintTime,
+ processedEventEntries: processedEventEntries,
+ longAnimationFrameEntries: longAnimationFrameEntries,
+ inputDelay: processingStart - firstEntry.startTime,
+ processingDuration: processingEnd - processingStart,
+ presentationDelay: Math.max(nextPaintTime - processingEnd, 0),
+ loadState: getLoadState(firstEntry.startTime),
+ };
+ // Use Object.assign to set property to keep tsc happy.
+ const metricWithAttribution = Object.assign(metric, { attribution });
+ return metricWithAttribution;
+};
+/**
+ * Calculates the [INP](https://web.dev/articles/inp) value for the current
+ * page and calls the `callback` function once the value is ready, along with
+ * the `event` performance entries reported for that interaction. The reported
+ * value is a `DOMHighResTimeStamp`.
+ *
+ * A custom `durationThreshold` configuration option can optionally be passed to
+ * control what `event-timing` entries are considered for INP reporting. The
+ * default threshold is `40`, which means INP scores of less than 40 are
+ * reported as 0. Note that this will not affect your 75th percentile INP value
+ * unless that value is also less than 40 (well below the recommended
+ * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** INP should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export const onINP = (onReport, opts) => {
+ if (!loafObserver) {
+ loafObserver = observe('long-animation-frame', handleLoAFEntries);
+ }
+ unattributedOnINP((metric) => {
+ const metricWithAttribution = attributeINP(metric);
+ onReport(metricWithAttribution);
+ }, opts);
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts
new file mode 100644
index 0000000..caa6ea7
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.d.ts
@@ -0,0 +1,13 @@
+import { LCPMetricWithAttribution, ReportOpts } from '../types.js';
+/**
+ * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
+ * calls the `callback` function once the value is ready (along with the
+ * relevant `largest-contentful-paint` performance entry used to determine the
+ * value). The reported value is a `DOMHighResTimeStamp`.
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called any time a new `largest-contentful-paint`
+ * performance entry is dispatched, or once the final value of the metric has
+ * been determined.
+ */
+export declare const onLCP: (onReport: (metric: LCPMetricWithAttribution) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.js
new file mode 100644
index 0000000..269323c
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onLCP.js
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getNavigationEntry } from '../lib/getNavigationEntry.js';
+import { getSelector } from '../lib/getSelector.js';
+import { onLCP as unattributedOnLCP } from '../onLCP.js';
+const attributeLCP = (metric) => {
+ // Use a default object if no other attribution has been set.
+ let attribution = {
+ timeToFirstByte: 0,
+ resourceLoadDelay: 0,
+ resourceLoadDuration: 0,
+ elementRenderDelay: metric.value,
+ };
+ if (metric.entries.length) {
+ const navigationEntry = getNavigationEntry();
+ if (navigationEntry) {
+ const activationStart = navigationEntry.activationStart || 0;
+ const lcpEntry = metric.entries[metric.entries.length - 1];
+ const lcpResourceEntry = lcpEntry.url &&
+ performance
+ .getEntriesByType('resource')
+ .filter((e) => e.name === lcpEntry.url)[0];
+ const ttfb = Math.max(0, navigationEntry.responseStart - activationStart);
+ const lcpRequestStart = Math.max(ttfb,
+ // Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
+ lcpResourceEntry
+ ? (lcpResourceEntry.requestStart || lcpResourceEntry.startTime) -
+ activationStart
+ : 0);
+ const lcpResponseEnd = Math.max(lcpRequestStart, lcpResourceEntry ? lcpResourceEntry.responseEnd - activationStart : 0);
+ const lcpRenderTime = Math.max(lcpResponseEnd, lcpEntry.startTime - activationStart);
+ attribution = {
+ element: getSelector(lcpEntry.element),
+ timeToFirstByte: ttfb,
+ resourceLoadDelay: lcpRequestStart - ttfb,
+ resourceLoadDuration: lcpResponseEnd - lcpRequestStart,
+ elementRenderDelay: lcpRenderTime - lcpResponseEnd,
+ navigationEntry,
+ lcpEntry,
+ };
+ // Only attribution the URL and resource entry if they exist.
+ if (lcpEntry.url) {
+ attribution.url = lcpEntry.url;
+ }
+ if (lcpResourceEntry) {
+ attribution.lcpResourceEntry = lcpResourceEntry;
+ }
+ }
+ }
+ // Use Object.assign to set property to keep tsc happy.
+ const metricWithAttribution = Object.assign(metric, { attribution });
+ return metricWithAttribution;
+};
+/**
+ * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
+ * calls the `callback` function once the value is ready (along with the
+ * relevant `largest-contentful-paint` performance entry used to determine the
+ * value). The reported value is a `DOMHighResTimeStamp`.
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called any time a new `largest-contentful-paint`
+ * performance entry is dispatched, or once the final value of the metric has
+ * been determined.
+ */
+export const onLCP = (onReport, opts) => {
+ unattributedOnLCP((metric) => {
+ const metricWithAttribution = attributeLCP(metric);
+ onReport(metricWithAttribution);
+ }, opts);
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts
new file mode 100644
index 0000000..a39d0ad
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.d.ts
@@ -0,0 +1,17 @@
+import { TTFBMetricWithAttribution, ReportOpts } from '../types.js';
+/**
+ * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
+ * current page and calls the `callback` function once the page has loaded,
+ * along with the relevant `navigation` performance entry used to determine the
+ * value. The reported value is a `DOMHighResTimeStamp`.
+ *
+ * Note, this function waits until after the page is loaded to call `callback`
+ * in order to ensure all properties of the `navigation` entry are populated.
+ * This is useful if you want to report on other metrics exposed by the
+ * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
+ * example, the TTFB metric starts from the page's [time
+ * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
+ * includes time spent on DNS lookup, connection negotiation, network latency,
+ * and server processing time.
+ */
+export declare const onTTFB: (onReport: (metric: TTFBMetricWithAttribution) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.js b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.js
new file mode 100644
index 0000000..cd0d6bb
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/attribution/onTTFB.js
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onTTFB as unattributedOnTTFB } from '../onTTFB.js';
+const attributeTTFB = (metric) => {
+ // Use a default object if no other attribution has been set.
+ let attribution = {
+ waitingDuration: 0,
+ cacheDuration: 0,
+ dnsDuration: 0,
+ connectionDuration: 0,
+ requestDuration: 0,
+ };
+ if (metric.entries.length) {
+ const navigationEntry = metric.entries[0];
+ const activationStart = navigationEntry.activationStart || 0;
+ // Measure from workerStart or fetchStart so any service worker startup
+ // time is included in cacheDuration (which also includes other sw time
+ // anyway, that cannot be accurately split out cross-browser).
+ const waitEnd = Math.max((navigationEntry.workerStart || navigationEntry.fetchStart) -
+ activationStart, 0);
+ const dnsStart = Math.max(navigationEntry.domainLookupStart - activationStart, 0);
+ const connectStart = Math.max(navigationEntry.connectStart - activationStart, 0);
+ const connectEnd = Math.max(navigationEntry.connectEnd - activationStart, 0);
+ attribution = {
+ waitingDuration: waitEnd,
+ cacheDuration: dnsStart - waitEnd,
+ // dnsEnd usually equals connectStart but use connectStart over dnsEnd
+ // for dnsDuration in case there ever is a gap.
+ dnsDuration: connectStart - dnsStart,
+ connectionDuration: connectEnd - connectStart,
+ // There is often a gap between connectEnd and requestStart. Attribute
+ // that to requestDuration so connectionDuration remains 0 for
+ // service worker controlled requests were connectStart and connectEnd
+ // are the same.
+ requestDuration: metric.value - connectEnd,
+ navigationEntry: navigationEntry,
+ };
+ }
+ // Use Object.assign to set property to keep tsc happy.
+ const metricWithAttribution = Object.assign(metric, { attribution });
+ return metricWithAttribution;
+};
+/**
+ * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
+ * current page and calls the `callback` function once the page has loaded,
+ * along with the relevant `navigation` performance entry used to determine the
+ * value. The reported value is a `DOMHighResTimeStamp`.
+ *
+ * Note, this function waits until after the page is loaded to call `callback`
+ * in order to ensure all properties of the `navigation` entry are populated.
+ * This is useful if you want to report on other metrics exposed by the
+ * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
+ * example, the TTFB metric starts from the page's [time
+ * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
+ * includes time spent on DNS lookup, connection negotiation, network latency,
+ * and server processing time.
+ */
+export const onTTFB = (onReport, opts) => {
+ unattributedOnTTFB((metric) => {
+ const metricWithAttribution = attributeTTFB(metric);
+ onReport(metricWithAttribution);
+ }, opts);
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/deprecated.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.d.ts
new file mode 100644
index 0000000..84d77ae
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.d.ts
@@ -0,0 +1,5 @@
+export {
+/**
+ * @deprecated Use `onINP()` instead.
+ */
+onFID, FIDThresholds, } from './onFID.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/deprecated.js b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.js
new file mode 100644
index 0000000..42756b9
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/deprecated.js
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {
+/**
+ * @deprecated Use `onINP()` instead.
+ */
+onFID, FIDThresholds, } from './onFID.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/index.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/index.d.ts
new file mode 100644
index 0000000..dfd2263
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/index.d.ts
@@ -0,0 +1,7 @@
+export { onCLS, CLSThresholds } from './onCLS.js';
+export { onFCP, FCPThresholds } from './onFCP.js';
+export { onINP, INPThresholds } from './onINP.js';
+export { onLCP, LCPThresholds } from './onLCP.js';
+export { onTTFB, TTFBThresholds } from './onTTFB.js';
+export * from './deprecated.js';
+export * from './types.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/index.js b/frontend-old/node_modules/web-vitals/dist/modules/index.js
new file mode 100644
index 0000000..d374950
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/index.js
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export { onCLS, CLSThresholds } from './onCLS.js';
+export { onFCP, FCPThresholds } from './onFCP.js';
+export { onINP, INPThresholds } from './onINP.js';
+export { onLCP, LCPThresholds } from './onLCP.js';
+export { onTTFB, TTFBThresholds } from './onTTFB.js';
+export * from './deprecated.js';
+export * from './types.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts
new file mode 100644
index 0000000..0870fd0
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.d.ts
@@ -0,0 +1,6 @@
+interface onBFCacheRestoreCallback {
+ (event: PageTransitionEvent): void;
+}
+export declare const getBFCacheRestoreTime: () => number;
+export declare const onBFCacheRestore: (cb: onBFCacheRestoreCallback) => void;
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.js
new file mode 100644
index 0000000..48050e3
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bfcache.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+let bfcacheRestoreTime = -1;
+export const getBFCacheRestoreTime = () => bfcacheRestoreTime;
+export const onBFCacheRestore = (cb) => {
+ addEventListener('pageshow', (event) => {
+ if (event.persisted) {
+ bfcacheRestoreTime = event.timeStamp;
+ cb(event);
+ }
+ }, true);
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts
new file mode 100644
index 0000000..54880d6
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.d.ts
@@ -0,0 +1,26 @@
+import { MetricType, MetricRatingThresholds } from '../types.js';
+export declare const bindReporter: <MetricName extends "CLS" | "FCP" | "FID" | "INP" | "LCP" | "TTFB">(callback: (metric: Extract<import("../types.js").CLSMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").FCPMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").FIDMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").INPMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").LCPMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").TTFBMetric, {
+ name: MetricName;
+}>) => void, metric: Extract<import("../types.js").CLSMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").FCPMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").FIDMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").INPMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").LCPMetric, {
+ name: MetricName;
+}> | Extract<import("../types.js").TTFBMetric, {
+ name: MetricName;
+}>, thresholds: MetricRatingThresholds, reportAllChanges?: boolean) => (forceReport?: boolean) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.js
new file mode 100644
index 0000000..e1afbbc
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/bindReporter.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const getRating = (value, thresholds) => {
+ if (value > thresholds[1]) {
+ return 'poor';
+ }
+ if (value > thresholds[0]) {
+ return 'needs-improvement';
+ }
+ return 'good';
+};
+export const bindReporter = (callback, metric, thresholds, reportAllChanges) => {
+ let prevValue;
+ let delta;
+ return (forceReport) => {
+ if (metric.value >= 0) {
+ if (forceReport || reportAllChanges) {
+ delta = metric.value - (prevValue || 0);
+ // Report the metric if there's a non-zero delta or if no previous
+ // value exists (which can happen in the case of the document becoming
+ // hidden when the metric value is 0).
+ // See: https://github.com/GoogleChrome/web-vitals/issues/14
+ if (delta || prevValue === undefined) {
+ prevValue = metric.value;
+ metric.delta = delta;
+ metric.rating = getRating(metric.value, thresholds);
+ callback(metric);
+ }
+ }
+ }
+ };
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts
new file mode 100644
index 0000000..7ac0933
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.d.ts
@@ -0,0 +1 @@
+export declare const doubleRAF: (cb: () => unknown) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.js
new file mode 100644
index 0000000..16da945
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/doubleRAF.js
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export const doubleRAF = (cb) => {
+ requestAnimationFrame(() => requestAnimationFrame(() => cb()));
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts
new file mode 100644
index 0000000..a049ad9
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.d.ts
@@ -0,0 +1,6 @@
+/**
+ * Performantly generate a unique, 30-char string by combining a version
+ * number, the current timestamp with a 13-digit number integer.
+ * @return {string}
+ */
+export declare const generateUniqueID: () => string;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js
new file mode 100644
index 0000000..5fabcc6
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/generateUniqueID.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Performantly generate a unique, 30-char string by combining a version
+ * number, the current timestamp with a 13-digit number integer.
+ * @return {string}
+ */
+export const generateUniqueID = () => {
+ return `v4-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts
new file mode 100644
index 0000000..b9f424e
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.d.ts
@@ -0,0 +1 @@
+export declare const getActivationStart: () => number;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.js
new file mode 100644
index 0000000..6bfcd5b
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getActivationStart.js
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getNavigationEntry } from './getNavigationEntry.js';
+export const getActivationStart = () => {
+ const navEntry = getNavigationEntry();
+ return (navEntry && navEntry.activationStart) || 0;
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts
new file mode 100644
index 0000000..a855155
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.d.ts
@@ -0,0 +1,2 @@
+import { LoadState } from '../types.js';
+export declare const getLoadState: (timestamp: number) => LoadState;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.js
new file mode 100644
index 0000000..cac5b57
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getLoadState.js
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getNavigationEntry } from './getNavigationEntry.js';
+export const getLoadState = (timestamp) => {
+ if (document.readyState === 'loading') {
+ // If the `readyState` is 'loading' there's no need to look at timestamps
+ // since the timestamp has to be the current time or earlier.
+ return 'loading';
+ }
+ else {
+ const navigationEntry = getNavigationEntry();
+ if (navigationEntry) {
+ if (timestamp < navigationEntry.domInteractive) {
+ return 'loading';
+ }
+ else if (navigationEntry.domContentLoadedEventStart === 0 ||
+ timestamp < navigationEntry.domContentLoadedEventStart) {
+ // If the `domContentLoadedEventStart` timestamp has not yet been
+ // set, or if the given timestamp is less than that value.
+ return 'dom-interactive';
+ }
+ else if (navigationEntry.domComplete === 0 ||
+ timestamp < navigationEntry.domComplete) {
+ // If the `domComplete` timestamp has not yet been
+ // set, or if the given timestamp is less than that value.
+ return 'dom-content-loaded';
+ }
+ }
+ }
+ // If any of the above fail, default to loaded. This could really only
+ // happy if the browser doesn't support the performance timeline, which
+ // most likely means this code would never run anyway.
+ return 'complete';
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts
new file mode 100644
index 0000000..af6a02b
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.d.ts
@@ -0,0 +1 @@
+export declare const getNavigationEntry: () => PerformanceNavigationTiming | void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js
new file mode 100644
index 0000000..94ac68e
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getNavigationEntry.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export const getNavigationEntry = () => {
+ const navigationEntry = self.performance &&
+ performance.getEntriesByType &&
+ performance.getEntriesByType('navigation')[0];
+ // Check to ensure the `responseStart` property is present and valid.
+ // In some cases no value is reported by the browser (for
+ // privacy/security reasons), and in other cases (bugs) the value is
+ // negative or is larger than the current page time. Ignore these cases:
+ // https://github.com/GoogleChrome/web-vitals/issues/137
+ // https://github.com/GoogleChrome/web-vitals/issues/162
+ // https://github.com/GoogleChrome/web-vitals/issues/275
+ if (navigationEntry &&
+ navigationEntry.responseStart > 0 &&
+ navigationEntry.responseStart < performance.now()) {
+ return navigationEntry;
+ }
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts
new file mode 100644
index 0000000..494212e
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.d.ts
@@ -0,0 +1 @@
+export declare const getSelector: (node: Node | null | undefined, maxLen?: number) => string;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.js
new file mode 100644
index 0000000..7b18244
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getSelector.js
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const getName = (node) => {
+ const name = node.nodeName;
+ return node.nodeType === 1
+ ? name.toLowerCase()
+ : name.toUpperCase().replace(/^#/, '');
+};
+export const getSelector = (node, maxLen) => {
+ let sel = '';
+ try {
+ while (node && node.nodeType !== 9) {
+ const el = node;
+ const part = el.id
+ ? '#' + el.id
+ : getName(el) +
+ (el.classList &&
+ el.classList.value &&
+ el.classList.value.trim() &&
+ el.classList.value.trim().length
+ ? '.' + el.classList.value.trim().replace(/\s+/g, '.')
+ : '');
+ if (sel.length + part.length > (maxLen || 100) - 1)
+ return sel || part;
+ sel = sel ? part + '>' + sel : part;
+ if (el.id)
+ break;
+ node = el.parentNode;
+ }
+ }
+ catch (err) {
+ // Do nothing...
+ }
+ return sel;
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts
new file mode 100644
index 0000000..0832a05
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.d.ts
@@ -0,0 +1,3 @@
+export declare const getVisibilityWatcher: () => {
+ readonly firstHiddenTime: number;
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js
new file mode 100644
index 0000000..4a052db
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/getVisibilityWatcher.js
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onBFCacheRestore } from './bfcache.js';
+let firstHiddenTime = -1;
+const initHiddenTime = () => {
+ // If the document is hidden when this code runs, assume it was always
+ // hidden and the page was loaded in the background, with the one exception
+ // that visibility state is always 'hidden' during prerendering, so we have
+ // to ignore that case until prerendering finishes (see: `prerenderingchange`
+ // event logic below).
+ return document.visibilityState === 'hidden' && !document.prerendering
+ ? 0
+ : Infinity;
+};
+const onVisibilityUpdate = (event) => {
+ // If the document is 'hidden' and no previous hidden timestamp has been
+ // set, update it based on the current event data.
+ if (document.visibilityState === 'hidden' && firstHiddenTime > -1) {
+ // If the event is a 'visibilitychange' event, it means the page was
+ // visible prior to this change, so the event timestamp is the first
+ // hidden time.
+ // However, if the event is not a 'visibilitychange' event, then it must
+ // be a 'prerenderingchange' event, and the fact that the document is
+ // still 'hidden' from the above check means the tab was activated
+ // in a background state and so has always been hidden.
+ firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0;
+ // Remove all listeners now that a `firstHiddenTime` value has been set.
+ removeChangeListeners();
+ }
+};
+const addChangeListeners = () => {
+ addEventListener('visibilitychange', onVisibilityUpdate, true);
+ // IMPORTANT: when a page is prerendering, its `visibilityState` is
+ // 'hidden', so in order to account for cases where this module checks for
+ // visibility during prerendering, an additional check after prerendering
+ // completes is also required.
+ addEventListener('prerenderingchange', onVisibilityUpdate, true);
+};
+const removeChangeListeners = () => {
+ removeEventListener('visibilitychange', onVisibilityUpdate, true);
+ removeEventListener('prerenderingchange', onVisibilityUpdate, true);
+};
+export const getVisibilityWatcher = () => {
+ if (firstHiddenTime < 0) {
+ // If the document is hidden when this code runs, assume it was hidden
+ // since navigation start. This isn't a perfect heuristic, but it's the
+ // best we can do until an API is available to support querying past
+ // visibilityState.
+ firstHiddenTime = initHiddenTime();
+ addChangeListeners();
+ // Reset the time on bfcache restores.
+ onBFCacheRestore(() => {
+ // Schedule a task in order to track the `visibilityState` once it's
+ // had an opportunity to change to visible in all browsers.
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=1133363
+ setTimeout(() => {
+ firstHiddenTime = initHiddenTime();
+ addChangeListeners();
+ }, 0);
+ });
+ }
+ return {
+ get firstHiddenTime() {
+ return firstHiddenTime;
+ },
+ };
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts
new file mode 100644
index 0000000..b14f969
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.d.ts
@@ -0,0 +1,21 @@
+export declare const initMetric: <MetricName extends "CLS" | "FCP" | "FID" | "INP" | "LCP" | "TTFB">(name: MetricName, value?: number) => {
+ name: MetricName;
+ value: number;
+ rating: "good";
+ delta: number;
+ entries: (Extract<import("../types.js").CLSMetric, {
+ name: MetricName;
+ }> | Extract<import("../types.js").FCPMetric, {
+ name: MetricName;
+ }> | Extract<import("../types.js").FIDMetric, {
+ name: MetricName;
+ }> | Extract<import("../types.js").INPMetric, {
+ name: MetricName;
+ }> | Extract<import("../types.js").LCPMetric, {
+ name: MetricName;
+ }> | Extract<import("../types.js").TTFBMetric, {
+ name: MetricName;
+ }>)["entries"];
+ id: string;
+ navigationType: "navigate" | "reload" | "back-forward" | "back-forward-cache" | "prerender" | "restore";
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.js
new file mode 100644
index 0000000..30da54e
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/initMetric.js
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getBFCacheRestoreTime } from './bfcache.js';
+import { generateUniqueID } from './generateUniqueID.js';
+import { getActivationStart } from './getActivationStart.js';
+import { getNavigationEntry } from './getNavigationEntry.js';
+export const initMetric = (name, value) => {
+ const navEntry = getNavigationEntry();
+ let navigationType = 'navigate';
+ if (getBFCacheRestoreTime() >= 0) {
+ navigationType = 'back-forward-cache';
+ }
+ else if (navEntry) {
+ if (document.prerendering || getActivationStart() > 0) {
+ navigationType = 'prerender';
+ }
+ else if (document.wasDiscarded) {
+ navigationType = 'restore';
+ }
+ else if (navEntry.type) {
+ navigationType = navEntry.type.replace(/_/g, '-');
+ }
+ }
+ // Use `entries` type specific for the metric.
+ const entries = [];
+ return {
+ name,
+ value: typeof value === 'undefined' ? -1 : value,
+ rating: 'good', // If needed, will be updated when reported. `const` to keep the type from widening to `string`.
+ delta: 0,
+ entries,
+ id: generateUniqueID(),
+ navigationType,
+ };
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.d.ts
new file mode 100644
index 0000000..5db2b71
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.d.ts
@@ -0,0 +1,31 @@
+interface Interaction {
+ id: number;
+ latency: number;
+ entries: PerformanceEventTiming[];
+}
+interface EntryPreProcessingHook {
+ (entry: PerformanceEventTiming): void;
+}
+export declare const longestInteractionList: Interaction[];
+export declare const longestInteractionMap: Map<number, Interaction>;
+export declare const DEFAULT_DURATION_THRESHOLD = 40;
+export declare const resetInteractions: () => void;
+/**
+ * Returns the estimated p98 longest interaction based on the stored
+ * interaction candidates and the interaction count for the current page.
+ */
+export declare const estimateP98LongestInteraction: () => Interaction;
+/**
+ * A list of callback functions to run before each entry is processed.
+ * Exposing this list allows the attribution build to hook into the
+ * entry processing pipeline.
+ */
+export declare const entryPreProcessingCallbacks: EntryPreProcessingHook[];
+/**
+ * Takes a performance entry and adds it to the list of worst interactions
+ * if its duration is long enough to make it among the worst. If the
+ * entry is part of an existing interaction, it is merged and the latency
+ * and entries list is updated as needed.
+ */
+export declare const processInteractionEntry: (entry: PerformanceEventTiming) => void;
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.js
new file mode 100644
index 0000000..0466ef1
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/interactions.js
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { getInteractionCount } from './polyfills/interactionCountPolyfill.js';
+// A list of longest interactions on the page (by latency) sorted so the
+// longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER long.
+export const longestInteractionList = [];
+// A mapping of longest interactions by their interaction ID.
+// This is used for faster lookup.
+export const longestInteractionMap = new Map();
+// The default `durationThreshold` used across this library for observing
+// `event` entries via PerformanceObserver.
+export const DEFAULT_DURATION_THRESHOLD = 40;
+// Used to store the interaction count after a bfcache restore, since p98
+// interaction latencies should only consider the current navigation.
+let prevInteractionCount = 0;
+/**
+ * Returns the interaction count since the last bfcache restore (or for the
+ * full page lifecycle if there were no bfcache restores).
+ */
+const getInteractionCountForNavigation = () => {
+ return getInteractionCount() - prevInteractionCount;
+};
+export const resetInteractions = () => {
+ prevInteractionCount = getInteractionCount();
+ longestInteractionList.length = 0;
+ longestInteractionMap.clear();
+};
+/**
+ * Returns the estimated p98 longest interaction based on the stored
+ * interaction candidates and the interaction count for the current page.
+ */
+export const estimateP98LongestInteraction = () => {
+ const candidateInteractionIndex = Math.min(longestInteractionList.length - 1, Math.floor(getInteractionCountForNavigation() / 50));
+ return longestInteractionList[candidateInteractionIndex];
+};
+// To prevent unnecessary memory usage on pages with lots of interactions,
+// store at most 10 of the longest interactions to consider as INP candidates.
+const MAX_INTERACTIONS_TO_CONSIDER = 10;
+/**
+ * A list of callback functions to run before each entry is processed.
+ * Exposing this list allows the attribution build to hook into the
+ * entry processing pipeline.
+ */
+export const entryPreProcessingCallbacks = [];
+/**
+ * Takes a performance entry and adds it to the list of worst interactions
+ * if its duration is long enough to make it among the worst. If the
+ * entry is part of an existing interaction, it is merged and the latency
+ * and entries list is updated as needed.
+ */
+export const processInteractionEntry = (entry) => {
+ entryPreProcessingCallbacks.forEach((cb) => cb(entry));
+ // Skip further processing for entries that cannot be INP candidates.
+ if (!(entry.interactionId || entry.entryType === 'first-input'))
+ return;
+ // The least-long of the 10 longest interactions.
+ const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];
+ const existingInteraction = longestInteractionMap.get(entry.interactionId);
+ // Only process the entry if it's possibly one of the ten longest,
+ // or if it's part of an existing interaction.
+ if (existingInteraction ||
+ longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
+ entry.duration > minLongestInteraction.latency) {
+ // If the interaction already exists, update it. Otherwise create one.
+ if (existingInteraction) {
+ // If the new entry has a longer duration, replace the old entries,
+ // otherwise add to the array.
+ if (entry.duration > existingInteraction.latency) {
+ existingInteraction.entries = [entry];
+ existingInteraction.latency = entry.duration;
+ }
+ else if (entry.duration === existingInteraction.latency &&
+ entry.startTime === existingInteraction.entries[0].startTime) {
+ existingInteraction.entries.push(entry);
+ }
+ }
+ else {
+ const interaction = {
+ id: entry.interactionId,
+ latency: entry.duration,
+ entries: [entry],
+ };
+ longestInteractionMap.set(interaction.id, interaction);
+ longestInteractionList.push(interaction);
+ }
+ // Sort the entries by latency (descending) and keep only the top ten.
+ longestInteractionList.sort((a, b) => b.latency - a.latency);
+ if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) {
+ longestInteractionList
+ .splice(MAX_INTERACTIONS_TO_CONSIDER)
+ .forEach((i) => longestInteractionMap.delete(i.id));
+ }
+ }
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.d.ts
new file mode 100644
index 0000000..1c8ba5f
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.d.ts
@@ -0,0 +1,20 @@
+interface PerformanceEntryMap {
+ 'event': PerformanceEventTiming[];
+ 'first-input': PerformanceEventTiming[];
+ 'layout-shift': LayoutShift[];
+ 'largest-contentful-paint': LargestContentfulPaint[];
+ 'long-animation-frame': PerformanceLongAnimationFrameTiming[];
+ 'paint': PerformancePaintTiming[];
+ 'navigation': PerformanceNavigationTiming[];
+ 'resource': PerformanceResourceTiming[];
+}
+/**
+ * Takes a performance entry type and a callback function, and creates a
+ * `PerformanceObserver` instance that will observe the specified entry type
+ * with buffering enabled and call the callback _for each entry_.
+ *
+ * This function also feature-detects entry support and wraps the logic in a
+ * try/catch to avoid errors in unsupporting browsers.
+ */
+export declare const observe: <K extends keyof PerformanceEntryMap>(type: K, callback: (entries: PerformanceEntryMap[K]) => void, opts?: PerformanceObserverInit) => PerformanceObserver | undefined;
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.js
new file mode 100644
index 0000000..241971d
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/observe.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Takes a performance entry type and a callback function, and creates a
+ * `PerformanceObserver` instance that will observe the specified entry type
+ * with buffering enabled and call the callback _for each entry_.
+ *
+ * This function also feature-detects entry support and wraps the logic in a
+ * try/catch to avoid errors in unsupporting browsers.
+ */
+export const observe = (type, callback, opts) => {
+ try {
+ if (PerformanceObserver.supportedEntryTypes.includes(type)) {
+ const po = new PerformanceObserver((list) => {
+ // Delay by a microtask to workaround a bug in Safari where the
+ // callback is invoked immediately, rather than in a separate task.
+ // See: https://github.com/GoogleChrome/web-vitals/issues/277
+ Promise.resolve().then(() => {
+ callback(list.getEntries());
+ });
+ });
+ po.observe(Object.assign({
+ type,
+ buffered: true,
+ }, opts || {}));
+ return po;
+ }
+ }
+ catch (e) {
+ // Do nothing.
+ }
+ return;
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts
new file mode 100644
index 0000000..1e4d041
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.d.ts
@@ -0,0 +1 @@
+export declare const onHidden: (cb: () => void) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.js
new file mode 100644
index 0000000..c78b585
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/onHidden.js
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export const onHidden = (cb) => {
+ document.addEventListener('visibilitychange', () => {
+ if (document.visibilityState === 'hidden') {
+ cb();
+ }
+ });
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts
new file mode 100644
index 0000000..86211bf
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.d.ts
@@ -0,0 +1,7 @@
+import { FirstInputPolyfillCallback } from '../../types.js';
+/**
+ * Accepts a callback to be invoked once the first input delay and event
+ * are known.
+ */
+export declare const firstInputPolyfill: (onFirstInput: FirstInputPolyfillCallback) => void;
+export declare const resetFirstInputPolyfill: () => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js
new file mode 100644
index 0000000..b3faa59
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/firstInputPolyfill.js
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+let firstInputEvent;
+let firstInputDelay;
+let firstInputTimeStamp;
+let callbacks;
+const listenerOpts = { passive: true, capture: true };
+const startTimeStamp = new Date();
+/**
+ * Accepts a callback to be invoked once the first input delay and event
+ * are known.
+ */
+export const firstInputPolyfill = (onFirstInput) => {
+ callbacks.push(onFirstInput);
+ reportFirstInputDelayIfRecordedAndValid();
+};
+export const resetFirstInputPolyfill = () => {
+ callbacks = [];
+ firstInputDelay = -1;
+ firstInputEvent = null;
+ eachEventType(addEventListener);
+};
+/**
+ * Records the first input delay and event, so subsequent events can be
+ * ignored. All added event listeners are then removed.
+ */
+const recordFirstInputDelay = (delay, event) => {
+ if (!firstInputEvent) {
+ firstInputEvent = event;
+ firstInputDelay = delay;
+ firstInputTimeStamp = new Date();
+ eachEventType(removeEventListener);
+ reportFirstInputDelayIfRecordedAndValid();
+ }
+};
+/**
+ * Reports the first input delay and event (if they're recorded and valid)
+ * by running the array of callback functions.
+ */
+const reportFirstInputDelayIfRecordedAndValid = () => {
+ // In some cases the recorded delay is clearly wrong, e.g. it's negative
+ // or it's larger than the delta between now and initialization.
+ // - https://github.com/GoogleChromeLabs/first-input-delay/issues/4
+ // - https://github.com/GoogleChromeLabs/first-input-delay/issues/6
+ // - https://github.com/GoogleChromeLabs/first-input-delay/issues/7
+ if (firstInputDelay >= 0 &&
+ // @ts-ignore (subtracting two dates always returns a number)
+ firstInputDelay < firstInputTimeStamp - startTimeStamp) {
+ const entry = {
+ entryType: 'first-input',
+ name: firstInputEvent.type,
+ target: firstInputEvent.target,
+ cancelable: firstInputEvent.cancelable,
+ startTime: firstInputEvent.timeStamp,
+ processingStart: firstInputEvent.timeStamp + firstInputDelay,
+ };
+ callbacks.forEach(function (callback) {
+ callback(entry);
+ });
+ callbacks = [];
+ }
+};
+/**
+ * Handles pointer down events, which are a special case.
+ * Pointer events can trigger main or compositor thread behavior.
+ * We differentiate these cases based on whether or not we see a
+ * 'pointercancel' event, which are fired when we scroll. If we're scrolling
+ * we don't need to report input delay since FID excludes scrolling and
+ * pinch/zooming.
+ */
+const onPointerDown = (delay, event) => {
+ /**
+ * Responds to 'pointerup' events and records a delay. If a pointer up event
+ * is the next event after a pointerdown event, then it's not a scroll or
+ * a pinch/zoom.
+ */
+ const onPointerUp = () => {
+ recordFirstInputDelay(delay, event);
+ removePointerEventListeners();
+ };
+ /**
+ * Responds to 'pointercancel' events and removes pointer listeners.
+ * If a 'pointercancel' is the next event to fire after a pointerdown event,
+ * it means this is a scroll or pinch/zoom interaction.
+ */
+ const onPointerCancel = () => {
+ removePointerEventListeners();
+ };
+ /**
+ * Removes added pointer event listeners.
+ */
+ const removePointerEventListeners = () => {
+ removeEventListener('pointerup', onPointerUp, listenerOpts);
+ removeEventListener('pointercancel', onPointerCancel, listenerOpts);
+ };
+ addEventListener('pointerup', onPointerUp, listenerOpts);
+ addEventListener('pointercancel', onPointerCancel, listenerOpts);
+};
+/**
+ * Handles all input events and records the time between when the event
+ * was received by the operating system and when it's JavaScript listeners
+ * were able to run.
+ */
+const onInput = (event) => {
+ // Only count cancelable events, which should trigger behavior
+ // important to the user.
+ if (event.cancelable) {
+ // In some browsers `event.timeStamp` returns a `DOMTimeStamp` value
+ // (epoch time) instead of the newer `DOMHighResTimeStamp`
+ // (document-origin time). To check for that we assume any timestamp
+ // greater than 1 trillion is a `DOMTimeStamp`, and compare it using
+ // the `Date` object rather than `performance.now()`.
+ // - https://github.com/GoogleChromeLabs/first-input-delay/issues/4
+ const isEpochTime = event.timeStamp > 1e12;
+ const now = isEpochTime ? new Date() : performance.now();
+ // Input delay is the delta between when the system received the event
+ // (e.g. event.timeStamp) and when it could run the callback (e.g. `now`).
+ const delay = now - event.timeStamp;
+ if (event.type == 'pointerdown') {
+ onPointerDown(delay, event);
+ }
+ else {
+ recordFirstInputDelay(delay, event);
+ }
+ }
+};
+/**
+ * Invokes the passed callback const for = each event type with t =>he
+ * `onInput` const and = `listenerOpts =>`.
+ */
+const eachEventType = (callback) => {
+ const eventTypes = ['mousedown', 'keydown', 'touchstart', 'pointerdown'];
+ eventTypes.forEach((type) => callback(type, onInput, listenerOpts));
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts
new file mode 100644
index 0000000..a5dd33e
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts
@@ -0,0 +1 @@
+export declare const getFirstHiddenTime: () => number;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js
new file mode 100644
index 0000000..e1d41f3
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+let firstHiddenTime = document.visibilityState === 'hidden' ? 0 : Infinity;
+const onVisibilityChange = (event) => {
+ if (document.visibilityState === 'hidden') {
+ firstHiddenTime = event.timeStamp;
+ removeEventListener('visibilitychange', onVisibilityChange, true);
+ }
+};
+// Note: do not add event listeners unconditionally (outside of polyfills).
+addEventListener('visibilitychange', onVisibilityChange, true);
+export const getFirstHiddenTime = () => firstHiddenTime;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts
new file mode 100644
index 0000000..1ed1de3
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts
@@ -0,0 +1,14 @@
+declare global {
+ interface Performance {
+ interactionCount: number;
+ }
+}
+/**
+ * Returns the `interactionCount` value using the native API (if available)
+ * or the polyfill estimate in this module.
+ */
+export declare const getInteractionCount: () => number;
+/**
+ * Feature detects native support or initializes the polyfill if needed.
+ */
+export declare const initInteractionCountPolyfill: () => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js
new file mode 100644
index 0000000..f523101
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/polyfills/interactionCountPolyfill.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { observe } from '../observe.js';
+let interactionCountEstimate = 0;
+let minKnownInteractionId = Infinity;
+let maxKnownInteractionId = 0;
+const updateEstimate = (entries) => {
+ entries.forEach((e) => {
+ if (e.interactionId) {
+ minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId);
+ maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId);
+ interactionCountEstimate = maxKnownInteractionId
+ ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1
+ : 0;
+ }
+ });
+};
+let po;
+/**
+ * Returns the `interactionCount` value using the native API (if available)
+ * or the polyfill estimate in this module.
+ */
+export const getInteractionCount = () => {
+ return po ? interactionCountEstimate : performance.interactionCount || 0;
+};
+/**
+ * Feature detects native support or initializes the polyfill if needed.
+ */
+export const initInteractionCountPolyfill = () => {
+ if ('interactionCount' in performance || po)
+ return;
+ po = observe('event', updateEstimate, {
+ type: 'event',
+ buffered: true,
+ durationThreshold: 0,
+ });
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts
new file mode 100644
index 0000000..dbf917a
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.d.ts
@@ -0,0 +1 @@
+export declare const runOnce: (cb: () => void) => () => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.js
new file mode 100644
index 0000000..ea00f53
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/runOnce.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export const runOnce = (cb) => {
+ let called = false;
+ return () => {
+ if (!called) {
+ cb();
+ called = true;
+ }
+ };
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts
new file mode 100644
index 0000000..76af10b
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.d.ts
@@ -0,0 +1 @@
+export declare const whenActivated: (callback: () => void) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.js
new file mode 100644
index 0000000..c3d853f
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenActivated.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export const whenActivated = (callback) => {
+ if (document.prerendering) {
+ addEventListener('prerenderingchange', () => callback(), true);
+ }
+ else {
+ callback();
+ }
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts
new file mode 100644
index 0000000..b503b5a
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.d.ts
@@ -0,0 +1,5 @@
+/**
+ * Runs the passed callback during the next idle period, or immediately
+ * if the browser's visibility state is (or becomes) hidden.
+ */
+export declare const whenIdle: (cb: () => void) => number;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.js b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.js
new file mode 100644
index 0000000..bab00c6
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/lib/whenIdle.js
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onHidden } from './onHidden.js';
+import { runOnce } from './runOnce.js';
+/**
+ * Runs the passed callback during the next idle period, or immediately
+ * if the browser's visibility state is (or becomes) hidden.
+ */
+export const whenIdle = (cb) => {
+ const rIC = self.requestIdleCallback || self.setTimeout;
+ let handle = -1;
+ cb = runOnce(cb);
+ // If the document is hidden, run the callback immediately, otherwise
+ // race an idle callback with the next `visibilitychange` event.
+ if (document.visibilityState === 'hidden') {
+ cb();
+ }
+ else {
+ handle = rIC(cb);
+ onHidden(cb);
+ }
+ return handle;
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onCLS.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.d.ts
new file mode 100644
index 0000000..c4c56b6
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.d.ts
@@ -0,0 +1,25 @@
+import { CLSMetric, MetricRatingThresholds, ReportOpts } from './types.js';
+/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */
+export declare const CLSThresholds: MetricRatingThresholds;
+/**
+ * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
+ * calls the `callback` function once the value is ready to be reported, along
+ * with all `layout-shift` performance entries that were used in the metric
+ * value calculation. The reported value is a `double` (corresponding to a
+ * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** CLS should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export declare const onCLS: (onReport: (metric: CLSMetric) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onCLS.js b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.js
new file mode 100644
index 0000000..7c75a10
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onCLS.js
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onBFCacheRestore } from './lib/bfcache.js';
+import { initMetric } from './lib/initMetric.js';
+import { observe } from './lib/observe.js';
+import { bindReporter } from './lib/bindReporter.js';
+import { doubleRAF } from './lib/doubleRAF.js';
+import { onHidden } from './lib/onHidden.js';
+import { runOnce } from './lib/runOnce.js';
+import { onFCP } from './onFCP.js';
+/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */
+export const CLSThresholds = [0.1, 0.25];
+/**
+ * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and
+ * calls the `callback` function once the value is ready to be reported, along
+ * with all `layout-shift` performance entries that were used in the metric
+ * value calculation. The reported value is a `double` (corresponding to a
+ * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** CLS should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export const onCLS = (onReport, opts) => {
+ // Set defaults
+ opts = opts || {};
+ // Start monitoring FCP so we can only report CLS if FCP is also reported.
+ // Note: this is done to match the current behavior of CrUX.
+ onFCP(runOnce(() => {
+ let metric = initMetric('CLS', 0);
+ let report;
+ let sessionValue = 0;
+ let sessionEntries = [];
+ const handleEntries = (entries) => {
+ entries.forEach((entry) => {
+ // Only count layout shifts without recent user input.
+ if (!entry.hadRecentInput) {
+ const firstSessionEntry = sessionEntries[0];
+ const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
+ // If the entry occurred less than 1 second after the previous entry
+ // and less than 5 seconds after the first entry in the session,
+ // include the entry in the current session. Otherwise, start a new
+ // session.
+ if (sessionValue &&
+ entry.startTime - lastSessionEntry.startTime < 1000 &&
+ entry.startTime - firstSessionEntry.startTime < 5000) {
+ sessionValue += entry.value;
+ sessionEntries.push(entry);
+ }
+ else {
+ sessionValue = entry.value;
+ sessionEntries = [entry];
+ }
+ }
+ });
+ // If the current session value is larger than the current CLS value,
+ // update CLS and the entries contributing to it.
+ if (sessionValue > metric.value) {
+ metric.value = sessionValue;
+ metric.entries = sessionEntries;
+ report();
+ }
+ };
+ const po = observe('layout-shift', handleEntries);
+ if (po) {
+ report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);
+ onHidden(() => {
+ handleEntries(po.takeRecords());
+ report(true);
+ });
+ // Only report after a bfcache restore if the `PerformanceObserver`
+ // successfully registered.
+ onBFCacheRestore(() => {
+ sessionValue = 0;
+ metric = initMetric('CLS', 0);
+ report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);
+ doubleRAF(() => report());
+ });
+ // Queue a task to report (if nothing else triggers a report first).
+ // This allows CLS to be reported as soon as FCP fires when
+ // `reportAllChanges` is true.
+ setTimeout(report, 0);
+ }
+ }));
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.d.ts
new file mode 100644
index 0000000..77e4c00
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.d.ts
@@ -0,0 +1,10 @@
+import { FCPMetric, MetricRatingThresholds, ReportOpts } from './types.js';
+/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */
+export declare const FCPThresholds: MetricRatingThresholds;
+/**
+ * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `paint` performance entry used to determine the value. The reported
+ * value is a `DOMHighResTimeStamp`.
+ */
+export declare const onFCP: (onReport: (metric: FCPMetric) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFCP.js b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.js
new file mode 100644
index 0000000..f4350cf
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onFCP.js
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onBFCacheRestore } from './lib/bfcache.js';
+import { bindReporter } from './lib/bindReporter.js';
+import { doubleRAF } from './lib/doubleRAF.js';
+import { getActivationStart } from './lib/getActivationStart.js';
+import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';
+import { initMetric } from './lib/initMetric.js';
+import { observe } from './lib/observe.js';
+import { whenActivated } from './lib/whenActivated.js';
+/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */
+export const FCPThresholds = [1800, 3000];
+/**
+ * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `paint` performance entry used to determine the value. The reported
+ * value is a `DOMHighResTimeStamp`.
+ */
+export const onFCP = (onReport, opts) => {
+ // Set defaults
+ opts = opts || {};
+ whenActivated(() => {
+ const visibilityWatcher = getVisibilityWatcher();
+ let metric = initMetric('FCP');
+ let report;
+ const handleEntries = (entries) => {
+ entries.forEach((entry) => {
+ if (entry.name === 'first-contentful-paint') {
+ po.disconnect();
+ // Only report if the page wasn't hidden prior to the first paint.
+ if (entry.startTime < visibilityWatcher.firstHiddenTime) {
+ // The activationStart reference is used because FCP should be
+ // relative to page activation rather than navigation start if the
+ // page was prerendered. But in cases where `activationStart` occurs
+ // after the FCP, this time should be clamped at 0.
+ metric.value = Math.max(entry.startTime - getActivationStart(), 0);
+ metric.entries.push(entry);
+ report(true);
+ }
+ }
+ });
+ };
+ const po = observe('paint', handleEntries);
+ if (po) {
+ report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);
+ // Only report after a bfcache restore if the `PerformanceObserver`
+ // successfully registered or the `paint` entry exists.
+ onBFCacheRestore((event) => {
+ metric = initMetric('FCP');
+ report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);
+ doubleRAF(() => {
+ metric.value = performance.now() - event.timeStamp;
+ report(true);
+ });
+ });
+ }
+ });
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFID.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onFID.d.ts
new file mode 100644
index 0000000..12c24c2
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onFID.d.ts
@@ -0,0 +1,13 @@
+import { FIDMetric, MetricRatingThresholds, ReportOpts } from './types.js';
+/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */
+export declare const FIDThresholds: MetricRatingThresholds;
+/**
+ * Calculates the [FID](https://web.dev/articles/fid) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `first-input` performance entry used to determine the value. The
+ * reported value is a `DOMHighResTimeStamp`.
+ *
+ * _**Important:** since FID is only reported after the user interacts with the
+ * page, it's possible that it will not be reported for some page loads._
+ */
+export declare const onFID: (onReport: (metric: FIDMetric) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onFID.js b/frontend-old/node_modules/web-vitals/dist/modules/onFID.js
new file mode 100644
index 0000000..c656b58
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onFID.js
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onBFCacheRestore } from './lib/bfcache.js';
+import { bindReporter } from './lib/bindReporter.js';
+import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';
+import { initMetric } from './lib/initMetric.js';
+import { observe } from './lib/observe.js';
+import { onHidden } from './lib/onHidden.js';
+import { firstInputPolyfill, resetFirstInputPolyfill, } from './lib/polyfills/firstInputPolyfill.js';
+import { runOnce } from './lib/runOnce.js';
+import { whenActivated } from './lib/whenActivated.js';
+/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */
+export const FIDThresholds = [100, 300];
+/**
+ * Calculates the [FID](https://web.dev/articles/fid) value for the current page and
+ * calls the `callback` function once the value is ready, along with the
+ * relevant `first-input` performance entry used to determine the value. The
+ * reported value is a `DOMHighResTimeStamp`.
+ *
+ * _**Important:** since FID is only reported after the user interacts with the
+ * page, it's possible that it will not be reported for some page loads._
+ */
+export const onFID = (onReport, opts) => {
+ // Set defaults
+ opts = opts || {};
+ whenActivated(() => {
+ const visibilityWatcher = getVisibilityWatcher();
+ let metric = initMetric('FID');
+ let report;
+ const handleEntry = (entry) => {
+ // Only report if the page wasn't hidden prior to the first input.
+ if (entry.startTime < visibilityWatcher.firstHiddenTime) {
+ metric.value = entry.processingStart - entry.startTime;
+ metric.entries.push(entry);
+ report(true);
+ }
+ };
+ const handleEntries = (entries) => {
+ entries.forEach(handleEntry);
+ };
+ const po = observe('first-input', handleEntries);
+ report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);
+ if (po) {
+ onHidden(runOnce(() => {
+ handleEntries(po.takeRecords());
+ po.disconnect();
+ }));
+ onBFCacheRestore(() => {
+ metric = initMetric('FID');
+ report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);
+ // Browsers don't re-emit FID on bfcache restore so fake it until you make it
+ resetFirstInputPolyfill();
+ firstInputPolyfill(handleEntry);
+ });
+ }
+ });
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onINP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onINP.d.ts
new file mode 100644
index 0000000..50c3e33
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onINP.d.ts
@@ -0,0 +1,31 @@
+import { INPMetric, MetricRatingThresholds, ReportOpts } from './types.js';
+/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */
+export declare const INPThresholds: MetricRatingThresholds;
+/**
+ * Calculates the [INP](https://web.dev/articles/inp) value for the current
+ * page and calls the `callback` function once the value is ready, along with
+ * the `event` performance entries reported for that interaction. The reported
+ * value is a `DOMHighResTimeStamp`.
+ *
+ * A custom `durationThreshold` configuration option can optionally be passed to
+ * control what `event-timing` entries are considered for INP reporting. The
+ * default threshold is `40`, which means INP scores of less than 40 are
+ * reported as 0. Note that this will not affect your 75th percentile INP value
+ * unless that value is also less than 40 (well below the recommended
+ * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** INP should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export declare const onINP: (onReport: (metric: INPMetric) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onINP.js b/frontend-old/node_modules/web-vitals/dist/modules/onINP.js
new file mode 100644
index 0000000..25ce110
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onINP.js
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onBFCacheRestore } from './lib/bfcache.js';
+import { bindReporter } from './lib/bindReporter.js';
+import { initMetric } from './lib/initMetric.js';
+import { DEFAULT_DURATION_THRESHOLD, processInteractionEntry, estimateP98LongestInteraction, resetInteractions, } from './lib/interactions.js';
+import { observe } from './lib/observe.js';
+import { onHidden } from './lib/onHidden.js';
+import { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill.js';
+import { whenActivated } from './lib/whenActivated.js';
+import { whenIdle } from './lib/whenIdle.js';
+/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */
+export const INPThresholds = [200, 500];
+/**
+ * Calculates the [INP](https://web.dev/articles/inp) value for the current
+ * page and calls the `callback` function once the value is ready, along with
+ * the `event` performance entries reported for that interaction. The reported
+ * value is a `DOMHighResTimeStamp`.
+ *
+ * A custom `durationThreshold` configuration option can optionally be passed to
+ * control what `event-timing` entries are considered for INP reporting. The
+ * default threshold is `40`, which means INP scores of less than 40 are
+ * reported as 0. Note that this will not affect your 75th percentile INP value
+ * unless that value is also less than 40 (well below the recommended
+ * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called as soon as the value is initially
+ * determined as well as any time the value changes throughout the page
+ * lifespan.
+ *
+ * _**Important:** INP should be continually monitored for changes throughout
+ * the entire lifespan of a page—including if the user returns to the page after
+ * it's been hidden/backgrounded. However, since browsers often [will not fire
+ * additional callbacks once the user has backgrounded a
+ * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),
+ * `callback` is always called when the page's visibility state changes to
+ * hidden. As a result, the `callback` function might be called multiple times
+ * during the same page load._
+ */
+export const onINP = (onReport, opts) => {
+ // Return if the browser doesn't support all APIs needed to measure INP.
+ if (!('PerformanceEventTiming' in self &&
+ 'interactionId' in PerformanceEventTiming.prototype)) {
+ return;
+ }
+ // Set defaults
+ opts = opts || {};
+ whenActivated(() => {
+ // TODO(philipwalton): remove once the polyfill is no longer needed.
+ initInteractionCountPolyfill();
+ let metric = initMetric('INP');
+ let report;
+ const handleEntries = (entries) => {
+ // Queue the `handleEntries()` callback in the next idle task.
+ // This is needed to increase the chances that all event entries that
+ // occurred between the user interaction and the next paint
+ // have been dispatched. Note: there is currently an experiment
+ // running in Chrome (EventTimingKeypressAndCompositionInteractionId)
+ // 123+ that if rolled out fully may make this no longer necessary.
+ whenIdle(() => {
+ entries.forEach(processInteractionEntry);
+ const inp = estimateP98LongestInteraction();
+ if (inp && inp.latency !== metric.value) {
+ metric.value = inp.latency;
+ metric.entries = inp.entries;
+ report();
+ }
+ });
+ };
+ const po = observe('event', handleEntries, {
+ // Event Timing entries have their durations rounded to the nearest 8ms,
+ // so a duration of 40ms would be any event that spans 2.5 or more frames
+ // at 60Hz. This threshold is chosen to strike a balance between usefulness
+ // and performance. Running this callback for any interaction that spans
+ // just one or two frames is likely not worth the insight that could be
+ // gained.
+ durationThreshold: opts.durationThreshold ?? DEFAULT_DURATION_THRESHOLD,
+ });
+ report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);
+ if (po) {
+ // Also observe entries of type `first-input`. This is useful in cases
+ // where the first interaction is less than the `durationThreshold`.
+ po.observe({ type: 'first-input', buffered: true });
+ onHidden(() => {
+ handleEntries(po.takeRecords());
+ report(true);
+ });
+ // Only report after a bfcache restore if the `PerformanceObserver`
+ // successfully registered.
+ onBFCacheRestore(() => {
+ resetInteractions();
+ metric = initMetric('INP');
+ report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);
+ });
+ }
+ });
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onLCP.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.d.ts
new file mode 100644
index 0000000..44e391c
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.d.ts
@@ -0,0 +1,15 @@
+import { LCPMetric, MetricRatingThresholds, ReportOpts } from './types.js';
+/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */
+export declare const LCPThresholds: MetricRatingThresholds;
+/**
+ * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
+ * calls the `callback` function once the value is ready (along with the
+ * relevant `largest-contentful-paint` performance entry used to determine the
+ * value). The reported value is a `DOMHighResTimeStamp`.
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called any time a new `largest-contentful-paint`
+ * performance entry is dispatched, or once the final value of the metric has
+ * been determined.
+ */
+export declare const onLCP: (onReport: (metric: LCPMetric) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onLCP.js b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.js
new file mode 100644
index 0000000..2f9d0f7
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onLCP.js
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { onBFCacheRestore } from './lib/bfcache.js';
+import { bindReporter } from './lib/bindReporter.js';
+import { doubleRAF } from './lib/doubleRAF.js';
+import { getActivationStart } from './lib/getActivationStart.js';
+import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';
+import { initMetric } from './lib/initMetric.js';
+import { observe } from './lib/observe.js';
+import { onHidden } from './lib/onHidden.js';
+import { runOnce } from './lib/runOnce.js';
+import { whenActivated } from './lib/whenActivated.js';
+import { whenIdle } from './lib/whenIdle.js';
+/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */
+export const LCPThresholds = [2500, 4000];
+const reportedMetricIDs = {};
+/**
+ * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and
+ * calls the `callback` function once the value is ready (along with the
+ * relevant `largest-contentful-paint` performance entry used to determine the
+ * value). The reported value is a `DOMHighResTimeStamp`.
+ *
+ * If the `reportAllChanges` configuration option is set to `true`, the
+ * `callback` function will be called any time a new `largest-contentful-paint`
+ * performance entry is dispatched, or once the final value of the metric has
+ * been determined.
+ */
+export const onLCP = (onReport, opts) => {
+ // Set defaults
+ opts = opts || {};
+ whenActivated(() => {
+ const visibilityWatcher = getVisibilityWatcher();
+ let metric = initMetric('LCP');
+ let report;
+ const handleEntries = (entries) => {
+ // If reportAllChanges is set then call this function for each entry,
+ // otherwise only consider the last one.
+ if (!opts.reportAllChanges) {
+ entries = entries.slice(-1);
+ }
+ entries.forEach((entry) => {
+ // Only report if the page wasn't hidden prior to LCP.
+ if (entry.startTime < visibilityWatcher.firstHiddenTime) {
+ // The startTime attribute returns the value of the renderTime if it is
+ // not 0, and the value of the loadTime otherwise. The activationStart
+ // reference is used because LCP should be relative to page activation
+ // rather than navigation start if the page was prerendered. But in cases
+ // where `activationStart` occurs after the LCP, this time should be
+ // clamped at 0.
+ metric.value = Math.max(entry.startTime - getActivationStart(), 0);
+ metric.entries = [entry];
+ report();
+ }
+ });
+ };
+ const po = observe('largest-contentful-paint', handleEntries);
+ if (po) {
+ report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);
+ const stopListening = runOnce(() => {
+ if (!reportedMetricIDs[metric.id]) {
+ handleEntries(po.takeRecords());
+ po.disconnect();
+ reportedMetricIDs[metric.id] = true;
+ report(true);
+ }
+ });
+ // Stop listening after input. Note: while scrolling is an input that
+ // stops LCP observation, it's unreliable since it can be programmatically
+ // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75
+ ['keydown', 'click'].forEach((type) => {
+ // Wrap in a setTimeout so the callback is run in a separate task
+ // to avoid extending the keyboard/click handler to reduce INP impact
+ // https://github.com/GoogleChrome/web-vitals/issues/383
+ addEventListener(type, () => whenIdle(stopListening), {
+ once: true,
+ capture: true,
+ });
+ });
+ onHidden(stopListening);
+ // Only report after a bfcache restore if the `PerformanceObserver`
+ // successfully registered.
+ onBFCacheRestore((event) => {
+ metric = initMetric('LCP');
+ report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);
+ doubleRAF(() => {
+ metric.value = performance.now() - event.timeStamp;
+ reportedMetricIDs[metric.id] = true;
+ report(true);
+ });
+ });
+ }
+ });
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.d.ts
new file mode 100644
index 0000000..14d7e4f
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.d.ts
@@ -0,0 +1,19 @@
+import { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types.js';
+/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */
+export declare const TTFBThresholds: MetricRatingThresholds;
+/**
+ * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
+ * current page and calls the `callback` function once the page has loaded,
+ * along with the relevant `navigation` performance entry used to determine the
+ * value. The reported value is a `DOMHighResTimeStamp`.
+ *
+ * Note, this function waits until after the page is loaded to call `callback`
+ * in order to ensure all properties of the `navigation` entry are populated.
+ * This is useful if you want to report on other metrics exposed by the
+ * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
+ * example, the TTFB metric starts from the page's [time
+ * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
+ * includes time spent on DNS lookup, connection negotiation, network latency,
+ * and server processing time.
+ */
+export declare const onTTFB: (onReport: (metric: TTFBMetric) => void, opts?: ReportOpts) => void;
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.js b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.js
new file mode 100644
index 0000000..9d12af4
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/onTTFB.js
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { bindReporter } from './lib/bindReporter.js';
+import { initMetric } from './lib/initMetric.js';
+import { onBFCacheRestore } from './lib/bfcache.js';
+import { getNavigationEntry } from './lib/getNavigationEntry.js';
+import { getActivationStart } from './lib/getActivationStart.js';
+import { whenActivated } from './lib/whenActivated.js';
+/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */
+export const TTFBThresholds = [800, 1800];
+/**
+ * Runs in the next task after the page is done loading and/or prerendering.
+ * @param callback
+ */
+const whenReady = (callback) => {
+ if (document.prerendering) {
+ whenActivated(() => whenReady(callback));
+ }
+ else if (document.readyState !== 'complete') {
+ addEventListener('load', () => whenReady(callback), true);
+ }
+ else {
+ // Queue a task so the callback runs after `loadEventEnd`.
+ setTimeout(callback, 0);
+ }
+};
+/**
+ * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the
+ * current page and calls the `callback` function once the page has loaded,
+ * along with the relevant `navigation` performance entry used to determine the
+ * value. The reported value is a `DOMHighResTimeStamp`.
+ *
+ * Note, this function waits until after the page is loaded to call `callback`
+ * in order to ensure all properties of the `navigation` entry are populated.
+ * This is useful if you want to report on other metrics exposed by the
+ * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For
+ * example, the TTFB metric starts from the page's [time
+ * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it
+ * includes time spent on DNS lookup, connection negotiation, network latency,
+ * and server processing time.
+ */
+export const onTTFB = (onReport, opts) => {
+ // Set defaults
+ opts = opts || {};
+ let metric = initMetric('TTFB');
+ let report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);
+ whenReady(() => {
+ const navigationEntry = getNavigationEntry();
+ if (navigationEntry) {
+ // The activationStart reference is used because TTFB should be
+ // relative to page activation rather than navigation start if the
+ // page was prerendered. But in cases where `activationStart` occurs
+ // after the first byte is received, this time should be clamped at 0.
+ metric.value = Math.max(navigationEntry.responseStart - getActivationStart(), 0);
+ metric.entries = [navigationEntry];
+ report(true);
+ // Only report TTFB after bfcache restores if a `navigation` entry
+ // was reported for the initial load.
+ onBFCacheRestore(() => {
+ metric = initMetric('TTFB', 0);
+ report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);
+ report(true);
+ });
+ }
+ });
+};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types.d.ts
new file mode 100644
index 0000000..080d366
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types.d.ts
@@ -0,0 +1,54 @@
+export * from './types/base.js';
+export * from './types/polyfills.js';
+export * from './types/cls.js';
+export * from './types/fcp.js';
+export * from './types/fid.js';
+export * from './types/inp.js';
+export * from './types/lcp.js';
+export * from './types/ttfb.js';
+interface PerformanceEntryMap {
+ navigation: PerformanceNavigationTiming;
+ resource: PerformanceResourceTiming;
+ paint: PerformancePaintTiming;
+}
+declare global {
+ interface Document {
+ prerendering?: boolean;
+ wasDiscarded?: boolean;
+ }
+ interface Performance {
+ getEntriesByType<K extends keyof PerformanceEntryMap>(type: K): PerformanceEntryMap[K][];
+ }
+ interface PerformanceObserverInit {
+ durationThreshold?: number;
+ }
+ interface PerformanceNavigationTiming {
+ activationStart?: number;
+ }
+ interface PerformanceEventTiming extends PerformanceEntry {
+ duration: DOMHighResTimeStamp;
+ interactionId: number;
+ }
+ interface LayoutShiftAttribution {
+ node?: Node;
+ previousRect: DOMRectReadOnly;
+ currentRect: DOMRectReadOnly;
+ }
+ interface LayoutShift extends PerformanceEntry {
+ value: number;
+ sources: LayoutShiftAttribution[];
+ hadRecentInput: boolean;
+ }
+ interface LargestContentfulPaint extends PerformanceEntry {
+ readonly renderTime: DOMHighResTimeStamp;
+ readonly loadTime: DOMHighResTimeStamp;
+ readonly size: number;
+ readonly id: string;
+ readonly url: string;
+ readonly element: Element | null;
+ }
+ interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {
+ renderStart: DOMHighResTimeStamp;
+ duration: DOMHighResTimeStamp;
+ }
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types.js b/frontend-old/node_modules/web-vitals/dist/modules/types.js
new file mode 100644
index 0000000..77da260
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export * from './types/base.js';
+export * from './types/polyfills.js';
+export * from './types/cls.js';
+export * from './types/fcp.js';
+export * from './types/fid.js';
+export * from './types/inp.js';
+export * from './types/lcp.js';
+export * from './types/ttfb.js';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/base.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/base.d.ts
new file mode 100644
index 0000000..944292b
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/base.d.ts
@@ -0,0 +1,101 @@
+import type { CLSMetric, CLSMetricWithAttribution } from './cls.js';
+import type { FCPMetric, FCPMetricWithAttribution } from './fcp.js';
+import type { FIDMetric, FIDMetricWithAttribution } from './fid.js';
+import type { INPMetric, INPMetricWithAttribution } from './inp.js';
+import type { LCPMetric, LCPMetricWithAttribution } from './lcp.js';
+import type { TTFBMetric, TTFBMetricWithAttribution } from './ttfb.js';
+export interface Metric {
+ /**
+ * The name of the metric (in acronym form).
+ */
+ name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB';
+ /**
+ * The current value of the metric.
+ */
+ value: number;
+ /**
+ * The rating as to whether the metric value is within the "good",
+ * "needs improvement", or "poor" thresholds of the metric.
+ */
+ rating: 'good' | 'needs-improvement' | 'poor';
+ /**
+ * The delta between the current value and the last-reported value.
+ * On the first report, `delta` and `value` will always be the same.
+ */
+ delta: number;
+ /**
+ * A unique ID representing this particular metric instance. This ID can
+ * be used by an analytics tool to dedupe multiple values sent for the same
+ * metric instance, or to group multiple deltas together and calculate a
+ * total. It can also be used to differentiate multiple different metric
+ * instances sent from the same page, which can happen if the page is
+ * restored from the back/forward cache (in that case new metrics object
+ * get created).
+ */
+ id: string;
+ /**
+ * Any performance entries relevant to the metric value calculation.
+ * The array may also be empty if the metric value was not based on any
+ * entries (e.g. a CLS value of 0 given no layout shifts).
+ */
+ entries: PerformanceEntry[];
+ /**
+ * The type of navigation.
+ *
+ * This will be the value returned by the Navigation Timing API (or
+ * `undefined` if the browser doesn't support that API), with the following
+ * exceptions:
+ * - 'back-forward-cache': for pages that are restored from the bfcache.
+ * - 'back_forward' is renamed to 'back-forward' for consistency.
+ * - 'prerender': for pages that were prerendered.
+ * - 'restore': for pages that were discarded by the browser and then
+ * restored by the user.
+ */
+ navigationType: 'navigate' | 'reload' | 'back-forward' | 'back-forward-cache' | 'prerender' | 'restore';
+}
+/** The union of supported metric types. */
+export type MetricType = CLSMetric | FCPMetric | FIDMetric | INPMetric | LCPMetric | TTFBMetric;
+/** The union of supported metric attribution types. */
+export type MetricWithAttribution = CLSMetricWithAttribution | FCPMetricWithAttribution | FIDMetricWithAttribution | INPMetricWithAttribution | LCPMetricWithAttribution | TTFBMetricWithAttribution;
+/**
+ * The thresholds of metric's "good", "needs improvement", and "poor" ratings.
+ *
+ * - Metric values up to and including [0] are rated "good"
+ * - Metric values up to and including [1] are rated "needs improvement"
+ * - Metric values above [1] are "poor"
+ *
+ * | Metric value | Rating |
+ * | --------------- | ------------------- |
+ * | ≦ [0] | "good" |
+ * | > [0] and ≦ [1] | "needs improvement" |
+ * | > [1] | "poor" |
+ */
+export type MetricRatingThresholds = [number, number];
+/**
+ * @deprecated Use metric-specific function types instead, such as:
+ * `(metric: LCPMetric) => void`. If a single callback type is needed for
+ * multiple metrics, use `(metric: MetricType) => void`.
+ */
+export interface ReportCallback {
+ (metric: MetricType): void;
+}
+export interface ReportOpts {
+ reportAllChanges?: boolean;
+ durationThreshold?: number;
+}
+/**
+ * The loading state of the document. Note: this value is similar to
+ * `document.readyState` but it subdivides the "interactive" state into the
+ * time before and after the DOMContentLoaded event fires.
+ *
+ * State descriptions:
+ * - `loading`: the initial document response has not yet been fully downloaded
+ * and parsed. This is equivalent to the corresponding `readyState` value.
+ * - `dom-interactive`: the document has been fully loaded and parsed, but
+ * scripts may not have yet finished loading and executing.
+ * - `dom-content-loaded`: the document is fully loaded and parsed, and all
+ * scripts (except `async` scripts) have loaded and finished executing.
+ * - `complete`: the document and all of its sub-resources have finished
+ * loading. This is equivalent to the corresponding `readyState` value.
+ */
+export type LoadState = 'loading' | 'dom-interactive' | 'dom-content-loaded' | 'complete';
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/base.js b/frontend-old/node_modules/web-vitals/dist/modules/types/base.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/base.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/cls.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.d.ts
new file mode 100644
index 0000000..f33cf17
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.d.ts
@@ -0,0 +1,55 @@
+import type { LoadState, Metric } from './base.js';
+/**
+ * A CLS-specific version of the Metric object.
+ */
+export interface CLSMetric extends Metric {
+ name: 'CLS';
+ entries: LayoutShift[];
+}
+/**
+ * An object containing potentially-helpful debugging information that
+ * can be sent along with the CLS value for the current page visit in order
+ * to help identify issues happening to real-users in the field.
+ */
+export interface CLSAttribution {
+ /**
+ * A selector identifying the first element (in document order) that
+ * shifted when the single largest layout shift contributing to the page's
+ * CLS score occurred.
+ */
+ largestShiftTarget?: string;
+ /**
+ * The time when the single largest layout shift contributing to the page's
+ * CLS score occurred.
+ */
+ largestShiftTime?: DOMHighResTimeStamp;
+ /**
+ * The layout shift score of the single largest layout shift contributing to
+ * the page's CLS score.
+ */
+ largestShiftValue?: number;
+ /**
+ * The `LayoutShiftEntry` representing the single largest layout shift
+ * contributing to the page's CLS score. (Useful when you need more than just
+ * `largestShiftTarget`, `largestShiftTime`, and `largestShiftValue`).
+ */
+ largestShiftEntry?: LayoutShift;
+ /**
+ * The first element source (in document order) among the `sources` list
+ * of the `largestShiftEntry` object. (Also useful when you need more than
+ * just `largestShiftTarget`, `largestShiftTime`, and `largestShiftValue`).
+ */
+ largestShiftSource?: LayoutShiftAttribution;
+ /**
+ * The loading state of the document at the time when the largest layout
+ * shift contribution to the page's CLS score occurred (see `LoadState`
+ * for details).
+ */
+ loadState?: LoadState;
+}
+/**
+ * A CLS-specific version of the Metric object with attribution.
+ */
+export interface CLSMetricWithAttribution extends CLSMetric {
+ attribution: CLSAttribution;
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/cls.js b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/cls.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.d.ts
new file mode 100644
index 0000000..fa4a6e2
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.d.ts
@@ -0,0 +1,46 @@
+import type { LoadState, Metric } from './base.js';
+/**
+ * An FCP-specific version of the Metric object.
+ */
+export interface FCPMetric extends Metric {
+ name: 'FCP';
+ entries: PerformancePaintTiming[];
+}
+/**
+ * An object containing potentially-helpful debugging information that
+ * can be sent along with the FCP value for the current page visit in order
+ * to help identify issues happening to real-users in the field.
+ */
+export interface FCPAttribution {
+ /**
+ * The time from when the user initiates loading the page until when the
+ * browser receives the first byte of the response (a.k.a. TTFB).
+ */
+ timeToFirstByte: number;
+ /**
+ * The delta between TTFB and the first contentful paint (FCP).
+ */
+ firstByteToFCP: number;
+ /**
+ * The loading state of the document at the time when FCP `occurred (see
+ * `LoadState` for details). Ideally, documents can paint before they finish
+ * loading (e.g. the `loading` or `dom-interactive` phases).
+ */
+ loadState: LoadState;
+ /**
+ * The `PerformancePaintTiming` entry corresponding to FCP.
+ */
+ fcpEntry?: PerformancePaintTiming;
+ /**
+ * The `navigation` entry of the current page, which is useful for diagnosing
+ * general page load issues. This can be used to access `serverTiming` for example:
+ * navigationEntry?.serverTiming
+ */
+ navigationEntry?: PerformanceNavigationTiming;
+}
+/**
+ * An FCP-specific version of the Metric object with attribution.
+ */
+export interface FCPMetricWithAttribution extends FCPMetric {
+ attribution: FCPAttribution;
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.js b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fcp.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fid.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.d.ts
new file mode 100644
index 0000000..25c5bd7
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.d.ts
@@ -0,0 +1,46 @@
+import type { LoadState, Metric } from './base.js';
+/**
+ * An FID-specific version of the Metric object.
+ */
+export interface FIDMetric extends Metric {
+ name: 'FID';
+ entries: PerformanceEventTiming[];
+}
+/**
+ * An object containing potentially-helpful debugging information that
+ * can be sent along with the FID value for the current page visit in order
+ * to help identify issues happening to real-users in the field.
+ */
+export interface FIDAttribution {
+ /**
+ * A selector identifying the element that the user interacted with. This
+ * element will be the `target` of the `event` dispatched.
+ */
+ eventTarget: string;
+ /**
+ * The time when the user interacted. This time will match the `timeStamp`
+ * value of the `event` dispatched.
+ */
+ eventTime: number;
+ /**
+ * The `type` of the `event` dispatched from the user interaction.
+ */
+ eventType: string;
+ /**
+ * The `PerformanceEventTiming` entry corresponding to FID.
+ */
+ eventEntry: PerformanceEventTiming;
+ /**
+ * The loading state of the document at the time when the first interaction
+ * occurred (see `LoadState` for details). If the first interaction occurred
+ * while the document was loading and executing script (e.g. usually in the
+ * `dom-interactive` phase) it can result in long input delays.
+ */
+ loadState: LoadState;
+}
+/**
+ * An FID-specific version of the Metric object with attribution.
+ */
+export interface FIDMetricWithAttribution extends FIDMetric {
+ attribution: FIDAttribution;
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/fid.js b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/fid.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/inp.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.d.ts
new file mode 100644
index 0000000..c60e86a
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.d.ts
@@ -0,0 +1,103 @@
+import type { LoadState, Metric } from './base.js';
+/**
+ * An INP-specific version of the Metric object.
+ */
+export interface INPMetric extends Metric {
+ name: 'INP';
+ entries: PerformanceEventTiming[];
+}
+/**
+ * An object containing potentially-helpful debugging information that
+ * can be sent along with the INP value for the current page visit in order
+ * to help identify issues happening to real-users in the field.
+ */
+export interface INPAttribution {
+ /**
+ * A selector identifying the element that the user first interacted with
+ * as part of the frame where the INP candidate interaction occurred.
+ * If this value is an empty string, that generally means the element was
+ * removed from the DOM after the interaction.
+ */
+ interactionTarget: string;
+ /**
+ * A reference to the HTML element identified by `interactionTargetSelector`.
+ * NOTE: for attribution purpose, a selector identifying the element is
+ * typically more useful than the element itself. However, the element is
+ * also made available in case additional context is needed.
+ */
+ interactionTargetElement: Node | undefined;
+ /**
+ * The time when the user first interacted during the frame where the INP
+ * candidate interaction occurred (if more than one interaction occurred
+ * within the frame, only the first time is reported).
+ */
+ interactionTime: DOMHighResTimeStamp;
+ /**
+ * The best-guess timestamp of the next paint after the interaction.
+ * In general, this timestamp is the same as the `startTime + duration` of
+ * the event timing entry. However, since `duration` values are rounded to
+ * the nearest 8ms, it can sometimes appear that the paint occurred before
+ * processing ended (which cannot happen). This value clamps the paint time
+ * so it's always after `processingEnd` from the Event Timing API and
+ * `renderStart` from the Long Animation Frame API (where available).
+ * It also averages the duration values for all entries in the same
+ * animation frame, which should be closer to the "real" value.
+ */
+ nextPaintTime: DOMHighResTimeStamp;
+ /**
+ * The type of interaction, based on the event type of the `event` entry
+ * that corresponds to the interaction (i.e. the first `event` entry
+ * containing an `interactionId` dispatched in a given animation frame).
+ * For "pointerdown", "pointerup", or "click" events this will be "pointer",
+ * and for "keydown" or "keyup" events this will be "keyboard".
+ */
+ interactionType: 'pointer' | 'keyboard';
+ /**
+ * An array of Event Timing entries that were processed within the same
+ * animation frame as the INP candidate interaction.
+ */
+ processedEventEntries: PerformanceEventTiming[];
+ /**
+ * If the browser supports the Long Animation Frame API, this array will
+ * include any `long-animation-frame` entries that intersect with the INP
+ * candidate interaction's `startTime` and the `processingEnd` time of the
+ * last event processed within that animation frame. If the browser does not
+ * support the Long Animation Frame API or no `long-animation-frame` entries
+ * are detect, this array will be empty.
+ */
+ longAnimationFrameEntries: PerformanceLongAnimationFrameTiming[];
+ /**
+ * The time from when the user interacted with the page until when the
+ * browser was first able to start processing event listeners for that
+ * interaction. This time captures the delay before event processing can
+ * begin due to the main thread being busy with other work.
+ */
+ inputDelay: number;
+ /**
+ * The time from when the first event listener started running in response to
+ * the user interaction until when all event listener processing has finished.
+ */
+ processingDuration: number;
+ /**
+ * The time from when the browser finished processing all event listeners for
+ * the user interaction until the next frame is presented on the screen and
+ * visible to the user. This time includes work on the main thread (such as
+ * `requestAnimationFrame()` callbacks, `ResizeObserver` and
+ * `IntersectionObserver` callbacks, and style/layout calculation) as well
+ * as off-main-thread work (such as compositor, GPU, and raster work).
+ */
+ presentationDelay: number;
+ /**
+ * The loading state of the document at the time when the interaction
+ * corresponding to INP occurred (see `LoadState` for details). If the
+ * interaction occurred while the document was loading and executing script
+ * (e.g. usually in the `dom-interactive` phase) it can result in long delays.
+ */
+ loadState: LoadState;
+}
+/**
+ * An INP-specific version of the Metric object with attribution.
+ */
+export interface INPMetricWithAttribution extends INPMetric {
+ attribution: INPAttribution;
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/inp.js b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/inp.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.d.ts
new file mode 100644
index 0000000..2e960e9
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.d.ts
@@ -0,0 +1,69 @@
+import type { Metric } from './base.js';
+/**
+ * An LCP-specific version of the Metric object.
+ */
+export interface LCPMetric extends Metric {
+ name: 'LCP';
+ entries: LargestContentfulPaint[];
+}
+/**
+ * An object containing potentially-helpful debugging information that
+ * can be sent along with the LCP value for the current page visit in order
+ * to help identify issues happening to real-users in the field.
+ */
+export interface LCPAttribution {
+ /**
+ * The element corresponding to the largest contentful paint for the page.
+ */
+ element?: string;
+ /**
+ * The URL (if applicable) of the LCP image resource. If the LCP element
+ * is a text node, this value will not be set.
+ */
+ url?: string;
+ /**
+ * The time from when the user initiates loading the page until when the
+ * browser receives the first byte of the response (a.k.a. TTFB). See
+ * [Optimize LCP](https://web.dev/articles/optimize-lcp) for details.
+ */
+ timeToFirstByte: number;
+ /**
+ * The delta between TTFB and when the browser starts loading the LCP
+ * resource (if there is one, otherwise 0). See [Optimize
+ * LCP](https://web.dev/articles/optimize-lcp) for details.
+ */
+ resourceLoadDelay: number;
+ /**
+ * The total time it takes to load the LCP resource itself (if there is one,
+ * otherwise 0). See [Optimize LCP](https://web.dev/articles/optimize-lcp) for
+ * details.
+ */
+ resourceLoadDuration: number;
+ /**
+ * The delta between when the LCP resource finishes loading until the LCP
+ * element is fully rendered. See [Optimize
+ * LCP](https://web.dev/articles/optimize-lcp) for details.
+ */
+ elementRenderDelay: number;
+ /**
+ * The `navigation` entry of the current page, which is useful for diagnosing
+ * general page load issues. This can be used to access `serverTiming` for example:
+ * navigationEntry?.serverTiming
+ */
+ navigationEntry?: PerformanceNavigationTiming;
+ /**
+ * The `resource` entry for the LCP resource (if applicable), which is useful
+ * for diagnosing resource load issues.
+ */
+ lcpResourceEntry?: PerformanceResourceTiming;
+ /**
+ * The `LargestContentfulPaint` entry corresponding to LCP.
+ */
+ lcpEntry?: LargestContentfulPaint;
+}
+/**
+ * An LCP-specific version of the Metric object with attribution.
+ */
+export interface LCPMetricWithAttribution extends LCPMetric {
+ attribution: LCPAttribution;
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.js b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/lcp.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.d.ts
new file mode 100644
index 0000000..e606728
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.d.ts
@@ -0,0 +1,4 @@
+export type FirstInputPolyfillEntry = Omit<PerformanceEventTiming, 'processingEnd'>;
+export interface FirstInputPolyfillCallback {
+ (entry: FirstInputPolyfillEntry): void;
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.js b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/polyfills.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.d.ts b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.d.ts
new file mode 100644
index 0000000..485eeb6
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.d.ts
@@ -0,0 +1,59 @@
+import type { Metric } from './base.js';
+/**
+ * A TTFB-specific version of the Metric object.
+ */
+export interface TTFBMetric extends Metric {
+ name: 'TTFB';
+ entries: PerformanceNavigationTiming[];
+}
+/**
+ * An object containing potentially-helpful debugging information that
+ * can be sent along with the TTFB value for the current page visit in order
+ * to help identify issues happening to real-users in the field.
+ *
+ * NOTE: these values are primarily useful for page loads not handled via
+ * service worker, as browsers differ in what they report when service worker
+ * is involved, see: https://github.com/w3c/navigation-timing/issues/199
+ */
+export interface TTFBAttribution {
+ /**
+ * The total time from when the user initiates loading the page to when the
+ * page starts to handle the request. Large values here are typically due
+ * to HTTP redirects, though other browser processing contributes to this
+ * duration as well (so even without redirect it's generally not zero).
+ */
+ waitingDuration: number;
+ /**
+ * The total time spent checking the HTTP cache for a match. For navigations
+ * handled via service worker, this duration usually includes service worker
+ * start-up time as well as time processing `fetch` event listeners, with
+ * some exceptions, see: https://github.com/w3c/navigation-timing/issues/199
+ */
+ cacheDuration: number;
+ /**
+ * The total time to resolve the DNS for the requested domain.
+ */
+ dnsDuration: number;
+ /**
+ * The total time to create the connection to the requested domain.
+ */
+ connectionDuration: number;
+ /**
+ * The total time from when the request was sent until the first byte of the
+ * response was received. This includes network time as well as server
+ * processing time.
+ */
+ requestDuration: number;
+ /**
+ * The `navigation` entry of the current page, which is useful for diagnosing
+ * general page load issues. This can be used to access `serverTiming` for
+ * example: navigationEntry?.serverTiming
+ */
+ navigationEntry?: PerformanceNavigationTiming;
+}
+/**
+ * A TTFB-specific version of the Metric object with attribution.
+ */
+export interface TTFBMetricWithAttribution extends TTFBMetric {
+ attribution: TTFBAttribution;
+}
diff --git a/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.js b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.js
new file mode 100644
index 0000000..e997715
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/modules/types/ttfb.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export {};
diff --git a/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.iife.js b/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.iife.js
new file mode 100644
index 0000000..2903fda
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.iife.js
@@ -0,0 +1 @@
+var webVitals=function(t){"use strict";var e,n,r=function(){var t=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(t&&t.responseStart>0&&t.responseStart<performance.now())return t},i=function(t){if("loading"===document.readyState)return"loading";var e=r();if(e){if(t<e.domInteractive)return"loading";if(0===e.domContentLoadedEventStart||t<e.domContentLoadedEventStart)return"dom-interactive";if(0===e.domComplete||t<e.domComplete)return"dom-content-loaded"}return"complete"},a=function(t){var e=t.nodeName;return 1===t.nodeType?e.toLowerCase():e.toUpperCase().replace(/^#/,"")},o=function(t,e){var n="";try{for(;t&&9!==t.nodeType;){var r=t,i=r.id?"#"+r.id:a(r)+(r.classList&&r.classList.value&&r.classList.value.trim()&&r.classList.value.trim().length?"."+r.classList.value.trim().replace(/\s+/g,"."):"");if(n.length+i.length>(e||100)-1)return n||i;if(n=n?i+">"+n:i,r.id)break;t=r.parentNode}}catch(t){}return n},c=-1,s=function(){return c},u=function(t){addEventListener("pageshow",(function(e){e.persisted&&(c=e.timeStamp,t(e))}),!0)},f=function(){var t=r();return t&&t.activationStart||0},d=function(t,e){var n=r(),i="navigate";s()>=0?i="back-forward-cache":n&&(document.prerendering||f()>0?i="prerender":document.wasDiscarded?i="restore":n.type&&(i=n.type.replace(/_/g,"-")));return{name:t,value:void 0===e?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:i}},l=function(t,e,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var r=new PerformanceObserver((function(t){Promise.resolve().then((function(){e(t.getEntries())}))}));return r.observe(Object.assign({type:t,buffered:!0},n||{})),r}}catch(t){}},m=function(t,e,n,r){var i,a;return function(o){e.value>=0&&(o||r)&&((a=e.value-(i||0))||void 0===i)&&(i=e.value,e.delta=a,e.rating=function(t,e){return t>e[1]?"poor":t>e[0]?"needs-improvement":"good"}(e.value,n),t(e))}},v=function(t){requestAnimationFrame((function(){return requestAnimationFrame((function(){return t()}))}))},p=function(t){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&t()}))},h=function(t){var e=!1;return function(){e||(t(),e=!0)}},g=-1,T=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},y=function(t){"hidden"===document.visibilityState&&g>-1&&(g="visibilitychange"===t.type?t.timeStamp:0,S())},E=function(){addEventListener("visibilitychange",y,!0),addEventListener("prerenderingchange",y,!0)},S=function(){removeEventListener("visibilitychange",y,!0),removeEventListener("prerenderingchange",y,!0)},b=function(){return g<0&&(g=T(),E(),u((function(){setTimeout((function(){g=T(),E()}),0)}))),{get firstHiddenTime(){return g}}},C=function(t){document.prerendering?addEventListener("prerenderingchange",(function(){return t()}),!0):t()},L=[1800,3e3],M=function(t,e){e=e||{},C((function(){var n,r=b(),i=d("FCP"),a=l("paint",(function(t){t.forEach((function(t){"first-contentful-paint"===t.name&&(a.disconnect(),t.startTime<r.firstHiddenTime&&(i.value=Math.max(t.startTime-f(),0),i.entries.push(t),n(!0)))}))}));a&&(n=m(t,i,L,e.reportAllChanges),u((function(r){i=d("FCP"),n=m(t,i,L,e.reportAllChanges),v((function(){i.value=performance.now()-r.timeStamp,n(!0)}))})))}))},D=[.1,.25],w=0,I=1/0,F=0,P=function(t){t.forEach((function(t){t.interactionId&&(I=Math.min(I,t.interactionId),F=Math.max(F,t.interactionId),w=F?(F-I)/7+1:0)}))},x=function(){return e?w:performance.interactionCount||0},k=function(){"interactionCount"in performance||e||(e=l("event",P,{type:"event",buffered:!0,durationThreshold:0}))},A=[],B=new Map,O=0,R=function(){var t=Math.min(A.length-1,Math.floor((x()-O)/50));return A[t]},j=[],q=function(t){if(j.forEach((function(e){return e(t)})),t.interactionId||"first-input"===t.entryType){var e=A[A.length-1],n=B.get(t.interactionId);if(n||A.length<10||t.duration>e.latency){if(n)t.duration>n.latency?(n.entries=[t],n.latency=t.duration):t.duration===n.latency&&t.startTime===n.entries[0].startTime&&n.entries.push(t);else{var r={id:t.interactionId,latency:t.duration,entries:[t]};B.set(r.id,r),A.push(r)}A.sort((function(t,e){return e.latency-t.latency})),A.length>10&&A.splice(10).forEach((function(t){return B.delete(t.id)}))}}},N=function(t){var e=self.requestIdleCallback||self.setTimeout,n=-1;return t=h(t),"hidden"===document.visibilityState?t():(n=e(t),p(t)),n},H=[200,500],V=function(t,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},C((function(){var n;k();var r,i=d("INP"),a=function(t){N((function(){t.forEach(q);var e=R();e&&e.latency!==i.value&&(i.value=e.latency,i.entries=e.entries,r())}))},o=l("event",a,{durationThreshold:null!==(n=e.durationThreshold)&&void 0!==n?n:40});r=m(t,i,H,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),p((function(){a(o.takeRecords()),r(!0)})),u((function(){O=x(),A.length=0,B.clear(),i=d("INP"),r=m(t,i,H,e.reportAllChanges)})))})))},W=[],z=[],U=0,_=new WeakMap,G=new Map,J=-1,K=function(t){W=W.concat(t),Q()},Q=function(){J<0&&(J=N(X))},X=function(){G.size>10&&G.forEach((function(t,e){B.has(e)||G.delete(e)}));var t=A.map((function(t){return _.get(t.entries[0])})),e=z.length-50;z=z.filter((function(n,r){return r>=e||t.includes(n)}));for(var n=new Set,r=0;r<z.length;r++){var i=z[r];et(i.startTime,i.processingEnd).forEach((function(t){n.add(t)}))}var a=W.length-1-50;W=W.filter((function(t,e){return t.startTime>U&&e>a||n.has(t)})),J=-1};j.push((function(t){t.interactionId&&t.target&&!G.has(t.interactionId)&&G.set(t.interactionId,t.target)}),(function(t){var e,n=t.startTime+t.duration;U=Math.max(U,t.processingEnd);for(var r=z.length-1;r>=0;r--){var i=z[r];if(Math.abs(n-i.renderTime)<=8){(e=i).startTime=Math.min(t.startTime,e.startTime),e.processingStart=Math.min(t.processingStart,e.processingStart),e.processingEnd=Math.max(t.processingEnd,e.processingEnd),e.entries.push(t);break}}e||(e={startTime:t.startTime,processingStart:t.processingStart,processingEnd:t.processingEnd,renderTime:n,entries:[t]},z.push(e)),(t.interactionId||"first-input"===t.entryType)&&_.set(t,e),Q()}));var Y,Z,$,tt,et=function(t,e){for(var n,r=[],i=0;n=W[i];i++)if(!(n.startTime+n.duration<t)){if(n.startTime>e)break;r.push(n)}return r},nt=[2500,4e3],rt={},it=[800,1800],at=function t(e){document.prerendering?C((function(){return t(e)})):"complete"!==document.readyState?addEventListener("load",(function(){return t(e)}),!0):setTimeout(e,0)},ot=function(t,e){e=e||{};var n=d("TTFB"),i=m(t,n,it,e.reportAllChanges);at((function(){var a=r();a&&(n.value=Math.max(a.responseStart-f(),0),n.entries=[a],i(!0),u((function(){n=d("TTFB",0),(i=m(t,n,it,e.reportAllChanges))(!0)})))}))},ct={passive:!0,capture:!0},st=new Date,ut=function(t,e){Y||(Y=e,Z=t,$=new Date,lt(removeEventListener),ft())},ft=function(){if(Z>=0&&Z<$-st){var t={entryType:"first-input",name:Y.type,target:Y.target,cancelable:Y.cancelable,startTime:Y.timeStamp,processingStart:Y.timeStamp+Z};tt.forEach((function(e){e(t)})),tt=[]}},dt=function(t){if(t.cancelable){var e=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,e){var n=function(){ut(t,e),i()},r=function(){i()},i=function(){removeEventListener("pointerup",n,ct),removeEventListener("pointercancel",r,ct)};addEventListener("pointerup",n,ct),addEventListener("pointercancel",r,ct)}(e,t):ut(e,t)}},lt=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return t(e,dt,ct)}))},mt=[100,300],vt=function(t,e){e=e||{},C((function(){var n,r=b(),i=d("FID"),a=function(t){t.startTime<r.firstHiddenTime&&(i.value=t.processingStart-t.startTime,i.entries.push(t),n(!0))},o=function(t){t.forEach(a)},c=l("first-input",o);n=m(t,i,mt,e.reportAllChanges),c&&(p(h((function(){o(c.takeRecords()),c.disconnect()}))),u((function(){var r;i=d("FID"),n=m(t,i,mt,e.reportAllChanges),tt=[],Z=-1,Y=null,lt(addEventListener),r=a,tt.push(r),ft()})))}))};return t.CLSThresholds=D,t.FCPThresholds=L,t.FIDThresholds=mt,t.INPThresholds=H,t.LCPThresholds=nt,t.TTFBThresholds=it,t.onCLS=function(t,e){!function(t,e){e=e||{},M(h((function(){var n,r=d("CLS",0),i=0,a=[],o=function(t){t.forEach((function(t){if(!t.hadRecentInput){var e=a[0],n=a[a.length-1];i&&t.startTime-n.startTime<1e3&&t.startTime-e.startTime<5e3?(i+=t.value,a.push(t)):(i=t.value,a=[t])}})),i>r.value&&(r.value=i,r.entries=a,n())},c=l("layout-shift",o);c&&(n=m(t,r,D,e.reportAllChanges),p((function(){o(c.takeRecords()),n(!0)})),u((function(){i=0,r=d("CLS",0),n=m(t,r,D,e.reportAllChanges),v((function(){return n()}))})),setTimeout(n,0))})))}((function(e){var n=function(t){var e,n={};if(t.entries.length){var r=t.entries.reduce((function(t,e){return t&&t.value>e.value?t:e}));if(r&&r.sources&&r.sources.length){var a=(e=r.sources).find((function(t){return t.node&&1===t.node.nodeType}))||e[0];a&&(n={largestShiftTarget:o(a.node),largestShiftTime:r.startTime,largestShiftValue:r.value,largestShiftSource:a,largestShiftEntry:r,loadState:i(r.startTime)})}}return Object.assign(t,{attribution:n})}(e);t(n)}),e)},t.onFCP=function(t,e){M((function(e){var n=function(t){var e={timeToFirstByte:0,firstByteToFCP:t.value,loadState:i(s())};if(t.entries.length){var n=r(),a=t.entries[t.entries.length-1];if(n){var o=n.activationStart||0,c=Math.max(0,n.responseStart-o);e={timeToFirstByte:c,firstByteToFCP:t.value-c,loadState:i(t.entries[0].startTime),navigationEntry:n,fcpEntry:a}}}return Object.assign(t,{attribution:e})}(e);t(n)}),e)},t.onFID=function(t,e){vt((function(e){var n=function(t){var e=t.entries[0],n={eventTarget:o(e.target),eventType:e.name,eventTime:e.startTime,eventEntry:e,loadState:i(e.startTime)};return Object.assign(t,{attribution:n})}(e);t(n)}),e)},t.onINP=function(t,e){n||(n=l("long-animation-frame",K)),V((function(e){var n=function(t){var e=t.entries[0],n=_.get(e),r=e.processingStart,a=n.processingEnd,c=n.entries.sort((function(t,e){return t.processingStart-e.processingStart})),s=et(e.startTime,a),u=t.entries.find((function(t){return t.target})),f=u&&u.target||G.get(e.interactionId),d=[e.startTime+e.duration,a].concat(s.map((function(t){return t.startTime+t.duration}))),l=Math.max.apply(Math,d),m={interactionTarget:o(f),interactionTargetElement:f,interactionType:e.name.startsWith("key")?"keyboard":"pointer",interactionTime:e.startTime,nextPaintTime:l,processedEventEntries:c,longAnimationFrameEntries:s,inputDelay:r-e.startTime,processingDuration:a-r,presentationDelay:Math.max(l-a,0),loadState:i(e.startTime)};return Object.assign(t,{attribution:m})}(e);t(n)}),e)},t.onLCP=function(t,e){!function(t,e){e=e||{},C((function(){var n,r=b(),i=d("LCP"),a=function(t){e.reportAllChanges||(t=t.slice(-1)),t.forEach((function(t){t.startTime<r.firstHiddenTime&&(i.value=Math.max(t.startTime-f(),0),i.entries=[t],n())}))},o=l("largest-contentful-paint",a);if(o){n=m(t,i,nt,e.reportAllChanges);var c=h((function(){rt[i.id]||(a(o.takeRecords()),o.disconnect(),rt[i.id]=!0,n(!0))}));["keydown","click"].forEach((function(t){addEventListener(t,(function(){return N(c)}),{once:!0,capture:!0})})),p(c),u((function(r){i=d("LCP"),n=m(t,i,nt,e.reportAllChanges),v((function(){i.value=performance.now()-r.timeStamp,rt[i.id]=!0,n(!0)}))}))}}))}((function(e){var n=function(t){var e={timeToFirstByte:0,resourceLoadDelay:0,resourceLoadDuration:0,elementRenderDelay:t.value};if(t.entries.length){var n=r();if(n){var i=n.activationStart||0,a=t.entries[t.entries.length-1],c=a.url&&performance.getEntriesByType("resource").filter((function(t){return t.name===a.url}))[0],s=Math.max(0,n.responseStart-i),u=Math.max(s,c?(c.requestStart||c.startTime)-i:0),f=Math.max(u,c?c.responseEnd-i:0),d=Math.max(f,a.startTime-i);e={element:o(a.element),timeToFirstByte:s,resourceLoadDelay:u-s,resourceLoadDuration:f-u,elementRenderDelay:d-f,navigationEntry:n,lcpEntry:a},a.url&&(e.url=a.url),c&&(e.lcpResourceEntry=c)}}return Object.assign(t,{attribution:e})}(e);t(n)}),e)},t.onTTFB=function(t,e){ot((function(e){var n=function(t){var e={waitingDuration:0,cacheDuration:0,dnsDuration:0,connectionDuration:0,requestDuration:0};if(t.entries.length){var n=t.entries[0],r=n.activationStart||0,i=Math.max((n.workerStart||n.fetchStart)-r,0),a=Math.max(n.domainLookupStart-r,0),o=Math.max(n.connectStart-r,0),c=Math.max(n.connectEnd-r,0);e={waitingDuration:i,cacheDuration:a-i,dnsDuration:o-a,connectionDuration:c-o,requestDuration:t.value-c,navigationEntry:n}}return Object.assign(t,{attribution:e})}(e);t(n)}),e)},t}({});
diff --git a/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.js b/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.js
new file mode 100644
index 0000000..98efa73
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.js
@@ -0,0 +1 @@
+var t,e,n=function(){var t=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(t&&t.responseStart>0&&t.responseStart<performance.now())return t},r=function(t){if("loading"===document.readyState)return"loading";var e=n();if(e){if(t<e.domInteractive)return"loading";if(0===e.domContentLoadedEventStart||t<e.domContentLoadedEventStart)return"dom-interactive";if(0===e.domComplete||t<e.domComplete)return"dom-content-loaded"}return"complete"},i=function(t){var e=t.nodeName;return 1===t.nodeType?e.toLowerCase():e.toUpperCase().replace(/^#/,"")},a=function(t,e){var n="";try{for(;t&&9!==t.nodeType;){var r=t,a=r.id?"#"+r.id:i(r)+(r.classList&&r.classList.value&&r.classList.value.trim()&&r.classList.value.trim().length?"."+r.classList.value.trim().replace(/\s+/g,"."):"");if(n.length+a.length>(e||100)-1)return n||a;if(n=n?a+">"+n:a,r.id)break;t=r.parentNode}}catch(t){}return n},o=-1,c=function(){return o},u=function(t){addEventListener("pageshow",(function(e){e.persisted&&(o=e.timeStamp,t(e))}),!0)},s=function(){var t=n();return t&&t.activationStart||0},f=function(t,e){var r=n(),i="navigate";c()>=0?i="back-forward-cache":r&&(document.prerendering||s()>0?i="prerender":document.wasDiscarded?i="restore":r.type&&(i=r.type.replace(/_/g,"-")));return{name:t,value:void 0===e?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:i}},d=function(t,e,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var r=new PerformanceObserver((function(t){Promise.resolve().then((function(){e(t.getEntries())}))}));return r.observe(Object.assign({type:t,buffered:!0},n||{})),r}}catch(t){}},l=function(t,e,n,r){var i,a;return function(o){e.value>=0&&(o||r)&&((a=e.value-(i||0))||void 0===i)&&(i=e.value,e.delta=a,e.rating=function(t,e){return t>e[1]?"poor":t>e[0]?"needs-improvement":"good"}(e.value,n),t(e))}},m=function(t){requestAnimationFrame((function(){return requestAnimationFrame((function(){return t()}))}))},p=function(t){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&t()}))},v=function(t){var e=!1;return function(){e||(t(),e=!0)}},g=-1,h=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},T=function(t){"hidden"===document.visibilityState&&g>-1&&(g="visibilitychange"===t.type?t.timeStamp:0,E())},y=function(){addEventListener("visibilitychange",T,!0),addEventListener("prerenderingchange",T,!0)},E=function(){removeEventListener("visibilitychange",T,!0),removeEventListener("prerenderingchange",T,!0)},S=function(){return g<0&&(g=h(),y(),u((function(){setTimeout((function(){g=h(),y()}),0)}))),{get firstHiddenTime(){return g}}},b=function(t){document.prerendering?addEventListener("prerenderingchange",(function(){return t()}),!0):t()},L=[1800,3e3],C=function(t,e){e=e||{},b((function(){var n,r=S(),i=f("FCP"),a=d("paint",(function(t){t.forEach((function(t){"first-contentful-paint"===t.name&&(a.disconnect(),t.startTime<r.firstHiddenTime&&(i.value=Math.max(t.startTime-s(),0),i.entries.push(t),n(!0)))}))}));a&&(n=l(t,i,L,e.reportAllChanges),u((function(r){i=f("FCP"),n=l(t,i,L,e.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,n(!0)}))})))}))},M=[.1,.25],D=function(t,e){!function(t,e){e=e||{},C(v((function(){var n,r=f("CLS",0),i=0,a=[],o=function(t){t.forEach((function(t){if(!t.hadRecentInput){var e=a[0],n=a[a.length-1];i&&t.startTime-n.startTime<1e3&&t.startTime-e.startTime<5e3?(i+=t.value,a.push(t)):(i=t.value,a=[t])}})),i>r.value&&(r.value=i,r.entries=a,n())},c=d("layout-shift",o);c&&(n=l(t,r,M,e.reportAllChanges),p((function(){o(c.takeRecords()),n(!0)})),u((function(){i=0,r=f("CLS",0),n=l(t,r,M,e.reportAllChanges),m((function(){return n()}))})),setTimeout(n,0))})))}((function(e){var n=function(t){var e,n={};if(t.entries.length){var i=t.entries.reduce((function(t,e){return t&&t.value>e.value?t:e}));if(i&&i.sources&&i.sources.length){var o=(e=i.sources).find((function(t){return t.node&&1===t.node.nodeType}))||e[0];o&&(n={largestShiftTarget:a(o.node),largestShiftTime:i.startTime,largestShiftValue:i.value,largestShiftSource:o,largestShiftEntry:i,loadState:r(i.startTime)})}}return Object.assign(t,{attribution:n})}(e);t(n)}),e)},w=function(t,e){C((function(e){var i=function(t){var e={timeToFirstByte:0,firstByteToFCP:t.value,loadState:r(c())};if(t.entries.length){var i=n(),a=t.entries[t.entries.length-1];if(i){var o=i.activationStart||0,u=Math.max(0,i.responseStart-o);e={timeToFirstByte:u,firstByteToFCP:t.value-u,loadState:r(t.entries[0].startTime),navigationEntry:i,fcpEntry:a}}}return Object.assign(t,{attribution:e})}(e);t(i)}),e)},x=0,I=1/0,k=0,A=function(t){t.forEach((function(t){t.interactionId&&(I=Math.min(I,t.interactionId),k=Math.max(k,t.interactionId),x=k?(k-I)/7+1:0)}))},F=function(){return t?x:performance.interactionCount||0},P=function(){"interactionCount"in performance||t||(t=d("event",A,{type:"event",buffered:!0,durationThreshold:0}))},B=[],O=new Map,R=0,j=function(){var t=Math.min(B.length-1,Math.floor((F()-R)/50));return B[t]},q=[],H=function(t){if(q.forEach((function(e){return e(t)})),t.interactionId||"first-input"===t.entryType){var e=B[B.length-1],n=O.get(t.interactionId);if(n||B.length<10||t.duration>e.latency){if(n)t.duration>n.latency?(n.entries=[t],n.latency=t.duration):t.duration===n.latency&&t.startTime===n.entries[0].startTime&&n.entries.push(t);else{var r={id:t.interactionId,latency:t.duration,entries:[t]};O.set(r.id,r),B.push(r)}B.sort((function(t,e){return e.latency-t.latency})),B.length>10&&B.splice(10).forEach((function(t){return O.delete(t.id)}))}}},N=function(t){var e=self.requestIdleCallback||self.setTimeout,n=-1;return t=v(t),"hidden"===document.visibilityState?t():(n=e(t),p(t)),n},W=[200,500],z=function(t,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},b((function(){var n;P();var r,i=f("INP"),a=function(t){N((function(){t.forEach(H);var e=j();e&&e.latency!==i.value&&(i.value=e.latency,i.entries=e.entries,r())}))},o=d("event",a,{durationThreshold:null!==(n=e.durationThreshold)&&void 0!==n?n:40});r=l(t,i,W,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),p((function(){a(o.takeRecords()),r(!0)})),u((function(){R=F(),B.length=0,O.clear(),i=f("INP"),r=l(t,i,W,e.reportAllChanges)})))})))},U=[],V=[],_=0,G=new WeakMap,J=new Map,K=-1,Q=function(t){U=U.concat(t),X()},X=function(){K<0&&(K=N(Y))},Y=function(){J.size>10&&J.forEach((function(t,e){O.has(e)||J.delete(e)}));var t=B.map((function(t){return G.get(t.entries[0])})),e=V.length-50;V=V.filter((function(n,r){return r>=e||t.includes(n)}));for(var n=new Set,r=0;r<V.length;r++){var i=V[r];nt(i.startTime,i.processingEnd).forEach((function(t){n.add(t)}))}var a=U.length-1-50;U=U.filter((function(t,e){return t.startTime>_&&e>a||n.has(t)})),K=-1};q.push((function(t){t.interactionId&&t.target&&!J.has(t.interactionId)&&J.set(t.interactionId,t.target)}),(function(t){var e,n=t.startTime+t.duration;_=Math.max(_,t.processingEnd);for(var r=V.length-1;r>=0;r--){var i=V[r];if(Math.abs(n-i.renderTime)<=8){(e=i).startTime=Math.min(t.startTime,e.startTime),e.processingStart=Math.min(t.processingStart,e.processingStart),e.processingEnd=Math.max(t.processingEnd,e.processingEnd),e.entries.push(t);break}}e||(e={startTime:t.startTime,processingStart:t.processingStart,processingEnd:t.processingEnd,renderTime:n,entries:[t]},V.push(e)),(t.interactionId||"first-input"===t.entryType)&&G.set(t,e),X()}));var Z,$,tt,et,nt=function(t,e){for(var n,r=[],i=0;n=U[i];i++)if(!(n.startTime+n.duration<t)){if(n.startTime>e)break;r.push(n)}return r},rt=function(t,n){e||(e=d("long-animation-frame",Q)),z((function(e){var n=function(t){var e=t.entries[0],n=G.get(e),i=e.processingStart,o=n.processingEnd,c=n.entries.sort((function(t,e){return t.processingStart-e.processingStart})),u=nt(e.startTime,o),s=t.entries.find((function(t){return t.target})),f=s&&s.target||J.get(e.interactionId),d=[e.startTime+e.duration,o].concat(u.map((function(t){return t.startTime+t.duration}))),l=Math.max.apply(Math,d),m={interactionTarget:a(f),interactionTargetElement:f,interactionType:e.name.startsWith("key")?"keyboard":"pointer",interactionTime:e.startTime,nextPaintTime:l,processedEventEntries:c,longAnimationFrameEntries:u,inputDelay:i-e.startTime,processingDuration:o-i,presentationDelay:Math.max(l-o,0),loadState:r(e.startTime)};return Object.assign(t,{attribution:m})}(e);t(n)}),n)},it=[2500,4e3],at={},ot=function(t,e){!function(t,e){e=e||{},b((function(){var n,r=S(),i=f("LCP"),a=function(t){e.reportAllChanges||(t=t.slice(-1)),t.forEach((function(t){t.startTime<r.firstHiddenTime&&(i.value=Math.max(t.startTime-s(),0),i.entries=[t],n())}))},o=d("largest-contentful-paint",a);if(o){n=l(t,i,it,e.reportAllChanges);var c=v((function(){at[i.id]||(a(o.takeRecords()),o.disconnect(),at[i.id]=!0,n(!0))}));["keydown","click"].forEach((function(t){addEventListener(t,(function(){return N(c)}),{once:!0,capture:!0})})),p(c),u((function(r){i=f("LCP"),n=l(t,i,it,e.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,at[i.id]=!0,n(!0)}))}))}}))}((function(e){var r=function(t){var e={timeToFirstByte:0,resourceLoadDelay:0,resourceLoadDuration:0,elementRenderDelay:t.value};if(t.entries.length){var r=n();if(r){var i=r.activationStart||0,o=t.entries[t.entries.length-1],c=o.url&&performance.getEntriesByType("resource").filter((function(t){return t.name===o.url}))[0],u=Math.max(0,r.responseStart-i),s=Math.max(u,c?(c.requestStart||c.startTime)-i:0),f=Math.max(s,c?c.responseEnd-i:0),d=Math.max(f,o.startTime-i);e={element:a(o.element),timeToFirstByte:u,resourceLoadDelay:s-u,resourceLoadDuration:f-s,elementRenderDelay:d-f,navigationEntry:r,lcpEntry:o},o.url&&(e.url=o.url),c&&(e.lcpResourceEntry=c)}}return Object.assign(t,{attribution:e})}(e);t(r)}),e)},ct=[800,1800],ut=function t(e){document.prerendering?b((function(){return t(e)})):"complete"!==document.readyState?addEventListener("load",(function(){return t(e)}),!0):setTimeout(e,0)},st=function(t,e){e=e||{};var r=f("TTFB"),i=l(t,r,ct,e.reportAllChanges);ut((function(){var a=n();a&&(r.value=Math.max(a.responseStart-s(),0),r.entries=[a],i(!0),u((function(){r=f("TTFB",0),(i=l(t,r,ct,e.reportAllChanges))(!0)})))}))},ft=function(t,e){st((function(e){var n=function(t){var e={waitingDuration:0,cacheDuration:0,dnsDuration:0,connectionDuration:0,requestDuration:0};if(t.entries.length){var n=t.entries[0],r=n.activationStart||0,i=Math.max((n.workerStart||n.fetchStart)-r,0),a=Math.max(n.domainLookupStart-r,0),o=Math.max(n.connectStart-r,0),c=Math.max(n.connectEnd-r,0);e={waitingDuration:i,cacheDuration:a-i,dnsDuration:o-a,connectionDuration:c-o,requestDuration:t.value-c,navigationEntry:n}}return Object.assign(t,{attribution:e})}(e);t(n)}),e)},dt={passive:!0,capture:!0},lt=new Date,mt=function(t,e){Z||(Z=e,$=t,tt=new Date,gt(removeEventListener),pt())},pt=function(){if($>=0&&$<tt-lt){var t={entryType:"first-input",name:Z.type,target:Z.target,cancelable:Z.cancelable,startTime:Z.timeStamp,processingStart:Z.timeStamp+$};et.forEach((function(e){e(t)})),et=[]}},vt=function(t){if(t.cancelable){var e=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,e){var n=function(){mt(t,e),i()},r=function(){i()},i=function(){removeEventListener("pointerup",n,dt),removeEventListener("pointercancel",r,dt)};addEventListener("pointerup",n,dt),addEventListener("pointercancel",r,dt)}(e,t):mt(e,t)}},gt=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return t(e,vt,dt)}))},ht=[100,300],Tt=function(t,e){e=e||{},b((function(){var n,r=S(),i=f("FID"),a=function(t){t.startTime<r.firstHiddenTime&&(i.value=t.processingStart-t.startTime,i.entries.push(t),n(!0))},o=function(t){t.forEach(a)},c=d("first-input",o);n=l(t,i,ht,e.reportAllChanges),c&&(p(v((function(){o(c.takeRecords()),c.disconnect()}))),u((function(){var r;i=f("FID"),n=l(t,i,ht,e.reportAllChanges),et=[],$=-1,Z=null,gt(addEventListener),r=a,et.push(r),pt()})))}))},yt=function(t,e){Tt((function(e){var n=function(t){var e=t.entries[0],n={eventTarget:a(e.target),eventType:e.name,eventTime:e.startTime,eventEntry:e,loadState:r(e.startTime)};return Object.assign(t,{attribution:n})}(e);t(n)}),e)};export{M as CLSThresholds,L as FCPThresholds,ht as FIDThresholds,W as INPThresholds,it as LCPThresholds,ct as TTFBThresholds,D as onCLS,w as onFCP,yt as onFID,rt as onINP,ot as onLCP,ft as onTTFB};
diff --git a/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.umd.cjs b/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.umd.cjs
new file mode 100644
index 0000000..3d3a396
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/web-vitals.attribution.umd.cjs
@@ -0,0 +1 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).webVitals={})}(this,(function(t){"use strict";var e,n,r=function(){var t=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(t&&t.responseStart>0&&t.responseStart<performance.now())return t},i=function(t){if("loading"===document.readyState)return"loading";var e=r();if(e){if(t<e.domInteractive)return"loading";if(0===e.domContentLoadedEventStart||t<e.domContentLoadedEventStart)return"dom-interactive";if(0===e.domComplete||t<e.domComplete)return"dom-content-loaded"}return"complete"},a=function(t){var e=t.nodeName;return 1===t.nodeType?e.toLowerCase():e.toUpperCase().replace(/^#/,"")},o=function(t,e){var n="";try{for(;t&&9!==t.nodeType;){var r=t,i=r.id?"#"+r.id:a(r)+(r.classList&&r.classList.value&&r.classList.value.trim()&&r.classList.value.trim().length?"."+r.classList.value.trim().replace(/\s+/g,"."):"");if(n.length+i.length>(e||100)-1)return n||i;if(n=n?i+">"+n:i,r.id)break;t=r.parentNode}}catch(t){}return n},c=-1,s=function(){return c},u=function(t){addEventListener("pageshow",(function(e){e.persisted&&(c=e.timeStamp,t(e))}),!0)},f=function(){var t=r();return t&&t.activationStart||0},d=function(t,e){var n=r(),i="navigate";s()>=0?i="back-forward-cache":n&&(document.prerendering||f()>0?i="prerender":document.wasDiscarded?i="restore":n.type&&(i=n.type.replace(/_/g,"-")));return{name:t,value:void 0===e?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:i}},l=function(t,e,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var r=new PerformanceObserver((function(t){Promise.resolve().then((function(){e(t.getEntries())}))}));return r.observe(Object.assign({type:t,buffered:!0},n||{})),r}}catch(t){}},m=function(t,e,n,r){var i,a;return function(o){e.value>=0&&(o||r)&&((a=e.value-(i||0))||void 0===i)&&(i=e.value,e.delta=a,e.rating=function(t,e){return t>e[1]?"poor":t>e[0]?"needs-improvement":"good"}(e.value,n),t(e))}},p=function(t){requestAnimationFrame((function(){return requestAnimationFrame((function(){return t()}))}))},v=function(t){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&t()}))},h=function(t){var e=!1;return function(){e||(t(),e=!0)}},g=-1,T=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},y=function(t){"hidden"===document.visibilityState&&g>-1&&(g="visibilitychange"===t.type?t.timeStamp:0,S())},E=function(){addEventListener("visibilitychange",y,!0),addEventListener("prerenderingchange",y,!0)},S=function(){removeEventListener("visibilitychange",y,!0),removeEventListener("prerenderingchange",y,!0)},b=function(){return g<0&&(g=T(),E(),u((function(){setTimeout((function(){g=T(),E()}),0)}))),{get firstHiddenTime(){return g}}},C=function(t){document.prerendering?addEventListener("prerenderingchange",(function(){return t()}),!0):t()},L=[1800,3e3],M=function(t,e){e=e||{},C((function(){var n,r=b(),i=d("FCP"),a=l("paint",(function(t){t.forEach((function(t){"first-contentful-paint"===t.name&&(a.disconnect(),t.startTime<r.firstHiddenTime&&(i.value=Math.max(t.startTime-f(),0),i.entries.push(t),n(!0)))}))}));a&&(n=m(t,i,L,e.reportAllChanges),u((function(r){i=d("FCP"),n=m(t,i,L,e.reportAllChanges),p((function(){i.value=performance.now()-r.timeStamp,n(!0)}))})))}))},D=[.1,.25],w=0,I=1/0,x=0,F=function(t){t.forEach((function(t){t.interactionId&&(I=Math.min(I,t.interactionId),x=Math.max(x,t.interactionId),w=x?(x-I)/7+1:0)}))},P=function(){return e?w:performance.interactionCount||0},k=function(){"interactionCount"in performance||e||(e=l("event",F,{type:"event",buffered:!0,durationThreshold:0}))},A=[],B=new Map,O=0,j=function(){var t=Math.min(A.length-1,Math.floor((P()-O)/50));return A[t]},R=[],q=function(t){if(R.forEach((function(e){return e(t)})),t.interactionId||"first-input"===t.entryType){var e=A[A.length-1],n=B.get(t.interactionId);if(n||A.length<10||t.duration>e.latency){if(n)t.duration>n.latency?(n.entries=[t],n.latency=t.duration):t.duration===n.latency&&t.startTime===n.entries[0].startTime&&n.entries.push(t);else{var r={id:t.interactionId,latency:t.duration,entries:[t]};B.set(r.id,r),A.push(r)}A.sort((function(t,e){return e.latency-t.latency})),A.length>10&&A.splice(10).forEach((function(t){return B.delete(t.id)}))}}},N=function(t){var e=self.requestIdleCallback||self.setTimeout,n=-1;return t=h(t),"hidden"===document.visibilityState?t():(n=e(t),v(t)),n},H=[200,500],V=function(t,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},C((function(){var n;k();var r,i=d("INP"),a=function(t){N((function(){t.forEach(q);var e=j();e&&e.latency!==i.value&&(i.value=e.latency,i.entries=e.entries,r())}))},o=l("event",a,{durationThreshold:null!==(n=e.durationThreshold)&&void 0!==n?n:40});r=m(t,i,H,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),v((function(){a(o.takeRecords()),r(!0)})),u((function(){O=P(),A.length=0,B.clear(),i=d("INP"),r=m(t,i,H,e.reportAllChanges)})))})))},W=[],z=[],U=0,_=new WeakMap,G=new Map,J=-1,K=function(t){W=W.concat(t),Q()},Q=function(){J<0&&(J=N(X))},X=function(){G.size>10&&G.forEach((function(t,e){B.has(e)||G.delete(e)}));var t=A.map((function(t){return _.get(t.entries[0])})),e=z.length-50;z=z.filter((function(n,r){return r>=e||t.includes(n)}));for(var n=new Set,r=0;r<z.length;r++){var i=z[r];et(i.startTime,i.processingEnd).forEach((function(t){n.add(t)}))}var a=W.length-1-50;W=W.filter((function(t,e){return t.startTime>U&&e>a||n.has(t)})),J=-1};R.push((function(t){t.interactionId&&t.target&&!G.has(t.interactionId)&&G.set(t.interactionId,t.target)}),(function(t){var e,n=t.startTime+t.duration;U=Math.max(U,t.processingEnd);for(var r=z.length-1;r>=0;r--){var i=z[r];if(Math.abs(n-i.renderTime)<=8){(e=i).startTime=Math.min(t.startTime,e.startTime),e.processingStart=Math.min(t.processingStart,e.processingStart),e.processingEnd=Math.max(t.processingEnd,e.processingEnd),e.entries.push(t);break}}e||(e={startTime:t.startTime,processingStart:t.processingStart,processingEnd:t.processingEnd,renderTime:n,entries:[t]},z.push(e)),(t.interactionId||"first-input"===t.entryType)&&_.set(t,e),Q()}));var Y,Z,$,tt,et=function(t,e){for(var n,r=[],i=0;n=W[i];i++)if(!(n.startTime+n.duration<t)){if(n.startTime>e)break;r.push(n)}return r},nt=[2500,4e3],rt={},it=[800,1800],at=function t(e){document.prerendering?C((function(){return t(e)})):"complete"!==document.readyState?addEventListener("load",(function(){return t(e)}),!0):setTimeout(e,0)},ot=function(t,e){e=e||{};var n=d("TTFB"),i=m(t,n,it,e.reportAllChanges);at((function(){var a=r();a&&(n.value=Math.max(a.responseStart-f(),0),n.entries=[a],i(!0),u((function(){n=d("TTFB",0),(i=m(t,n,it,e.reportAllChanges))(!0)})))}))},ct={passive:!0,capture:!0},st=new Date,ut=function(t,e){Y||(Y=e,Z=t,$=new Date,lt(removeEventListener),ft())},ft=function(){if(Z>=0&&Z<$-st){var t={entryType:"first-input",name:Y.type,target:Y.target,cancelable:Y.cancelable,startTime:Y.timeStamp,processingStart:Y.timeStamp+Z};tt.forEach((function(e){e(t)})),tt=[]}},dt=function(t){if(t.cancelable){var e=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,e){var n=function(){ut(t,e),i()},r=function(){i()},i=function(){removeEventListener("pointerup",n,ct),removeEventListener("pointercancel",r,ct)};addEventListener("pointerup",n,ct),addEventListener("pointercancel",r,ct)}(e,t):ut(e,t)}},lt=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return t(e,dt,ct)}))},mt=[100,300],pt=function(t,e){e=e||{},C((function(){var n,r=b(),i=d("FID"),a=function(t){t.startTime<r.firstHiddenTime&&(i.value=t.processingStart-t.startTime,i.entries.push(t),n(!0))},o=function(t){t.forEach(a)},c=l("first-input",o);n=m(t,i,mt,e.reportAllChanges),c&&(v(h((function(){o(c.takeRecords()),c.disconnect()}))),u((function(){var r;i=d("FID"),n=m(t,i,mt,e.reportAllChanges),tt=[],Z=-1,Y=null,lt(addEventListener),r=a,tt.push(r),ft()})))}))};t.CLSThresholds=D,t.FCPThresholds=L,t.FIDThresholds=mt,t.INPThresholds=H,t.LCPThresholds=nt,t.TTFBThresholds=it,t.onCLS=function(t,e){!function(t,e){e=e||{},M(h((function(){var n,r=d("CLS",0),i=0,a=[],o=function(t){t.forEach((function(t){if(!t.hadRecentInput){var e=a[0],n=a[a.length-1];i&&t.startTime-n.startTime<1e3&&t.startTime-e.startTime<5e3?(i+=t.value,a.push(t)):(i=t.value,a=[t])}})),i>r.value&&(r.value=i,r.entries=a,n())},c=l("layout-shift",o);c&&(n=m(t,r,D,e.reportAllChanges),v((function(){o(c.takeRecords()),n(!0)})),u((function(){i=0,r=d("CLS",0),n=m(t,r,D,e.reportAllChanges),p((function(){return n()}))})),setTimeout(n,0))})))}((function(e){var n=function(t){var e,n={};if(t.entries.length){var r=t.entries.reduce((function(t,e){return t&&t.value>e.value?t:e}));if(r&&r.sources&&r.sources.length){var a=(e=r.sources).find((function(t){return t.node&&1===t.node.nodeType}))||e[0];a&&(n={largestShiftTarget:o(a.node),largestShiftTime:r.startTime,largestShiftValue:r.value,largestShiftSource:a,largestShiftEntry:r,loadState:i(r.startTime)})}}return Object.assign(t,{attribution:n})}(e);t(n)}),e)},t.onFCP=function(t,e){M((function(e){var n=function(t){var e={timeToFirstByte:0,firstByteToFCP:t.value,loadState:i(s())};if(t.entries.length){var n=r(),a=t.entries[t.entries.length-1];if(n){var o=n.activationStart||0,c=Math.max(0,n.responseStart-o);e={timeToFirstByte:c,firstByteToFCP:t.value-c,loadState:i(t.entries[0].startTime),navigationEntry:n,fcpEntry:a}}}return Object.assign(t,{attribution:e})}(e);t(n)}),e)},t.onFID=function(t,e){pt((function(e){var n=function(t){var e=t.entries[0],n={eventTarget:o(e.target),eventType:e.name,eventTime:e.startTime,eventEntry:e,loadState:i(e.startTime)};return Object.assign(t,{attribution:n})}(e);t(n)}),e)},t.onINP=function(t,e){n||(n=l("long-animation-frame",K)),V((function(e){var n=function(t){var e=t.entries[0],n=_.get(e),r=e.processingStart,a=n.processingEnd,c=n.entries.sort((function(t,e){return t.processingStart-e.processingStart})),s=et(e.startTime,a),u=t.entries.find((function(t){return t.target})),f=u&&u.target||G.get(e.interactionId),d=[e.startTime+e.duration,a].concat(s.map((function(t){return t.startTime+t.duration}))),l=Math.max.apply(Math,d),m={interactionTarget:o(f),interactionTargetElement:f,interactionType:e.name.startsWith("key")?"keyboard":"pointer",interactionTime:e.startTime,nextPaintTime:l,processedEventEntries:c,longAnimationFrameEntries:s,inputDelay:r-e.startTime,processingDuration:a-r,presentationDelay:Math.max(l-a,0),loadState:i(e.startTime)};return Object.assign(t,{attribution:m})}(e);t(n)}),e)},t.onLCP=function(t,e){!function(t,e){e=e||{},C((function(){var n,r=b(),i=d("LCP"),a=function(t){e.reportAllChanges||(t=t.slice(-1)),t.forEach((function(t){t.startTime<r.firstHiddenTime&&(i.value=Math.max(t.startTime-f(),0),i.entries=[t],n())}))},o=l("largest-contentful-paint",a);if(o){n=m(t,i,nt,e.reportAllChanges);var c=h((function(){rt[i.id]||(a(o.takeRecords()),o.disconnect(),rt[i.id]=!0,n(!0))}));["keydown","click"].forEach((function(t){addEventListener(t,(function(){return N(c)}),{once:!0,capture:!0})})),v(c),u((function(r){i=d("LCP"),n=m(t,i,nt,e.reportAllChanges),p((function(){i.value=performance.now()-r.timeStamp,rt[i.id]=!0,n(!0)}))}))}}))}((function(e){var n=function(t){var e={timeToFirstByte:0,resourceLoadDelay:0,resourceLoadDuration:0,elementRenderDelay:t.value};if(t.entries.length){var n=r();if(n){var i=n.activationStart||0,a=t.entries[t.entries.length-1],c=a.url&&performance.getEntriesByType("resource").filter((function(t){return t.name===a.url}))[0],s=Math.max(0,n.responseStart-i),u=Math.max(s,c?(c.requestStart||c.startTime)-i:0),f=Math.max(u,c?c.responseEnd-i:0),d=Math.max(f,a.startTime-i);e={element:o(a.element),timeToFirstByte:s,resourceLoadDelay:u-s,resourceLoadDuration:f-u,elementRenderDelay:d-f,navigationEntry:n,lcpEntry:a},a.url&&(e.url=a.url),c&&(e.lcpResourceEntry=c)}}return Object.assign(t,{attribution:e})}(e);t(n)}),e)},t.onTTFB=function(t,e){ot((function(e){var n=function(t){var e={waitingDuration:0,cacheDuration:0,dnsDuration:0,connectionDuration:0,requestDuration:0};if(t.entries.length){var n=t.entries[0],r=n.activationStart||0,i=Math.max((n.workerStart||n.fetchStart)-r,0),a=Math.max(n.domainLookupStart-r,0),o=Math.max(n.connectStart-r,0),c=Math.max(n.connectEnd-r,0);e={waitingDuration:i,cacheDuration:a-i,dnsDuration:o-a,connectionDuration:c-o,requestDuration:t.value-c,navigationEntry:n}}return Object.assign(t,{attribution:e})}(e);t(n)}),e)}}));
diff --git a/frontend-old/node_modules/web-vitals/dist/web-vitals.iife.js b/frontend-old/node_modules/web-vitals/dist/web-vitals.iife.js
new file mode 100644
index 0000000..075dee8
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/web-vitals.iife.js
@@ -0,0 +1 @@
+var webVitals=function(e){"use strict";var n,t,r,i,o,a=-1,c=function(e){addEventListener("pageshow",(function(n){n.persisted&&(a=n.timeStamp,e(n))}),!0)},u=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},s=function(){var e=u();return e&&e.activationStart||0},f=function(e,n){var t=u(),r="navigate";a>=0?r="back-forward-cache":t&&(document.prerendering||s()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-")));return{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},d=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},l=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},p=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},v=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e()}))},m=function(e){var n=!1;return function(){n||(e(),n=!0)}},h=-1,g=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},T=function(e){"hidden"===document.visibilityState&&h>-1&&(h="visibilitychange"===e.type?e.timeStamp:0,E())},y=function(){addEventListener("visibilitychange",T,!0),addEventListener("prerenderingchange",T,!0)},E=function(){removeEventListener("visibilitychange",T,!0),removeEventListener("prerenderingchange",T,!0)},C=function(){return h<0&&(h=g(),y(),c((function(){setTimeout((function(){h=g(),y()}),0)}))),{get firstHiddenTime(){return h}}},L=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},S=[1800,3e3],b=function(e,n){n=n||{},L((function(){var t,r=C(),i=f("FCP"),o=d("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-s(),0),i.entries.push(e),t(!0)))}))}));o&&(t=l(e,i,S,n.reportAllChanges),c((function(r){i=f("FCP"),t=l(e,i,S,n.reportAllChanges),p((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},w=[.1,.25],I=0,P=1/0,A=0,F=function(e){e.forEach((function(e){e.interactionId&&(P=Math.min(P,e.interactionId),A=Math.max(A,e.interactionId),I=A?(A-P)/7+1:0)}))},M=function(){return n?I:performance.interactionCount||0},k=function(){"interactionCount"in performance||n||(n=d("event",F,{type:"event",buffered:!0,durationThreshold:0}))},D=[],B=new Map,R=0,x=function(){var e=Math.min(D.length-1,Math.floor((M()-R)/50));return D[e]},H=[],N=function(e){if(H.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=D[D.length-1],t=B.get(e.interactionId);if(t||D.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};B.set(r.id,r),D.push(r)}D.sort((function(e,n){return n.latency-e.latency})),D.length>10&&D.splice(10).forEach((function(e){return B.delete(e.id)}))}}},q=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=m(e),"hidden"===document.visibilityState?e():(t=n(e),v(e)),t},O=[200,500],j=[2500,4e3],V={},_=[800,1800],z=function e(n){document.prerendering?L((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},G={passive:!0,capture:!0},J=new Date,K=function(e,n){t||(t=n,r=e,i=new Date,W(removeEventListener),Q())},Q=function(){if(r>=0&&r<i-J){var e={entryType:"first-input",name:t.type,target:t.target,cancelable:t.cancelable,startTime:t.timeStamp,processingStart:t.timeStamp+r};o.forEach((function(n){n(e)})),o=[]}},U=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){K(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,G),removeEventListener("pointercancel",r,G)};addEventListener("pointerup",t,G),addEventListener("pointercancel",r,G)}(n,e):K(n,e)}},W=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,U,G)}))},X=[100,300];return e.CLSThresholds=w,e.FCPThresholds=S,e.FIDThresholds=X,e.INPThresholds=O,e.LCPThresholds=j,e.TTFBThresholds=_,e.onCLS=function(e,n){n=n||{},b(m((function(){var t,r=f("CLS",0),i=0,o=[],a=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,t())},u=d("layout-shift",a);u&&(t=l(e,r,w,n.reportAllChanges),v((function(){a(u.takeRecords()),t(!0)})),c((function(){i=0,r=f("CLS",0),t=l(e,r,w,n.reportAllChanges),p((function(){return t()}))})),setTimeout(t,0))})))},e.onFCP=b,e.onFID=function(e,n){n=n||{},L((function(){var i,a=C(),u=f("FID"),s=function(e){e.startTime<a.firstHiddenTime&&(u.value=e.processingStart-e.startTime,u.entries.push(e),i(!0))},p=function(e){e.forEach(s)},h=d("first-input",p);i=l(e,u,X,n.reportAllChanges),h&&(v(m((function(){p(h.takeRecords()),h.disconnect()}))),c((function(){var a;u=f("FID"),i=l(e,u,X,n.reportAllChanges),o=[],r=-1,t=null,W(addEventListener),a=s,o.push(a),Q()})))}))},e.onINP=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},L((function(){var t;k();var r,i=f("INP"),o=function(e){q((function(){e.forEach(N);var n=x();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r())}))},a=d("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=l(e,i,O,n.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),v((function(){o(a.takeRecords()),r(!0)})),c((function(){R=M(),D.length=0,B.clear(),i=f("INP"),r=l(e,i,O,n.reportAllChanges)})))})))},e.onLCP=function(e,n){n=n||{},L((function(){var t,r=C(),i=f("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-s(),0),i.entries=[e],t())}))},a=d("largest-contentful-paint",o);if(a){t=l(e,i,j,n.reportAllChanges);var u=m((function(){V[i.id]||(o(a.takeRecords()),a.disconnect(),V[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return q(u)}),{once:!0,capture:!0})})),v(u),c((function(r){i=f("LCP"),t=l(e,i,j,n.reportAllChanges),p((function(){i.value=performance.now()-r.timeStamp,V[i.id]=!0,t(!0)}))}))}}))},e.onTTFB=function(e,n){n=n||{};var t=f("TTFB"),r=l(e,t,_,n.reportAllChanges);z((function(){var i=u();i&&(t.value=Math.max(i.responseStart-s(),0),t.entries=[i],r(!0),c((function(){t=f("TTFB",0),(r=l(e,t,_,n.reportAllChanges))(!0)})))}))},e}({});
diff --git a/frontend-old/node_modules/web-vitals/dist/web-vitals.js b/frontend-old/node_modules/web-vitals/dist/web-vitals.js
new file mode 100644
index 0000000..357cffe
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/web-vitals.js
@@ -0,0 +1 @@
+var e,n,t,r,i,o=-1,a=function(e){addEventListener("pageshow",(function(n){n.persisted&&(o=n.timeStamp,e(n))}),!0)},c=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},u=function(){var e=c();return e&&e.activationStart||0},f=function(e,n){var t=c(),r="navigate";o>=0?r="back-forward-cache":t&&(document.prerendering||u()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-")));return{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},s=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},d=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},l=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},p=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e()}))},v=function(e){var n=!1;return function(){n||(e(),n=!0)}},m=-1,h=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},g=function(e){"hidden"===document.visibilityState&&m>-1&&(m="visibilitychange"===e.type?e.timeStamp:0,T())},y=function(){addEventListener("visibilitychange",g,!0),addEventListener("prerenderingchange",g,!0)},T=function(){removeEventListener("visibilitychange",g,!0),removeEventListener("prerenderingchange",g,!0)},E=function(){return m<0&&(m=h(),y(),a((function(){setTimeout((function(){m=h(),y()}),0)}))),{get firstHiddenTime(){return m}}},C=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},b=[1800,3e3],S=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("FCP"),o=s("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries.push(e),t(!0)))}))}));o&&(t=d(e,i,b,n.reportAllChanges),a((function(r){i=f("FCP"),t=d(e,i,b,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},L=[.1,.25],w=function(e,n){n=n||{},S(v((function(){var t,r=f("CLS",0),i=0,o=[],c=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,t())},u=s("layout-shift",c);u&&(t=d(e,r,L,n.reportAllChanges),p((function(){c(u.takeRecords()),t(!0)})),a((function(){i=0,r=f("CLS",0),t=d(e,r,L,n.reportAllChanges),l((function(){return t()}))})),setTimeout(t,0))})))},A=0,I=1/0,P=0,M=function(e){e.forEach((function(e){e.interactionId&&(I=Math.min(I,e.interactionId),P=Math.max(P,e.interactionId),A=P?(P-I)/7+1:0)}))},k=function(){return e?A:performance.interactionCount||0},F=function(){"interactionCount"in performance||e||(e=s("event",M,{type:"event",buffered:!0,durationThreshold:0}))},D=[],x=new Map,R=0,B=function(){var e=Math.min(D.length-1,Math.floor((k()-R)/50));return D[e]},H=[],q=function(e){if(H.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=D[D.length-1],t=x.get(e.interactionId);if(t||D.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};x.set(r.id,r),D.push(r)}D.sort((function(e,n){return n.latency-e.latency})),D.length>10&&D.splice(10).forEach((function(e){return x.delete(e.id)}))}}},O=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=v(e),"hidden"===document.visibilityState?e():(t=n(e),p(e)),t},N=[200,500],j=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},C((function(){var t;F();var r,i=f("INP"),o=function(e){O((function(){e.forEach(q);var n=B();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r())}))},c=s("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=d(e,i,N,n.reportAllChanges),c&&(c.observe({type:"first-input",buffered:!0}),p((function(){o(c.takeRecords()),r(!0)})),a((function(){R=k(),D.length=0,x.clear(),i=f("INP"),r=d(e,i,N,n.reportAllChanges)})))})))},_=[2500,4e3],z={},G=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries=[e],t())}))},c=s("largest-contentful-paint",o);if(c){t=d(e,i,_,n.reportAllChanges);var m=v((function(){z[i.id]||(o(c.takeRecords()),c.disconnect(),z[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return O(m)}),{once:!0,capture:!0})})),p(m),a((function(r){i=f("LCP"),t=d(e,i,_,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,z[i.id]=!0,t(!0)}))}))}}))},J=[800,1800],K=function e(n){document.prerendering?C((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},Q=function(e,n){n=n||{};var t=f("TTFB"),r=d(e,t,J,n.reportAllChanges);K((function(){var i=c();i&&(t.value=Math.max(i.responseStart-u(),0),t.entries=[i],r(!0),a((function(){t=f("TTFB",0),(r=d(e,t,J,n.reportAllChanges))(!0)})))}))},U={passive:!0,capture:!0},V=new Date,W=function(e,i){n||(n=i,t=e,r=new Date,Z(removeEventListener),X())},X=function(){if(t>=0&&t<r-V){var e={entryType:"first-input",name:n.type,target:n.target,cancelable:n.cancelable,startTime:n.timeStamp,processingStart:n.timeStamp+t};i.forEach((function(n){n(e)})),i=[]}},Y=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){W(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,U),removeEventListener("pointercancel",r,U)};addEventListener("pointerup",t,U),addEventListener("pointercancel",r,U)}(n,e):W(n,e)}},Z=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,Y,U)}))},$=[100,300],ee=function(e,r){r=r||{},C((function(){var o,c=E(),u=f("FID"),l=function(e){e.startTime<c.firstHiddenTime&&(u.value=e.processingStart-e.startTime,u.entries.push(e),o(!0))},m=function(e){e.forEach(l)},h=s("first-input",m);o=d(e,u,$,r.reportAllChanges),h&&(p(v((function(){m(h.takeRecords()),h.disconnect()}))),a((function(){var a;u=f("FID"),o=d(e,u,$,r.reportAllChanges),i=[],t=-1,n=null,Z(addEventListener),a=l,i.push(a),X()})))}))};export{L as CLSThresholds,b as FCPThresholds,$ as FIDThresholds,N as INPThresholds,_ as LCPThresholds,J as TTFBThresholds,w as onCLS,S as onFCP,ee as onFID,j as onINP,G as onLCP,Q as onTTFB};
diff --git a/frontend-old/node_modules/web-vitals/dist/web-vitals.umd.cjs b/frontend-old/node_modules/web-vitals/dist/web-vitals.umd.cjs
new file mode 100644
index 0000000..1f40e68
--- /dev/null
+++ b/frontend-old/node_modules/web-vitals/dist/web-vitals.umd.cjs
@@ -0,0 +1 @@
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).webVitals={})}(this,(function(e){"use strict";var n,t,r,i,o,a=-1,c=function(e){addEventListener("pageshow",(function(n){n.persisted&&(a=n.timeStamp,e(n))}),!0)},u=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},s=function(){var e=u();return e&&e.activationStart||0},f=function(e,n){var t=u(),r="navigate";a>=0?r="back-forward-cache":t&&(document.prerendering||s()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-")));return{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},d=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},l=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},p=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},v=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e()}))},m=function(e){var n=!1;return function(){n||(e(),n=!0)}},h=-1,g=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},T=function(e){"hidden"===document.visibilityState&&h>-1&&(h="visibilitychange"===e.type?e.timeStamp:0,E())},y=function(){addEventListener("visibilitychange",T,!0),addEventListener("prerenderingchange",T,!0)},E=function(){removeEventListener("visibilitychange",T,!0),removeEventListener("prerenderingchange",T,!0)},C=function(){return h<0&&(h=g(),y(),c((function(){setTimeout((function(){h=g(),y()}),0)}))),{get firstHiddenTime(){return h}}},b=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},L=[1800,3e3],S=function(e,n){n=n||{},b((function(){var t,r=C(),i=f("FCP"),o=d("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-s(),0),i.entries.push(e),t(!0)))}))}));o&&(t=l(e,i,L,n.reportAllChanges),c((function(r){i=f("FCP"),t=l(e,i,L,n.reportAllChanges),p((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},w=[.1,.25],I=0,P=1/0,A=0,F=function(e){e.forEach((function(e){e.interactionId&&(P=Math.min(P,e.interactionId),A=Math.max(A,e.interactionId),I=A?(A-P)/7+1:0)}))},M=function(){return n?I:performance.interactionCount||0},k=function(){"interactionCount"in performance||n||(n=d("event",F,{type:"event",buffered:!0,durationThreshold:0}))},D=[],x=new Map,B=0,R=function(){var e=Math.min(D.length-1,Math.floor((M()-B)/50));return D[e]},H=[],N=function(e){if(H.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=D[D.length-1],t=x.get(e.interactionId);if(t||D.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};x.set(r.id,r),D.push(r)}D.sort((function(e,n){return n.latency-e.latency})),D.length>10&&D.splice(10).forEach((function(e){return x.delete(e.id)}))}}},q=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=m(e),"hidden"===document.visibilityState?e():(t=n(e),v(e)),t},O=[200,500],j=[2500,4e3],V={},_=[800,1800],z=function e(n){document.prerendering?b((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},G={passive:!0,capture:!0},J=new Date,K=function(e,n){t||(t=n,r=e,i=new Date,W(removeEventListener),Q())},Q=function(){if(r>=0&&r<i-J){var e={entryType:"first-input",name:t.type,target:t.target,cancelable:t.cancelable,startTime:t.timeStamp,processingStart:t.timeStamp+r};o.forEach((function(n){n(e)})),o=[]}},U=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){K(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,G),removeEventListener("pointercancel",r,G)};addEventListener("pointerup",t,G),addEventListener("pointercancel",r,G)}(n,e):K(n,e)}},W=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,U,G)}))},X=[100,300];e.CLSThresholds=w,e.FCPThresholds=L,e.FIDThresholds=X,e.INPThresholds=O,e.LCPThresholds=j,e.TTFBThresholds=_,e.onCLS=function(e,n){n=n||{},S(m((function(){var t,r=f("CLS",0),i=0,o=[],a=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,t())},u=d("layout-shift",a);u&&(t=l(e,r,w,n.reportAllChanges),v((function(){a(u.takeRecords()),t(!0)})),c((function(){i=0,r=f("CLS",0),t=l(e,r,w,n.reportAllChanges),p((function(){return t()}))})),setTimeout(t,0))})))},e.onFCP=S,e.onFID=function(e,n){n=n||{},b((function(){var i,a=C(),u=f("FID"),s=function(e){e.startTime<a.firstHiddenTime&&(u.value=e.processingStart-e.startTime,u.entries.push(e),i(!0))},p=function(e){e.forEach(s)},h=d("first-input",p);i=l(e,u,X,n.reportAllChanges),h&&(v(m((function(){p(h.takeRecords()),h.disconnect()}))),c((function(){var a;u=f("FID"),i=l(e,u,X,n.reportAllChanges),o=[],r=-1,t=null,W(addEventListener),a=s,o.push(a),Q()})))}))},e.onINP=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},b((function(){var t;k();var r,i=f("INP"),o=function(e){q((function(){e.forEach(N);var n=R();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r())}))},a=d("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=l(e,i,O,n.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),v((function(){o(a.takeRecords()),r(!0)})),c((function(){B=M(),D.length=0,x.clear(),i=f("INP"),r=l(e,i,O,n.reportAllChanges)})))})))},e.onLCP=function(e,n){n=n||{},b((function(){var t,r=C(),i=f("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-s(),0),i.entries=[e],t())}))},a=d("largest-contentful-paint",o);if(a){t=l(e,i,j,n.reportAllChanges);var u=m((function(){V[i.id]||(o(a.takeRecords()),a.disconnect(),V[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return q(u)}),{once:!0,capture:!0})})),v(u),c((function(r){i=f("LCP"),t=l(e,i,j,n.reportAllChanges),p((function(){i.value=performance.now()-r.timeStamp,V[i.id]=!0,t(!0)}))}))}}))},e.onTTFB=function(e,n){n=n||{};var t=f("TTFB"),r=l(e,t,_,n.reportAllChanges);z((function(){var i=u();i&&(t.value=Math.max(i.responseStart-s(),0),t.entries=[i],r(!0),c((function(){t=f("TTFB",0),(r=l(e,t,_,n.reportAllChanges))(!0)})))}))}}));