@dra2020/district-analytics 15.0.0 → 15.0.3

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.
@@ -44,15 +44,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
44
44
  Object.defineProperty(exports, "__esModule", ({ value: true }));
45
45
  exports.AnalyticsSession = void 0;
46
46
  const baseclient_1 = __webpack_require__(/*! @dra2020/baseclient */ "@dra2020/baseclient");
47
- // LEGACY - DELETE
48
- // import * as DT from '@dra2020/dra-types';
49
- // LEGACY - DELETE
50
- // import * as Score from '@dra2020/dra-score';
51
47
  const dra_analytics_1 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
52
48
  const preprocess_1 = __webpack_require__(/*! ./preprocess */ "./src/preprocess.ts");
53
49
  const analyze_1 = __webpack_require__(/*! ./analyze */ "./src/analyze.ts");
54
- // LEGACY - DELETE
55
- // import { profilePlan, scorePlan, computeMetrics, rateKeyDimensions, thunkScorecard, compareScorecards } from './score'
56
50
  const score_1 = __webpack_require__(/*! ./score */ "./src/score.ts");
57
51
  const results_1 = __webpack_require__(/*! ./results */ "./src/results.ts");
58
52
  const results_2 = __webpack_require__(/*! ./results */ "./src/results.ts");
@@ -60,8 +54,6 @@ const minority_1 = __webpack_require__(/*! ./minority */ "./src/minority.ts");
60
54
  const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
61
55
  const M = __importStar(__webpack_require__(/*! ./minority */ "./src/minority.ts"));
