agent-inspect 6.29.0 → 6.29.1
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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/docs/CLI.md +19 -1
- package/docs/LIMITATIONS.md +1 -1
- package/docs/SAFE-TRACE-SHARING.md +1 -1
- package/docs/STANDARDS.md +1 -1
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-D7PT6TXM.mjs → chunk-UK4HD5M3.mjs} +126 -26
- package/packages/cli/dist/chunk-UK4HD5M3.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +196 -97
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +63 -72
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-QONEBW2F.mjs → src-CMPIJGUE.mjs} +3 -3
- package/packages/cli/dist/{src-QONEBW2F.mjs.map → src-CMPIJGUE.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +100 -24
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +11 -0
- package/packages/core/dist/advanced.d.ts +11 -0
- package/packages/core/dist/advanced.mjs +109 -33
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +225 -33
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +3 -3
- package/packages/core/dist/{chunk-TNOPL75V.mjs → chunk-5RF7FYGL.mjs} +3 -3
- package/packages/core/dist/{chunk-TNOPL75V.mjs.map → chunk-5RF7FYGL.mjs.map} +1 -1
- package/packages/core/dist/{chunk-3B24355S.mjs → chunk-65LFRW2T.mjs} +3 -3
- package/packages/core/dist/{chunk-3B24355S.mjs.map → chunk-65LFRW2T.mjs.map} +1 -1
- package/packages/core/dist/{chunk-TIGBAVED.mjs → chunk-AQMJFKI6.mjs} +4 -4
- package/packages/core/dist/{chunk-TIGBAVED.mjs.map → chunk-AQMJFKI6.mjs.map} +1 -1
- package/packages/core/dist/{chunk-MVRZ7JBH.mjs → chunk-COZPMOUF.mjs} +3 -3
- package/packages/core/dist/{chunk-MVRZ7JBH.mjs.map → chunk-COZPMOUF.mjs.map} +1 -1
- package/packages/core/dist/{chunk-LGTPSHH2.mjs → chunk-GPGBKN7W.mjs} +228 -36
- package/packages/core/dist/chunk-GPGBKN7W.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +10 -5
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.d.cts +12 -2
- package/packages/core/dist/exporters.d.ts +12 -2
- package/packages/core/dist/exporters.mjs +13 -8
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/index.mjs +4 -4
- package/packages/core/dist/writers.mjs +1 -1
- package/packages/cli/dist/chunk-D7PT6TXM.mjs.map +0 -1
- package/packages/core/dist/chunk-LGTPSHH2.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, resolveBundleRunIds, getTraceFilePath, openTrace, sha256Hex, collectTraceSchemaVersions, aggregateBundleSafeStatus, bundleFailsOnSafety, bundleRunAssetRelativePath, buildPlaceholderArtifact, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceHtmlShell, buildEvidenceProvenanceViewHtml, EVIDENCE_FORMAT_VERSION, inferEvidenceFileRole, buildEvidenceSafetyViewHtml, buildEvidenceDiffViewHtml, buildEvidenceCircuitViewHtml, buildEvidenceOutcomesViewHtml, buildEvidenceContractsViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceCausalFailureViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceTreeViewHtml, buildEvidenceManifest, serializeEvidenceManifest, buildZipArchive, assertBundlePathContained, enrichSessionRunRecord, normalizeBundleOutputPath, sanitizeBundleRunId, defaultBundleOutputPath, runTraceChecks, assertEvidenceRelativePath, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, TraceReadError, resolveRedactionProfile, applyProfileMetadataCaps, Redactor, flattenTree, escapeHtml, safeString, compactAttributes, stableJson, escapeMarkdown, truncateStringForProfile, extractMetadata, filterTraces, truncateName, buildRunSummary, formatDuration, formatTimestamp, renderErrorLine, isAgentInspectTrace, filterMetasBySessionScope, aggregateSessionCheckResults, createBaselineRegressionRule, summarizeSemanticParity, buildEvidenceCiPackage, verifyEvidenceDirectory, diffTraceEvents, renderRunDiff, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, formatStepLabel, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, getIndent, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, diffRuns, manualTraceEventsToComparableRun } from './chunk-
|
|
2
|
+
import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, resolveBundleRunIds, getTraceFilePath, openTrace, sha256Hex, collectTraceSchemaVersions, aggregateBundleSafeStatus, bundleFailsOnSafety, bundleRunAssetRelativePath, buildPlaceholderArtifact, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceHtmlShell, buildEvidenceProvenanceViewHtml, EVIDENCE_FORMAT_VERSION, inferEvidenceFileRole, buildEvidenceSafetyViewHtml, buildEvidenceDiffViewHtml, buildEvidenceCircuitViewHtml, buildEvidenceOutcomesViewHtml, buildEvidenceContractsViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceCausalFailureViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceTreeViewHtml, buildEvidenceManifest, serializeEvidenceManifest, buildZipArchive, assertBundlePathContained, enrichSessionRunRecord, normalizeBundleOutputPath, sanitizeBundleRunId, defaultBundleOutputPath, runTraceChecks, assertEvidenceRelativePath, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, TraceReadError, resolveRedactionProfile, applyProfileMetadataCaps, Redactor, flattenTree, escapeHtml, safeString, compactAttributes, stableJson, escapeMarkdown, truncateStringForProfile, extractMetadata, filterTraces, truncateName, buildRunSummary, formatDuration, formatTimestamp, renderErrorLine, isAgentInspectTrace, filterMetasBySessionScope, aggregateSessionCheckResults, createBaselineRegressionRule, summarizeSemanticParity, buildEvidenceCiPackage, verifyEvidenceDirectory, diffTraceEvents, renderRunDiff, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, formatStepLabel, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, getIndent, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, diffRuns, manualTraceEventsToComparableRun } from './chunk-UK4HD5M3.mjs';
|
|
3
3
|
import { realpathSync, constants as constants$1, existsSync, readFileSync } from 'fs';
|
|
4
4
|
import path19 from 'path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
@@ -13,7 +13,7 @@ import { createServer } from 'http';
|
|
|
13
13
|
import { createRequire } from 'module';
|
|
14
14
|
|
|
15
15
|
// package.json
|
|
16
|
-
var version = "6.29.
|
|
16
|
+
var version = "6.29.1";
|
|
17
17
|
|
|
18
18
|
// packages/cli/src/trace-dir-scale.ts
|
|
19
19
|
var TRACE_COUNT_WARN = 1e3;
|
|
@@ -3397,7 +3397,7 @@ async function newestTraceMtimeMs(traceDir) {
|
|
|
3397
3397
|
}
|
|
3398
3398
|
async function loadSessionRuns(traceDir) {
|
|
3399
3399
|
try {
|
|
3400
|
-
const mod = await import('./src-
|
|
3400
|
+
const mod = await import('./src-CMPIJGUE.mjs');
|
|
3401
3401
|
const dbPath = mod.resolveIndexDbPath(traceDir);
|
|
3402
3402
|
const status = mod.indexStatus(dbPath);
|
|
3403
3403
|
if (!status.healthy) {
|
|
@@ -4396,15 +4396,14 @@ var REDACTION_POLICY_LIMITS = {
|
|
|
4396
4396
|
maxPatterns: 32,
|
|
4397
4397
|
maxPatternLength: 128,
|
|
4398
4398
|
maxPatternIdLength: 64,
|
|
4399
|
-
|
|
4399
|
+
/** Maximum policy file size before parse (bytes). */
|
|
4400
|
+
maxPolicyFileBytes: 64 * 1024
|
|
4400
4401
|
};
|
|
4401
|
-
var
|
|
4402
|
+
var ALLOWED_TOP_LEVEL = /* @__PURE__ */ new Set(["version", "extraKeys", "patterns"]);
|
|
4403
|
+
var ALLOWED_PATTERN_FIELDS = /* @__PURE__ */ new Set(["id", "type", "value", "severity"]);
|
|
4402
4404
|
function isRecord6(value) {
|
|
4403
4405
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4404
4406
|
}
|
|
4405
|
-
function escapeRegExp(value) {
|
|
4406
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4407
|
-
}
|
|
4408
4407
|
function rejectRemotePolicyPath(policyPath) {
|
|
4409
4408
|
const trimmed = policyPath.trim();
|
|
4410
4409
|
if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) {
|
|
@@ -4433,43 +4432,23 @@ function validateExtraKey(key, index) {
|
|
|
4433
4432
|
}
|
|
4434
4433
|
return key;
|
|
4435
4434
|
}
|
|
4436
|
-
function
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
`${label} exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
|
|
4441
|
-
);
|
|
4442
|
-
}
|
|
4443
|
-
if (!SAFE_TYPED_PATTERN.test(pattern)) {
|
|
4444
|
-
throw new Error(
|
|
4445
|
-
`${label} contains unsupported characters for bounded typed patterns.`
|
|
4446
|
-
);
|
|
4447
|
-
}
|
|
4448
|
-
if (/\(\?/.test(pattern) || /\\[1-9]/.test(pattern)) {
|
|
4449
|
-
throw new Error(
|
|
4450
|
-
`${label} rejects lookaround, backreferences, and nested quantifiers.`
|
|
4451
|
-
);
|
|
4452
|
-
}
|
|
4453
|
-
if (/\([^)]*[+*{][^)]*\)[+*{]/.test(pattern) || /\[[^\]]*[+*{][^\]]*\][+*{]/.test(pattern)) {
|
|
4454
|
-
throw new Error(`${label} rejects nested quantifiers.`);
|
|
4455
|
-
}
|
|
4456
|
-
if (/\.[*+]/.test(pattern) || /[*+]\{/.test(pattern)) {
|
|
4457
|
-
throw new Error(`${label} rejects unbounded .* / .+ style quantifiers.`);
|
|
4458
|
-
}
|
|
4459
|
-
for (const match of pattern.matchAll(/\{(\d+)(?:,(\d*))?\}/g)) {
|
|
4460
|
-
const min = Number(match[1]);
|
|
4461
|
-
const maxRaw = match[2];
|
|
4462
|
-
const max = maxRaw === void 0 || maxRaw === "" ? min : Number(maxRaw);
|
|
4463
|
-
if (!Number.isFinite(min) || !Number.isFinite(max) || min > REDACTION_POLICY_LIMITS.maxTypedQuantifier || max > REDACTION_POLICY_LIMITS.maxTypedQuantifier) {
|
|
4464
|
-
throw new Error(
|
|
4465
|
-
`${label} quantifiers must be <= ${REDACTION_POLICY_LIMITS.maxTypedQuantifier}.`
|
|
4466
|
-
);
|
|
4435
|
+
function rejectUnknownFields(record, allowed, label) {
|
|
4436
|
+
for (const key of Object.keys(record)) {
|
|
4437
|
+
if (!allowed.has(key)) {
|
|
4438
|
+
throw new Error(`${label} rejects unknown field "${key}".`);
|
|
4467
4439
|
}
|
|
4468
4440
|
}
|
|
4469
4441
|
}
|
|
4470
4442
|
function compilePatternDetector(input3, index) {
|
|
4471
4443
|
const label = `patterns[${index}]`;
|
|
4472
4444
|
if (!isRecord6(input3)) throw new Error(`${label} must be an object.`);
|
|
4445
|
+
const typeEarly = input3.type;
|
|
4446
|
+
if (typeEarly === "typed") {
|
|
4447
|
+
throw new Error(
|
|
4448
|
+
`${label}.type "typed" is no longer supported (removed in 6.29.1). Use type "literal" or "prefix" with a fixed value; arbitrary regex patterns are not accepted.`
|
|
4449
|
+
);
|
|
4450
|
+
}
|
|
4451
|
+
rejectUnknownFields(input3, ALLOWED_PATTERN_FIELDS, label);
|
|
4473
4452
|
const idRaw = input3.id;
|
|
4474
4453
|
if (typeof idRaw !== "string" || idRaw.trim() === "") {
|
|
4475
4454
|
throw new Error(`${label}.id must be a non-empty string.`);
|
|
@@ -4484,48 +4463,35 @@ function compilePatternDetector(input3, index) {
|
|
|
4484
4463
|
throw new Error(`${label}.id must be an identifier-like detector id.`);
|
|
4485
4464
|
}
|
|
4486
4465
|
const type = input3.type;
|
|
4487
|
-
if (type !== "literal" && type !== "prefix"
|
|
4488
|
-
throw new Error(`${label}.type must be literal
|
|
4466
|
+
if (type !== "literal" && type !== "prefix") {
|
|
4467
|
+
throw new Error(`${label}.type must be literal or prefix.`);
|
|
4468
|
+
}
|
|
4469
|
+
if (input3.pattern !== void 0) {
|
|
4470
|
+
throw new Error(
|
|
4471
|
+
`${label}.pattern is not accepted; use .value with type literal or prefix.`
|
|
4472
|
+
);
|
|
4489
4473
|
}
|
|
4490
4474
|
const severity = parseSeverity(input3.severity, label);
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
if (typeof input3.pattern !== "string") {
|
|
4494
|
-
throw new Error(`${label}.pattern must be a string for typed patterns.`);
|
|
4495
|
-
}
|
|
4496
|
-
assertBoundedTypedPattern(input3.pattern, `${label}.pattern`);
|
|
4497
|
-
source = input3.pattern;
|
|
4498
|
-
} else {
|
|
4499
|
-
if (typeof input3.value !== "string") {
|
|
4500
|
-
throw new Error(`${label}.value must be a string for ${type} patterns.`);
|
|
4501
|
-
}
|
|
4502
|
-
if (input3.value.length === 0) {
|
|
4503
|
-
throw new Error(`${label}.value must be non-empty.`);
|
|
4504
|
-
}
|
|
4505
|
-
if (input3.value.length > REDACTION_POLICY_LIMITS.maxPatternLength) {
|
|
4506
|
-
throw new Error(
|
|
4507
|
-
`${label}.value exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
|
|
4508
|
-
);
|
|
4509
|
-
}
|
|
4510
|
-
const escaped = escapeRegExp(input3.value);
|
|
4511
|
-
source = type === "prefix" ? `^${escaped}` : escaped;
|
|
4475
|
+
if (typeof input3.value !== "string") {
|
|
4476
|
+
throw new Error(`${label}.value must be a string for ${type} patterns.`);
|
|
4512
4477
|
}
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4478
|
+
if (input3.value.length === 0) {
|
|
4479
|
+
throw new Error(`${label}.value must be non-empty.`);
|
|
4480
|
+
}
|
|
4481
|
+
if (input3.value.length > REDACTION_POLICY_LIMITS.maxPatternLength) {
|
|
4517
4482
|
throw new Error(
|
|
4518
|
-
`${label}
|
|
4483
|
+
`${label}.value exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
|
|
4519
4484
|
);
|
|
4520
4485
|
}
|
|
4486
|
+
const needle = input3.value;
|
|
4487
|
+
const match = type === "prefix" ? (haystack) => haystack.startsWith(needle) : (haystack) => haystack.includes(needle);
|
|
4521
4488
|
return {
|
|
4522
4489
|
id: `policy.${id}`,
|
|
4523
4490
|
severity,
|
|
4524
4491
|
matchKind: "custom",
|
|
4525
4492
|
detect({ value }) {
|
|
4526
4493
|
if (typeof value !== "string") return [];
|
|
4527
|
-
|
|
4528
|
-
return regex.test(value) ? [{ action: "replace", severity, matchKind: "custom" }] : [];
|
|
4494
|
+
return match(value) ? [{ action: "replace", severity, matchKind: "custom" }] : [];
|
|
4529
4495
|
}
|
|
4530
4496
|
};
|
|
4531
4497
|
}
|
|
@@ -4533,6 +4499,7 @@ function compileRedactionPolicy(raw, policyPath) {
|
|
|
4533
4499
|
if (!isRecord6(raw)) {
|
|
4534
4500
|
throw new Error(`Redaction policy must be a JSON object (${policyPath}).`);
|
|
4535
4501
|
}
|
|
4502
|
+
rejectUnknownFields(raw, ALLOWED_TOP_LEVEL, "Redaction policy");
|
|
4536
4503
|
const diagnostics = [];
|
|
4537
4504
|
if (raw.version !== void 0 && raw.version !== 1) {
|
|
4538
4505
|
throw new Error(`Unsupported redaction policy version (supported: 1).`);
|
|
@@ -4596,14 +4563,38 @@ function compileRedactionPolicy(raw, policyPath) {
|
|
|
4596
4563
|
async function loadRedactionPolicy(policyPath) {
|
|
4597
4564
|
rejectRemotePolicyPath(policyPath);
|
|
4598
4565
|
const resolved = path19.resolve(policyPath);
|
|
4599
|
-
let
|
|
4566
|
+
let fileStat;
|
|
4600
4567
|
try {
|
|
4601
|
-
|
|
4568
|
+
fileStat = await stat(resolved);
|
|
4602
4569
|
} catch (error) {
|
|
4603
4570
|
throw new Error(
|
|
4604
4571
|
`Failed to read --policy file "${resolved}": ${error instanceof Error ? error.message : String(error)}`
|
|
4605
4572
|
);
|
|
4606
4573
|
}
|
|
4574
|
+
if (!fileStat.isFile()) {
|
|
4575
|
+
throw new Error(
|
|
4576
|
+
`--policy must be a regular local JSON file (not a directory or special file): "${resolved}".`
|
|
4577
|
+
);
|
|
4578
|
+
}
|
|
4579
|
+
if (fileStat.size > REDACTION_POLICY_LIMITS.maxPolicyFileBytes) {
|
|
4580
|
+
throw new Error(
|
|
4581
|
+
`--policy file exceeds max size ${REDACTION_POLICY_LIMITS.maxPolicyFileBytes} bytes.`
|
|
4582
|
+
);
|
|
4583
|
+
}
|
|
4584
|
+
let buffer;
|
|
4585
|
+
try {
|
|
4586
|
+
buffer = await readFile(resolved);
|
|
4587
|
+
} catch (error) {
|
|
4588
|
+
throw new Error(
|
|
4589
|
+
`Failed to read --policy file "${resolved}": ${error instanceof Error ? error.message : String(error)}`
|
|
4590
|
+
);
|
|
4591
|
+
}
|
|
4592
|
+
if (buffer.byteLength > REDACTION_POLICY_LIMITS.maxPolicyFileBytes) {
|
|
4593
|
+
throw new Error(
|
|
4594
|
+
`--policy file exceeds max size ${REDACTION_POLICY_LIMITS.maxPolicyFileBytes} bytes.`
|
|
4595
|
+
);
|
|
4596
|
+
}
|
|
4597
|
+
const text = buffer.toString("utf-8");
|
|
4607
4598
|
let parsed;
|
|
4608
4599
|
try {
|
|
4609
4600
|
parsed = JSON.parse(text);
|
|
@@ -12079,7 +12070,7 @@ function isModuleNotFound4(e) {
|
|
|
12079
12070
|
}
|
|
12080
12071
|
async function loadIndexSqlite() {
|
|
12081
12072
|
try {
|
|
12082
|
-
return await import('./src-
|
|
12073
|
+
return await import('./src-CMPIJGUE.mjs');
|
|
12083
12074
|
} catch (e) {
|
|
12084
12075
|
if (isModuleNotFound4(e)) {
|
|
12085
12076
|
console.error(
|