@dra2020/district-analytics 5.0.1 → 5.1.0

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/cli.js CHANGED
@@ -89315,23 +89315,33 @@ const C = __importStar(__webpack_require__(/*! ./config */ "./src/config.ts"));
89315
89315
  const normalize_1 = __webpack_require__(/*! ./normalize */ "./src/normalize.ts");
89316
89316
  function scoreCountySplitting(rawValue, nCounties, nDistricts) {
89317
89317
  const _normalizer = new normalize_1.Normalizer(rawValue);
89318
- const best = C.countySplittingRange()[C.BEG];
89319
- const worst = countySplitThreshold(nCounties, nDistricts);
89320
- _normalizer.clip(best, worst);
89321
- _normalizer.unitize(best, worst);
89318
+ const singleBest = C.countySplittingRange()[C.BEG];
89319
+ const singleWorst = C.countySplittingRange()[C.END];
89320
+ // The practical ideal score depends on the # of counties & districts
89321
+ const avgBest = countySplitBest(nCounties, nDistricts);
89322
+ const avgWorst = countySplitWorst(avgBest);
89323
+ _normalizer.clip(avgBest, avgWorst);
89324
+ _normalizer.unitize(avgBest, avgWorst);
89322
89325
  _normalizer.invert();
89323
89326
  _normalizer.rescale();
89324
89327
  return _normalizer.normalizedNum;
89325
89328
  }
89326
89329
  exports.scoreCountySplitting = scoreCountySplitting;