62
56
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
63
- // LEGACY - DELETE
64
- // import * as S from './settings';
65
57
  class AnalyticsSession {
66
58
  constructor(SessionRequest) {
67
59
  this.legislativeDistricts = false; // 2020
@@ -115,46 +107,21 @@ class AnalyticsSession {
115
107
  (0, analyze_1.doAnalyzeDistricts)(this, bLog);
116
108
  // This does a little stuff that didn't get factored out into dra-score and then dra-analytics
117
109
  (0, analyze_1.doAnalyzePlan)(this, bLog);
118
- // THE MAIN ANALYTICS ARE NEXT
110
+ // THE MAIN ANALYTICS
119
111
  // Even though we don't save the profile (as I thought we would),
120
112
  // we allow it to be exported, so keep generating it, and use it
121
113
  // to gather the inputs to new analytics (as well as the legacy).
122
114
  this._profile = (0, score_1.profilePlan)(this, bLog);
123
- // LEGACY - DELETE
124
- // let legacyScorecard = {} as Score.Scorecard;
125
115
  let legacyScorecardAlt = {};
126
116
  let newScorecard = {};
127
- // LEGACY - DELETE: Run legacy analytics
128
- /*
129
- if (this.config.legacyanalytics)
130
- {
131
- if (bLog) console.log("Running legacy analytics ...");
132
- legacyScorecard = scorePlan(this, this._profile, bLog, overridesJSON);
133
- }
134
- */
135
117
  // Construct a new/alternate scorecard
136
- // LEGACY - DELETE
137
- // if (this.config.newanalytics)
138
- // {
139
- // if (bLog) console.log("Running new analytics ...");
140
118
  newScorecard = (0, score_1.computeMetrics)(this._profile, this.getGoodShapes(), bLog); // w/o ratings
141
119
  newScorecard = (0, score_1.rateKeyDimensions)(newScorecard, this._profile, bLog); // w/ ratings
142
120
  legacyScorecardAlt = (0, score_1.thunkScorecard)(newScorecard, bLog);
143
121
  // Add minority notes
144
122
  legacyScorecardAlt.minority.details['majorityMinority'] = M.getMajorityMinority(this);
145
123
  legacyScorecardAlt.minority.details['vraPreclearance'] = M.getVRASection5(this);
146
- // LEGACY - DELETE
147
- // // Compare the new & legacy scorecards
148
- // compareScorecards(legacyScorecardAlt, legacyScorecard, bLog);
149
- // }
150
- // LEGACY - DELETE
151
- // Use the new scorecard, after creating it
152
- // this._scorecard = (this.config.newanalytics) ? legacyScorecardAlt : legacyScorecard;
153
124
  this._scorecard = legacyScorecardAlt;
154
- // Post-scorecard housekeeping - copied from scorePlan()
155
- // LEGACY - DELETE
156
- // if (this.config.newanalytics)
157
- // {
158
125
  // Before returning, create a dummy population deviation test, for
159
126
  // doHasEqualPopulations() to use later.This is preserving the old calling sequence.
160
127
  let test = this.getTest(4 /* PopulationDeviation */);
@@ -175,8 +142,6 @@ class AnalyticsSession {
175
142
  // Use 'roughly' equal population from dra-analytics
176
143
  let test2 = this.getTest(3 /* EqualPopulation */);
177
144
  test2['score'] = newScorecard.populationDeviation.roughlyEqual;
178
- // LEGACY - DELETE
179
- // }
180
145
  // END main analytics
181
146
  (0, results_1.doAnalyzePostProcessing)(this, bLog);
182
147
  }
@@ -282,21 +247,9 @@ class AnalyticsSession {
282
247
  // Return a pointer to the the test entry for this test
283
248
  return this.tests[testID];
284
249
  }
285
- // LEGACY - Threshold defined in dra-analytics for new analytics
286
250
  // NOTE - Not sure why this has to be up here ...
287
251
  populationDeviationThreshold() {
288
- // LEGACY - DELETE
289
- // let threshold: number;
290
- // if (this.config.legacyanalytics && !this.config.newanalytics)
291
- // {
292
- // // NOTE - This assumes the plan has been profiled
293
- // const scorer = new Score.Scorer();
294
- // threshold = scorer.populationDeviationThreshold(this.legislativeDistricts); // TODO - 2020
295
- // }
296
- // else
297
- // {
298
252
  const threshold = dra_analytics_1.Rate.popdevThreshold(this.legislativeDistricts);
299
- // }
300
253
  return threshold;
301
254
  }
302
255
  }
@@ -348,7 +301,6 @@ const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
348
301
  const S = __importStar(__webpack_require__(/*! ./settings */ "./src/settings.ts"));
349
302
  const compact_1 = __webpack_require__(/*! ./compact */ "./src/compact.ts");
350
303
  const dra_analytics_2 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
351
- // import { fptpWin } from './political'
352
304
  // DEBUG COUNTERS
353
305
  let nMissingDataset = 0;
354
306
  let nMissingProperty = 0;
@@ -1283,7 +1235,7 @@ exports.doDeriveSecondaryTests = doDeriveSecondaryTests;
1283
1235
 
1284
1236
 
1285
1237
  //
1286
- // SPLITTING of counties & districts
1238
+ // SPLITTING
1287
1239
  //
1288
1240
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1289
1241
  if (k2 === undefined) k2 = k;
@@ -1307,7 +1259,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
1307
1259
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1308
1260
  exports.doFindSplitVTDs = exports.doFindCountiesSplitUnexpectedly = void 0;
1309
1261
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
1310
- // NOTE - The active code is below the long multi-line section to be deleted.
1262
+ // The main county-district splitting code is in the dra-analytics package.
1311
1263
  // ANALYZE SIMPLE COUNTY & VTD SPLITTING
1312
1264
  /*
1313
1265
 
@@ -1520,10 +1472,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
1520
1472
  return result;
1521
1473
  };
1522
1474
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1523
- exports.scoreKIWYSICompactness = exports.extractDistrictProperties = void 0;
1475
+ exports.extractDistrictProperties = void 0;
1524
1476
  const baseclient_1 = __webpack_require__(/*! @dra2020/baseclient */ "@dra2020/baseclient");
1525
- const dra_analytics_1 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
1526
1477
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
1478
+ // The main compactness code is in the dra-analytics package.
1527
1479
  // HELPER TO EXTRACT PROPERTIES OF DISTRICT SHAPES
1528
1480
  function extractDistrictProperties(s, bLog = false) {
1529
1481
  // NOTE - I am assuming that district IDs are integers 1–N
@@ -1551,35 +1503,6 @@ function isAShape(poly) {
1551
1503
  return false;
1552
1504
  return poly.geometry && poly.geometry.coordinates && !U.isArrayEmpty(poly.geometry.coordinates);
1553
1505
  }
1554
- // SCORE KIWYSI COMPACTNESS
1555
- // LEGACY
1556
- function scoreKIWYSICompactness(s, bLog = false) {
1557
- const rawShapes = s.districts.getDistrictShapes();
1558
- // Filter the real shapes & throw everything else away
1559
- let goodShapes = {};
1560
- goodShapes['type'] = "FeatureCollection";
1561
- goodShapes['features'] = [];
1562
- for (let i = 0; i < rawShapes.features.length; i++) {
1563
- const shape = rawShapes.features[i];
1564
- if (isAShape(shape)) {
1565
- const d = baseclient_1.Poly.polyDescribe(shape);
1566
- let f = {
1567
- type: 'Feature',
1568
- properties: { districtID: `${i + 1}` },
1569
- geometry: {
1570
- type: (d.npoly > 1) ? 'MultiPolygon' : 'Polygon',
1571
- coordinates: shape.geometry.coordinates
1572
- }
1573
- };
1574
- goodShapes.features.push(f);
1575
- }
1576
- }
1577
- const scores = dra_analytics_1.Compactness.kiwysiScoreShapes(goodShapes, 0 /* Revised */);
1578
- // Round & invert the scores here at the source vs. later on, higher up.
1579
- // Raw KIWYSI scores will be 1–100 with smaller better, so map to 1–100 bigger better.
1580
- return scores.map(n => 100 - Math.round(n) + 1);
1581
- }
1582
- exports.scoreKIWYSICompactness = scoreKIWYSICompactness;
1583
1506
  // SAVE THESE NOTES, IN CASE WE NEED TO REWORK HOW WE PERFORM THESE CALCS.
1584
1507
  // THEY REFLECT HOW I DID THEM IN PYTHON.
1585
1508
  //
@@ -1632,26 +1555,6 @@ function doHasEqualPopulations(s, bLog = false) {
1632
1555
  let popDevTest = s.getTest(4 /* PopulationDeviation */);
1633
1556
  const popDevPct = popDevTest['score'];
1634
1557
  const popDevNormalized = popDevTest['normalizedScore'];
1635
- // LEGACY - DELETE: Has 'roughly' equal populations is calculated in dra-analytics
1636
- /*
1637
- if (s.config.legacyanalytics && !s.config.newanalytics)
1638
- {
1639
- // 09-19-2020 - Added to catch edge case of only one non-empty district
1640
- const p = s._profile as L.Profile;
1641
- const totPopByDistrict = p.population.byDistrict.filter(x => x > 0);
1642
- const bTwoOrMoreDistricts: boolean = (totPopByDistrict.length > 1) ? true : false;
1643
-
1644
- // Populate the test entry
1645
- if (bTwoOrMoreDistricts && (popDevNormalized > 0))
1646
- {
1647
- test['score'] = true;
1648
- }
1649
- else
1650
- {
1651
- test['score'] = false;
1652
- }
1653
- }
1654
- */
1655
1558
  test['details']['deviation'] = popDevPct;
1656
1559
  test['details']['thresholds'] = popDevTest['details']['scale'];
1657
1560
  // Populate the N+1 summary "district" in district.statistics
@@ -1760,7 +1663,7 @@ function doAnalyzeRacialPolarization(s, districtID, groups, bLog = false) {
1760
1663
  return dra_analytics_1.Minority.analyzeRacialVoting(points, districtID, groups);
1761
1664
  }
1762
1665
  exports.doAnalyzeRacialPolarization = doAnalyzeRacialPolarization;
1763
- // 11-18-2020 - Moved RPV to racial-voting package.
1666
+ // RPV is in the dra-analytics package.
1764
1667
 
1765
1668
 
1766
1669
  /***/ }),
@@ -2296,76 +2199,7 @@ function getStatewideDemographics(s, bLog = false) {
2296
2199
  return demographics;
2297
2200
  }
2298
2201
  exports.getStatewideDemographics = getStatewideDemographics;
2299
- // SCORE A PLAN - Legacy using dra-score
2300
- // LEGACY - DELETE
2301
- /*
2302
- export function scorePlan(s: AnalyticsSession, p: Score.Profile, bLog: boolean = false, overridesJSON?: any): Score.Scorecard
2303
- {
2304
- let scorer = new Score.Scorer();
2305
- const scorecard: Score.Scorecard = scorer.score(p, overridesJSON);
2306
-
2307
- // LEGACY POST-SCORECARD HOUSEKEEPING
2308
- if (s.config.legacyanalytics && !s.config.newanalytics)
2309
- {
2310
- // Before returning, create a dummy population deviation test, for
2311
- // doHasEqualPopulations() to use later.This is preserving the old calling sequence.
2312
- let test = s.getTest(T.Test.PopulationDeviation) as T.TestEntry;
2313
-
2314
- // Get the raw population deviation
2315
- const popDev = scorecard.populationDeviation.raw;
2316
-
2317
- // Populate the test entry
2318
- test['score'] = popDev;
2319
- test['details'] = { 'maxDeviation': scorecard.populationDeviation.notes['maxDeviation'] };
2320
-
2321
- // Populate the N+1 summary "district" in district.statistics
2322
- let totalPop = s.districts.table.totalPop;
2323
- let popDevPct = s.districts.table.popDevPct;
2324
- let totalVAP = s.districts.table.totalVAP;
2325
-
2326
- const summaryRow = s.districts.numberOfRows() - 1;
2327
- totalPop[summaryRow] = p.population.targetSize;
2328
- popDevPct[summaryRow] = popDev;
2329
- totalVAP[summaryRow] = Math.round(totalVAP[summaryRow] / p.nDistricts);
2330
-
2331
- } // end
2332
-
2333
- // Add minority notes
2334
- scorecard.minority.details['majorityMinority'] = M.getMajorityMinority(s);
2335
- scorecard.minority.details['vraPreclearance'] = M.getVRASection5(s);
2336
-
2337
- try
2338
- {
2339
- // Add KIWYSI compactness score
2340
- const kiwysiScores: number[] = C.scoreKIWYSICompactness(s, bLog);
2341
- // 10-21-2020 - Computing the average score here
2342
- const avgKIWYSIScore: number = Math.round(U.avgArray(kiwysiScores));
2343
- scorecard.compactness.details['kiwysi'] = avgKIWYSIScore;
2344
-
2345
- // 10-21-2020 - Added KIWYSI scores to the by-district details
2346
- let byDistrict: Score.CompactnessByDistrict[] = scorecard.compactness.details['byDistrict'];
2347
- const nDistricts = byDistrict.length;
2348
-
2349
- for (let districtID = 1; districtID <= nDistricts; districtID++)
2350
- {
2351
- byDistrict[districtID - 1].kiwysiScore = kiwysiScores[districtID - 1];
2352
-
2353
- // 09-17-21 - Fix the normalized Polsby–Popper score!
2354
- const rawPolsby = byDistrict[districtID - 1].rawPolsby;
2355
- byDistrict[districtID - 1].normalizedPolsby = Rate.ratePolsby(rawPolsby);
2356
- }
2357
- }
2358
- catch (e)
2359
- {
2360
- console.log("Exception caught scoring KIWYSI compactness.");
2361
- console.log((<Error>e).message);
2362
- // throw e;
2363
- }
2364
-
2365
- return scorecard;
2366
- }
2367
- */
2368
- // SCORE A PLAN - New using dra-analytics
2202
+ // SCORE A PLAN using dra-analytics
2369
2203
  function computeMetrics(p, districtShapes, bLog = false) {
2370
2204
  if (bLog)
2371
2205
  console.log("Computing metrics ...");
@@ -2428,8 +2262,12 @@ function rateKeyDimensions(scorecard, p, bLog = false) {
2428
2262
  const rawDistrictSplitting = scorecard.splitting.district;
2429
2263
  const nCounties = p.nCounties;
2430
2264
  const nDistricts = p.nDistricts;
2431
- const countyRating = dra_analytics_1.Rate.rateCountySplitting(rawCountySplitting, nCounties, nDistricts, bLegislative);
2432
- const districtRating = dra_analytics_1.Rate.rateDistrictSplitting(rawDistrictSplitting, bLegislative);
2265
+ // HACK - Temporary fix to revert ratings for state legislative maps. Rate everything as CD's.
2266
+ // const countyRating = Rate.rateCountySplitting(rawCountySplitting, nCounties, nDistricts, bLegislative);
2267
+ // const districtRating = Rate.rateDistrictSplitting(rawDistrictSplitting, bLegislative);
2268
+ const countyRating = dra_analytics_1.Rate.rateCountySplitting(rawCountySplitting, nCounties, nDistricts);
2269
+ const districtRating = dra_analytics_1.Rate.rateDistrictSplitting(rawDistrictSplitting);
2270
+ //end
2433
2271
  const unadjusted = dra_analytics_1.Rate.rateSplitting(countyRating, districtRating);
2434
2272
  scorecard.splitting.score = dra_analytics_1.Rate.adjustSplittingRating(unadjusted, rawCountySplitting, rawDistrictSplitting);
2435
2273
  // Rate population deviation
@@ -2510,341 +2348,6 @@ function thunkScorecard(newScorecard, bLog = false) {
2510
2348
  return scorecard;
2511
2349
  }
2512
2350
  exports.thunkScorecard = thunkScorecard;
2513
- // LEGACY - DELETE
2514
- /*
2515
- export function compareScorecards(altLegacyScorecard: Score.Scorecard, legacyScorecard: Score.Scorecard, bLog: boolean = false): void
2516
- {
2517
- if (bLog) console.log("Comparing new & legacy scorecards ...");
2518
-
2519
- // A pretty loose tolerance, because we're not trimming values in the new analytics
2520
- const DECIMAL_PLACES = 2;
2521
- const DEFAULT_TOLERANCE = toleranceFn(DECIMAL_PLACES);
2522
-
2523
- // COMPARE PARTISAN SCORECARD
2524
-
2525
- // Compare BIAS section
2526
-
2527
- matchFloats("bestS", altLegacyScorecard.partisan.bias.bestS, legacyScorecard.partisan.bias.bestS, DEFAULT_TOLERANCE);
2528
- matchFloats("bestSf", altLegacyScorecard.partisan.bias.bestSf, legacyScorecard.partisan.bias.bestSf, DEFAULT_TOLERANCE);
2529
- matchFloats("estS", altLegacyScorecard.partisan.bias.estS, legacyScorecard.partisan.bias.estS, DEFAULT_TOLERANCE);
2530
- matchFloats("estSf", altLegacyScorecard.partisan.bias.estSf, legacyScorecard.partisan.bias.estSf, DEFAULT_TOLERANCE);
2531
- matchFloats("deviation", altLegacyScorecard.partisan.bias.deviation, legacyScorecard.partisan.bias.deviation, DEFAULT_TOLERANCE);
2532
- matchInts("proportionality/score", altLegacyScorecard.partisan.bias.score, legacyScorecard.partisan.bias.score);
2533
-
2534
- matchFloats("tOf", altLegacyScorecard.partisan.bias.tOf as number, legacyScorecard.partisan.bias.tOf as number, DEFAULT_TOLERANCE);
2535
- matchFloats("fptpS", altLegacyScorecard.partisan.bias.fptpS as number, legacyScorecard.partisan.bias.fptpS as number, DEFAULT_TOLERANCE);
2536
- matchFloats("bS50", altLegacyScorecard.partisan.bias.bS50 as number, legacyScorecard.partisan.bias.bS50 as number, DEFAULT_TOLERANCE);
2537
- matchFloats("deviation", altLegacyScorecard.partisan.bias.deviation, legacyScorecard.partisan.bias.deviation, DEFAULT_TOLERANCE);
2538
- matchUndefinableFloats("decl", altLegacyScorecard.partisan.bias.decl, legacyScorecard.partisan.bias.decl, toleranceFn(1));
2539
-
2540
- let rvPointsAlt = altLegacyScorecard.partisan.bias.rvPoints;
2541
- let rvPoints = legacyScorecard.partisan.bias.rvPoints;
2542
- if (matchUndefinedness("rvPoints", rvPointsAlt, rvPoints)) {
2543
- rvPointsAlt = rvPointsAlt as L.rVpoints;
2544
- rvPoints = rvPoints as L.rVpoints;
2545
- matchFloats("rvPoints/Sb", rvPointsAlt.Sb, rvPoints.Sb, DEFAULT_TOLERANCE);
2546
- matchFloats("rvPoints/Ra", rvPointsAlt.Ra, rvPoints.Ra, DEFAULT_TOLERANCE);
2547
- matchFloats("rvPoints/Rb", rvPointsAlt.Rb, rvPoints.Rb, DEFAULT_TOLERANCE);
2548
- matchFloats("rvPoints/Va", rvPointsAlt.Va, rvPoints.Va, DEFAULT_TOLERANCE);
2549
- matchFloats("rvPoints/Vb", rvPointsAlt.Vb, rvPoints.Vb, DEFAULT_TOLERANCE);
2550
- }
2551
-
2552
- matchFloats("gSym", altLegacyScorecard.partisan.bias.gSym as number, legacyScorecard.partisan.bias.gSym as number, DEFAULT_TOLERANCE);
2553
- matchUndefinableFloats("gamma", altLegacyScorecard.partisan.bias.gamma, legacyScorecard.partisan.bias.gamma, DEFAULT_TOLERANCE);
2554
- matchFloats("eG", altLegacyScorecard.partisan.bias.eG as number, legacyScorecard.partisan.bias.eG as number, DEFAULT_TOLERANCE);
2555
- matchUndefinableFloats("bSV", altLegacyScorecard.partisan.bias.bSV, legacyScorecard.partisan.bias.bSV, DEFAULT_TOLERANCE);
2556
- matchFloats("prop", altLegacyScorecard.partisan.bias.prop as number, legacyScorecard.partisan.bias.prop as number, DEFAULT_TOLERANCE);
2557
- matchFloats("mMs", altLegacyScorecard.partisan.bias.mMs as number, legacyScorecard.partisan.bias.mMs as number, DEFAULT_TOLERANCE);
2558
- matchFloats("mMd", altLegacyScorecard.partisan.bias.mMd as number, legacyScorecard.partisan.bias.mMd as number, DEFAULT_TOLERANCE);
2559
- matchUndefinableFloats("lO", altLegacyScorecard.partisan.bias.lO, legacyScorecard.partisan.bias.lO, DEFAULT_TOLERANCE);
2560
-
2561
- // Compare Impact section
2562
-
2563
- matchFloats("unearnedS", altLegacyScorecard.partisan.impact.unearnedS, legacyScorecard.partisan.impact.unearnedS, DEFAULT_TOLERANCE);
2564
- // Note - We don't use the impact score, so we don't compute it in the new scorecard.
2565
- // matchInts("impact/score", altLegacyScorecard.partisan.impact.score as number, legacyScorecard.partisan.impact.score);
2566
-
2567
- // Compare Responsiveness section
2568
-
2569
- matchUndefinableFloats("bigR", altLegacyScorecard.partisan.responsiveness.bigR, legacyScorecard.partisan.responsiveness.bigR, DEFAULT_TOLERANCE);
2570
- matchUndefinableFloats("littleR", altLegacyScorecard.partisan.responsiveness.littleR, legacyScorecard.partisan.responsiveness.littleR, DEFAULT_TOLERANCE);
2571
- matchUndefinableFloats("mIR", altLegacyScorecard.partisan.responsiveness.mIR, legacyScorecard.partisan.responsiveness.mIR, DEFAULT_TOLERANCE);
2572
- matchFloats("rD", altLegacyScorecard.partisan.responsiveness.rD as number, legacyScorecard.partisan.responsiveness.rD as number, DEFAULT_TOLERANCE);
2573
- matchFloats("rDf", altLegacyScorecard.partisan.responsiveness.rDf as number, legacyScorecard.partisan.responsiveness.rDf as number, DEFAULT_TOLERANCE);
2574
-
2575
- matchFloats("cSimple", altLegacyScorecard.partisan.responsiveness.cSimple, legacyScorecard.partisan.responsiveness.cSimple, DEFAULT_TOLERANCE);
2576
- matchFloats("cD", altLegacyScorecard.partisan.responsiveness.cD, legacyScorecard.partisan.responsiveness.cD, DEFAULT_TOLERANCE);
2577
- matchFloats("cDf", altLegacyScorecard.partisan.responsiveness.cDf, legacyScorecard.partisan.responsiveness.cDf, DEFAULT_TOLERANCE);
2578
- matchInts("competitiveness/score", altLegacyScorecard.partisan.responsiveness.score as number, legacyScorecard.partisan.responsiveness.score);
2579
-
2580
- matchPointArrays("dSVpoints", altLegacyScorecard.partisan.dSVpoints, legacyScorecard.partisan.dSVpoints, DEFAULT_TOLERANCE);
2581
- matchPointArrays("rSVpoints", altLegacyScorecard.partisan.rSVpoints, legacyScorecard.partisan.rSVpoints, DEFAULT_TOLERANCE);
2582
-
2583
- matchUndefinableFloats("averageDVf", altLegacyScorecard.partisan.averageDVf, legacyScorecard.partisan.averageDVf, DEFAULT_TOLERANCE);
2584
- matchUndefinableFloats("averageRVf", altLegacyScorecard.partisan.averageRVf, legacyScorecard.partisan.averageRVf, DEFAULT_TOLERANCE);
2585
- matchDicts("partisan/details", altLegacyScorecard.partisan.details, legacyScorecard.partisan.details);
2586
-
2587
- // COMPARE MINORITY SCORECARD
2588
-
2589
- matchObjectsAndArrays("pivotByDemographic", altLegacyScorecard.minority.pivotByDemographic, legacyScorecard.minority.pivotByDemographic);
2590
- matchFloats("opportunityDistricts", altLegacyScorecard.minority.opportunityDistricts, legacyScorecard.minority.opportunityDistricts, DEFAULT_TOLERANCE);
2591
- matchFloats("coalitionDistricts", altLegacyScorecard.minority.coalitionDistricts, legacyScorecard.minority.coalitionDistricts, DEFAULT_TOLERANCE);
2592
- matchInts("minority/score", altLegacyScorecard.minority.score as number, legacyScorecard.minority.score);
2593
- matchDicts("minority/details", altLegacyScorecard.minority.details, legacyScorecard.minority.details);
2594
-
2595
- // COMPARE COMPACTNESS SCORECARD
2596
-
2597
- matchFloats("reock", altLegacyScorecard.compactness.reock.raw, legacyScorecard.compactness.reock.raw, DEFAULT_TOLERANCE);
2598
- matchInts("reock/normalized", altLegacyScorecard.compactness.reock.normalized, legacyScorecard.compactness.reock.normalized);
2599
- matchFloats("polsby", altLegacyScorecard.compactness.polsby.raw, legacyScorecard.compactness.polsby.raw, DEFAULT_TOLERANCE);
2600
- matchInts("polsby/normalized", altLegacyScorecard.compactness.polsby.normalized, legacyScorecard.compactness.polsby.normalized);
2601
- matchInts("compactness/score", altLegacyScorecard.compactness.score as number, legacyScorecard.compactness.score);
2602
- // Compare 'byDistrict' results separately
2603
- const _altCompactnessByDistrict = Utils.deepCopy(altLegacyScorecard.compactness.details['byDistrict']);
2604
- const _CompactnessByDistrict = Utils.deepCopy(legacyScorecard.compactness.details['byDistrict']);
2605
- const _altCompactnessDetails = Utils.deepCopy(altLegacyScorecard.compactness.details);
2606
- const _CompactnessDetails = Utils.deepCopy(legacyScorecard.compactness.details);
2607
- delete _altCompactnessDetails['byDistrict'];
2608
- delete _CompactnessDetails['byDistrict'];
2609
- matchDicts("compactness/details", _altCompactnessDetails, _CompactnessDetails);
2610
- matchCompactnessByDistrict("compactness/byDistrict", _altCompactnessByDistrict, _CompactnessByDistrict, DEFAULT_TOLERANCE);
2611
-
2612
- // COMPARE SPLITTING SCORECARD
2613
-
2614
- matchFloats("county", altLegacyScorecard.splitting.county.raw, legacyScorecard.splitting.county.raw, DEFAULT_TOLERANCE);
2615
- matchInts("county/normalized", altLegacyScorecard.splitting.county.normalized, legacyScorecard.splitting.county.normalized);
2616
- matchFloats("district", altLegacyScorecard.splitting.district.raw, legacyScorecard.splitting.district.raw, DEFAULT_TOLERANCE);
2617
- matchInts("district/normalized", altLegacyScorecard.splitting.district.normalized, legacyScorecard.splitting.district.normalized);
2618
- matchInts("splitting/score", altLegacyScorecard.splitting.score as number, legacyScorecard.splitting.score);
2619
- matchDicts("splitting/details", altLegacyScorecard.splitting.details, legacyScorecard.splitting.details);
2620
-
2621
- // COMPARE POPULATION SCORECARD
2622
-
2623
- matchFloats("popdev", altLegacyScorecard.populationDeviation.raw, legacyScorecard.populationDeviation.raw, DEFAULT_TOLERANCE);
2624
- matchInts("popdev/score", altLegacyScorecard.populationDeviation.normalized, legacyScorecard.populationDeviation.normalized);
2625
- matchDicts("popdev/notes", altLegacyScorecard.populationDeviation.notes, legacyScorecard.populationDeviation.notes);
2626
-
2627
- matchDicts("details", altLegacyScorecard.details, legacyScorecard.details);
2628
- }
2629
- */
2630
- // LEGACY - DELETE
2631
- /*
2632
- // Matching helpers
2633
-
2634
- function matchFloats(property: string, received: number, good: number, tolerance: number): boolean
2635
- {
2636
- if (Utils.areRoughlyEqual(received, good, tolerance)) {
2637
- return true;
2638
- }
2639
- else {
2640
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2641
- return false;
2642
- }
2643
- }
2644
-
2645
- function toleranceFn (places: number): number{
2646
- return 0.5 / Math.pow(10, places)
2647
- }
2648
-
2649
- function matchInts(property: string, received: number, good: number): boolean
2650
- {
2651
- if (received == good) {
2652
- return true;
2653
- }
2654
- else {
2655
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2656
- return false;
2657
- }
2658
- }
2659
-
2660
- function matchUndefinableFloats(property: string, received: number | undefined, good: number | undefined, tolerance: number): boolean
2661
- {
2662
- if ((received === undefined) && (good === undefined)) return true;
2663
- if ((received === undefined) || (good === undefined)) {
2664
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2665
- return false;
2666
- }
2667
-
2668
- return matchFloats(property, received as number, good as number, tolerance);
2669
- }
2670
-
2671
- // https://stackoverflow.com/questions/13142968/deep-comparison-of-objects-arrays
2672
- function matchObjectsAndArrays (property: string, received: object | undefined, good: object | undefined): boolean
2673
- {
2674
- if ((received === undefined) && (good === undefined)) return true; // Both undefined
2675
-
2676
- if ((received === undefined) || (good === undefined)) { // One undefined but not the other
2677
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2678
- return false;
2679
- }
2680
-
2681
- if ((Object.keys(received).length === 0) && (Object.keys(good).length === 0)) return true; // Both empty
2682
-
2683
- if (JSON.stringify(received) === JSON.stringify(good)) return true; // Contents match
2684
-
2685
- console.log(`${property} objects or arrays do not match.`); // Contents don't match
2686
- return false;
2687
- }
2688
-
2689
- function matchDicts (property: string, received: L.Dict, good: L.Dict): boolean
2690
- {
2691
- if ((Object.keys(received).length === 0) && (Object.keys(good).length === 0)) return true; // Both empty
2692
-
2693
- const receivedStr: string = JSON.stringify(received);
2694
- const goodStr = JSON.stringify(good);
2695
- if (receivedStr === goodStr) return true; // Contents match
2696
-
2697
- console.log(`${property} does not match: ${goodStr} expected. Received ${receivedStr}.`); // Contents don't match
2698
-
2699
- return false;
2700
- }
2701
-
2702
- function matchUndefinedness(property: string, received: any | undefined, good: any | undefined): boolean
2703
- {
2704
- if ((received === undefined) && (good === undefined)) return true;
2705
-
2706
- if ((received === undefined) || (good === undefined)) return false;
2707
-
2708
- return true;
2709
- }
2710
-
2711
- function matchPointArrays(property: string, received: L.SVpoint[], good: L.SVpoint[], tolerance: number): boolean
2712
- {
2713
- if (received.length != good.length)
2714
- {
2715
- console.log(`${property} does not match: Different number of points.`);
2716
- return false;
2717
- }
2718
-
2719
- for (var i = 0; i < received.length; i++)
2720
- {
2721
- const vLabel: string = property + '/' + i.toString() + '/' + 'v';
2722
- const sLabel: string = property + '/' + i.toString() + '/' + 's';
2723
- if (!matchFloats(vLabel, received[i].v, good[i].v, tolerance)) return false;
2724
- if (!matchFloats(sLabel, received[i].s, good[i].s, tolerance)) return false;
2725
- }
2726
-
2727
- return true;
2728
- }
2729
-
2730
- function matchCompactnessByDistrict(property: string, received: L.CompactnessByDistrict[], good: L.CompactnessByDistrict[], tolerance: number): boolean
2731
- {
2732
- if (received.length != good.length)
2733
- {
2734
- console.log(`${property} does not match: Different number of districts.`);
2735
- return false;
2736
- }
2737
-
2738
- let bMismatched = false;
2739
- for (var i = 0; i < received.length; i++)
2740
- {
2741
- const rawReock: string = property + '/' + i.toString() + '/' + 'rawReock';
2742
- if (!matchFloats(rawReock, received[i].rawReock, good[i].rawReock, tolerance)) bMismatched = true;
2743
-
2744
- const normalizedReock: string = property + '/' + i.toString() + '/' + 'normalizedReock';
2745
- if (!matchInts(normalizedReock, received[i].normalizedReock, good[i].normalizedReock)) bMismatched = true;
2746
-
2747
- const rawPolsby: string = property + '/' + i.toString() + '/' + 'rawPolsby';
2748
- if (!matchFloats(rawPolsby, received[i].rawPolsby, good[i].rawPolsby, tolerance)) bMismatched = true;
2749
-
2750
- // TODO
2751
- // 09-17-21 - By-district Polsby–Popper ratings from dra-score in production are wrong!
2752
- const normalizedPolsby: string = property + '/' + i.toString() + '/' + 'normalizedPolsby';
2753
- if (!matchInts(normalizedPolsby, received[i].normalizedPolsby, good[i].normalizedPolsby)) bMismatched = true;
2754
-
2755
- const kiwysiScore: string = property + '/' + i.toString() + '/' + 'kiwysiScore';
2756
- if (!matchInts(kiwysiScore, received[i].kiwysiScore as number, good[i].kiwysiScore as number)) bMismatched = true;
2757
- }
2758
- if (bMismatched = true) return false;
2759
-
2760
- return true;
2761
- }
2762
- */
2763
- // LEGACY - DELETE
2764
- // Not used, after all
2765
- /* Modeled after David Sielaff's Jest extension 'toBeArrayWithValuesCloseTo'
2766
-
2767
- function matchFloatArrays(property: string, received: Array<any>, expected: Array<any>, tolerance: number): boolean
2768
- {
2769
- // Note - Not sure what this check was for ...
2770
- // if (expected.length == 0) {
2771
- // return {
2772
- // message: () => `expected arrays of same size`,
2773
- // pass: received.length == 0
2774
- // }
2775
- // }
2776
-
2777
- if (typeof expected[0] === "number")
2778
- {
2779
- if (typeof received[0] === "number") return matchArrays1d(property, received, expected, tolerance);
2780
-
2781
- console.log(`${property} does not match: array doesn't contain numbers.`);
2782
- return false;
2783
- }
2784
-
2785
- // Note - Ditto
2786
- // if (expected[0].length == 0) {
2787
- // return {
2788
- // message: () => `expected arrays of same size`,
2789
- // pass: received[0].length == 0
2790
- // }
2791
- // }
2792
-
2793
- if (expected[0] instanceof Array && typeof expected[0][0] === "number")
2794
- {
2795
- if (received[0] instanceof Array && typeof received[0][0] === "number") return matchArrays2d(property, received, expected, tolerance);
2796
-
2797
- console.log(`${property} does not match: arrays don't have the same dimensionality and content.`);
2798
- return false;
2799
- }
2800
-
2801
- console.log(`${property}: Expected 1d or 2d arrays.`);
2802
- return false;
2803
- }
2804
-
2805
- function matchArrays1d(property: string, received: number[], expected: number[], tolerance: number): boolean
2806
- {
2807
- if (received.length != expected.length)
2808
- {
2809
- console.log(`${property} does not match: arrays have different lengths.`);
2810
- return false;
2811
- }
2812
-
2813
- for (var index = 0; index < received.length; index++)
2814
- {
2815
- const cell: string = property + '/' + index.toString();
2816
- if (!matchFloats(cell, received[index], expected[index], tolerance)) return false;
2817
- }
2818
-
2819
- return true;
2820
- }
2821
-
2822
- function matchArrays2d(property: string, received: number[][], expected: number[][], tolerance: number): boolean
2823
- {
2824
- if (received.length != expected.length)
2825
- {
2826
- console.log(`${property} does not match: arrays have different lengths.`);
2827
- return false;
2828
- }
2829
-
2830
- for (var index = 0; index < received.length; index++)
2831
- {
2832
- if (received[index].length != expected[index].length)
2833
- {
2834
- console.log(`${property} does not match: arrays have different lengths.`);
2835
- return false;
2836
- }
2837
-
2838
- for (var inner = 0; inner < received[index].length; inner++)
2839
- {
2840
- const cell: string = property + '/' + index.toString() + '/' + inner.toString();
2841
- if (!matchFloats(cell, received[index][inner], expected[index][inner], tolerance)) return false;
2842
- }
2843
- }
2844
-
2845
- return true;
2846
- }
2847
- */
2848
2351
 
2849
2352
 
2850
2353
  /***/ }),
@@ -2864,25 +2367,12 @@ exports.OUT_OF_STATE = exports.NUMBER_OF_ITEMS_TO_REPORT = exports.NOT_ASSIGNED
2864
2367
  // Keep four decimal places for fractions [0–1], i.e.,
2865
2368
  // keep two decimal places for %'s [0–100].
2866
2369
  exports.PRECISION = 4;
2867
- // LEGACY - Not used
2868
- // Normalized scores [0-100]
2869
- // export const NORMALIZED_RANGE: number = 100;
2870
2370
  // The dummy district ID for features not assigned districts yet
2871
2371
  exports.NOT_ASSIGNED = 0;
2872
2372
  // # of items to report as problematic (e.g., features, districts, etc.)
2873
2373
  exports.NUMBER_OF_ITEMS_TO_REPORT = 10;
2874
2374
  // The virtual geoID for "neighbors" in other states
2875
2375
  exports.OUT_OF_STATE = "OUT_OF_STATE";
2876
- // LEGACY - Not used
2877
- // "Roughly equal" = average census block size / 2
2878
- // const AVERAGE_BLOCK_SIZE = 30;
2879
- // export const EQUAL_TOLERANCE: number = AVERAGE_BLOCK_SIZE / 2;
2880
- // LEGACY - Not used
2881
- // County & district splitting weights
2882
- // export const COUNTY_SPLITTING_WEIGHT = 0.8;
2883
- // export const DISTRICT_SPLITTING_WEIGHT = 1.0 - COUNTY_SPLITTING_WEIGHT;
2884
- // 2020
2885
- // export const SHAPES = "2010 VTD shapes";
2886
2376
 
2887
2377
 
2888
2378
  /***/ }),
