lighthouse 9.5.0-dev.20220908 → 9.5.0-dev.20220909
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +1 -1
- package/cli/test/smokehouse/lighthouse-runners/bundle.js +1 -1
- package/core/gather/driver/execution-context.js +1 -1
- package/core/gather/gatherers/accessibility.js +1 -1
- package/core/gather/gatherers/anchor-elements.js +2 -2
- package/core/gather/gatherers/dobetterweb/domstats.js +1 -1
- package/core/gather/gatherers/dobetterweb/password-inputs-with-prevented-paste.js +1 -1
- package/core/gather/gatherers/full-page-screenshot.js +1 -1
- package/core/gather/gatherers/iframe-elements.js +3 -3
- package/core/gather/gatherers/image-elements.js +3 -3
- package/core/gather/gatherers/inputs.js +2 -2
- package/core/gather/gatherers/link-elements.js +1 -1
- package/core/gather/gatherers/meta-elements.js +1 -1
- package/core/gather/gatherers/script-elements.js +1 -1
- package/core/gather/gatherers/seo/embedded-content.js +1 -1
- package/core/gather/gatherers/seo/font-size.js +1 -1
- package/core/gather/gatherers/seo/tap-targets.js +1 -1
- package/core/gather/gatherers/trace-elements.js +1 -1
- package/core/index.js +4 -4
- package/core/{config → legacy/config}/config.js +7 -7
- package/core/{config → legacy/config}/legacy-default-config.js +1 -1
- package/core/{gather → legacy/gather}/connections/connection.js +1 -1
- package/core/{gather → legacy/gather}/connections/cri.js +1 -1
- package/core/{gather → legacy/gather}/connections/raw.js +0 -0
- package/core/{gather → legacy/gather}/driver.js +7 -7
- package/core/{gather → legacy/gather}/gather-runner.js +19 -19
- package/core/lib/page-functions.js +11 -18
- package/core/runner.js +5 -4
- package/package.json +1 -1
- package/tsconfig.json +1 -1
- package/types/gatherer.d.ts +1 -1
package/CONTRIBUTING.md
CHANGED
|
@@ -128,7 +128,7 @@ accept your pull requests.
|
|
|
128
128
|
|
|
129
129
|
## Tracking Errors
|
|
130
130
|
|
|
131
|
-
We track our errors in the wild with Sentry. In general, do not worry about wrapping your audits or gatherers in try/catch blocks and reporting every error that could possibly occur; `core/runner.js` and `core/
|
|
131
|
+
We track our errors in the wild with Sentry. In general, do not worry about wrapping your audits or gatherers in try/catch blocks and reporting every error that could possibly occur; `core/runner.js` and `core/fraggle-rock/gather/*-runner.js` already catch and report any errors that occur while running a gatherer or audit, including errors fatal to the entire run. However, there are some situations when you might want to explicitly handle an error and report it to Sentry or wrap it to avoid reporting. Generally, you can interact with Sentry simply by requiring the `core/lib/sentry.js` file and call its methods. The module exports a delegate that will correctly handle the error reporting based on the user's opt-in preference and will simply no-op if they haven't so you don't need to check.
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
#### If you have an expected error that is recoverable but want to track how frequently it happens, *use Sentry.captureException*.
|
|
@@ -19,7 +19,7 @@ import {once} from 'events';
|
|
|
19
19
|
import puppeteer from 'puppeteer-core';
|
|
20
20
|
import ChromeLauncher from 'chrome-launcher';
|
|
21
21
|
|
|
22
|
-
import {CriConnection} from '../../../../core/gather/connections/cri.js';
|
|
22
|
+
import {CriConnection} from '../../../../core/legacy/gather/connections/cri.js';
|
|
23
23
|
import {LH_ROOT} from '../../../../root.js';
|
|
24
24
|
import {loadArtifacts, saveArtifacts} from '../../../../core/lib/asset-saver.js';
|
|
25
25
|
|
|
@@ -110,7 +110,7 @@ class ExecutionContext {
|
|
|
110
110
|
return new Promise(function (resolve) {
|
|
111
111
|
return Promise.resolve()
|
|
112
112
|
.then(_ => ${expression})
|
|
113
|
-
.catch(${pageFunctions.
|
|
113
|
+
.catch(${pageFunctions.wrapRuntimeEvalErrorInBrowser})
|
|
114
114
|
.then(resolve);
|
|
115
115
|
});
|
|
116
116
|
}())
|
|
@@ -106,8 +106,8 @@ class AnchorElements extends FRGatherer {
|
|
|
106
106
|
args: [],
|
|
107
107
|
useIsolation: true,
|
|
108
108
|
deps: [
|
|
109
|
-
pageFunctions.
|
|
110
|
-
pageFunctions.
|
|
109
|
+
pageFunctions.getElementsInDocument,
|
|
110
|
+
pageFunctions.getNodeDetails,
|
|
111
111
|
],
|
|
112
112
|
});
|
|
113
113
|
await session.sendCommand('DOM.enable');
|
|
@@ -92,7 +92,7 @@ class DOMStats extends FRGatherer {
|
|
|
92
92
|
const results = await driver.executionContext.evaluate(getDOMStats, {
|
|
93
93
|
args: [],
|
|
94
94
|
useIsolation: true,
|
|
95
|
-
deps: [pageFunctions.
|
|
95
|
+
deps: [pageFunctions.getNodeDetails],
|
|
96
96
|
});
|
|
97
97
|
await driver.defaultSession.sendCommand('DOM.disable');
|
|
98
98
|
return results;
|
|
@@ -40,7 +40,7 @@ class PasswordInputsWithPreventedPaste extends FRGatherer {
|
|
|
40
40
|
getArtifact(passContext) {
|
|
41
41
|
return passContext.driver.executionContext.evaluate(findPasswordInputsWithPreventedPaste, {
|
|
42
42
|
args: [],
|
|
43
|
-
deps: [pageFunctions.
|
|
43
|
+
deps: [pageFunctions.getNodeDetails],
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -163,7 +163,7 @@ class FullPageScreenshot extends FRGatherer {
|
|
|
163
163
|
return context.driver.executionContext.evaluate(resolveNodes, {
|
|
164
164
|
args: [],
|
|
165
165
|
useIsolation,
|
|
166
|
-
deps: [pageFunctions.
|
|
166
|
+
deps: [pageFunctions.getBoundingClientRect],
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -55,9 +55,9 @@ class IFrameElements extends FRGatherer {
|
|
|
55
55
|
args: [],
|
|
56
56
|
useIsolation: true,
|
|
57
57
|
deps: [
|
|
58
|
-
pageFunctions.
|
|
59
|
-
pageFunctions.
|
|
60
|
-
pageFunctions.
|
|
58
|
+
pageFunctions.getElementsInDocument,
|
|
59
|
+
pageFunctions.isPositionFixed,
|
|
60
|
+
pageFunctions.getNodeDetails,
|
|
61
61
|
],
|
|
62
62
|
});
|
|
63
63
|
return iframeElements;
|
|
@@ -344,9 +344,9 @@ class ImageElements extends FRGatherer {
|
|
|
344
344
|
args: [],
|
|
345
345
|
useIsolation: true,
|
|
346
346
|
deps: [
|
|
347
|
-
pageFunctions.
|
|
348
|
-
pageFunctions.
|
|
349
|
-
pageFunctions.
|
|
347
|
+
pageFunctions.getElementsInDocument,
|
|
348
|
+
pageFunctions.getBoundingClientRect,
|
|
349
|
+
pageFunctions.getNodeDetails,
|
|
350
350
|
getClientRect,
|
|
351
351
|
getPosition,
|
|
352
352
|
getHTMLImages,
|
|
@@ -102,8 +102,8 @@ class Inputs extends FRGatherer {
|
|
|
102
102
|
args: [],
|
|
103
103
|
useIsolation: true,
|
|
104
104
|
deps: [
|
|
105
|
-
pageFunctions.
|
|
106
|
-
pageFunctions.
|
|
105
|
+
pageFunctions.getElementsInDocument,
|
|
106
|
+
pageFunctions.getNodeDetails,
|
|
107
107
|
],
|
|
108
108
|
});
|
|
109
109
|
}
|
|
@@ -22,7 +22,7 @@ const MINIMAL_LEGIBLE_FONT_SIZE_PX = 12;
|
|
|
22
22
|
// limit number of protocol calls to make sure that gatherer doesn't take more than 1-2s
|
|
23
23
|
const MAX_NODES_SOURCE_RULE_FETCHED = 50; // number of nodes to fetch the source font-size rule
|
|
24
24
|
|
|
25
|
-
/** @typedef {import('
|
|
25
|
+
/** @typedef {import('../../../legacy/gather/driver.js')} Driver */
|
|
26
26
|
/** @typedef {LH.Artifacts.FontSize['analyzedFailingNodesData'][0]} NodeFontData */
|
|
27
27
|
/** @typedef {Map<number, {fontSize: number, textLength: number}>} BackendIdsToFontData */
|
|
28
28
|
|
|
@@ -341,7 +341,7 @@ class TapTargets extends FRGatherer {
|
|
|
341
341
|
args: [tapTargetsSelector, className],
|
|
342
342
|
useIsolation: true,
|
|
343
343
|
deps: [
|
|
344
|
-
pageFunctions.
|
|
344
|
+
pageFunctions.getNodeDetails,
|
|
345
345
|
pageFunctions.getElementsInDocument,
|
|
346
346
|
disableFixedAndStickyElementPointerEvents,
|
|
347
347
|
elementIsVisible,
|
|
@@ -295,7 +295,7 @@ class TraceElements extends FRGatherer {
|
|
|
295
295
|
objectId,
|
|
296
296
|
functionDeclaration: `function () {
|
|
297
297
|
${getNodeDetailsData.toString()};
|
|
298
|
-
${pageFunctions.
|
|
298
|
+
${pageFunctions.getNodeDetails};
|
|
299
299
|
return getNodeDetailsData.call(this);
|
|
300
300
|
}`,
|
|
301
301
|
returnByValue: true,
|
package/core/index.js
CHANGED
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
import log from 'lighthouse-logger';
|
|
8
8
|
|
|
9
9
|
import {Runner} from './runner.js';
|
|
10
|
-
import {CriConnection} from './gather/connections/cri.js';
|
|
11
|
-
import {Config} from './config/config.js';
|
|
10
|
+
import {CriConnection} from './legacy/gather/connections/cri.js';
|
|
11
|
+
import {Config} from './legacy/config/config.js';
|
|
12
12
|
import UrlUtils from './lib/url-utils.js';
|
|
13
13
|
import * as fraggleRock from './fraggle-rock/api.js';
|
|
14
|
-
import {Driver} from './gather/driver.js';
|
|
14
|
+
import {Driver} from './legacy/gather/driver.js';
|
|
15
15
|
import {initializeConfig} from './fraggle-rock/config/config.js';
|
|
16
16
|
|
|
17
|
-
/** @typedef {import('./gather/connections/connection.js').Connection} Connection */
|
|
17
|
+
/** @typedef {import('./legacy/gather/connections/connection.js').Connection} Connection */
|
|
18
18
|
|
|
19
19
|
/*
|
|
20
20
|
* The relationship between these root modules:
|
|
@@ -9,10 +9,10 @@ import path from 'path';
|
|
|
9
9
|
import log from 'lighthouse-logger';
|
|
10
10
|
|
|
11
11
|
import legacyDefaultConfig from './legacy-default-config.js';
|
|
12
|
-
import * as constants from '
|
|
13
|
-
import * as format from '
|
|
14
|
-
import * as validation from '
|
|
15
|
-
import {Runner} from '
|
|
12
|
+
import * as constants from '../../config/constants.js';
|
|
13
|
+
import * as format from '../../../shared/localization/format.js';
|
|
14
|
+
import * as validation from '../../fraggle-rock/config/validation.js';
|
|
15
|
+
import {Runner} from '../../runner.js';
|
|
16
16
|
import {
|
|
17
17
|
mergePlugins,
|
|
18
18
|
mergeConfigFragment,
|
|
@@ -21,12 +21,12 @@ import {
|
|
|
21
21
|
resolveGathererToDefn,
|
|
22
22
|
deepClone,
|
|
23
23
|
deepCloneConfigJson,
|
|
24
|
-
} from '
|
|
25
|
-
import {getModuleDirectory} from '
|
|
24
|
+
} from '../../config/config-helpers.js';
|
|
25
|
+
import {getModuleDirectory} from '../../../esm-utils.js';
|
|
26
26
|
|
|
27
27
|
const defaultConfigPath = './legacy-default-config.js';
|
|
28
28
|
|
|
29
|
-
/** @typedef {typeof import('
|
|
29
|
+
/** @typedef {typeof import('../../gather/gatherers/gatherer.js').Gatherer} GathererConstructor */
|
|
30
30
|
/** @typedef {InstanceType<GathererConstructor>} Gatherer */
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @fileoverview Construct the legacy default config from the standard default config.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import defaultConfig from '
|
|
11
|
+
import defaultConfig from '../../config/default-config.js';
|
|
12
12
|
|
|
13
13
|
/** @type {LH.Config.Json} */
|
|
14
14
|
const legacyDefaultConfig = JSON.parse(JSON.stringify(defaultConfig));
|
|
@@ -8,7 +8,7 @@ import {EventEmitter} from 'events';
|
|
|
8
8
|
|
|
9
9
|
import log from 'lighthouse-logger';
|
|
10
10
|
|
|
11
|
-
import {LighthouseError} from '
|
|
11
|
+
import {LighthouseError} from '../../../lib/lh-error.js';
|
|
12
12
|
|
|
13
13
|
// TODO(bckenny): CommandCallback properties should be tied by command type after
|
|
14
14
|
// https://github.com/Microsoft/TypeScript/pull/22348. See driver.js TODO.
|
|
@@ -10,7 +10,7 @@ import WebSocket from 'ws';
|
|
|
10
10
|
import log from 'lighthouse-logger';
|
|
11
11
|
|
|
12
12
|
import {Connection} from './connection.js';
|
|
13
|
-
import {LighthouseError} from '
|
|
13
|
+
import {LighthouseError} from '../../../lib/lh-error.js';
|
|
14
14
|
|
|
15
15
|
const DEFAULT_HOSTNAME = '127.0.0.1';
|
|
16
16
|
const CONNECT_TIMEOUT = 10000;
|
|
File without changes
|
|
@@ -8,13 +8,13 @@ import {EventEmitter} from 'events';
|
|
|
8
8
|
|
|
9
9
|
import log from 'lighthouse-logger';
|
|
10
10
|
|
|
11
|
-
import {Fetcher} from '
|
|
12
|
-
import {ExecutionContext} from '
|
|
13
|
-
import {LighthouseError} from '
|
|
14
|
-
import {fetchResponseBodyFromCache} from '
|
|
15
|
-
import {DevtoolsMessageLog} from '
|
|
16
|
-
import TraceGatherer from '
|
|
17
|
-
import {getBrowserVersion} from '
|
|
11
|
+
import {Fetcher} from '../../gather/fetcher.js';
|
|
12
|
+
import {ExecutionContext} from '../../gather/driver/execution-context.js';
|
|
13
|
+
import {LighthouseError} from '../../lib/lh-error.js';
|
|
14
|
+
import {fetchResponseBodyFromCache} from '../../gather/driver/network.js';
|
|
15
|
+
import {DevtoolsMessageLog} from '../../gather/gatherers/devtools-log.js';
|
|
16
|
+
import TraceGatherer from '../../gather/gatherers/trace.js';
|
|
17
|
+
import {getBrowserVersion} from '../../gather/driver/environment.js';
|
|
18
18
|
|
|
19
19
|
// Controls how long to wait for a response after sending a DevTools protocol command.
|
|
20
20
|
const DEFAULT_PROTOCOL_TIMEOUT = 30000;
|
|
@@ -6,25 +6,25 @@
|
|
|
6
6
|
|
|
7
7
|
import log from 'lighthouse-logger';
|
|
8
8
|
|
|
9
|
-
import {NetworkRecords} from '
|
|
10
|
-
import {getPageLoadError} from '
|
|
11
|
-
import * as emulation from '
|
|
12
|
-
import * as constants from '
|
|
13
|
-
import * as format from '
|
|
14
|
-
import {getBenchmarkIndex, getEnvironmentWarnings} from '
|
|
15
|
-
import * as prepare from '
|
|
16
|
-
import * as storage from '
|
|
17
|
-
import * as navigation from '
|
|
18
|
-
import * as serviceWorkers from '
|
|
19
|
-
import WebAppManifest from '
|
|
20
|
-
import InstallabilityErrors from '
|
|
21
|
-
import NetworkUserAgent from '
|
|
22
|
-
import Stacks from '
|
|
23
|
-
import {finalizeArtifacts} from '
|
|
24
|
-
import UrlUtils from '
|
|
25
|
-
|
|
26
|
-
/** @typedef {import('
|
|
27
|
-
/** @typedef {import('
|
|
9
|
+
import {NetworkRecords} from '../../computed/network-records.js';
|
|
10
|
+
import {getPageLoadError} from '../../lib/navigation-error.js';
|
|
11
|
+
import * as emulation from '../../lib/emulation.js';
|
|
12
|
+
import * as constants from '../../config/constants.js';
|
|
13
|
+
import * as format from '../../../shared/localization/format.js';
|
|
14
|
+
import {getBenchmarkIndex, getEnvironmentWarnings} from '../../gather/driver/environment.js';
|
|
15
|
+
import * as prepare from '../../gather/driver/prepare.js';
|
|
16
|
+
import * as storage from '../../gather/driver/storage.js';
|
|
17
|
+
import * as navigation from '../../gather/driver/navigation.js';
|
|
18
|
+
import * as serviceWorkers from '../../gather/driver/service-workers.js';
|
|
19
|
+
import WebAppManifest from '../../gather/gatherers/web-app-manifest.js';
|
|
20
|
+
import InstallabilityErrors from '../../gather/gatherers/installability-errors.js';
|
|
21
|
+
import NetworkUserAgent from '../../gather/gatherers/network-user-agent.js';
|
|
22
|
+
import Stacks from '../../gather/gatherers/stacks.js';
|
|
23
|
+
import {finalizeArtifacts} from '../../fraggle-rock/gather/base-artifacts.js';
|
|
24
|
+
import UrlUtils from '../../lib/url-utils.js';
|
|
25
|
+
|
|
26
|
+
/** @typedef {import('./driver.js').Driver} Driver */
|
|
27
|
+
/** @typedef {import('../../lib/arbitrary-equality-map.js').ArbitraryEqualityMap} ArbitraryEqualityMap */
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Each entry in each gatherer result array is the output of a gatherer phase:
|
|
@@ -539,35 +539,28 @@ function getNodeDetails(element) {
|
|
|
539
539
|
return details;
|
|
540
540
|
}
|
|
541
541
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
${
|
|
546
|
-
${
|
|
547
|
-
${
|
|
548
|
-
|
|
542
|
+
/** @type {string} */
|
|
543
|
+
const getNodeDetailsRawString = getNodeDetails.toString();
|
|
544
|
+
getNodeDetails.toString = () => `function getNodeDetails(element) {
|
|
545
|
+
${getNodePath};
|
|
546
|
+
${getNodeSelector};
|
|
547
|
+
${getBoundingClientRect};
|
|
548
|
+
${getOuterHTMLSnippet};
|
|
549
|
+
${getNodeLabel};
|
|
550
|
+
return (${getNodeDetailsRawString})(element);
|
|
549
551
|
}`;
|
|
550
552
|
|
|
551
|
-
// TODO(esmodules): should this be refactored to export each function individually?
|
|
552
553
|
export const pageFunctions = {
|
|
553
|
-
wrapRuntimeEvalErrorInBrowserString: wrapRuntimeEvalErrorInBrowser.toString(),
|
|
554
554
|
wrapRuntimeEvalErrorInBrowser,
|
|
555
555
|
getElementsInDocument,
|
|
556
|
-
getElementsInDocumentString: getElementsInDocument.toString(),
|
|
557
|
-
getOuterHTMLSnippetString: getOuterHTMLSnippet.toString(),
|
|
558
556
|
getOuterHTMLSnippet,
|
|
559
557
|
computeBenchmarkIndex,
|
|
560
|
-
computeBenchmarkIndexString: computeBenchmarkIndex.toString(),
|
|
561
558
|
getMaxTextureSize,
|
|
562
|
-
getNodeDetailsString,
|
|
563
559
|
getNodeDetails,
|
|
564
|
-
getNodePathString: getNodePath.toString(),
|
|
565
|
-
getNodeSelectorString: getNodeSelector.toString(),
|
|
566
560
|
getNodePath,
|
|
567
561
|
getNodeSelector,
|
|
568
562
|
getNodeLabel,
|
|
569
|
-
|
|
570
|
-
isPositionFixedString: isPositionFixed.toString(),
|
|
563
|
+
isPositionFixed,
|
|
571
564
|
wrapRequestIdleCallback,
|
|
572
|
-
|
|
565
|
+
getBoundingClientRect,
|
|
573
566
|
};
|
package/core/runner.js
CHANGED
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
import fs from 'fs';
|
|
8
8
|
import path from 'path';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
import log from 'lighthouse-logger';
|
|
12
|
+
import isDeepEqual from 'lodash/isEqual.js';
|
|
12
13
|
|
|
13
|
-
import {Driver} from './gather/driver.js';
|
|
14
|
-
import {GatherRunner} from './gather/gather-runner.js';
|
|
14
|
+
import {Driver} from './legacy/gather/driver.js';
|
|
15
|
+
import {GatherRunner} from './legacy/gather/gather-runner.js';
|
|
15
16
|
import {ReportScoring} from './scoring.js';
|
|
16
17
|
import {Audit} from './audits/audit.js';
|
|
17
18
|
import * as format from '../shared/localization/format.js';
|
|
@@ -25,7 +26,7 @@ import {getModuleDirectory} from '../esm-utils.js';
|
|
|
25
26
|
|
|
26
27
|
const moduleDir = getModuleDirectory(import.meta);
|
|
27
28
|
|
|
28
|
-
/** @typedef {import('./gather/connections/connection.js').Connection} Connection */
|
|
29
|
+
/** @typedef {import('./legacy/gather/connections/connection.js').Connection} Connection */
|
|
29
30
|
/** @typedef {import('./lib/arbitrary-equality-map.js').ArbitraryEqualityMap} ArbitraryEqualityMap */
|
|
30
31
|
/** @typedef {LH.Config.Config} Config */
|
|
31
32
|
|
package/package.json
CHANGED
package/tsconfig.json
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"core/test/config/budget-test.js",
|
|
42
42
|
"core/test/config/config-helpers-test.js",
|
|
43
43
|
"core/test/config/config-plugin-test.js",
|
|
44
|
-
"core/test/config/config-test.js",
|
|
44
|
+
"core/test/legacy/config/config-test.js",
|
|
45
45
|
"core/test/config/default-config-test.js",
|
|
46
46
|
"core/test/create-test-trace.js",
|
|
47
47
|
"core/test/gather/driver/wait-for-condition-test.js",
|
package/types/gatherer.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import {NetworkNode as _NetworkNode} from '../core/lib/dependency-graph/network-node';
|
|
8
8
|
import {CPUNode as _CPUNode} from '../core/lib/dependency-graph/cpu-node';
|
|
9
9
|
import {Simulator as _Simulator} from '../core/lib/dependency-graph/simulator/simulator';
|
|
10
|
-
import {Driver} from '../core/gather/driver';
|
|
10
|
+
import {Driver} from '../core/legacy/gather/driver';
|
|
11
11
|
import {ExecutionContext} from '../core/gather/driver/execution-context';
|
|
12
12
|
import {Fetcher} from '../core/gather/fetcher';
|
|
13
13
|
import {ArbitraryEqualityMap} from '../core/lib/arbitrary-equality-map';
|