89327
- function countySplitThreshold(nCounties, nDistricts) {
89328
- const m = C.allowableSplitsMultiplier();
89329
- const worst = C.countySplittingRange()[1];
89330
- const nAllowableSplits = Math.min(m * (nDistricts - 1), nCounties);
89331
- const threshold = ((nAllowableSplits * worst) + ((nCounties - nAllowableSplits) * 1.0)) / nCounties;
89330
+ function countySplitBest(nCounties, nDistricts) {
89331
+ const practicalBest = C.countySplittingRange()[C.BEG];
89332
+ const nAllowableSplits = Math.min(nDistricts - 1, nCounties);
89333
+ const threshold = ((nAllowableSplits * practicalBest) + ((nCounties - nAllowableSplits) * 1.0)) / nCounties;
89332
89334
  return threshold;
89333
89335
  }
89334
- exports.countySplitThreshold = countySplitThreshold;
89336
+ exports.countySplitBest = countySplitBest;
89337
+ function countySplitWorst(avgBest) {
89338
+ const singleBest = C.countySplittingRange()[C.BEG];
89339
+ const singleWorst = C.countySplittingRange()[C.END];
89340
+ // The practical ideal score depends on the # of counties & districts
89341
+ const avgWorst = avgBest * (singleWorst / singleBest);
89342
+ return avgWorst;
89343
+ }
89344
+ exports.countySplitWorst = countySplitWorst;
89335
89345
  function scoreDistrictSplitting(rawValue) {
89336
89346
  const _normalizer = new normalize_1.Normalizer(rawValue);
89337
89347
  const best = C.districtSplittingRange()[C.BEG];
@@ -89793,7 +89803,7 @@ exports.scorePolsbyPopper = scorePolsbyPopper;
89793
89803
  /*! exports provided: partisan, minority, traditionalPrinciples, default */
89794
89804
  /***/ (function(module) {
89795
89805
 
89796
- module.exports = JSON.parse("{\"partisan\":{\"bias\":{\"range\":[0,0.2],\"weight\":[50,80]},\"impact\":{\"weight\":[50,0],\"threshold\":4},\"competitiveness\":{\"overall\":{\"range\":[0,0.67],\"weight\":100},\"marginal\":{\"range\":[0,0.85],\"weight\":0},\"range\":[0.45,0.55],\"distribution\":[0.25,0.75],\"weight\":[0,20]},\"bonus\":2,\"weight\":[100,80]},\"minority\":{\"range\":[0.37,0.5],\"distribution\":[0.25,0.75],\"shift\":0.15,\"bonus\":20},\"traditionalPrinciples\":{\"compactness\":{\"reock\":{\"range\":[0.25,0.5],\"weight\":50},\"polsby\":{\"range\":[0.1,0.5],\"weight\":50},\"weight\":[0,50]},\"splitting\":{\"county\":{\"range\":[1,1.71],\"allowableSplitsMultiplier\":1.5,\"weight\":50},\"district\":{\"range\":[1,1.5],\"weight\":50},\"weight\":[0,50]},\"popdev\":{\"range\":[[0.0075,0.002],[0.1,-1]],\"weight\":[0,0]},\"weight\":[0,20]}}");
89806
+ module.exports = JSON.parse("{\"partisan\":{\"bias\":{\"range\":[0,0.2],\"weight\":[50,80]},\"impact\":{\"weight\":[50,0],\"threshold\":4},\"competitiveness\":{\"overall\":{\"range\":[0,0.67],\"weight\":100},\"marginal\":{\"range\":[0,0.85],\"weight\":0},\"range\":[0.45,0.55],\"distribution\":[0.25,0.75],\"weight\":[0,20]},\"bonus\":2,\"weight\":[100,80]},\"minority\":{\"range\":[0.37,0.5],\"distribution\":[0.25,0.75],\"shift\":0.15,\"bonus\":20},\"traditionalPrinciples\":{\"compactness\":{\"reock\":{\"range\":[0.25,0.5],\"weight\":50},\"polsby\":{\"range\":[0.1,0.5],\"weight\":50},\"weight\":[0,50]},\"splitting\":{\"county\":{\"range\":[1.26,1.68],\"weight\":50},\"district\":{\"range\":[1.26,1.68],\"weight\":50},\"weight\":[0,50]},\"popdev\":{\"range\":[[0.0075,0.002],[0.1,-1]],\"weight\":[0,0]},\"weight\":[0,20]}}");
89797
89807
 
89798
89808
  /***/ }),
89799
89809
 
@@ -89948,11 +89958,6 @@ function countySplittingRange(overridesJSON) {
89948
89958
  return range;
89949
89959
  }
89950
89960
  exports.countySplittingRange = countySplittingRange;
89951
- function allowableSplitsMultiplier(overridesJSON) {
89952
- const m = config_json_1.default.traditionalPrinciples.splitting.county.allowableSplitsMultiplier;
89953
- return m;
89954
- }
89955
- exports.allowableSplitsMultiplier = allowableSplitsMultiplier;
89956
89961
  function districtSplittingWeight(overridesJSON) {
89957
89962
  const dsW = config_json_1.default.traditionalPrinciples.splitting.district.weight;
89958
89963
  return dsW;
@@ -90165,12 +90170,10 @@ function evalMinorityOpportunity(p, bLog = false) {
90165
90170
  averageDVf: averageDVf,
90166
90171
  bucketsByDemographic: bucketsByDemo
90167
90172
  },
90168
- // nOpportunity1: l1,
90169
- // nOpportunity2: l2,
90170
90173
  nProportional: pD,
90171
90174
  opportunityDistricts: oD,
90172
90175
  score: score,
90173
- details: {} // TODO - Add notes
90176
+ details: {}
90174
90177
  };
90175
90178
  return mS;
90176
90179
  }
@@ -90500,7 +90503,7 @@ function scorePartisan(Vf, VfArray, options) {
90500
90503
  competitiveness: competitiveScoring,
90501
90504
  score: acrossStatesPartisanScore,
90502
90505
  score2: withinStatesPartisanScore,
90503
- details: {} // TODO - Add notes
90506
+ details: {}
90504
90507
  };
90505
90508
  return s;
90506
90509
  }
@@ -91185,7 +91188,7 @@ function calcMinimalInverseResponsiveness(Vf, r) {
91185
91188
  const bBalanced = isBalanced(Vf);
91186
91189
  const ideal = bBalanced ? 0.1 : 0.2;
91187
91190
  MIR = (1 / r) - ideal;
91188
- MIR = U.trim(MIR);
91191
+ MIR = U.trim(Math.max(MIR, 0.0));
91189
91192
  }
91190
91193
  return MIR;
91191
91194
  }
@@ -91290,7 +91293,7 @@ function scorePlan(p, overridesJSON) {
91290
91293
  compactness: cS,
91291
91294
  splitting: sS,
91292
91295
  populationDeviation: pdS,
91293
- details: {} // TODO - Add notes
91296
+ details: {}
91294
91297
  };
91295
91298
  // PARTISAN ("fair") subcategories - bias, impact, & competitiveness (plus lots of supporting measures)
91296
91299
  const options = {
@@ -91311,7 +91314,7 @@ function scorePlan(p, overridesJSON) {
91311
91314
  minority: mS,
91312
91315
  traditionalPrinciples: tpS,
91313
91316
  score: score,
91314
- details: {} // TODO - Add notes
91317
+ details: {}
91315
91318
  };
91316
91319
  return scorecard;
91317
91320
  }