@@ -2898,14 +2388,6 @@ exports.OUT_OF_STATE = "OUT_OF_STATE";
2898
2388
  // TYPE DEFINITIONS
2899
2389
  //
2900
2390
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2901
- // LEGACY - DELETE
2902
- // export
2903
- // {
2904
- // Profile, Scorecard,
2905
- // // LEGACY - DELETE
2906
- // // estSeatProbability
2907
- // } from '@dra2020/dra-score';
2908
- // END
2909
2391
 
2910
2392
 
2911
2393
  /***/ }),
@@ -2945,18 +2427,6 @@ const DT = __importStar(__webpack_require__(/*! @dra2020/dra-types */ "@dra2020/
2945
2427
  const _data_1 = __webpack_require__(/*! ./_data */ "./src/_data.ts");
2946
2428
  const S = __importStar(__webpack_require__(/*! ./settings */ "./src/settings.ts"));
2947
2429
  // PLAN HELPERS
2948
- // LEGACY - Not used
2949
- // Is a "neighbor" in state?
2950
- // export function isInState(geoID: string): boolean
2951
- // {
2952
- // return geoID != S.OUT_OF_STATE;
2953
- // }
2954
- // LEGACY - Not used
2955
- // Is a "neighbor" out of state?
2956
- // export function isOutOfState(geoID: string): boolean
2957
- // {
2958
- // return geoID == S.OUT_OF_STATE;
2959
- // }
2960
2430
  // Get the districtID to which a geoID is assigned
2961
2431
  function getDistrict(plan, geoID) {
2962
2432
  // All geoIDs in a state *should be* assigned to a district (including the
@@ -3185,12 +2655,6 @@ function depthof(a) {
3185
2655
  }
3186
2656
  }
3187
2657
  exports.depthof = depthof;
3188
- /* TriState
3189
- export function mapBooleanToTriState(bool: boolean): T.TriState
3190
- {
3191
- return (bool) ? T.TriState.Green : T.TriState.Red;
3192
- }
3193
- */
3194
2658
 
3195
2659
 
3196
2660
  /***/ }),