{"version":3,"sources":["webpack:///./app/scripts/components/OtherCandidate.js","webpack:///./app/scripts/components/Contest.tsx","webpack:///./app/scripts/components/FramesChild.js","webpack:///./app/scripts/components/HeadshotCandidateRow.tsx","webpack:///./app/scripts/utils/format-percent.ts","webpack:///./config/modern-polyfills.js","webpack:///./app/scripts/endpoints.ts","webpack:///./app/scripts/utils/load-json-script.js","webpack:///./app/scripts/utils/sum-values.js","webpack:///./app/scripts/constants.ts","webpack:///./app/scripts/election-utils.ts","webpack:///./app/scripts/utils/get-json.js","webpack:///./app/scripts/utils/shallow-equal.ts","webpack:///./app/scripts/components/PureComponent.tsx","webpack:///../src/utils.mjs","webpack:///../src/constants.mjs","webpack:///../src/framer.mjs","webpack:///../src/frames.mjs","webpack:///./app/scripts/components/PartyPill.tsx"],"names":["OtherCandidate","_ref","isViewable","candidateCount","embedType","onClick","classes","cx","h","class","xlinkHref","Contest","Component","constructor","super","this","state","viewAllCandidates","onViewableToggle","bind","setState","prevState","render","directory_slug","contest","columnCount","contestTitle","isShowcaseRace","renderCandidate","annotations","notes","tableHeader","isHomepage","asOf","source","candidatesRender","props","converter","PreactHTMLConverter","shouldDisplayResult","contest_result","get_directory_slug","office","getDistrictNum","division_type","office_division","candidates","totalVotes","sumValues","candidacies","uncontested","sort_candidates_by_party","sort_candidates_by_votes","length","pct_votes","formatPercent","estimated_votes_mid","eevp","pct_votes_turnout","concat","pct_votes_turnout_zero_winner","pct_votes_turnout_w_uncontested","text_conditionals","pct_votes_explain","text_conditional_winner_zero","ManualoverrideSource","showcaseClass","seat__races","seat__highlight_races","raceClass","election_type","office_slug","seatClass","klaxon","alert_winners","alert_conditionals","checkClass","party","contestMetricsClass","homepage__metrics","precinctsClass","IsAnnotations","value","IsNoted","href","title","isCanvass","intcomma","pollinglocationsreporting","total_pollinglocations","pollinglocations_reporting_percent","toFixed","map","candidate","idx","visibleCandidatesCount","convert","aria-hidden","defaultProps","includeCountyRundown","FramesChild","ref","createRef","polling","componentDidMount","initFrameAndPoll","componentDidUpdate","sendFrameHeight","klass","children","HeadshotCandidateRow","PureComponent","getColor","ballotName","candidateId","contestIsCalled","contestResult","isIncumbent","isWinner","totalVotesInContest","candidateColors","votes","divStyle","filter","obj","name","color","checkStyle","IsAsterisk","rowClass","PartyPill","style","_defineProperty","isCalled","Header","colSpan","n","d","require","HOMEPAGE_URL","STORY_API_URL","id","showBubbleMap","showCategoriesMap","showPrecinctsReporting","RESULTS_IN_USE","loadJsonScript","elementId","element","document","getElementById","getAttribute","JSON","parse","textContent","arr","key","reduce","acc","LENGTH_OF_CHECK_INTERVAL","journalize","lastUpdatedFormat","now","apdate","formatted_time","aptime","apmonth","getDate","timer","chunk","size","_","i","push","slice","delay","callback","ms","clearTimeout","setTimeout","APTotalVotesToCount","total_votes","Math","round","NaN","PARTY_SORT_ORDER","TT_directory_slugs","slug","type","sort","a","b","indexOf","vote_pct","cand_num","context","label_conditionals","result","winner_conditionals","determineDistrictTitle","capfirst","trim","division_number","determineContestTitle","determineContestTitleYourRaces","jsonResponse","res","ok","Error","status","statusText","json","getJSON","input","init","fetch","then","hOP","Object","prototype","hasOwnProperty","is","x","y","shallowEqual","objA","objB","keysA","keys","keysB","call","shouldComponentUpdate","t","o","allowfullscreen","referrerpolicy","r","sandbox","s","src","e","container","window","addEventListener","f","documentElement","offsetHeight","height","parent","postMessage","sentinel","v","removeEventListener","w","setInterval","l","remove","removeChild","iframe","createElement","setAttribute","appendChild","contentWindow","data","excludeInitial","partyPrefix","toLowerCase","partyInitial","toUpperCase","memoize","_ref2"],"mappings":"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","file":"3.9f5ec267bd.mjs","sourcesContent":["import cx from 'classnames';\nimport { h } from 'preact';\n\nfunction OtherCandidate({ isViewable, candidateCount, embedType, onClick }) {\n  const classes = cx('candidate race__candidate-row', {\n    'race__candidate-row--hidden': !isViewable,\n  });\n\n  return (\n    <tr class={classes}>\n      <td\n        class=\"candidate__cell candidate__party t-align-center\"\n        onClick={onClick}\n      >\n        <svg class=\"icon icon-angle-down\">\n          <use xlinkHref=\"#icon-angle-down\" />\n        </svg>\n      </td>\n      <th class=\"candidate__cell candidate__name\">\n        <button class={embedType} onClick={onClick}>\n          Show All ({candidateCount}){' '}\n        </button>\n      </th>\n      <th class=\"candidate__cell candidate__votes\"></th>\n      <th class=\"candidate__cell candidate__pct\"></th>\n    </tr>\n  );\n}\n\nexport default OtherCandidate;","import cx from 'classnames';\nimport { intcomma } from 'journalize';\nimport { Component, h } from 'preact';\n\nimport OtherCandidate from './OtherCandidate';\nimport { PreactHTMLConverter } from 'preact-html-converter';\n\n// internal\nimport {\n  sort_candidates_by_party,\n  sort_candidates_by_votes,\n  alert_conditionals,\n  alert_winners,\n  text_conditionals,\n  text_conditional_winner_zero,\n  get_directory_slug,\n  getDistrictNum\n} from '../election-utils';\nimport sumValues from '../utils/sum-values';\nimport formatPercent from '../utils/format-percent';\n\nimport { isCanvass, visibleCandidatesCount } from '../endpoints';\n\ntype Props = {\n  contest: { [key: string]: any };\n  columnCount: number;\n  contestTitle: string;\n  includeCountyRundown?: boolean;\n  isShowcaseRace?: boolean;\n  renderParty: any;\n  renderCandidate: any;\n  candidatesRender: any;\n  embedType: string;\n  broadcastHeaderImage: string;\n  activeContestId: string;\n  tableHeader: JSX.Element;\n  annotations: { [key: string]: any };\n  notes: { [key: string]: any };\n  isHomepage?: boolean;\n  asOf: string;\n  source: string;\n};\n\nclass Contest extends Component<Props> {\n  constructor() {\n    super();\n\n    this.state = {\n      viewAllCandidates: false,\n    };\n    this.onViewableToggle = this.onViewableToggle.bind(this);\n  }\n\n  onViewableToggle() {\n    this.setState(prevState => ({\n      viewAllCandidates: !prevState.viewAllCandidates, // set viewAllCandidates to what is wasn't before\n    }));\n  }\n  render() {\n    const {\n      contest,\n      columnCount,\n      contestTitle,\n      isShowcaseRace,\n      renderCandidate,\n      annotations,\n      notes,\n      tableHeader,\n      isHomepage,\n      asOf,\n      source,\n      embedType,\n      candidatesRender,\n    } = this.props;\n\n    const { viewAllCandidates } = this.state;\n\n    const converter = PreactHTMLConverter();\n\n    const shouldDisplayResult = contest.contest_result !== 'not called';\n\n    let directory_slug, district_num;\n\n    if (contest) {\n      directory_slug = get_directory_slug(contest.office);\n      district_num = getDistrictNum(contest.division_type, contest.office_division)\n    }\n\n    const totalVotes = sumValues(contest.candidacies, 'votes');\n\n    let candidates;\n\n    candidates =\n      totalVotes == 0\n        ? sort_candidates_by_party(contest.candidacies, 'table')\n        : sort_candidates_by_votes(contest.candidacies);\n\n    const uncontested = candidates.length == 1;\n\n    const pct_votes = source == 'Decision Desk HQ' ? formatPercent(\n      totalVotes,\n      contest.estimated_votes_mid\n    )  : contest.eevp\n\n    const pct_votes_turnout =\n      pct_votes < 100\n        ? `An estimated ${pct_votes}% of votes have been counted, according to the ${source}.`\n        : `An estimated >99% of votes have been counted, according to the ${source}.`;\n\n\n    const pct_votes_turnout_zero_winner = \n    pct_votes == 0 && shouldDisplayResult \n    ? ``\n    : pct_votes_turnout;\n\n    const pct_votes_turnout_w_uncontested =\n        (uncontested == true)\n           ? text_conditionals(pct_votes, contest.candidacies.length) :\n           pct_votes_turnout_zero_winner\n\n    const pct_votes_explain = !shouldDisplayResult && !uncontested\n      ? text_conditionals(pct_votes, contest.candidacies.length)\n      : text_conditional_winner_zero(pct_votes, contest.candidacies.length);\n\n    let firstShowcaseRace;\n\n    let embedTypeUsable = 'none';\n\n    if (typeof embedType !== 'undefined') {\n      embedTypeUsable = embedType;\n    }\n\n\n    const showcaseClass = cx({\n      seat__races: !isShowcaseRace,\n      seat__highlight_races: isShowcaseRace,\n    });\n\n\n    let raceClass = cx('seat__race', {\n      'special-election': contest.election_type == 'special',\n      'general-seat-before-special': (contest.office_slug == 'us-house-district-18') || (contest.office_slug == 'texas-house-district-56'),\n    })\n\n    let seatClass = cx('seat',  {\n      'special-election__grid': contest.election_type == 'special',\n    })\n\n    const klaxon_sos = 'Race has been declared'; // if we switch sources to TX SOS and someone else has declared the winner\n\n    const klaxon = shouldDisplayResult\n      ? source == 'Decision Desk HQ' || source == 'Associated Press'\n        ? alert_winners(contest.contest_result, contest.office)\n        : klaxon_sos\n      : alert_conditionals(pct_votes, contest.candidacies.length);\n\n    const checkmark = '\\u2713';\n\n    let checkClass = cx('check', {\n      'dem-winner':\n      contest.party == 'Democrat' &&\n      contest.contest_result != 'runoff',\n      'rep-winner':\n      contest.party == 'Republican' &&\n      contest.contest_result != 'runoff',\n      'runoff-winner': contest.contest_result == 'runoff',\n    });\n\n\n    const contestMetricsClass = cx('contest__metrics', {\n      homepage__metrics: isHomepage,\n      'non-homepage__metrics': !isHomepage,\n    });\n\n    let hasTurnoutmodel = (source == 'Decision Desk HQ' || source == 'Associated Press')? true : false;\n\n    const precinctsClass = cx('contest__precincts', 't-wrap-balance');\n\n    let ManualoverrideSource;\n\n    // If there is a race, that's being manually updated, you can change the Source to whatever the new votes are coming from here if you uncomment the code below. This is only if the source isn't Texas Secretary of State. If it is, then you don't have to do anything.\n\n    // if (contest.office == 'U.S. House' && contest.office_division == 37 && contest.party == 'Republican') {\n    //   ManualoverrideSource = 'Travis County Elections'\n    // }\n    // else {\n    //   ManualoverrideSource = ''\n    // }\n\n    ManualoverrideSource = '';\n\n    const IsAnnotations =\n      annotations && annotations.length > 0 && annotations[0].value != ''\n        ? true\n        : false;\n\n    const IsNoted = notes && notes.length > 0 ? true : false;\n\n    return (\n      <div class={seatClass}>\n        <div class={showcaseClass}>\n          <div class={raceClass}>\n          {!isShowcaseRace && (\n              <h3 class=\"seat__title\">\n                <span>{contest.election_type == 'special' && (\n                <div class=\"special-election__title\">Special Election</div>\n              )}{contestTitle}</span>\n                {directory_slug[0] != null && (\n              <a class=\"t-links-unset\"\n                href={`https://www.texastribune.org/directory/districts/${directory_slug[0]['directory-slug']}/${contest['office_division']}`}\n              >\n                <span class=\"icon-div\" title=\"Click to learn more about this district\">\n                  <svg class=\"icon icon-info\">\n                    <use xlinkHref=\"#icon-info\"></use>\n                  </svg>\n                </span>\n              </a>\n            )}\n              </h3>\n            )}\n            <div class=\"race\">\n              {embedType == 'homepage' && (\n                <span>\n                  <div class=\"office__title\">{contestTitle}</div>\n                </span>\n              )}\n              {/* {embedType == 'internal' && (\n                <span>\n                  <h2 class=\"office__title\">{contestTitle}</h2>\n                </span>\n              )} */}\n\n              <div class={contestMetricsClass}>\n                {isCanvass == false && (\n                  <h4 class=\"klaxon__text\">\n                    {shouldDisplayResult && (source == 'Decision Desk HQ' || source == 'Associated Press') ? (\n                      <span class={checkClass}>{checkmark}</span>\n                    ) : (\n                      ''\n                    )}\n                    {klaxon}\n                  </h4>\n                )}\n                {ManualoverrideSource == '' && isCanvass == false && (\n                  <p class={precinctsClass}>\n                    {source != 'Associated Press'\n                      ? `${intcomma(\n                          contest.pollinglocationsreporting\n                        )} of ${intcomma(\n                          contest.total_pollinglocations\n                        )} polling locations reporting (${contest.pollinglocations_reporting_percent.toFixed(\n                          1\n                        )}%).`\n                      : pct_votes_turnout_w_uncontested}{' '}\n                    {pct_votes_explain}\n                  </p>\n                )}\n                {\n                  (ManualoverrideSource =! '' &&\n                    source != 'Texas Secretary of State' &&\n                    source != 'Decision Desk HQ' &&\n                    source != 'Associated Press' &&\n                    isCanvass == false && (\n                      <p class={precinctsClass}>\n                        {`${intcomma(\n                          contest.pollinglocationsreporting\n                        )} of ${intcomma(\n                          contest.total_pollinglocations\n                        )} polling locations reporting (${contest.pollinglocations_reporting_percent.toFixed(\n                          1\n                        )}%).`}\n\n                        {/* <span class=\"source\">{` Source: ${ManualoverrideSource}`}</span> */}\n                      </p>\n                    ))\n                }\n              </div>\n\n              <table class=\"race__candidates\">\n                {tableHeader}\n                <tbody>\n                  {isShowcaseRace &&\n                    candidates.map((candidate: any, idx: any) =>\n                      renderCandidate(\n                        candidate,\n                        idx,\n                        candidatesRender,\n                        viewAllCandidates,\n                        { totalVotes }\n                      )\n                    )}\n\n                  {!isShowcaseRace &&\n                    candidates.map((candidate: any, idx: any) =>\n                      renderCandidate(candidate, idx, viewAllCandidates, {\n                        totalVotes,\n                      })\n                    )}\n                  {candidates.length > visibleCandidatesCount && (\n                    <OtherCandidate\n                      isViewable={!viewAllCandidates}\n                      candidateCount={candidates.length}\n                      embedType={embedType}\n                      onClick={() => {\n                        this.onViewableToggle();\n                      }}\n                    />\n                  )}\n                </tbody>\n                {candidates.length > visibleCandidatesCount &&\n                  viewAllCandidates && (\n                    <tr class=\"candidate race__candidate-row\">\n                      <td\n                        class=\"candidate__cell candidate__party t-align-center\"\n                        onClick={() => {\n                          this.onViewableToggle();\n                        }}\n                      >\n                        <svg class=\"icon icon-angle-up\">\n                          <use xlinkHref=\"#icon-angle-up\" />\n                        </svg>\n                      </td>\n                      <th class=\"candidate__cell candidate__name\">\n                        <button\n                          class={embedType}\n                          onClick={() => {\n                            this.onViewableToggle();\n                          }}\n                        >\n                          Show fewer ({visibleCandidatesCount})\n                        </button>\n                      </th>\n                      <th class=\"candidate__cell candidate__votes\"></th>\n                      <th class=\"candidate__cell candidate__pct\"></th>\n                    </tr>\n                  )}\n              </table>\n              {IsNoted == true && (\n                <p class=\"note__text t-wrap-balance\">{converter.convert(notes[0].value)}</p>\n              )}\n              {IsAnnotations == true && (\n                <div class=\"anno-text notes-annotations t-wrap-balance\">\n                  <span class=\"is-sr-only\">Note:</span>\n                  <svg class=\"icon note-icon anno-div\" aria-hidden=\"true\">\n                    <use xlinkHref=\"#note-icon\" />\n                  </svg>\n\n                  <p class=\"annotations t-links-underlined\">\n                    <span class=\"font-weight-bold\">Noteworthy: </span>\n                    {converter.convert(annotations[0].value)}\n                  </p>\n                </div>\n              )}\n\n              {/* Final canvass source */}\n\n              {(isCanvass == true) ? (\n                 <div class=\"below-races\">\n                 <div class=\"source\">{` Source: ${source}`}</div>\n                   {(embedType == 'homepage' || embedType == 'internal') && (\n                     <div class=\"countdown\">\n                       <span class=\"counter-homepage\">LAST UPDATED {asOf}</span>\n                     </div>\n                   )}\n                 </div>\n\n              ) : (\n                (embedType == 'internal' || embedType == 'homepage') && (\n                  <div class=\"below-races\">\n                  <div class=\"source\">{` Source: ${source}`}</div>\n                  <div class=\"countdown\">\n                    <span class=\"counter-homepage\">LAST UPDATED {asOf}</span>\n                  </div>\n                  </div>\n                )\n              )}\n\n            </div>\n          </div>\n        </div>\n      </div>\n    );\n  }\n}\n\nContest.defaultProps = {\n  isShowcaseRace: false,\n  includeCountyRundown: false,\n};\n\nexport default Contest;","import { Component, h, createRef } from 'preact';\nimport { initFrameAndPoll, sendFrameHeight } from '@newswire/frames';\n\nclass FramesChild extends Component {\n  constructor(props) {\n    super(props);\n    this.ref = createRef();\n\n    const { polling } = this.props;\n\n    let opts = {};\n    if (polling) opts.polling = polling;\n  }\n\n  componentDidMount() {\n    const { polling } = this.props;\n\n    initFrameAndPoll(polling);\n  }\n\n  componentDidUpdate() {\n    sendFrameHeight();\n  }\n\n  render({ class: klass }) {\n    return (\n      <div class={klass} ref={this.ref}>\n        {this.props.children}\n      </div>\n    );\n  }\n}\n\nexport default FramesChild;","import cx from 'classnames';\nimport { intcomma } from 'journalize';\nimport { h, VNode } from 'preact';\n\nimport PureComponent from './PureComponent';\n\nimport formatPercent from '../utils/format-percent';\nimport { isCanvass } from '../endpoints';\nimport PartyPill from './PartyPill';\n\ninterface Props {\n  ballotName: string;\n  candidateId: string;\n  contestIsCalled: boolean;\n  contestResult: string;\n  isIncumbent: boolean;\n  isWinner: boolean;\n  candidateColors: { [key: string]: any };\n  party: string;\n  totalVotesInContest: number;\n  votes: number;\n}\n\nclass HeadshotCandidateRow extends PureComponent<Props> {\n  static columnCount: number;\n  static Header: VNode;\n\n  render() {\n    const {\n      ballotName,\n      candidateId,\n      contestIsCalled,\n      contestResult,\n      isIncumbent,\n      isWinner,\n      party,\n      isViewable,\n      totalVotesInContest,\n      candidateColors,\n      votes,\n    } = this.props;\n\n    let getColor;\n\n    if (candidateColors) {\n      getColor = candidateColors\n        .filter(obj => obj.name == ballotName)\n        .map(obj => obj.color);\n    } else {\n      getColor = ['#777777'];\n    }\n\n    const divStyle = {\n      'background-color': getColor[0],\n    };\n\n    const checkStyle = {\n      color: getColor[0],\n    };\n\n    const IsAsterisk = ballotName == 'Rick Perry' ? true : false;\n\n    let rowClass = cx(\n      'candidate',\n      'contest__candidate-row',\n      'contest__candidate-row--headshot',\n      {\n        'contest__candidate-row--winner dem--border':\n          contestIsCalled && isWinner && party == 'Democrat',\n        'contest__candidate-row--winner rep--border':\n          contestIsCalled && isWinner && party == 'Republican',\n      }\n    );\n\n    let checkClass = cx('check', {\n      'dem-winner': party == 'Democrat',\n      'rep-winner': party == 'Republican',\n      'runoff-winner': contestResult == 'runoff',\n    });\n\n    if (!isViewable) {\n      rowClass += ' race__candidate-row--hidden';\n    }\n\n    const checkmark = '\\u2713';\n\n    return (\n      <tr class={rowClass}>\n        <td class=\"candidate__cell candidate__party\">\n            <PartyPill party={party} style={divStyle} />\n        </td>\n        <th class=\"candidate__cell candidate__name\">\n          {contestIsCalled && isWinner && contestResult != 'runoff' && (\n            <span class={checkClass} style={checkStyle}>\n              {checkmark}\n            </span>\n          )}\n          {contestIsCalled && isWinner && contestResult == 'runoff' && (\n            <span class={checkClass}>{checkmark}</span>\n          )}\n          {contestIsCalled &&\n          isWinner &&\n          isCanvass == true &&\n          contestResult != 'runoff' ? (\n            <span class={checkClass}>{ballotName}</span>\n          ) : (\n            ballotName\n          )}\n          {IsAsterisk && <span class=\"asterisk\">*</span>}{' '}\n          {isIncumbent && (\n            <span class=\"pill pill--basic\" title=\"Currently holds this seat\">\n              Incumbent\n            </span>\n          )}\n        </th>\n        <td class=\"candidate__cell candidate__votes\">{intcomma(votes)}</td>\n        <td class=\"candidate__cell candidate__pct\">\n          {formatPercent(votes, totalVotesInContest)}\n          <span class=\"candidate__pct-symbol\">%</span>\n        </td>\n      </tr>\n    );\n  }\n}\n\nHeadshotCandidateRow.defaultProps = {\n  isIncumbent: false,\n  isCalled: false,\n  isWinner: false,\n  isViewable: true,\n};\n\nHeadshotCandidateRow.Header = (\n  <thead>\n    <tr>\n      <th class=\"contest__candidate-header\" colSpan={2}>\n        Candidates\n      </th>\n      <th class=\"contest__candidate-header contest__candidate-header--numeric\">\n        Votes\n      </th>\n      <th class=\"contest__candidate-header contest__candidate-header--numeric\">\n        Pct.\n        <span class=\"candidate__pct-symbol\">%</span>\n      </th>\n    </tr>\n  </thead>\n);\n\nHeadshotCandidateRow.columnCount = 6;\n\nexport default HeadshotCandidateRow;","function formatPercent(n: number, d: number): string {\n  if (d == null || d <= 0) return '0.0';\n\n  return ((n / d) * 100).toFixed(1);\n}\n\nexport default formatPercent;","'use strict';\n\n// We depend on intersection-observer enough that it should just be assumed as necessary\nrequire('intersection-observer');\n","// Live results being updated by Republic\nconst FLAT_RESULTS_URL =\n  'https://s3.amazonaws.com/sos-test-2.texastribune.org/2024_general/republic_json/results_FLAT.json';\n\n// This has emptied out results i.e. is static\nconst STATIC_FLAT_RESULTS_URL =\n  'https://s3.amazonaws.com/sos-test-2.texastribune.org/2024_general/republic_json/results_static_FLAT.json';\n\n// This has the final certified results and is static\nconst FINAL_RESULTS_URL =\n  'https://s3.amazonaws.com/sos-test-2.texastribune.org/2024_general/republic_json/results_FLAT_FINAL_RESULTS.json'\n\n// Includes fake results data for testing\nconst FAKE_RESULTS_URL =\n  'https://s3.us-east-1.amazonaws.com/sos-test-2.texastribune.org/2024_general/republic_json/results_FLAT_COMPLETE_TEST.json';\n\nconst FAKE_RESULTS_URL_TWO =\n  'https://s3.amazonaws.com/sos-test-2.texastribune.org/2024_general/republic_json/results_FLAT_AP_test.json';\n\n// Used for homepage takeover\nconst HOMEPAGE_URL =\n  'https://s3.amazonaws.com/sos-test-2.texastribune.org/2024_general/homepage_takeover/2024-general.json';\n\n// Calls TT stories using the API\nconst STORY_API_URL = (id: number): string =>\n  `https://www.texastribune.org/api/v2/articles/${id}/?format=json&fields=sitewide_image,summary,authors,url,pub_date,updated_date,homepage_headline`;\n\n// This is for the other candidates for the hide/show toggle\nconst visibleCandidatesCount = 6;\n\n// This is for the other candidates for the hide/show toggle just in the homepage\nconst visibleCandidatesCountHomepage = 2;\n\n// Show bubble map toggle option. Set to false if we want to hide it.\nconst showBubbleMap = true;\n\n// Show categories map toggle option. Set to false if we want to hide it.\nconst showCategoriesMap = true;\n\n// Show precincts or estimated votes still being counted text\nconst showPrecinctsReporting = false;\n\n// Adds the checkmark if this is the final official results from local canvass\nconst isCanvass = true;\n\n// Show last updated timestamp, set to true to last updated text\nconst showLastUpdated = false;\n\n// What we are using across the ap\n// will be used on the results page, in the homepage takeover\n// and in the embeds\nconst RESULTS_IN_USE = FINAL_RESULTS_URL;\n\nexport {\n  RESULTS_IN_USE,\n  HOMEPAGE_URL,\n  STORY_API_URL,\n  visibleCandidatesCount,\n  visibleCandidatesCountHomepage,\n  showPrecinctsReporting,\n  isCanvass,\n  showLastUpdated,\n  showBubbleMap,\n  showCategoriesMap,\n};","/**\n * Grabs the contents of a `jsonScript` created JSON inline string and returns\n * it as a JSON object. If the element does not exist, or if the script\n * element does not have the JSON MIME type, null is returned instead.\n *\n * @param  {String} elementId the ID of the JSON script element\n * @return {Object|null}\n */\nexport default function loadJsonScript(elementId) {\n  const element = document.getElementById(elementId);\n\n  if (element && element.getAttribute('type') === 'application/json') {\n    return JSON.parse(element.textContent);\n  } else {\n    return null;\n  }\n}\n","/**\n * Sums up values of a property across objects in an array.\n *\n * @param {Array} arr An array of objects.\n * @param {String} key The property to sum across objects.\n * @return {Number}\n */\nexport default function sumValues(arr, key) {\n  return arr.reduce((acc, obj) => acc + obj[key], 0);\n}\n","const LENGTH_OF_CHECK_INTERVAL = 1000 * 60 * 2; // 2 minutes\nconst TIMERS_SHOULD_RUN = false;\n\nexport { LENGTH_OF_CHECK_INTERVAL, TIMERS_SHOULD_RUN };","var journalize = require('journalize');\n\nimport { capfirst } from 'journalize';\n\nimport context from 'Data/text.json';\n\nexport function lastUpdatedFormat(now) {\n  // format dates to ap style\n  const formatted_date = journalize.apdate(now),\n    formatted_time = journalize.aptime(now),\n    formatted_month = journalize.apmonth(now),\n    just_day = now.getDate();\n\n  return formatted_time;\n}\n\nexport function format(num) {\n  return num < 10 ? '0' + num : num;\n}\n\nexport const chunk = (arr, size) =>\n  arr.reduce((acc, _, i) => {\n    if (i % size === 0) acc.push(arr.slice(i, i + size));\n    return acc;\n  }, []);\n\nexport const delay = (function() {\n  var timer = 0;\n  return function(callback, ms) {\n    clearTimeout(timer);\n    timer = setTimeout(callback, ms);\n  };\n})();\n\nexport function APTotalVotesToCount(eevp, total_votes) {\n  return eevp > 0 ? Math.round((100 * total_votes)/eevp) : NaN\n}\n\nconst PARTY_SORT_ORDER = [\n  'Republican',\n  'Democrat',\n  'Libertarian',\n  'Green',\n  'Independent',\n  'Write-in',\n];\n// This is just the order for the top page\nconst PARTY_SORT_ORDER_TOP = [\n  'Democrat',\n  'Republican',\n  'Libertarian',\n  'Green',\n  'Independent',\n  'Write-in',\n];\n\n// If we need light blue #99d2da; background-color:rgba(153, 210, 218, .1)\n// If we need dark blue #325ba8; background-color:rgba(90, 137, 204, .1)\n\nconst TT_directory_slugs = [\n  { office: 'Texas House', 'directory-slug': 'tx-house' },\n  { office: 'Texas Senate', 'directory-slug': 'tx-senate' },\n  { office: 'U.S. House', 'directory-slug': 'us-house' },\n  { office: 'State Board of Education', 'directory-slug': 'sboe' },\n];\n\nexport function get_directory_slug(office) {\n  return TT_directory_slugs.filter(slug => slug.office == office);\n}\n\nexport function sort_candidates_by_party(candidates, type) {\n  if (type == 'top_races')\n  {\n    return candidates.sort(\n      (a, b) =>\n        PARTY_SORT_ORDER.indexOf(a.party) - PARTY_SORT_ORDER.indexOf(b.party)\n    );\n  }\n\n  else {\n    return candidates.sort(\n      (a, b) =>\n        PARTY_SORT_ORDER.indexOf(a.party) - PARTY_SORT_ORDER.indexOf(b.party)\n    );\n  }\n \n}\n\nexport function sort_candidates_by_votes(candidates) {\n  return candidates.sort(\n    (a, b) =>\n      b.votes - a.votes\n  );\n}\n\nexport function alert_conditionals(vote_pct, cand_num) {\n  if (vote_pct == 0 && cand_num > 1) {\n    return context.label_conditionals['zero-results'];\n  } else if (vote_pct > 0 && vote_pct <= 50 && cand_num > 1) {\n    return context.label_conditionals['more-than-0-less-than-50'];\n  } else if (vote_pct > 50 && vote_pct < 90 && cand_num > 1) {\n    return context.label_conditionals['more-than-50-no-winner'];\n  } else if (vote_pct >= 90 && cand_num > 1) {\n    return context.label_conditionals['all-results-in-no-winner'];\n  } else if (cand_num == 1) {\n    return context.label_conditionals['uncontested'];\n  }\n}\n\nexport function alert_winners(result, office) {\n  if (result == 'winner' && office != 'President') {\n    return context.winner_conditionals['winner'];\n  } else if (result == 'winner' && office == 'President') {\n    return context.winner_conditionals['winner_prez'];\n  } else if (result == 'uncontested') {\n    return context.winner_conditionals['uncontested'];\n  } else if (result == 'runoff') {\n    return context.winner_conditionals['runoff'];\n  }\n}\n\nexport function text_conditionals(vote_pct, cand_num) {\n  if (vote_pct == 0 && cand_num > 1) {\n    return context.text_conditionals['zero-results'];\n  } else if (vote_pct > 1 && vote_pct <= 50 && cand_num > 1) {\n    return context.text_conditionals['more-than-0-less-than-50'];\n  } else if (vote_pct > 50 && vote_pct < 90 && cand_num > 1) {\n    return context.text_conditionals['more-than-50-no-winner'];\n  } else if (vote_pct >= 90 && cand_num > 1) {\n    return context.text_conditionals['all-results-in-no-winner'];\n  } else if (cand_num == 1) {\n    return context.text_conditionals['uncontested'];\n  }\n}\n\nexport function text_conditional_winner_zero(vote_pct, cand_num) {\n  if (vote_pct == 0 && cand_num > 1) {\n    return context.text_conditionals['zero-results_winner'];\n  } else {\n    return ``;\n  }\n}\n\nexport function determineDistrictTitle(contest) {\n  return `${contest.office} ${\n    contest.office === 'President' ||\n    contest.division_type === 'class' ||\n    contest.division_type === 'statewide'\n      ? ''\n      : contest.division_type === 'place' && contest.office_division === 1\n      ? 'Chief Justice'\n      : capfirst(contest.division_type) + ' ' + contest.office_division\n  }`.trim();\n}\n\nexport function getDistrictNum(division_type, division_number) {\n  return capfirst(division_type) + ' ' + division_number\n}\n\nexport function determineContestTitle(contest) {\n  if (contest.division_type === 'statewide' || contest.division_type === 'seat')\n    return '';\n\n  return determineDistrictTitle(contest);\n}\n\nexport function determineContestTitleYourRaces(contest) {\n  return determineDistrictTitle(contest);\n}","/**\n * A wrapper for the initial response from a fetch call that funnels to\n * res.json().\n *\n * @private\n * @param {Response} res\n * @returns {Promise}\n */\nfunction jsonResponse(res) {\n  if (!res.ok) throw new Error(`${res.status}: ${res.statusText}`);\n\n  return res.json();\n}\n\n/**\n * A light wrapper around fetch that assumes you're seeking a JSON response.\n *\n * @param {String|Request} input\n * @param {Object} init\n * @returns {Promise}\n */\nexport default function getJSON(input, init) {\n  return fetch(input, init).then(jsonResponse);\n}\n","const hOP = Object.prototype.hasOwnProperty;\n\n/**\n * inlined Object.is polyfill to avoid requiring consumers ship their own\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n */\nfunction is(x: any, y: any): boolean {\n  // SameValue algorithm\n  if (x === y) {\n    // Steps 1-5, 7-10\n    // Steps 6.b-6.e: +0 != -0\n    // Added the nonzero y check to make Flow happy, but it is redundant\n    return x !== 0 || y !== 0 || 1 / x === 1 / y;\n  }\n  // Step 6.a: NaN == NaN\n  return x !== x && y !== y;\n}\n\n/**\n * Performs equality by iterating through keys on an object and returning false\n * when any key has values which are not strictly equal between the arguments.\n * Returns true when the values of all keys are strictly equal.\n */\nfunction shallowEqual(objA: object, objB: object): boolean {\n  if (is(objA, objB)) {\n    return true;\n  }\n\n  if (\n    typeof objA !== 'object' ||\n    objA === null ||\n    typeof objB !== 'object' ||\n    objB === null\n  ) {\n    return false;\n  }\n\n  const keysA = Object.keys(objA);\n  const keysB = Object.keys(objB);\n\n  if (keysA.length !== keysB.length) {\n    return false;\n  }\n\n  // Test for A's keys different from B.\n  for (let i = 0; i < keysA.length; i++) {\n    if (!hOP.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nexport default shallowEqual;","// packages\nimport { Component } from 'preact';\n\n// internal\nimport shallowEqual from '../utils/shallow-equal';\n\nabstract class PureComponent<P = {}, S = {}> extends Component<P, S> {\n  shouldComponentUpdate(props, state) {\n    const check =\n      shallowEqual(props, this.props) && shallowEqual(state, this.state);\n    // if (props.projection)\n    //   console.log(\n    //     'projection check:',\n    //     props.projection === this.props.projection,\n    //     !check\n    //   );\n    return !check;\n  }\n}\n\nexport default PureComponent;","/**\n * A white-list of attributes to consider booleans for our purposes. Because\n * iframe attributes like \"sandbox\" actually mean something when they're an\n * empty string, we can't assume that means \"true\" across the board.\n *\n * @private\n * @type {Array}\n */\nconst booleans = ['allowfullscreen'];\n\n/**\n * Searches an element's attributes and returns an Object of all the ones that\n * begin with a specified prefix. Each matching attribute name is returned\n * without the prefix.\n *\n * @private\n * @param  {Element} element\n * @param  {string} prefix\n * @return {object}\n */\nfunction getMatchingAttributes(element, prefix) {\n  // prepare the object to return\n  const attrs = {};\n\n  // grab all the attributes off the element\n  const map = element.attributes;\n\n  // get a count of the number of attributes\n  const length = map.length;\n\n  // get the prefix's length\n  const prefixLength = prefix.length;\n\n  // loop through the attributes\n  for (let i = 0; i < length; i++) {\n    // get each attribute key\n    const key = map[i].name;\n\n    // continue if the key begins with supplied prefix\n    if (key.substr(0, prefixLength) === prefix) {\n      // slice off the prefix to get the bare field key\n      const field = key.slice(prefixLength);\n\n      // grab the value associated with the key\n      let value = map[i].value;\n\n      if (booleans.indexOf(field) > -1) {\n        value = true;\n      }\n\n      // add matching key to object\n      attrs[field] = value;\n    }\n  }\n\n  return attrs;\n}\n\nfunction extend(obj, props) {\n  for (let i in props) obj[i] = props[i];\n  return obj;\n}\n\nexport { extend, getMatchingAttributes };\n","const EMBED_SIZE = 'embed-size';\nconst AMP_SENTINEL = 'amp';\nconst FRAME_PREFIX = 'data-frame-';\nconst FRAME_AUTO_INITIALIZED_ATTRIBUTE = `${FRAME_PREFIX}auto-initialized`;\nconst FRAME_SRC_ATTRIBUTE = `${FRAME_PREFIX}src`;\n\nexport {\n  AMP_SENTINEL,\n  EMBED_SIZE,\n  FRAME_PREFIX,\n  FRAME_AUTO_INITIALIZED_ATTRIBUTE,\n  FRAME_SRC_ATTRIBUTE,\n};\n","import { extend, getMatchingAttributes } from './utils.mjs';\nimport {\n  AMP_SENTINEL,\n  EMBED_SIZE,\n  FRAME_PREFIX,\n  FRAME_AUTO_INITIALIZED_ATTRIBUTE,\n  FRAME_SRC_ATTRIBUTE,\n} from './constants.mjs';\n\n/**\n * The Framer object to be called in the host page. Effectively a wrapper around\n * interactions with an embedded iframe.\n *\n * @param {object} options options used to prepare the iframe\n * @param {Element} options.container the containing DOM element for the iframe\n * @param {string} options.src the URL to set as the `src` of the iframe\n * @param {boolean} [options.allowfullscreen] toggles the `allowfullscreen` attribute\n * @param {string} [options.name] sets the `name` attribute\n * @param {string} [options.referrerpolicy] sets the `referrerpolicy` attribute\n * @param {string} [options.sandbox] sets the `sandbox` attribute\n * @param {string} [options.title] sets the `title` attribute\n */\nclass Framer {\n  constructor({\n    allowfullscreen = false,\n    container,\n    name,\n    referrerpolicy,\n    sandbox = 'allow-scripts',\n    src,\n    title,\n  }) {\n    this.container = container;\n    this.src = src;\n    this.allowfullscreen = allowfullscreen;\n    this.name = name;\n    this.referrerpolicy = referrerpolicy;\n    this.sandbox = sandbox;\n    this.title = title;\n\n    this.processMessage_ = this.processMessage_.bind(this);\n    window.addEventListener('message', this.processMessage_, false);\n\n    this.createIframe_();\n  }\n\n  /**\n   * Removes event listeners and removes the iframe from the container.\n   *\n   * @returns {void}\n   * @example\n   *\n   * const framer = new Framer(...);\n   * // tears down the Framer\n   * framer.remove();\n   */\n  remove() {\n    window.removeEventListener('message', this.processMessage_, false);\n    this.container.removeChild(this.iframe);\n    // important to de-reference the iframe so it can be GC'ed\n    this.iframe = null;\n  }\n\n  /**\n   * Creates the iframe element and sets the source of the iframe.\n   *\n   * @private\n   * @returns {void}\n   */\n  createIframe_() {\n    const iframe = (this.iframe = document.createElement('iframe'));\n\n    iframe.setAttribute('src', this.src);\n    iframe.setAttribute('width', '100%');\n    iframe.setAttribute('scrolling', 'no');\n    iframe.setAttribute('marginheight', '0');\n    iframe.setAttribute('frameborder', '0');\n\n    if (this.allowfullscreen) {\n      iframe.setAttribute('allowfullscreen', '');\n    }\n\n    if (this.name) {\n      iframe.setAttribute('name', name);\n    }\n\n    if (this.referrerpolicy) {\n      iframe.setAttribute('referrerpolicy', this.referrerpolicy);\n    }\n\n    iframe.setAttribute('sandbox', this.sandbox);\n\n    if (this.title) {\n      iframe.setAttribute('title', this.title);\n    }\n\n    this.container.appendChild(iframe);\n  }\n\n  /**\n   * Receives a message from the frame. Checks to make sure it is only listening\n   * to the iframe it created, and that the sentinel value and type matches.\n   *\n   * @private\n   * @param {Event} event\n   * @returns {void}\n   */\n  processMessage_(event) {\n    // this message isn't from our created frame, stop here\n    if (event.source !== this.iframe.contentWindow) return;\n\n    const { data } = event;\n\n    // if the sentinel and type matches, update our height\n    if (data.sentinel === AMP_SENTINEL && data.type === EMBED_SIZE) {\n      this.setIframeHeight_(data.height);\n    }\n  }\n\n  /**\n   * Sets the iframe's height.\n   *\n   * @private\n   * @param {number} height\n   * @returns {void}\n   */\n  setIframeHeight_(height) {\n    this.iframe.setAttribute('height', height);\n  }\n}\n\n/**\n * Automatically initializes any frames that have not already been\n * auto-activated.\n *\n * @returns {Array} An array of all the created Framers\n * @example\n *\n * // sets up all frames that have not been initialized yet\n * autoInitFrames();\n */\nfunction autoInitFrames() {\n  const elements = document.querySelectorAll(\n    `[${FRAME_SRC_ATTRIBUTE}]:not([${FRAME_AUTO_INITIALIZED_ATTRIBUTE}])`\n  );\n\n  const activated = [];\n\n  for (let i = 0; i < elements.length; i++) {\n    const container = elements[i];\n\n    const attributes = getMatchingAttributes(container, FRAME_PREFIX);\n    container.setAttribute(FRAME_AUTO_INITIALIZED_ATTRIBUTE, '');\n\n    activated.push(\n      new Framer(\n        extend(\n          {\n            container,\n          },\n          attributes\n        )\n      )\n    );\n  }\n\n  return activated;\n}\n\nexport { autoInitFrames, Framer };\n","// internal\nimport { AMP_SENTINEL, EMBED_SIZE } from './constants.mjs';\nimport { extend } from './utils.mjs';\n\n/**\n * A wrapper around postMessage to normalize the message body. Automatically\n * includes the AMP sentinel value.\n *\n * @private\n * @param {string} type Type of message being sent\n * @param {Object} [data] Any additional data to send\n * @returns {void}\n */\nfunction sendMessage(type, data = {}) {\n  window.parent.postMessage(\n    extend({ sentinel: AMP_SENTINEL, type }, data),\n    '*'\n  );\n}\n\n/**\n * Gets the height of the current document's body. Uses offsetHeight to ensure\n * that margins are accounted for.\n *\n * @private\n * @returns {number}\n */\nfunction getDocumentHeight() {\n  return document.documentElement.offsetHeight;\n}\n\n/**\n * Sends the current document's height or provided value to the host window\n * using postMessage.\n *\n * @param {number} [height] The height to pass to the host page, is determined automatically if not passed\n * @returns {void}\n * @example\n *\n * // Uses the document's height to tell the host page\n * sendFrameHeight();\n *\n * // Pass a height you've determined in another way\n * sendFrameHeight(500);\n *\n */\nfunction sendFrameHeight(height = getDocumentHeight()) {\n  sendMessage(EMBED_SIZE, { height });\n}\n\n/**\n * Sets up an event listener for the load event that sends the new frame\n * height to the host. Automatically removes itself once fired.\n *\n * @returns {void}\n * @example\n *\n * // once the frame's load event is fired, tell the host page its new height\n * sendHeightOnLoad();\n */\nfunction sendHeightOnLoad() {\n  window.addEventListener('load', function cb() {\n    sendFrameHeight();\n\n    window.removeEventListener('load', cb);\n  });\n}\n\n/**\n * Sets up an event listener for the resize event that sends the new frame\n * height to the host.\n *\n * @returns {void}\n * @example\n *\n * // every time the frame is resized, tell the host page what its new height is\n * sendHeightOnResize();\n */\nfunction sendHeightOnResize() {\n  window.addEventListener('resize', () => sendFrameHeight());\n}\n\n/**\n * Sends height updates to the host page on an interval.\n *\n * @param {number} [delay] How long to set the interval\n * @returns {void}\n * @example\n *\n * // will call sendFrameHeight every 300ms\n * sendHeightOnPoll();\n *\n * // will call sendFrameHeight every 150ms\n * sendHeightOnPoll(150);\n */\nfunction sendHeightOnPoll(delay = 300) {\n  setInterval(sendFrameHeight, delay);\n}\n\n/**\n * A helper for running the standard functions for setting up a frame.\n *\n * Automatically calls an sendFrameHeight, sendHeightOnLoad and sendHeightOnResize.\n *\n * @returns {void}\n * @example\n *\n * initFrame();\n */\nfunction initFrame() {\n  sendFrameHeight();\n  sendHeightOnLoad();\n  sendHeightOnResize();\n}\n\n/**\n * Initializes a frame, then sets up a poll to continue to update on an interval.\n *\n * @param {number} [delay] An optional custom delay to pass to sendHeightOnPoll\n * @returns {void}\n * @example\n *\n * // calls initFrame, then calls sendHeightOnPoll\n * initFrameAndPoll();\n */\nfunction initFrameAndPoll(delay) {\n  initFrame();\n  sendHeightOnPoll(delay);\n}\n\nexport {\n  initFrame,\n  initFrameAndPoll,\n  sendFrameHeight,\n  sendHeightOnLoad,\n  sendHeightOnPoll,\n  sendHeightOnResize,\n};\n","// packages\nimport cx from 'classnames';\nimport { capfirst } from 'journalize';\nimport memoize from 'lodash/memoize';\nimport { h } from 'preact';\n\ntype Props = {\n  excludeInitial?: boolean;\n  party: string;\n  style: string;\n};\n\nfunction PartyPill({ excludeInitial, party, style }: Props) {\n  const partyPrefix = party.slice(0, 3).toLowerCase();\n  const partyInitial = party[0].toUpperCase();\n\n  const classes = cx('circle-pill', `pill--${partyPrefix}`);\n\n  return (\n    <span class={classes} style={style} title={capfirst(party)}>\n      {!excludeInitial && partyInitial}\n    </span>\n  );\n}\n\nPartyPill.defaultProps = {\n  excludeInitial: false,\n};\n\nexport default memoize(PartyPill, ({ party, style }) => ({\n  party: party,\n  style: style,\n}));"],"sourceRoot":""}