@@ -91366,12 +91369,7 @@ function printScorecardRow(xx, name, N, Vf, s) {
91366
91369
  s.partisan.bias.score, s.partisan.impact.unearnedS, // 9
91367
91370
  s.partisan.impact.score, s.partisan.competitiveness.cSimple, // 11
91368
91371
  s.partisan.competitiveness.cD, s.partisan.competitiveness.mD, s.partisan.competitiveness.score, s.partisan.score2, // 15
91369
- s.traditionalPrinciples.compactness.reock.raw, s.traditionalPrinciples.compactness.reock.normalized, s.traditionalPrinciples.compactness.polsby.raw, s.traditionalPrinciples.compactness.polsby.normalized, s.traditionalPrinciples.compactness.score, s.traditionalPrinciples.splitting.county.raw, s.traditionalPrinciples.splitting.county.normalized, s.traditionalPrinciples.splitting.district.raw, s.traditionalPrinciples.splitting.district.normalized, s.traditionalPrinciples.splitting.score, s.traditionalPrinciples.populationDeviation.raw, s.traditionalPrinciples.populationDeviation.normalized, s.traditionalPrinciples.score,
91370
- // s.minority.nOpportunity1,
91371
- // s.minority.nOpportunity2,
91372
- s.minority.opportunityDistricts,
91373
- // s.minority.nProportional,
91374
- s.minority.score, s.score);
91372
+ s.traditionalPrinciples.compactness.reock.raw, s.traditionalPrinciples.compactness.reock.normalized, s.traditionalPrinciples.compactness.polsby.raw, s.traditionalPrinciples.compactness.polsby.normalized, s.traditionalPrinciples.compactness.score, s.traditionalPrinciples.splitting.county.raw, s.traditionalPrinciples.splitting.county.normalized, s.traditionalPrinciples.splitting.district.raw, s.traditionalPrinciples.splitting.district.normalized, s.traditionalPrinciples.splitting.score, s.traditionalPrinciples.populationDeviation.raw, s.traditionalPrinciples.populationDeviation.normalized, s.traditionalPrinciples.score, s.minority.opportunityDistricts, s.minority.score, s.score);
91375
91373
  }
91376
91374
  exports.printScorecardRow = printScorecardRow;
91377
91375
 
@@ -102185,7 +102183,7 @@ Compactness: None
102185
102183
  Proportionality: 27.67% gap
102186
102184
  Cohesiveness: 11 unexpected splits, affecting 27.14% of the total population
102187
102185
 
102188
- These counties are split unexpectedly:
102186
+ These counties are split unexpectedly (meaning that they're smaller than a district):
102189
102187
 
102190
102188
  • Bladen
102191
102189
  • Buncombe
@@ -102289,6 +102287,7 @@ function doFindCountiesSplitUnexpectedly(s, bLog = false) {
102289
102287
  }
102290
102288
  countiesSplitUnexpectedly = countiesSplitUnexpectedly.sort();
102291
102289
  test['score'] = U.trim(unexpectedAffected);
102290
+ test['details']['nSplits'] = nSplits;
102292
102291
  test['details']['unexpectedSplits'] = unexpectedSplits;
102293
102292
  test['details']['countiesSplitUnexpectedly'] = countiesSplitUnexpectedly;
102294
102293
  return test;
@@ -102571,6 +102570,49 @@ function gfDiameter(poly) {
102571
102570
  exports.gfDiameter = gfDiameter;
102572
102571
 
102573
102572
 
102573
+ /***/ }),
102574
+
102575
+ /***/ "./src/minority.ts":
102576
+ /*!*************************!*\
102577
+ !*** ./src/minority.ts ***!
102578
+ \*************************/
102579
+ /*! no static exports found */
102580
+ /***/ (function(module, exports, __webpack_require__) {
102581
+
102582
+ "use strict";
102583
+
102584
+ //
102585
+ // PROTECTS MINORITIES
102586
+ //
102587
+ var __importDefault = (this && this.__importDefault) || function (mod) {
102588
+ return (mod && mod.__esModule) ? mod : { "default": mod };
102589
+ };
102590
+ Object.defineProperty(exports, "__esModule", { value: true });
102591
+ const majority_minority_json_1 = __importDefault(__webpack_require__(/*! ../static/majority-minority.json */ "./static/majority-minority.json"));
102592
+ const vra5_preclearance_json_1 = __importDefault(__webpack_require__(/*! ../static/vra5-preclearance.json */ "./static/vra5-preclearance.json"));
102593
+ // import stateContacts from '../static/state-contacts.json';
102594
+ // import demographicDefs from '../static/demographic-defns.json';
102595
+ // TODO - 2020: Update/revise this, when the update comes out in September:
102596
+ // Sources for majority-minority info:
102597
+ // - https://en.wikipedia.org/wiki/List_of_majority-minority_United_States_congressional_districts
102598
+ // - http://www.ncsl.org/Portals/1/Documents/Redistricting/Redistricting_2010.pdf (PP. 80–84)
102599
+ // - https://www.justice.gov/crt/jurisdictions-previously-covered-section-5
102600
+ function getMajorityMinority(s) {
102601
+ const xx = s.state.xx;
102602
+ const mMDict = majority_minority_json_1.default;
102603
+ const stateMM = mMDict[xx];
102604
+ return stateMM;
102605
+ }
102606
+ exports.getMajorityMinority = getMajorityMinority;
102607
+ function getVRASection5(s) {
102608
+ const xx = s.state.xx;
102609
+ const vraPreDict = vra5_preclearance_json_1.default;
102610
+ const stateVRAPre = vraPreDict[xx];
102611
+ return stateVRAPre;
102612
+ }
102613
+ exports.getVRASection5 = getVRASection5;
102614
+
102615
+
102574
102616
  /***/ }),
