@cdc/map 2.6.2 → 2.6.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.
- package/dist/cdcmap.js +27 -27
- package/examples/default-county.json +105 -0
- package/examples/default-single-state.json +109 -0
- package/examples/default-usa.json +744 -603
- package/examples/example-city-state.json +474 -0
- package/examples/example-world-map.json +1596 -0
- package/examples/gender-rate-map.json +1 -0
- package/package.json +50 -47
- package/src/CdcMap.js +422 -159
- package/src/components/CityList.js +3 -2
- package/src/components/CountyMap.js +556 -0
- package/src/components/DataTable.js +73 -19
- package/src/components/EditorPanel.js +2088 -1230
- package/src/components/Sidebar.js +5 -5
- package/src/components/SingleStateMap.js +326 -0
- package/src/components/UsaMap.js +20 -3
- package/src/data/abbreviations.js +57 -0
- package/src/data/color-palettes.js +10 -1
- package/src/data/county-map-halfquality.json +58453 -0
- package/src/data/county-map-quarterquality.json +1 -0
- package/src/data/county-topo.json +1 -0
- package/src/data/dfc-map.json +1 -0
- package/src/data/initial-state.js +2 -2
- package/src/data/newtest.json +1 -0
- package/src/data/state-abbreviations.js +60 -0
- package/src/data/supported-geos.js +3504 -151
- package/src/data/test.json +1 -0
- package/src/hooks/useActiveElement.js +19 -0
- package/src/index.html +27 -20
- package/src/index.js +8 -4
- package/src/scss/datatable.scss +2 -1
- package/src/scss/main.scss +10 -1
- package/src/scss/map.scss +153 -123
- package/src/scss/sidebar.scss +0 -1
- package/uploads/upload-example-city-state.json +392 -0
- package/uploads/upload-example-world-data.json +1490 -0
- package/LICENSE +0 -201
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import parse from 'html-react-parser';
|
|
3
3
|
|
|
4
4
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
@@ -52,7 +52,7 @@ const Sidebar = (props) => {
|
|
|
52
52
|
|
|
53
53
|
const entryMin = addCommas(entry.min);
|
|
54
54
|
|
|
55
|
-
let formattedText = `${prefix + entryMin + suffix} - ${prefix + entryMax + suffix}`;
|
|
55
|
+
let formattedText = `${prefix + entryMin + suffix}${entryMax !== entryMin ? ` - ${prefix + entryMax + suffix}` : ''}`;
|
|
56
56
|
|
|
57
57
|
// If interval, add some formatting
|
|
58
58
|
if (legend.type === 'equalinterval' && idx !== runtimeLegend.length - 1) {
|
|
@@ -72,7 +72,7 @@ const Sidebar = (props) => {
|
|
|
72
72
|
let legendLabel = formattedText;
|
|
73
73
|
|
|
74
74
|
if (entry.hasOwnProperty('special')) {
|
|
75
|
-
legendLabel = entry.value;
|
|
75
|
+
legendLabel = entry.label || entry.value;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
return (
|
|
@@ -119,7 +119,7 @@ const Sidebar = (props) => {
|
|
|
119
119
|
|
|
120
120
|
return (
|
|
121
121
|
<ErrorBoundary component="Sidebar">
|
|
122
|
-
<aside className={`${legend.position} ${legend.singleColumn ? 'single-column' : ''} ${viewport}`}>
|
|
122
|
+
<aside id="legend" className={`${legend.position} ${legend.singleColumn ? 'single-column cdcdataviz-sr-focusable' : 'cdcdataviz-sr-focusable'} ${viewport}`} role="region" aria-label="Legend" tabIndex="0">
|
|
123
123
|
<section className="legend-section" aria-label="Map Legend">
|
|
124
124
|
{runtimeLegend.disabledAmt > 0 &&
|
|
125
125
|
(
|
|
@@ -164,4 +164,4 @@ const Sidebar = (props) => {
|
|
|
164
164
|
);
|
|
165
165
|
};
|
|
166
166
|
|
|
167
|
-
export default Sidebar;
|
|
167
|
+
export default Sidebar;
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import React, { useState, useEffect, memo, useRef } from 'react';
|
|
2
|
+
/** @jsx jsx */
|
|
3
|
+
import { jsx } from '@emotion/react'
|
|
4
|
+
import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
|
|
5
|
+
import { geoCentroid, geoPath } from "d3-geo";
|
|
6
|
+
import { feature, mesh } from "topojson-client";
|
|
7
|
+
import { CustomProjection } from '@visx/geo';
|
|
8
|
+
import colorPalettes from '../data/color-palettes';
|
|
9
|
+
import { geoAlbersUsaTerritories } from 'd3-composite-projections';
|
|
10
|
+
import testJSON from '../data/dfc-map.json';
|
|
11
|
+
|
|
12
|
+
const abbrs = {
|
|
13
|
+
Alabama: 'AL',
|
|
14
|
+
Alaska: 'AK',
|
|
15
|
+
Arizona: 'AZ',
|
|
16
|
+
Arkansas: 'AR',
|
|
17
|
+
California: 'CA',
|
|
18
|
+
Colorado: 'CO',
|
|
19
|
+
Connecticut: 'CT',
|
|
20
|
+
Delaware: 'DE',
|
|
21
|
+
Florida: 'FL',
|
|
22
|
+
Georgia: 'GA',
|
|
23
|
+
Hawaii: 'HI',
|
|
24
|
+
Idaho: 'ID',
|
|
25
|
+
Illinois: 'IL',
|
|
26
|
+
Indiana: 'IN',
|
|
27
|
+
Iowa: 'IA',
|
|
28
|
+
Kansas: 'KS',
|
|
29
|
+
Kentucky: 'KY',
|
|
30
|
+
Louisiana: 'LA',
|
|
31
|
+
Maine: 'ME',
|
|
32
|
+
Maryland: 'MD',
|
|
33
|
+
Massachusetts: 'MA',
|
|
34
|
+
Michigan: 'MI',
|
|
35
|
+
Minnesota: 'MN',
|
|
36
|
+
Mississippi: 'MS',
|
|
37
|
+
Missouri: 'MO',
|
|
38
|
+
Montana: 'MT',
|
|
39
|
+
Nebraska: 'NE',
|
|
40
|
+
Nevada: 'NV',
|
|
41
|
+
'New Hampshire': 'NH',
|
|
42
|
+
'New Jersey': 'NJ',
|
|
43
|
+
'New Mexico': 'NM',
|
|
44
|
+
'New York': 'NY',
|
|
45
|
+
'North Carolina': 'NC',
|
|
46
|
+
'North Dakota': 'ND',
|
|
47
|
+
Ohio: 'OH',
|
|
48
|
+
Oklahoma: 'OK',
|
|
49
|
+
Oregon: 'OR',
|
|
50
|
+
Pennsylvania: 'PA',
|
|
51
|
+
'Rhode Island': 'RI',
|
|
52
|
+
'South Carolina': 'SC',
|
|
53
|
+
'South Dakota': 'SD',
|
|
54
|
+
Tennessee: 'TN',
|
|
55
|
+
Texas: 'TX',
|
|
56
|
+
Utah: 'UT',
|
|
57
|
+
Vermont: 'VT',
|
|
58
|
+
Virginia: 'VA',
|
|
59
|
+
Washington: 'WA',
|
|
60
|
+
'West Virginia': 'WV',
|
|
61
|
+
Wisconsin: 'WI',
|
|
62
|
+
Wyoming: 'WY',
|
|
63
|
+
'District of Columbia': 'DC',
|
|
64
|
+
Guam: 'GU',
|
|
65
|
+
'Virgin Islands': 'VI',
|
|
66
|
+
'Puerto Rico': 'PR',
|
|
67
|
+
'American Samoa': 'AS'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
// SVG ITEMS
|
|
73
|
+
const WIDTH = 880;
|
|
74
|
+
const HEIGHT = 500;
|
|
75
|
+
const PADDING = 25;
|
|
76
|
+
|
|
77
|
+
// DATA
|
|
78
|
+
let { features: counties } = feature(testJSON, testJSON.objects.counties)
|
|
79
|
+
let { features: states } = feature(testJSON, testJSON.objects.states);
|
|
80
|
+
|
|
81
|
+
// CONSTANTS
|
|
82
|
+
const STATE_BORDER = '#c0cad4';
|
|
83
|
+
const STATE_INACTIVE_FILL = '#F4F7FA';
|
|
84
|
+
|
|
85
|
+
// CREATE STATE LINES
|
|
86
|
+
// const projection = geoAlbersUsaTerritories().translate([WIDTH/2,HEIGHT/2])
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
const SingleStateMap = (props) => {
|
|
91
|
+
|
|
92
|
+
const {
|
|
93
|
+
state,
|
|
94
|
+
applyTooltipsToGeo,
|
|
95
|
+
data,
|
|
96
|
+
geoClickHandler,
|
|
97
|
+
applyLegendToRow,
|
|
98
|
+
displayGeoName,
|
|
99
|
+
supportedTerritories,
|
|
100
|
+
rebuildTooltips,
|
|
101
|
+
runtimeLegend,
|
|
102
|
+
generateColorsArray
|
|
103
|
+
} = props;
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
const projection = geoAlbersUsaTerritories().translate([WIDTH/2, HEIGHT/2])
|
|
108
|
+
|
|
109
|
+
const geoStrokeColor = state.general.geoBorderColor === 'darkGray' ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255,255,255,0.7)'
|
|
110
|
+
|
|
111
|
+
const [stateToShow, setStateToShow ] = useState( null )
|
|
112
|
+
const [countiesToShow, setCountiesToShow] = useState( null )
|
|
113
|
+
const [translate, setTranslate] = useState()
|
|
114
|
+
const [scale, setScale] = useState()
|
|
115
|
+
const [strokeWidth, setStrokeWidth ] = useState(.75)
|
|
116
|
+
|
|
117
|
+
let mapColorPalette = colorPalettes[state.color] || '#fff';
|
|
118
|
+
let focusedBorderColor = mapColorPalette[3];
|
|
119
|
+
useEffect(() => rebuildTooltips());
|
|
120
|
+
|
|
121
|
+
const path = geoPath().projection(projection)
|
|
122
|
+
|
|
123
|
+
// When choosing a state changes...
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
if(state.general.hasOwnProperty('statePicked')) {
|
|
126
|
+
let statePicked = state.general.statePicked.stateName;
|
|
127
|
+
let statePickedData = states.find(s => s.properties.name === statePicked)
|
|
128
|
+
setStateToShow(statePickedData)
|
|
129
|
+
|
|
130
|
+
let countiesFound = counties.filter( c => c.id.substring(0,2) === state.general.statePicked.fipsCode)
|
|
131
|
+
|
|
132
|
+
setCountiesToShow(countiesFound)
|
|
133
|
+
|
|
134
|
+
const projection = geoAlbersUsaTerritories().translate([WIDTH/2,HEIGHT/2])
|
|
135
|
+
const newProjection = projection.fitExtent([[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], statePickedData)
|
|
136
|
+
const newScale = newProjection.scale();
|
|
137
|
+
const newScaleWithHypot = newScale / 1070;
|
|
138
|
+
|
|
139
|
+
let [x, y] = newProjection.translate()
|
|
140
|
+
x = (x - WIDTH/2);
|
|
141
|
+
y = (y - HEIGHT/2);
|
|
142
|
+
|
|
143
|
+
setTranslate([x,y])
|
|
144
|
+
setScale(newScaleWithHypot)
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
}, [state.general.statePicked]);
|
|
148
|
+
|
|
149
|
+
const geoLabel = (geo, projection) => {
|
|
150
|
+
//projection = geoAlbersUsaTerritories().translate([WIDTH/2,HEIGHT/2])
|
|
151
|
+
//const newProjection = projection.fitExtent([[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], geo)
|
|
152
|
+
let [x, y] = projection( geoCentroid(geo) )
|
|
153
|
+
let abbr = abbrs[geo.properties.name]
|
|
154
|
+
if (abbr === 'NJ') x += 3
|
|
155
|
+
if(undefined === abbr) return null
|
|
156
|
+
let [dx, dy] = offsets[geo.properties.name]
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<>
|
|
160
|
+
<line className="abbrLine" x1={x} y1={y} x2={x + dx} y2={y + dy} stroke="black" strokeWidth={1} />
|
|
161
|
+
<text className="abbrText" x={4} strokeWidth="0" fontSize={13} style={{fill: "#202020"}} alignmentBaseline="middle" transform={`translate(${x + dx}, ${y + dy})`}>
|
|
162
|
+
{abbr}
|
|
163
|
+
</text>
|
|
164
|
+
</>
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Constructs and displays markup for all geos on the map (except territories right now)
|
|
169
|
+
const constructGeoJsx = (geographies, projection) => {
|
|
170
|
+
const statePassed = geographies[0].feature.states;
|
|
171
|
+
const counties = geographies[0].feature.counties;
|
|
172
|
+
|
|
173
|
+
let geosJsx = [];
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
const StateOutput = () => {
|
|
177
|
+
|
|
178
|
+
let geo = testJSON.objects.states.geometries.filter( s => {
|
|
179
|
+
return s.id === statePassed.id
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
// const stateLine = path(mesh(testJSON, lines ))
|
|
184
|
+
let stateLines = path(mesh(testJSON, geo[0]))
|
|
185
|
+
return (
|
|
186
|
+
<g
|
|
187
|
+
key={'single-state'}
|
|
188
|
+
className="single-state"
|
|
189
|
+
style={{ fill: '#E6E6E6'}}
|
|
190
|
+
stroke={geoStrokeColor}
|
|
191
|
+
strokeWidth={ .95 / scale }
|
|
192
|
+
>
|
|
193
|
+
<path
|
|
194
|
+
tabIndex={-1}
|
|
195
|
+
className='state-path'
|
|
196
|
+
d={stateLines}
|
|
197
|
+
/>
|
|
198
|
+
</g>
|
|
199
|
+
)
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const countyOutput = ( counties.map(( county ) => {
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
// Map the name from the geo data with the appropriate key for the processed data
|
|
206
|
+
let geoKey = county.id;
|
|
207
|
+
|
|
208
|
+
if(!geoKey) return;
|
|
209
|
+
|
|
210
|
+
let countyPath = path(county);
|
|
211
|
+
|
|
212
|
+
let geoData = data[county.id];
|
|
213
|
+
let legendColors;
|
|
214
|
+
|
|
215
|
+
// Once we receive data for this geographic item, setup variables.
|
|
216
|
+
if (geoData !== undefined ) {
|
|
217
|
+
legendColors = applyLegendToRow(geoData);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const geoDisplayName = displayGeoName(geoKey);
|
|
221
|
+
|
|
222
|
+
// For some reason, these two geos are breaking the display.
|
|
223
|
+
if (geoDisplayName === 'Franklin City' || geoDisplayName === 'Waynesboro') return null;
|
|
224
|
+
|
|
225
|
+
const tooltip = applyTooltipsToGeo(geoDisplayName, geoData);
|
|
226
|
+
|
|
227
|
+
if (legendColors && legendColors[0] !== '#000000') {
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
let styles = {
|
|
231
|
+
fill: legendColors[0],
|
|
232
|
+
cursor: 'default',
|
|
233
|
+
'&:hover': {
|
|
234
|
+
fill: legendColors[1],
|
|
235
|
+
},
|
|
236
|
+
'&:active': {
|
|
237
|
+
fill: legendColors[2],
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// When to add pointer cursor
|
|
242
|
+
if ((state.columns.navigate && geoData[state.columns.navigate.name]) || state.tooltips.appearanceType === 'hover') {
|
|
243
|
+
styles.cursor = 'pointer'
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return (
|
|
247
|
+
<g
|
|
248
|
+
data-for="tooltip"
|
|
249
|
+
data-tip={tooltip}
|
|
250
|
+
key={`key--${county.id}`}
|
|
251
|
+
className={`county county--${geoDisplayName.split(" ").join("")} county--${geoData[state.columns.geo.name]}`}
|
|
252
|
+
css={styles}
|
|
253
|
+
onClick={() => geoClickHandler(geoDisplayName, geoData)}
|
|
254
|
+
>
|
|
255
|
+
<path
|
|
256
|
+
tabIndex={-1}
|
|
257
|
+
className={`county`}
|
|
258
|
+
stroke={geoStrokeColor}
|
|
259
|
+
d={countyPath}
|
|
260
|
+
strokeWidth={ .75 / scale }
|
|
261
|
+
/>
|
|
262
|
+
</g>
|
|
263
|
+
)
|
|
264
|
+
} else {
|
|
265
|
+
return (
|
|
266
|
+
<g
|
|
267
|
+
data-for="tooltip"
|
|
268
|
+
data-tip={tooltip}
|
|
269
|
+
key={`key--${county.id}`}
|
|
270
|
+
className={`county county--${geoDisplayName.split(" ").join("")}`}
|
|
271
|
+
style={{ fill : '#e6e6e6'}}
|
|
272
|
+
>
|
|
273
|
+
<path
|
|
274
|
+
tabIndex={-1}
|
|
275
|
+
className={`county`}
|
|
276
|
+
stroke={geoStrokeColor}
|
|
277
|
+
d={countyPath}
|
|
278
|
+
strokeWidth={ .75 / scale }
|
|
279
|
+
/>
|
|
280
|
+
</g>
|
|
281
|
+
)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
}));
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
geosJsx.push( <StateOutput /> );
|
|
288
|
+
geosJsx.push( countyOutput );
|
|
289
|
+
|
|
290
|
+
return geosJsx;
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
<ErrorBoundary component="SingleStateMap">
|
|
296
|
+
{stateToShow &&
|
|
297
|
+
<svg viewBox={`0 0 ${WIDTH} ${HEIGHT}`} preserveAspectRatio="xMinYMin" className="svg-container">
|
|
298
|
+
<rect className="background center-container ocean" width={WIDTH} height={HEIGHT} fillOpacity={1} fill="white"></rect>
|
|
299
|
+
<CustomProjection
|
|
300
|
+
data={ [{states: stateToShow, counties: countiesToShow }] }
|
|
301
|
+
// translate={translate}
|
|
302
|
+
// scale={scale}
|
|
303
|
+
projection={geoAlbersUsaTerritories}
|
|
304
|
+
fitExtent={[[[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], stateToShow]}
|
|
305
|
+
>
|
|
306
|
+
{ ({ features, projection }) => {
|
|
307
|
+
return (
|
|
308
|
+
<g
|
|
309
|
+
id="mapGroup"
|
|
310
|
+
className="countyMapGroup"
|
|
311
|
+
transform={`translate(${translate}) scale(${scale})`}
|
|
312
|
+
data-scale=""
|
|
313
|
+
key="countyMapGroup">
|
|
314
|
+
{ constructGeoJsx(features, geoAlbersUsaTerritories) }
|
|
315
|
+
</g>
|
|
316
|
+
)
|
|
317
|
+
}}
|
|
318
|
+
</CustomProjection>
|
|
319
|
+
</svg>
|
|
320
|
+
}
|
|
321
|
+
{!stateToShow && 'No State Picked'}
|
|
322
|
+
</ErrorBoundary>
|
|
323
|
+
);
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
export default memo(SingleStateMap)
|
package/src/components/UsaMap.js
CHANGED
|
@@ -67,9 +67,21 @@ const UsaMap = (props) => {
|
|
|
67
67
|
applyLegendToRow,
|
|
68
68
|
displayGeoName,
|
|
69
69
|
supportedTerritories,
|
|
70
|
-
rebuildTooltips
|
|
70
|
+
rebuildTooltips,
|
|
71
|
+
titleCase
|
|
71
72
|
} = props;
|
|
72
73
|
|
|
74
|
+
// "Choose State" options
|
|
75
|
+
const [extent, setExtent] = useState(null)
|
|
76
|
+
const [focusedStates, setFocusedStates] = useState(unitedStates)
|
|
77
|
+
const [translate, setTranslate] = useState([455,200])
|
|
78
|
+
|
|
79
|
+
// When returning from another map we want to reset the state
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
setTranslate( [455,250] )
|
|
82
|
+
setExtent( null )
|
|
83
|
+
}, [state.general.geoType]);
|
|
84
|
+
|
|
73
85
|
const isHex = state.general.displayAsHex
|
|
74
86
|
|
|
75
87
|
const [territoriesData, setTerritoriesData] = useState([]);
|
|
@@ -295,11 +307,12 @@ const UsaMap = (props) => {
|
|
|
295
307
|
applyTooltipsToGeo={applyTooltipsToGeo}
|
|
296
308
|
displayGeoName={displayGeoName}
|
|
297
309
|
applyLegendToRow={applyLegendToRow}
|
|
310
|
+
titleCase={titleCase}
|
|
298
311
|
/>)
|
|
299
312
|
|
|
300
313
|
return geosJsx;
|
|
301
314
|
};
|
|
302
|
-
|
|
315
|
+
|
|
303
316
|
return (
|
|
304
317
|
<ErrorBoundary component="UsaMap">
|
|
305
318
|
<svg viewBox="0 0 880 500">
|
|
@@ -307,7 +320,11 @@ const UsaMap = (props) => {
|
|
|
307
320
|
(<Mercator data={unitedStatesHex} scale={650} translate={[1600, 775]}>
|
|
308
321
|
{({ features, projection }) => constructGeoJsx(features, projection)}
|
|
309
322
|
</Mercator>) :
|
|
310
|
-
(<AlbersUsa
|
|
323
|
+
(<AlbersUsa
|
|
324
|
+
data={focusedStates}
|
|
325
|
+
translate={translate}
|
|
326
|
+
fitExtent={extent}
|
|
327
|
+
>
|
|
311
328
|
{({ features, projection }) => constructGeoJsx(features, projection)}
|
|
312
329
|
</AlbersUsa>)
|
|
313
330
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const abbrs = {
|
|
2
|
+
Alabama: 'AL',
|
|
3
|
+
Alaska: 'AK',
|
|
4
|
+
Arizona: 'AZ',
|
|
5
|
+
Arkansas: 'AR',
|
|
6
|
+
California: 'CA',
|
|
7
|
+
Colorado: 'CO',
|
|
8
|
+
Connecticut: 'CT',
|
|
9
|
+
Delaware: 'DE',
|
|
10
|
+
Florida: 'FL',
|
|
11
|
+
Georgia: 'GA',
|
|
12
|
+
Hawaii: 'HI',
|
|
13
|
+
Idaho: 'ID',
|
|
14
|
+
Illinois: 'IL',
|
|
15
|
+
Indiana: 'IN',
|
|
16
|
+
Iowa: 'IA',
|
|
17
|
+
Kansas: 'KS',
|
|
18
|
+
Kentucky: 'KY',
|
|
19
|
+
Louisiana: 'LA',
|
|
20
|
+
Maine: 'ME',
|
|
21
|
+
Maryland: 'MD',
|
|
22
|
+
Massachusetts: 'MA',
|
|
23
|
+
Michigan: 'MI',
|
|
24
|
+
Minnesota: 'MN',
|
|
25
|
+
Mississippi: 'MS',
|
|
26
|
+
Missouri: 'MO',
|
|
27
|
+
Montana: 'MT',
|
|
28
|
+
Nebraska: 'NE',
|
|
29
|
+
Nevada: 'NV',
|
|
30
|
+
'New Hampshire': 'NH',
|
|
31
|
+
'New Jersey': 'NJ',
|
|
32
|
+
'New Mexico': 'NM',
|
|
33
|
+
'New York': 'NY',
|
|
34
|
+
'North Carolina': 'NC',
|
|
35
|
+
'North Dakota': 'ND',
|
|
36
|
+
Ohio: 'OH',
|
|
37
|
+
Oklahoma: 'OK',
|
|
38
|
+
Oregon: 'OR',
|
|
39
|
+
Pennsylvania: 'PA',
|
|
40
|
+
'Rhode Island': 'RI',
|
|
41
|
+
'South Carolina': 'SC',
|
|
42
|
+
'South Dakota': 'SD',
|
|
43
|
+
Tennessee: 'TN',
|
|
44
|
+
Texas: 'TX',
|
|
45
|
+
Utah: 'UT',
|
|
46
|
+
Vermont: 'VT',
|
|
47
|
+
Virginia: 'VA',
|
|
48
|
+
Washington: 'WA',
|
|
49
|
+
'West Virginia': 'WV',
|
|
50
|
+
Wisconsin: 'WI',
|
|
51
|
+
Wyoming: 'WY',
|
|
52
|
+
'District of Columbia': 'DC',
|
|
53
|
+
Guam: 'GU',
|
|
54
|
+
'Virgin Islands': 'VI',
|
|
55
|
+
'Puerto Rico': 'PR',
|
|
56
|
+
'American Samoa': 'AS',
|
|
57
|
+
};
|