PageSourceSearch

https://patilv.com/spokane-nonprofits/

html patilv.com collected 2026-10-03 23:19:12 UTC 29,749 bytes, 634 lines download raw bytes

1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
4<meta charset="utf-8">
5<meta name="generator" content="quarto-1.9.38">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9
10<title>Inland Northwest Nonprofit Sector Intelligence</title>
11<style>
12/* Default styles provided by pandoc.
13** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
14*/
15code{white-space: pre-wrap;}
16span.smallcaps{font-variant: small-caps;}
17div.columns{display: flex; gap: min(4vw, 1.5em);}
18div.column{flex: auto; overflow-x: auto;}
19div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
20ul.task-list{list-style: none;}
21ul.task-list li input[type="checkbox"] {
22  width: 0.8em;
23  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
24  vertical-align: middle;
25}
26</style>
27
28
29<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 31
31
32<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 32
32
33<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 33
33
34<script src="site_libs/quarto-search/quarto-search.js"></script>
34
35<meta name="quarto:offset" content="./">
36<script src="site_libs/quarto-html/quarto.js" type="module"></script>
vendor: 1 bytes, line 36
36
37<script src="site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
vendor: 1 bytes, line 37
37
38<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 38
38
39<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 39
39
40<script src="site_libs/quarto-html/anchor.min.js"></script>
40
41<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
42<link href="site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css" rel="stylesheet" id="quarto-text-highlighting-styles">
43<script src="site_libs/bootstrap/bootstrap.min.js"></script>
43
44<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
45<link href="site_libs/bootstrap/bootstrap-c81d55332d48a6358ab6ce3d5cfa0db1.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
46<script id="quarto-search-options" type="application/json">{
47  "location": "navbar",
48  "copy-button": false,
49  "collapse-after": 3,
50  "panel-placement": "end",
51  "type": "overlay",
52  "limit": 50,
53  "keyboard-shortcut": [
54    "f",
55    "/",
56    "s"
57  ],
58  "show-item-context": false,
59  "language": {
60    "search-no-results-text": "No results",
61    "search-matching-documents-text": "matching documents",
62    "search-copy-link-title": "Copy link to search",
63    "search-hide-matches-text": "Hide additional matches",
64    "search-more-match-text": "more match in this document",
65    "search-more-matches-text": "more matches in this document",
66    "search-clear-button-title": "Clear",
67    "search-text-placeholder": "",
68    "search-detached-cancel-button-title": "Cancel",
69    "search-submit-button-title": "Submit",
70    "search-label": "Search"
71  }
72}</script>
72
73<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="">
74
75
76</head>
77
78<body class="nav-fixed fullcontent quarto-light">
79
80<div id="quarto-search-results"></div>
81  <header id="quarto-header" class="headroom fixed-top">
82    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
83      <div class="navbar-container container-fluid">
84      <div class="navbar-brand-container mx-auto">
85    <a class="navbar-brand" href="./index.html">
86    <span class="navbar-title">Inland Northwest Nonprofit Sector Intelligence</span>
87    </a>
88  </div>
89            <div id="quarto-search" class="" title="Search"></div>
90          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
91  <span class="navbar-toggler-icon"></span>
92</button>
93          <div class="collapse navbar-collapse" id="navbarCollapse">
94            <ul class="navbar-nav navbar-nav-scroll me-auto">
95  <li class="nav-item">
96    <a class="nav-link active" href="./index.html" aria-current="page"> 
97<span class="menu-text">Home</span></a>
98  </li>  
99  <li class="nav-item">
100    <a class="nav-link" href="./sector-overview.html"> 
101<span class="menu-text">Sector Overview</span></a>
102  </li>  
103  <li class="nav-item">
104    <a class="nav-link" href="./trends.html"> 
105<span class="menu-text">Trends</span></a>
106  </li>  
107  <li class="nav-item">
108    <a class="nav-link" href="./geography.html"> 
109<span class="menu-text">Geography</span></a>
110  </li>  
111  <li class="nav-item">
112    <a class="nav-link" href="./human-services.html"> 
113<span class="menu-text">Human Services</span></a>
114  </li>  
115  <li class="nav-item">
116    <a class="nav-link" href="./financial-health.html"> 
117<span class="menu-text">Financial Health</span></a>
118  </li>  
119  <li class="nav-item">
120    <a class="nav-link" href="./service-gaps.html"> 
121<span class="menu-text">Service Gaps</span></a>
122  </li>  
123  <li class="nav-item">
124    <a class="nav-link" href="./methodology.html"> 
125<span class="menu-text">Methodology</span></a>
126  </li>  
127</ul>
128          </div> <!-- /navcollapse -->
129            <div class="quarto-navbar-tools">
130</div>
131      </div> <!-- /container-fluid -->
132    </nav>
133</header>
134<!-- content -->
135<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
136<!-- sidebar -->
137<!-- margin-sidebar -->
138    
139<!-- main -->
140<main class="content" id="quarto-document-content">
141
142<header id="title-block-header" class="quarto-title-block default">
143<div class="quarto-title">
144<h1 class="title">Inland Northwest Nonprofit Sector Intelligence</h1>
145<p class="subtitle lead">A public-data portrait of the nonprofit sector in Spokane County and the surrounding Inland Northwest</p>
146</div>
147
148
149
150<div class="quarto-title-meta">
151
152    
153  
154    
155  </div>
156  
157
158
159</header>
160
161
162<div class="key-finding">
163<p><span class="kf-label">Executive summary</span> The seven-county Inland Northwest is home to <strong>5,256 active nonprofits</strong> serving about 882,000 residents — roughly 60 organizations for every 10,000 people. The sector generates <strong>$6.5 billion in annual revenue</strong> and holds <strong>$26.2 billion in assets</strong>, but both are concentrated in a handful of large institutions. Formation activity is surging, finances are broadly stable but thin — a third of larger organizations ran a deficit in their most recent filing — and per-capita human-services coverage is weakest exactly where measured social vulnerability is highest: Spokane County.</p>
164</div>
165<div class="stat-row">
166<div class="stat-tile">
167<p><span class="stat-value">5,256</span> <span class="stat-label">Active nonprofits</span> <span class="stat-note">NCCS BMF, June 2026</span></p>
168</div>
169<div class="stat-tile">
170<p><span class="stat-value">$6.5B</span> <span class="stat-label">Annual revenue</span> <span class="stat-note">most recent IRS filings</span></p>
171</div>
172<div class="stat-tile">
173<p><span class="stat-value">$26.2B</span> <span class="stat-label">Total assets</span> <span class="stat-note">most recent IRS filings</span></p>
174</div>
175<div class="stat-tile accent">
176<p><span class="stat-value">768</span> <span class="stat-label">Human services organizations</span> <span class="stat-note">NTEE I, J, K, L, O, P</span></p>
177</div>
178<div class="stat-tile accent">
179<p><span class="stat-value">395</span> <span class="stat-label">New nonprofits in 2025</span> <span class="stat-note">strongest organic year on record</span></p>
180</div>
181</div>
182<section id="key-findings" class="level2">
183<h2 class="anchored" data-anchor-id="key-findings">Key findings</h2>
184<p><strong>1. The sector is large, and growing faster than ever.</strong> New IRS tax-exempt rulings reached 310 in 2024 and 395 in 2025 — the strongest two-year run in the region’s history, even counting the one-time IRS administrative spike of 2014, following a brief pandemic dip. The 2020s are on pace to out-produce the 2010s, the previous record decade. <a href="./trends.html">→ Trends</a></p>
185<p><strong>
1852. Composition mirrors the states; scale does not.</strong> The region’s category mix — human services first (23% of all registered organizations, a third of those with a classified category), then education and public benefit — tracks Washington and Idaho statewide averages closely. What distinguishes the region is concentration: 73 organizations with more than $10 million in revenue, led by Kootenai Health, Gonzaga University, and the region’s community health systems, account for the large majority of all nonprofit dollars. <a href="./sector-overview.html">→ Sector Overview</a></p>
186<p><strong>3. Density is highest where populations are smallest.</strong> Spokane and Kootenai counties host about three-quarters of the region’s nonprofits, but rural and college counties (Lincoln, Latah, Whitman) sustain far more organizations per resident. Spokane County itself has the region’s thinnest per-capita nonprofit coverage, with fast-growing Kootenai County next. <a href="./geography.html">→ Geography</a></p>
187<p><strong>4. Finances are stable but thin.</strong> Among 502 larger organizations with current Form 990 filings, the median operating margin is +5.0% and median reserves are about 10.6 months of expenses — healthy on the surface. But <strong>one in three ran a deficit</strong> in the latest year, and <strong>one in five holds less than three months of reserves</strong>. Human services organizations hold thinner reserves than the sector overall. <a href="./financial-health.html">→ Financial Health</a></p>
188<p><strong>5. Coverage is weakest where vulnerability is highest.</strong> Spokane County has the region’s highest CDC Social Vulnerability Index score and 22 of its 38 high-vulnerability census tracts — yet the region’s <em>lowest</em> rate of human-services nonprofits per resident. Twenty-seven ZIP c
188odes combine above-median poverty with below-median human-services coverage. <a href="./service-gaps.html">→ Service Gaps</a></p>
189</section>
190<section id="why-this-exists-and-what-to-do-with-it" class="level2">
191<h2 class="anchored" data-anchor-id="why-this-exists-and-what-to-do-with-it">Why this exists — and what to do with it</h2>
192<p>The Inland Northwest’s nonprofit sector is one of the region’s largest economic and social forces — more than 5,200 organizations, $6.5 billion in annual revenue, and the primary safety net for food, housing, employment, and youth services. Yet decisions about it — where philanthropy goes, which services get funded, where new organizations form — are routinely made from anecdote, because the underlying facts sit scattered across IRS files, Census tables, and federal vulnerability indices that few people have time to assemble. And because the region spans a state line, no single state-level report has ever described it whole. This site assembles that picture from public data, documents every method, and keeps it reproducible.</p>
193<p><strong>Who it’s for.</strong> Funders can see where dollars concentrate and where coverage gaps persist. Nonprofit boards can benchmark their reserves and margins against 500 regional peers. Policymakers can overlay service coverage with poverty and social vulnerability at the neighborhood level. Researchers and students can build on an open, documented pipeline.</p>
194<p><strong>What the data suggest doing:</strong></p>
195<ol type="1">
196<li><strong>Fund resilience, not just programs.</strong> One in five larger nonprofits holds less than three months of operating reserves. General operating support and multi-year grants matter as much as new initiatives.</li>
197<li><strong>Target the gap map.</strong>
197 Twenty-seven ZIP codes pair above-median poverty with below-median human-services coverage, and Spokane County’s most vulnerable neighborhoods have the region’s thinnest per-capita coverage — addressable through siting decisions, satellite services, and capacity grants. <a href="./service-gaps.html">→ Service Gaps</a></li>
198<li><strong>Plan for Kootenai’s growth.</strong> The region’s fastest-growing county has nearly its thinnest nonprofit infrastructure per resident — a gap that compounds if unaddressed.</li>
199</ol>
200</section>
201<section id="about-this-project" class="level2">
202<h2 class="anchored" data-anchor-id="about-this-project">About this project</h2>
203<p>This site analyzes the nonprofit sector across seven counties: <strong>Spokane, Whitman, Stevens, Pend Oreille, and Lincoln</strong> in Washington, and <strong>Kootenai and Latah</strong> in Idaho — the greater Inland Northwest centered on Spokane and Coeur d’Alene.</p>
204<p>All data are public: the Urban Institute’s <a href="https://urbaninstitute.github.io/nccs/datasets/bmf/">NCCS Business Master File</a>, IRS Form 990 extracts via the <a href="https://projects.propublica.org/nonprofits/api/">ProPublica Nonprofit Explorer API</a>, U.S. Census Bureau American Community Survey estimates, and the <a href="https://www.atsdr.cdc.gov/placeandhealth/svi/">CDC/ATSDR Social Vulnerability Index</a>. Methods, definitions, and limitations are documented on the <a href="./methodology.html">Methodology</a> page.</p>
205<p><em>Created by Vivek H. Patil, Ph.D., Professor of Marketing and Director of Graduate Business Programs, Gonzaga University School of Business Administration. Analyses run July 2026.</em></p>
206
207
208</section>
209
210</main> <!-- /main -->
211<script id="quarto-html-after-body" type="application/javascript">
212  window.document.addEventListener("DOMContentLoaded", function (event) {
213    const icon = "";
214    const anchorJS = new window.AnchorJS();
215    anchorJS.options = {
216      placement: 'right',
217      icon: icon
218    };
219    anchorJS.add('.anchored');
220    const isCodeAnnotation = (el) => {
221      for (const clz of el.classList) {
222        if (clz.startsWith('code-annotation-')) {                     
223          return true;
224        }
225      }
226      return false;
227    }
228    const onCopySuccess = function(e) {
229      // button target
230      const button = e.trigger;
231      // don't keep focus
232      button.blur();
233      // flash "checked"
234      button.classList.add('code-copy-button-checked');
235      var currentTitle = button.getAttribute("title");
236      button.setAttribute("title", "Copied!");
237      let tooltip;
238      if (window.bootstrap) {
239        button.setAttribute("data-bs-toggle", "tooltip");
240        button.setAttribute("data-bs-placement", "left");
241        button.setAttribute("data-bs-title", "Copied!");
242        tooltip = new bootstrap.Tooltip(button, 
243          { trigger: "manual", 
244            customClass: "code-copy-button-tooltip",
245            offset: [0, -8]});
246        tooltip.show();    
247      }
248      setTimeout(function() {
249        if (tooltip) {
250          tooltip.hide();
251          button.removeAttribute("data-bs-title");
252          button.removeAttribute("data-bs-toggle");
253          button.removeAttribute("data-bs-placement");
254        }
255        button.setAttribute("title", currentTitle);
256        button.classList.remove('code-copy-button-checked');
257      }, 1000);
258      // clear code selection
259      e.clearSelection();
260    }
261    const getTextToCopy = function(trigger) {
262      const outerScaffold = trigger.parentElement.cloneNode(true);
263      const codeEl = outerScaffold.querySelector('code');
264      for (const childEl of codeEl.children) {
265        if (isCodeAnnotation(childEl)) {
266          childEl.remove();
267        }
268      }
269      return codeEl.innerText;
270    }
271    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
272      text: getTextToCopy
273    });
274    clipboard.on('success', onCopySuccess);
275    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
276      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
277        text: getTextToCopy,
278        container: window.document.getElementById('quarto-embedded-source-code-modal')
279      });
280      clipboardModal.on('success', onCopySuccess);
281    }
282      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
283      var mailtoRegex = new RegExp(/^mailto:/);
284        var filterRegex = new RegExp("https:\/\/patilv\.com\/spokane-nonprofits\/");
285      var isInternal = (href) => {
286          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
287      }
288      // Inspect non-navigation links and adorn them if external
289     var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
290      for (var i=0; i<links.length; i++) {
291        const link = links[i];
292        if (!isInternal(link.href)) {
293          // undo the damage that might have been done by quarto-nav.js in the case of
294          // links that we want to consider external
295          if (link.dataset.originalHref !== undefined) {
296            link.href = link.dataset.originalHref;
297          }
298            // target, if specified
299            link.setAttribute("target", "_blank");
300            if (link.getAttribute("rel") === null) {
301              link.setAttribute("rel", "noopener");
302            }
303        }
304      }
305    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
306      const config = {
307        allowHTML: true,
308        maxWidth: 500,
309        delay: 100,
310        arrow: false,
311        appendTo: function(el) {
312            return el.parentElement;
313        },
314        interactive: true,
315        interactiveBorder: 10,
316        theme: 'quarto',
317        placement: 'bottom-start',
318      };
319      if (contentFn) {
320        config.content = contentFn;
321      }
322      if (onTriggerFn) {
323        config.onTrigger = onTriggerFn;
324      }
325      if (onUntriggerFn) {
326        config.onUntrigger = onUntriggerFn;
327      }
328      window.tippy(el, config); 
329    }
330    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
331    for (var i=0; i<noterefs.length; i++) {
332      const ref = noterefs[i];
333      tippyHover(ref, function() {
334        // use id or data attribute instead here
335        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
336        try { href = new URL(href).hash; } catch {}
337        const id = href.replace(/^#\/?/, "");
338        const note = window.document.getElementById(id);
339        if (note) {
340          return note.innerHTML;
341        } else {
342          return "";
343        }
344      });
345    }
346    const xrefs = window.document.querySelectorAll('a.quarto-xref');
347    const processXRef = (id, note) => {
348      // Strip column container classes
349      const stripColumnClz = (el) => {
350        el.classList.remove("page-full", "page-columns");
351        if (el.children) {
352          for (const child of el.children) {
353            stripColumnClz(child);
354          }
355        }
356      }
357      stripColumnClz(note)
358      if (id === null || id.startsWith('sec-')) {
359        // Special case sections, only their first couple elements
360        const container = document.createElement("div");
361        if (note.children && note.children.length > 2) {
362          container.appendChild(note.children[0].cloneNode(true));
363          for (let i = 1; i < note.children.length; i++) {
364            const child = note.children[i];
365            if (child.tagName === "P" && child.innerText === "") {
366              continue;
367            } else {
368              container.appendChild(child.cloneNode(true));
369              break;
370            }
371          }
372          if (window.Quarto?.typesetMath) {
373            window.Quarto.typesetMath(container);
374          }
375          return container.innerHTML
376        } else {
377          if (window.Quarto?.typesetMath) {
378            window.Quarto.typesetMath(note);
379          }
380          return note.innerHTML;
381        }
382      } else {
383        // Remove any anchor links if they are present
384        const anchorLink = note.querySelector('a.anchorjs-link');
385        if (anchorLink) {
386          anchorLink.remove();
387        }
388        if (window.Quarto?.typesetMath) {
389          window.Quarto.typesetMath(note);
390        }
391        if (note.classList.contains("callout")) {
392          return note.outerHTML;
393        } else {
394          return note.innerHTML;
395        }
396      }
397    }
398    for (var i=0; i<xrefs.length; i++) {
399      const xref = xrefs[i];
400      tippyHover(xref, undefined, function(instance) {
401        instance.disable();
402        let url = xref.getAttribute('href');
403        let hash = undefined; 
404        if (url.startsWith('#')) {
405          hash = url;
406        } else {
407          try { hash = new URL(url).hash; } catch {}
408        }
409        if (hash) {
410          const id = hash.replace(/^#\/?/, "");
411          const note = window.document.getElementById(id);
412          if (note !== null) {
413            try {
414              const html = processXRef(id, note.cloneNode(true));
415              instance.setContent(html);
416            } finally {
417              instance.enable();
418              instance.show();
419            }
420          } else {
421            // See if we can fetch this
422            fetch(url.split('#')[0])
423            .then(res => res.text())
424            .then(html => {
425              const parser = new DOMParser();
426              const htmlDoc = parser.parseFromString(html, "text/html");
427              const note = htmlDoc.getElementById(id);
428              if (note !== null) {
429                const html = processXRef(id, note);
430                instance.setContent(html);
431              } 
432            }).finally(() => {
433              instance.enable();
434              instance.show();
435            });
436          }
437        } else {
438          // See if we can fetch a full url (with no hash to target)
439          // This is a special case and we should probably do some content thinning / targeting
440          fetch(url)
441          .then(res => res.text())
442          .then(html => {
443            const parser = new DOMParser();
444            const htmlDoc = parser.parseFromString(html, "text/html");
445            const note = htmlDoc.querySelector('main.content');
446            if (note !== null) {
447              // This should only happen for chapter cross references
448              // (since there is no id in the URL)
449              // remove the first header
450              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
451                note.children[0].remove();
452              }
453              const html = processXRef(null, note);
454              instance.setContent(html);
455            } 
456          }).finally(() => {
457            instance.enable();
458            instance.show();
459          });
460        }
461      }, function(instance) {
462      });
463    }
464        let selectedAnnoteEl;
465        const selectorForAnnotation = ( cell, annotation) => {
466          let cellAttr = 'data-code-cell="' + cell + '"';
467          let lineAttr = 'data-code-annotation="' +  annotation + '"';
468          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
469          return selector;
470        }
471        const selectCodeLines = (annoteEl) => {
472          const doc = window.document;
473          const targetCell = annoteEl.getAttribute("data-target-cell");
474          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
475          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
476          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
477          const lineIds = lines.map((line) => {
478            return targetCell + "-" + line;
479          })
480          let top = null;
481          let height = null;
482          let parent = null;
483          if (lineIds.length > 0) {
484              //compute the position of the single el (top and bottom and make a div)
485              const el = window.document.getElementById(lineIds[0]);
486              top = el.offsetTop;
487              height = el.offsetHeight;
488              parent = el.parentElement.parentElement;
489            if (lineIds.length > 1) {
490              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
491              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
492              height = bottom - top;
493            }
494            if (top !== null && height !== null && parent !== null) {
495              // cook up a div (if necessary) and position it 
496              let div = window.document.getElementById("code-annotation-line-highlight");
497              if (div === null) {
498                div = window.document.createElement("div");
499                div.setAttribute("id", "code-annotation-line-highlight");
500                div.style.position = 'absolute';
501                parent.appendChild(div);
502              }
503              div.style.top = top - 2 + "px";
504              div.style.height = height + 4 + "px";
505              div.style.left = 0;
506              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
507              if (gutterDiv === null) {
508                gutterDiv = window.document.createElement("div");
509                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
510                gutterDiv.style.position = 'absolute';
511                const codeCell = window.document.getElementById(targetCell);
512                const gutter = codeCell.querySelector('.code-annotation-gutter');
513                gutter.appendChild(gutterDiv);
514              }
515              gutterDiv.style.top = top - 2 + "px";
516              gutterDiv.style.height = height + 4 + "px";
517            }
518            selectedAnnoteEl = annoteEl;
519          }
520        };
521        const unselectCodeLines = () => {
522          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
523          elementsIds.forEach((elId) => {
524            const div = window.document.getElementById(elId);
525            if (div) {
526              div.remove();
527            }
528          });
529          selectedAnnoteEl = undefined;
530        };
531          // Handle positioning of the toggle
532      window.addEventListener(
533        "resize",
534        throttle(() => {
535          elRect = undefined;
536          if (selectedAnnoteEl) {
537            selectCodeLines(selectedAnnoteEl);
538          }
539        }, 10)
540      );
541      function throttle(fn, ms) {
542      let throttle = false;
543      let timer;
544        return (...args) => {
545          if(!throttle) { // first call gets through
546              fn.apply(this, args);
547              throttle = true;
548          } else { // all the others get throttled
549              if(timer) clearTimeout(timer); // cancel #2
550              timer = setTimeout(() => {
551                fn.apply(this, args);
552                timer = throttle = false;
553              }, ms);
554          }
555        };
556      }
557        // Attach click handler to the DT
558        const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
559        for (const annoteDlNode of annoteDls) {
560          annoteDlNode.addEventListener('click', (event) => {
561            const clickedEl = event.target;
562            if (clickedEl !== selectedAnnoteEl) {
563              unselectCodeLines();
564              const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
565              if (activeEl) {
566                activeEl.classList.remove('code-annotation-active');
567              }
568              selectCodeLines(clickedEl);
569              clickedEl.classList.add('code-annotation-active');
570            } else {
571              // Unselect the line
572              unselectCodeLines();
573              clickedEl.classList.remove('code-annotation-active');
574            }
575          });
576        }
577    const findCites = (el) => {
578      const parentEl = el.parentElement;
579      if (parentEl) {
580        const cites = parentEl.dataset.cites;
581        if (cites) {
582          return {
583            el,
584            cites: cites.split(' ')
585          };
586        } else {
587          return findCites(el.parentElement)
588        }
589      } else {
590        return undefined;
591      }
592    };
593    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
594    for (var i=0; i<bibliorefs.length; i++) {
595      const ref = bibliorefs[i];
596      const citeInfo = findCites(ref);
597      if (citeInfo) {
598        tippyHover(citeInfo.el, function() {
599          var popup = window.document.createElement('div');
600          citeInfo.cites.forEach(function(cite) {
601            var citeDiv = window.document.createElement('div');
602            citeDiv.classList.add('hanging-indent');
603            citeDiv.classList.add('csl-entry');
604            var biblioDiv = window.document.getElementById('ref-' + cite);
605            if (biblioDiv) {
606              citeDiv.innerHTML = biblioDiv.innerHTML;
607            }
608            popup.appendChild(citeDiv);
609          });
610          return popup.innerHTML;
611        });
612      }
613    }
614  });
615  </script>
615
616</div> <!-- /content -->
617<footer class="footer">
618  <div class="nav-footer">
619    <div class="nav-footer-left">
620<p>Created by <a href="https://www.gonzaga.edu/school-of-business-administration">Vivek H. Patil, Ph.D.</a>, Professor of Marketing and Director of Graduate Business Programs, Gonzaga University School of Business Administration.</p>
621</div>   
622    <div class="nav-footer-center">
623      &nbsp;
624    </div>
625    <div class="nav-footer-right">
626<p>Public data: NCCS · IRS 990 / ProPublica · Census ACS · CDC SVI</p>
627</div>
628  </div>
629</footer>
630
631
632
633
634</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.