seo 0.4.0 → 0.4.2

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/dist/index.d.ts CHANGED
@@ -3538,10 +3538,10 @@ declare const crawlPageSnapshotSchema: z.ZodObject<{
3538
3538
  raw: z.ZodString;
3539
3539
  resolved: z.ZodOptional<z.ZodString>;
3540
3540
  ignoredReason: z.ZodOptional<z.ZodEnum<{
3541
+ "invalid-url": "invalid-url";
3541
3542
  "outside-head": "outside-head";
3542
3543
  "alternate-qualifier": "alternate-qualifier";
3543
3544
  fragment: "fragment";
3544
- "invalid-url": "invalid-url";
3545
3545
  "non-http-url": "non-http-url";
3546
3546
  }>>;
3547
3547
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -4175,15 +4175,15 @@ declare const crawlReportSummarySchema: z.ZodObject<{
4175
4175
  skippedUrls: z.ZodNumber;
4176
4176
  skipReasons: z.ZodArray<z.ZodObject<{
4177
4177
  reason: z.ZodEnum<{
4178
- "invalid-url": "invalid-url";
4179
- "robots-disallowed": "robots-disallowed";
4180
- "origin-backpressure": "origin-backpressure";
4181
4178
  "asset-url": "asset-url";
4182
4179
  "configured-exclusion": "configured-exclusion";
4183
4180
  "duplicate-normalization": "duplicate-normalization";
4181
+ "invalid-url": "invalid-url";
4184
4182
  "memory-pressure": "memory-pressure";
4185
4183
  "off-origin": "off-origin";
4184
+ "origin-backpressure": "origin-backpressure";
4186
4185
  "queue-safety-limit": "queue-safety-limit";
4186
+ "robots-disallowed": "robots-disallowed";
4187
4187
  "robots-uncertain": "robots-uncertain";
4188
4188
  "legacy-unclassified": "legacy-unclassified";
4189
4189
  }>;
@@ -4341,15 +4341,15 @@ declare const crawlReportSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4341
4341
  skippedUrls: z.ZodNumber;
4342
4342
  skipReasons: z.ZodArray<z.ZodObject<{
4343
4343
  reason: z.ZodEnum<{
4344
- "invalid-url": "invalid-url";
4345
- "robots-disallowed": "robots-disallowed";
4346
- "origin-backpressure": "origin-backpressure";
4347
4344
  "asset-url": "asset-url";
4348
4345
  "configured-exclusion": "configured-exclusion";
4349
4346
  "duplicate-normalization": "duplicate-normalization";
4347
+ "invalid-url": "invalid-url";
4350
4348
  "memory-pressure": "memory-pressure";
4351
4349
  "off-origin": "off-origin";
4350
+ "origin-backpressure": "origin-backpressure";
4352
4351
  "queue-safety-limit": "queue-safety-limit";
4352
+ "robots-disallowed": "robots-disallowed";
4353
4353
  "robots-uncertain": "robots-uncertain";
4354
4354
  "legacy-unclassified": "legacy-unclassified";
4355
4355
  }>;
@@ -4721,10 +4721,10 @@ declare const crawlReportSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4721
4721
  raw: z.ZodString;
4722
4722
  resolved: z.ZodOptional<z.ZodString>;
4723
4723
  ignoredReason: z.ZodOptional<z.ZodEnum<{
4724
+ "invalid-url": "invalid-url";
4724
4725
  "outside-head": "outside-head";
4725
4726
  "alternate-qualifier": "alternate-qualifier";
4726
4727
  fragment: "fragment";
4727
- "invalid-url": "invalid-url";
4728
4728
  "non-http-url": "non-http-url";
4729
4729
  }>>;
4730
4730
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -5583,15 +5583,15 @@ declare const crawlReportSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5583
5583
  skippedUrls: z.ZodNumber;
5584
5584
  skipReasons: z.ZodArray<z.ZodObject<{
5585
5585
  reason: z.ZodEnum<{
5586
- "invalid-url": "invalid-url";
5587
- "robots-disallowed": "robots-disallowed";
5588
- "origin-backpressure": "origin-backpressure";
5589
5586
  "asset-url": "asset-url";
5590
5587
  "configured-exclusion": "configured-exclusion";
5591
5588
  "duplicate-normalization": "duplicate-normalization";
5589
+ "invalid-url": "invalid-url";
5592
5590
  "memory-pressure": "memory-pressure";
5593
5591
  "off-origin": "off-origin";
5592
+ "origin-backpressure": "origin-backpressure";
5594
5593
  "queue-safety-limit": "queue-safety-limit";
5594
+ "robots-disallowed": "robots-disallowed";
5595
5595
  "robots-uncertain": "robots-uncertain";
5596
5596
  "legacy-unclassified": "legacy-unclassified";
5597
5597
  }>;
@@ -5963,10 +5963,10 @@ declare const crawlReportSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5963
5963
  raw: z.ZodString;
5964
5964
  resolved: z.ZodOptional<z.ZodString>;
5965
5965
  ignoredReason: z.ZodOptional<z.ZodEnum<{
5966
+ "invalid-url": "invalid-url";
5966
5967
  "outside-head": "outside-head";
5967
5968
  "alternate-qualifier": "alternate-qualifier";
5968
5969
  fragment: "fragment";
5969
- "invalid-url": "invalid-url";
5970
5970
  "non-http-url": "non-http-url";
5971
5971
  }>>;
5972
5972
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -6825,15 +6825,15 @@ declare const crawlReportSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
6825
6825
  skippedUrls: z.ZodNumber;
6826
6826
  skipReasons: z.ZodArray<z.ZodObject<{
6827
6827
  reason: z.ZodEnum<{
6828
- "invalid-url": "invalid-url";
6829
- "robots-disallowed": "robots-disallowed";
6830
- "origin-backpressure": "origin-backpressure";
6831
6828
  "asset-url": "asset-url";
6832
6829
  "configured-exclusion": "configured-exclusion";
6833
6830
  "duplicate-normalization": "duplicate-normalization";
6831
+ "invalid-url": "invalid-url";
6834
6832
  "memory-pressure": "memory-pressure";
6835
6833
  "off-origin": "off-origin";
6834
+ "origin-backpressure": "origin-backpressure";
6836
6835
  "queue-safety-limit": "queue-safety-limit";
6836
+ "robots-disallowed": "robots-disallowed";
6837
6837
  "robots-uncertain": "robots-uncertain";
6838
6838
  "legacy-unclassified": "legacy-unclassified";
6839
6839
  }>;
@@ -7205,10 +7205,10 @@ declare const crawlReportSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
7205
7205
  raw: z.ZodString;
7206
7206
  resolved: z.ZodOptional<z.ZodString>;
7207
7207
  ignoredReason: z.ZodOptional<z.ZodEnum<{
7208
+ "invalid-url": "invalid-url";
7208
7209
  "outside-head": "outside-head";
7209
7210
  "alternate-qualifier": "alternate-qualifier";
7210
7211
  fragment: "fragment";
7211
- "invalid-url": "invalid-url";
7212
7212
  "non-http-url": "non-http-url";
7213
7213
  }>>;
7214
7214
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -8069,15 +8069,15 @@ declare const crawlerSchemas: {
8069
8069
  skippedUrls: z.ZodNumber;
8070
8070
  skipReasons: z.ZodArray<z.ZodObject<{
8071
8071
  reason: z.ZodEnum<{
8072
- "invalid-url": "invalid-url";
8073
- "robots-disallowed": "robots-disallowed";
8074
- "origin-backpressure": "origin-backpressure";
8075
8072
  "asset-url": "asset-url";
8076
8073
  "configured-exclusion": "configured-exclusion";
8077
8074
  "duplicate-normalization": "duplicate-normalization";
8075
+ "invalid-url": "invalid-url";
8078
8076
  "memory-pressure": "memory-pressure";
8079
8077
  "off-origin": "off-origin";
8078
+ "origin-backpressure": "origin-backpressure";
8080
8079
  "queue-safety-limit": "queue-safety-limit";
8080
+ "robots-disallowed": "robots-disallowed";
8081
8081
  "robots-uncertain": "robots-uncertain";
8082
8082
  "legacy-unclassified": "legacy-unclassified";
8083
8083
  }>;
@@ -8449,10 +8449,10 @@ declare const crawlerSchemas: {
8449
8449
  raw: z.ZodString;
8450
8450
  resolved: z.ZodOptional<z.ZodString>;
8451
8451
  ignoredReason: z.ZodOptional<z.ZodEnum<{
8452
+ "invalid-url": "invalid-url";
8452
8453
  "outside-head": "outside-head";
8453
8454
  "alternate-qualifier": "alternate-qualifier";
8454
8455
  fragment: "fragment";
8455
- "invalid-url": "invalid-url";
8456
8456
  "non-http-url": "non-http-url";
8457
8457
  }>>;
8458
8458
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -9311,15 +9311,15 @@ declare const crawlerSchemas: {
9311
9311
  skippedUrls: z.ZodNumber;
9312
9312
  skipReasons: z.ZodArray<z.ZodObject<{
9313
9313
  reason: z.ZodEnum<{
9314
- "invalid-url": "invalid-url";
9315
- "robots-disallowed": "robots-disallowed";
9316
- "origin-backpressure": "origin-backpressure";
9317
9314
  "asset-url": "asset-url";
9318
9315
  "configured-exclusion": "configured-exclusion";
9319
9316
  "duplicate-normalization": "duplicate-normalization";
9317
+ "invalid-url": "invalid-url";
9320
9318
  "memory-pressure": "memory-pressure";
9321
9319
  "off-origin": "off-origin";
9320
+ "origin-backpressure": "origin-backpressure";
9322
9321
  "queue-safety-limit": "queue-safety-limit";
9322
+ "robots-disallowed": "robots-disallowed";
9323
9323
  "robots-uncertain": "robots-uncertain";
9324
9324
  "legacy-unclassified": "legacy-unclassified";
9325
9325
  }>;
@@ -9691,10 +9691,10 @@ declare const crawlerSchemas: {
9691
9691
  raw: z.ZodString;
9692
9692
  resolved: z.ZodOptional<z.ZodString>;
9693
9693
  ignoredReason: z.ZodOptional<z.ZodEnum<{
9694
+ "invalid-url": "invalid-url";
9694
9695
  "outside-head": "outside-head";
9695
9696
  "alternate-qualifier": "alternate-qualifier";
9696
9697
  fragment: "fragment";
9697
- "invalid-url": "invalid-url";
9698
9698
  "non-http-url": "non-http-url";
9699
9699
  }>>;
9700
9700
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -10553,15 +10553,15 @@ declare const crawlerSchemas: {
10553
10553
  skippedUrls: z.ZodNumber;
10554
10554
  skipReasons: z.ZodArray<z.ZodObject<{
10555
10555
  reason: z.ZodEnum<{
10556
- "invalid-url": "invalid-url";
10557
- "robots-disallowed": "robots-disallowed";
10558
- "origin-backpressure": "origin-backpressure";
10559
10556
  "asset-url": "asset-url";
10560
10557
  "configured-exclusion": "configured-exclusion";
10561
10558
  "duplicate-normalization": "duplicate-normalization";
10559
+ "invalid-url": "invalid-url";
10562
10560
  "memory-pressure": "memory-pressure";
10563
10561
  "off-origin": "off-origin";
10562
+ "origin-backpressure": "origin-backpressure";
10564
10563
  "queue-safety-limit": "queue-safety-limit";
10564
+ "robots-disallowed": "robots-disallowed";
10565
10565
  "robots-uncertain": "robots-uncertain";
10566
10566
  "legacy-unclassified": "legacy-unclassified";
10567
10567
  }>;
@@ -10933,10 +10933,10 @@ declare const crawlerSchemas: {
10933
10933
  raw: z.ZodString;
10934
10934
  resolved: z.ZodOptional<z.ZodString>;
10935
10935
  ignoredReason: z.ZodOptional<z.ZodEnum<{
10936
+ "invalid-url": "invalid-url";
10936
10937
  "outside-head": "outside-head";
10937
10938
  "alternate-qualifier": "alternate-qualifier";
10938
10939
  fragment: "fragment";
10939
- "invalid-url": "invalid-url";
10940
10940
  "non-http-url": "non-http-url";
10941
10941
  }>>;
10942
10942
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -12299,10 +12299,10 @@ declare const crawlerSchemas: {
12299
12299
  raw: z.ZodString;
12300
12300
  resolved: z.ZodOptional<z.ZodString>;
12301
12301
  ignoredReason: z.ZodOptional<z.ZodEnum<{
12302
+ "invalid-url": "invalid-url";
12302
12303
  "outside-head": "outside-head";
12303
12304
  "alternate-qualifier": "alternate-qualifier";
12304
12305
  fragment: "fragment";
12305
- "invalid-url": "invalid-url";
12306
12306
  "non-http-url": "non-http-url";
12307
12307
  }>>;
12308
12308
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -12723,15 +12723,15 @@ declare const crawlerJsonSchemas: {
12723
12723
  skippedUrls: z.ZodNumber;
12724
12724
  skipReasons: z.ZodArray<z.ZodObject<{
12725
12725
  reason: z.ZodEnum<{
12726
- "invalid-url": "invalid-url";
12727
- "robots-disallowed": "robots-disallowed";
12728
- "origin-backpressure": "origin-backpressure";
12729
12726
  "asset-url": "asset-url";
12730
12727
  "configured-exclusion": "configured-exclusion";
12731
12728
  "duplicate-normalization": "duplicate-normalization";
12729
+ "invalid-url": "invalid-url";
12732
12730
  "memory-pressure": "memory-pressure";
12733
12731
  "off-origin": "off-origin";
12732
+ "origin-backpressure": "origin-backpressure";
12734
12733
  "queue-safety-limit": "queue-safety-limit";
12734
+ "robots-disallowed": "robots-disallowed";
12735
12735
  "robots-uncertain": "robots-uncertain";
12736
12736
  "legacy-unclassified": "legacy-unclassified";
12737
12737
  }>;
@@ -13103,10 +13103,10 @@ declare const crawlerJsonSchemas: {
13103
13103
  raw: z.ZodString;
13104
13104
  resolved: z.ZodOptional<z.ZodString>;
13105
13105
  ignoredReason: z.ZodOptional<z.ZodEnum<{
13106
+ "invalid-url": "invalid-url";
13106
13107
  "outside-head": "outside-head";
13107
13108
  "alternate-qualifier": "alternate-qualifier";
13108
13109
  fragment: "fragment";
13109
- "invalid-url": "invalid-url";
13110
13110
  "non-http-url": "non-http-url";
13111
13111
  }>>;
13112
13112
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -13965,15 +13965,15 @@ declare const crawlerJsonSchemas: {
13965
13965
  skippedUrls: z.ZodNumber;
13966
13966
  skipReasons: z.ZodArray<z.ZodObject<{
13967
13967
  reason: z.ZodEnum<{
13968
- "invalid-url": "invalid-url";
13969
- "robots-disallowed": "robots-disallowed";
13970
- "origin-backpressure": "origin-backpressure";
13971
13968
  "asset-url": "asset-url";
13972
13969
  "configured-exclusion": "configured-exclusion";
13973
13970
  "duplicate-normalization": "duplicate-normalization";
13971
+ "invalid-url": "invalid-url";
13974
13972
  "memory-pressure": "memory-pressure";
13975
13973
  "off-origin": "off-origin";
13974
+ "origin-backpressure": "origin-backpressure";
13976
13975
  "queue-safety-limit": "queue-safety-limit";
13976
+ "robots-disallowed": "robots-disallowed";
13977
13977
  "robots-uncertain": "robots-uncertain";
13978
13978
  "legacy-unclassified": "legacy-unclassified";
13979
13979
  }>;
@@ -14345,10 +14345,10 @@ declare const crawlerJsonSchemas: {
14345
14345
  raw: z.ZodString;
14346
14346
  resolved: z.ZodOptional<z.ZodString>;
14347
14347
  ignoredReason: z.ZodOptional<z.ZodEnum<{
14348
+ "invalid-url": "invalid-url";
14348
14349
  "outside-head": "outside-head";
14349
14350
  "alternate-qualifier": "alternate-qualifier";
14350
14351
  fragment: "fragment";
14351
- "invalid-url": "invalid-url";
14352
14352
  "non-http-url": "non-http-url";
14353
14353
  }>>;
14354
14354
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -15207,15 +15207,15 @@ declare const crawlerJsonSchemas: {
15207
15207
  skippedUrls: z.ZodNumber;
15208
15208
  skipReasons: z.ZodArray<z.ZodObject<{
15209
15209
  reason: z.ZodEnum<{
15210
- "invalid-url": "invalid-url";
15211
- "robots-disallowed": "robots-disallowed";
15212
- "origin-backpressure": "origin-backpressure";
15213
15210
  "asset-url": "asset-url";
15214
15211
  "configured-exclusion": "configured-exclusion";
15215
15212
  "duplicate-normalization": "duplicate-normalization";
15213
+ "invalid-url": "invalid-url";
15216
15214
  "memory-pressure": "memory-pressure";
15217
15215
  "off-origin": "off-origin";
15216
+ "origin-backpressure": "origin-backpressure";
15218
15217
  "queue-safety-limit": "queue-safety-limit";
15218
+ "robots-disallowed": "robots-disallowed";
15219
15219
  "robots-uncertain": "robots-uncertain";
15220
15220
  "legacy-unclassified": "legacy-unclassified";
15221
15221
  }>;
@@ -15587,10 +15587,10 @@ declare const crawlerJsonSchemas: {
15587
15587
  raw: z.ZodString;
15588
15588
  resolved: z.ZodOptional<z.ZodString>;
15589
15589
  ignoredReason: z.ZodOptional<z.ZodEnum<{
15590
+ "invalid-url": "invalid-url";
15590
15591
  "outside-head": "outside-head";
15591
15592
  "alternate-qualifier": "alternate-qualifier";
15592
15593
  fragment: "fragment";
15593
- "invalid-url": "invalid-url";
15594
15594
  "non-http-url": "non-http-url";
15595
15595
  }>>;
15596
15596
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -16953,10 +16953,10 @@ declare const crawlerJsonSchemas: {
16953
16953
  raw: z.ZodString;
16954
16954
  resolved: z.ZodOptional<z.ZodString>;
16955
16955
  ignoredReason: z.ZodOptional<z.ZodEnum<{
16956
+ "invalid-url": "invalid-url";
16956
16957
  "outside-head": "outside-head";
16957
16958
  "alternate-qualifier": "alternate-qualifier";
16958
16959
  fragment: "fragment";
16959
- "invalid-url": "invalid-url";
16960
16960
  "non-http-url": "non-http-url";
16961
16961
  }>>;
16962
16962
  streamedMetadata: z.ZodOptional<z.ZodLiteral<true>>;
@@ -19080,12 +19080,13 @@ interface TrafficAnomaly {
19080
19080
  /** The step-change heuristic and its thresholds, returned with the report. */
19081
19081
  declare const STEP_CHANGE_RULES: {
19082
19082
  readonly method: "best-split";
19083
- readonly description: "Heuristic. The change date is the split of the daily series where the mean before and the mean after differ most, weighted by segment length. It counts as a step change only when it is sudden and sustained. Sudden: the median of up to localDays observed days after the date differs from the median of up to localDays days before it by at least minLocalShiftInStdDevs pooled within-segment standard deviations, so one unusual day is not a step and a slow trend is not a step. Sustained: the mean of every day from the date differs from the mean before it by a z-score of at least minZScore, stricter than the recent-window test because the date is chosen from the data. Otherwise the last recentDays are compared with the days before them.";
19083
+ readonly description: "Heuristic. The change date is the split of the daily series where the mean before and the mean after differ most, weighted by segment length. It counts as a step change only when it is sudden and sustained. Sudden: the median of up to localDays observed days after the date differs from the median of up to localDays days before it by at least minLocalShiftInStdDevs pooled within-segment standard deviations, so one unusual day is not a step and a slow trend is not a step. Sustained: the mean of every day from the date differs from the mean before it by a z-score of at least minZScore, stricter than the recent-window test because the date is chosen from the data. These tests use daily values capped at the capDays and 1 - capDays quantiles, so one spike day cannot hide a lasting step. Otherwise the last recentDays are compared with the days before them.";
19084
19084
  readonly minDaysBefore: 7;
19085
19085
  readonly minDaysAfter: 3;
19086
19086
  readonly localDays: 7;
19087
19087
  readonly minLocalShiftInStdDevs: 2;
19088
19088
  readonly minZScore: 3;
19089
+ readonly capDays: 0.05;
19089
19090
  };
19090
19091
  type TrafficAnomalyDetection = typeof STEP_CHANGE_RULES & {
19091
19092
  recentDays: number;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __seoCreateRequire } from 'node:module'; const require = __seoCreateRequire(import.meta.url);
2
- import { n as load, t as version } from "./package-BfqlCbxN.js";
2
+ import { n as load, t as version } from "./package-D46BDwUk.js";
3
3
  import { SEO_PROVIDER_API_VERSION } from "./provider-sdk.js";
4
4
  import crypto, { createHash, randomUUID, sign } from "node:crypto";
5
5
  import { z } from "zod";
@@ -8341,7 +8341,7 @@ const TOPIC_WORDS = /* @__PURE__ */ new Set([
8341
8341
  "free",
8342
8342
  "guide",
8343
8343
  "how",
8344
- "inference",
8344
+ "example",
8345
8345
  "install",
8346
8346
  "integration",
8347
8347
  "local",
@@ -20251,12 +20251,13 @@ async function listSearchUpdates(input = {}) {
20251
20251
  /** The step-change heuristic and its thresholds, returned with the report. */
20252
20252
  const STEP_CHANGE_RULES = {
20253
20253
  method: "best-split",
20254
- description: "Heuristic. The change date is the split of the daily series where the mean before and the mean after differ most, weighted by segment length. It counts as a step change only when it is sudden and sustained. Sudden: the median of up to localDays observed days after the date differs from the median of up to localDays days before it by at least minLocalShiftInStdDevs pooled within-segment standard deviations, so one unusual day is not a step and a slow trend is not a step. Sustained: the mean of every day from the date differs from the mean before it by a z-score of at least minZScore, stricter than the recent-window test because the date is chosen from the data. Otherwise the last recentDays are compared with the days before them.",
20254
+ description: "Heuristic. The change date is the split of the daily series where the mean before and the mean after differ most, weighted by segment length. It counts as a step change only when it is sudden and sustained. Sudden: the median of up to localDays observed days after the date differs from the median of up to localDays days before it by at least minLocalShiftInStdDevs pooled within-segment standard deviations, so one unusual day is not a step and a slow trend is not a step. Sustained: the mean of every day from the date differs from the mean before it by a z-score of at least minZScore, stricter than the recent-window test because the date is chosen from the data. These tests use daily values capped at the capDays and 1 - capDays quantiles, so one spike day cannot hide a lasting step. Otherwise the last recentDays are compared with the days before them.",
20255
20255
  minDaysBefore: 7,
20256
20256
  minDaysAfter: 3,
20257
20257
  localDays: 7,
20258
20258
  minLocalShiftInStdDevs: 2,
20259
- minZScore: 3
20259
+ minZScore: 3,
20260
+ capDays: .05
20260
20261
  };
20261
20262
  /**
20262
20263
  * The dates to check against Google updates (before padding): the change
@@ -20432,10 +20433,18 @@ function sumOfSquaredDeviations(values) {
20432
20433
  const average = mean(values);
20433
20434
  return values.reduce((sum, value) => sum + (value - average) ** 2, 0);
20434
20435
  }
20435
- function findStepChange(values) {
20436
+ function capped(values) {
20437
+ const sorted = [...values].sort((a, b) => a - b);
20438
+ const last = sorted.length - 1;
20439
+ const low = sorted[Math.floor(last * STEP_CHANGE_RULES.capDays)] ?? 0;
20440
+ const high = sorted[Math.ceil(last * (1 - STEP_CHANGE_RULES.capDays))] ?? 0;
20441
+ return values.map((value) => Math.min(high, Math.max(low, value)));
20442
+ }
20443
+ function findStepChange(observed) {
20436
20444
  const { minDaysBefore, minDaysAfter, localDays, minLocalShiftInStdDevs, minZScore } = STEP_CHANGE_RULES;
20437
- const count = values.length;
20445
+ const count = observed.length;
20438
20446
  if (count < minDaysBefore + minDaysAfter) return null;
20447
+ const values = capped(observed);
20439
20448
  const sums = [0];
20440
20449
  for (const value of values) sums.push((sums.at(-1) ?? 0) + value);
20441
20450
  const total = sums[count] ?? 0;