102575
102617
 
102576
102618
  /***/ "./src/political.ts":
@@ -103000,6 +103042,7 @@ function doAnalyzePostProcessing(s, bLog = false) {
103000
103042
  scorecard.traditionalPrinciples.details['census'] = datasets.census;
103001
103043
  const simpleSplits = s.getTest(5 /* UnexpectedCountySplits */);
103002
103044
  scorecard.traditionalPrinciples.details['unexpectedAffected'] = simpleSplits['score'];
103045
+ scorecard.traditionalPrinciples.details['nSplits'] = simpleSplits['details']['nSplits'];
103003
103046
  scorecard.traditionalPrinciples.details['countiesSplitUnexpectedly'] = U.deepCopy(simpleSplits['details']['countiesSplitUnexpectedly']);
103004
103047
  // NOTE - Add split precincts in dra-client directly
103005
103048
  // Derive secondary tests
@@ -103035,6 +103078,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
103035
103078
  const Score = __importStar(__webpack_require__(/*! @dra2020/dra-score */ "./node_modules/@dra2020/dra-score/dist/dra-score.bundle.js"));
103036
103079
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
103037
103080
  const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
103081
+ const M = __importStar(__webpack_require__(/*! ./minority */ "./src/minority.ts"));
103038
103082
  // PROFILE A PLAN
103039
103083
  function profilePlan(s, bLog = false) {
103040
103084
  const state = s.state.xx;
@@ -103154,7 +103198,9 @@ function scorePlan(s, p, bLog = false, overridesJSON) {
103154
103198
  let summaryRow = s.districts.numberOfRows() - 1;
103155
103199
  totalPop[summaryRow] = p.populationProfile.targetSize;
103156
103200
  popDevPct[summaryRow] = popDev;
103157
- //
103201
+ // Add minority notes
103202
+ scorecard.minority.details['majorityMinority'] = M.getMajorityMinority(s);
103203
+ scorecard.minority.details['vraPreclearance'] = M.getVRASection5(s);
103158
103204
  return scorecard;
103159
103205
  }
103160
103206
  exports.scorePlan = scorePlan;
@@ -103688,6 +103734,17 @@ function isEmbedded(districtID, geoIDs, plan, graph) {
103688
103734
  exports.isEmbedded = isEmbedded;
103689
103735
 
103690
103736
 
103737
+ /***/ }),
103738
+
103739
+ /***/ "./static/majority-minority.json":
103740
+ /*!***************************************!*\
103741
+ !*** ./static/majority-minority.json ***!
103742
+ \***************************************/
103743
+ /*! exports provided: AL, AK, AZ, AR, CA, CO, CT, DE, FL, GA, HI, ID, IL, IN, IA, KS, KY, LA, ME, MD, MA, MI, MN, MS, MO, MT, NE, NV, NH, NJ, NM, NY, NC, ND, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VT, VA, WA, WV, WI, WY, default */
103744
+ /***/ (function(module) {
103745
+
103746
+ module.exports = JSON.parse("{\"AL\":{\"Black\":[7],\"Hispanic\":[],\"Pacific\":[]},\"AK\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"AZ\":{\"Black\":[],\"Hispanic\":[2,4,7],\"Pacific\":[]},\"AR\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"CA\":{\"Black\":[13,37,43],\"Hispanic\":[17,18,20,21,28,31,32,34,35,38,39,43,45,47,51],\"Pacific\":[12,13,14,15,17,18,19,27,34,39,45,47,52]},\"CO\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"CT\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"DE\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"FL\":{\"Black\":[5,20,24],\"Hispanic\":[18,21,25],\"Pacific\":[]},\"GA\":{\"Black\":[2,4,5,13],\"Hispanic\":[],\"Pacific\":[]},\"HI\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[2]},\"ID\":{\"Black\":[],\"Hispanic\":[1],\"Pacific\":[]},\"IL\":{\"Black\":[1,2,7],\"Hispanic\":[4],\"Pacific\":[]},\"IN\":{\"Black\":[7],\"Hispanic\":[],\"Pacific\":[]},\"IA\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"KS\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"KY\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"LA\":{\"Black\":[2],\"Hispanic\":[],\"Pacific\":[]},\"ME\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"MD\":{\"Black\":[4,7],\"Hispanic\":[],\"Pacific\":[]},\"MA\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"MI\":{\"Black\":[13,14],\"Hispanic\":[],\"Pacific\":[]},\"MN\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"MS\":{\"Black\":[2],\"Hispanic\":[],\"Pacific\":[]},\"MO\":{\"Black\":[1,5],\"Hispanic\":[],\"Pacific\":[]},\"MT\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"NE\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"NV\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"NH\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"NJ\":{\"Black\":[10,12],\"Hispanic\":[13],\"Pacific\":[6]},\"NM\":{\"Black\":[],\"Hispanic\":[2,13],\"Pacific\":[]},\"NY\":{\"Black\":[5,8,9,13],\"Hispanic\":[12,16],\"Pacific\":[6,7,10]},\"NC\":{\"Black\":[1,12],\"Hispanic\":[],\"Pacific\":[]},\"ND\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"OH\":{\"Black\":[3,11],\"Hispanic\":[],\"Pacific\":[]},\"OK\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"OR\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"PA\":{\"Black\":[2],\"Hispanic\":[],\"Pacific\":[]},\"RI\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"SC\":{\"Black\":[6],\"Hispanic\":[],\"Pacific\":[]},\"SD\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"TN\":{\"Black\":[9],\"Hispanic\":[],\"Pacific\":[]},\"TX\":{\"Black\":[9,18,33],\"Hispanic\":[15,16,19,20,23,27,28,29,32],\"Pacific\":[]},\"UT\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"VT\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"VA\":{\"Black\":[3],\"Hispanic\":[],\"Pacific\":[]},\"WA\":{\"Black\":[],\"Hispanic\":[3],\"Pacific\":[9]},\"WV\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]},\"WI\":{\"Black\":[4],\"Hispanic\":[],\"Pacific\":[]},\"WY\":{\"Black\":[],\"Hispanic\":[],\"Pacific\":[]}}");
103747
+
103691
103748
  /***/ }),
103692
103749
 
103693
103750
  /***/ "./static/state-reqs.json":
@@ -103701,6 +103758,17 @@ module.exports = JSON.parse("{\"AL\":\"https://www.brennancenter.org/sites/defau
103701
103758
 
103702
103759
  /***/ }),
103703
103760
 
103761
+ /***/ "./static/vra5-preclearance.json":
103762
+ /*!***************************************!*\
103763
+ !*** ./static/vra5-preclearance.json ***!
103764
+ \***************************************/
103765
+ /*! exports provided: AL, AK, AZ, CA, FL, GA, LA, MI, MS, NY, NC, SC, SD, TX, VA, default */
103766
+ /***/ (function(module) {
103767
+
103768
+ module.exports = JSON.parse("{\"AL\":\"all\",\"AK\":\"all\",\"AZ\":\"all\",\"CA\":\"parts\",\"FL\":\"parts\",\"GA\":\"all\",\"LA\":\"all\",\"MI\":\"parts\",\"MS\":\"all\",\"NY\":\"parts\",\"NC\":\"parts\",\"SC\":\"all\",\"SD\":\"parts\",\"TX\":\"all\",\"VA\":\"all\"}");
103769
+
103770
+ /***/ }),
103771
+
103704
103772
  /***/ "./test/_cli.ts":
103705
103773
  /*!**********************!*\
103706
103774
  !*** ./test/_cli.ts ***!