PageSourceSearch

https://johnsoncitypress.com/news-category/news/local-news/1/6/

html johnsoncitypress.com collected 2026-10-02 04:55:27 UTC 92,173 bytes, 2,729 lines download raw bytes

1
2
3<!DOCTYPE html>
4<html id="ctl00_ctl00_mainhtml" xmlns="http://www.w3.org/1999/xhtml" lang="en">
5<head id="ctl00_ctl00_Head1">
6
7   
7<script type="text/javascript">
8      if (window.name == "refresh")
9      {
10         window.stop();
11         window.location.replace(window.location.pathname + window.location.search + window.location.hash);
12         window.name = "";
13      }
14   </script>
14
15
16   <link rel="preconnect" href="https://fonts.googleapis.com" /><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" /><meta name="viewport" content="width=device-width, initial-scale=1" />
17
18   <link rel="stylesheet" type="text/css" href="https://media-sixrivers.mynews360.com/css/smartBanner.css?v=1.14.5.35260" media="screen" />
19   <link rel="stylesheet" type="text/css" href="https://media-sixrivers.mynews360.com/css/common.css?v=1.14.5.35260" />
20   <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700,700i,900,900i&amp;display=swap" />
21   <link rel="stylesheet" type="text/css" href="https://media-sixrivers.mynews360.com/css/fontawesome/fontawesome.min.css?v=1.14.5.35260" />
22   <link rel="stylesheet" type="text/css" href="https://media-sixrivers.mynews360.com/css/fontawesome/brands.min.css?v=1.14.5.35260" />
23   
24
25   
25<script type="text/javascript" src="https://media-sixrivers.mynews360.com/js/jquery.js?v=1.14.5.35260"></script>
25
26   
27   
27<script type="text/javascript">
28      var _fbClientId = "309214499646406",
29         _fbTarget = window.location.pathname,
30         _baseUri = "https://timesnews.mynews360.com/",
31         _webUri = "https://johnsoncitypress.com",
32         _mediaUrl = "https://media-sixrivers.mynews360.com/",
33         _logoTemplate = "https://media-sixrivers.mynews360.com/logo/%%TEAM_ID%%/213",
34         _schoolTemplate = "https://media-sixrivers.mynews360.com/logo/%%SCHOOL_ID%%/school/%%SPORT_ID%%/213",
35         _MTS_PHOTO_TEMPLATE = "https://media-sixrivers.mynews360.com/image/%%IMG_ID%%/%%SIZE%%/%%TEAM_ID%%/%%USER_ID%%/%%TYPE%%/213",
36         _portalId = 213,
37         _portalName = "Johnson City Press",
38         _portalUrl = "https://johnsoncitypress.com/",
39         _twitterName = "",
40         _facebookName = "",
41         _region = "Johnson City",
42         _MTS_widgetsReady = false,
43         _MTS_userId = -1,
44         _MTS_thirdPartyId = null,
45         _MTS_urlRegex = new RegExp("[|+<>\\*%&:\\?\\/\\\\\'.\"\\r\\n#]", "g"),
46         _isAdmin = false,
47         _warnAboutRejected = false,
48         _MTS_cssList = [],
49         _MTS_jsList = [],
50         _MTS_pageVP = "~/newsHome.aspx",
51         _MTS_pageId = 0,
52         _MTS_histCount = 0,
53         _MTS_sportsEnabled = false,
54         _MTS_uploadLimit = 41943040,
55         
56         _hasAlerts = false,
57         _registrationPop = false,
58         _targetList = "team,".split(',');
59   </script>
59
60
61   
62   <!--[if lt IE 9]>
63      <link rel="stylesheet" type="text/css" href="../../../../../%3C%25=SportsApp.Core.MediaUrl%20%25%3Ecss/?pid=&lt;%=_portal.Id %>&amp;ie=1&amp;v=&lt;%=SportsApp.Core.Version %>" />
64   <![endif]-->
65   
66<script type="text/javascript">
67   var _pageName = "Johnson City Press | News | Local News News";
68   var _ga_sport = "";
69   var _ga_school = "";
70   var _ga_guid = "";
71   var _ga_author = "";
72   var _ga_pagetype = "newshome";
73   var _ga_tags = "";
74</script>
vendor: 67 bytes, lines 74-76
74
75
76<script async src="https://www.googletagmanager.com/gtag/js?id=
76G-ZJ4C47N33G
vendor: 13 bytes, line 76
76"></script>
77<script type="text/javascript">
78   
vendor: 144 bytes, lines 78-82
78window.dataLayer = window.dataLayer || [];
79   function gtag() { dataLayer.push(arguments); }
80   gtag('js', new Date());
81
82   gtag('config', '
82G-ZJ4C47N33G
vendor: 5 bytes, line 82
82');
83</script>
83
84
85
86<style>
87#silktide-wrapper {
88              --focus: 0 0 0 2px #ffffff, 0 0 0 4px #000000, 0 0 0 6px #ffffff;
89              --boxShadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;
90              --fontFamily: Helvetica Neue, Segoe UI, Arial, sans-serif;
91              --primaryColor: white;
92              --backgroundColor: #050505;
93              --textColor: #F4F0DF;
94              --backdropBackgroundColor: #00000033;
95              --backdropBackgroundBlur: 0px;
96              --cookieIconColor: #050505;
97              --cookieIconBackgroundColor: white;
98}
99</style>
100<script>
101  // Initialize the dataLayer
102  window.dataLayer = window.dataLayer || [];
103
104  // Create the gtag function that pushes to the dataLayer
105  function gtag() {
106    dataLayer.push(arguments);
107  }
108
109  // Set consent defaults
110  gtag('consent', 'default', {
111    analytics_storage: localStorage.getItem('silktideCookieChoice_analytics') === 'true' ? 'granted' : 'denied',
112    ad_storage: localStorage.getItem('silktideCookieChoice_marketing') === 'true' ? 'granted' : 'denied',
113    ad_user_data: localStorage.getItem('silktideCookieChoice_marketing') === 'true' ? 'granted' : 'denied',
114    ad_personalization: localStorage.getItem('silktideCookieChoice_marketing') === 'true' ? 'granted' : 'denied',
115    functionality_storage: localStorage.getItem('silktideCookieChoice_necessary') === 'true' ? 'granted' : 'denied',
116    security_storage: localStorage.getItem('silktideCookieChoice_necessary') === 'true' ? 'granted' : 'denied'
117  });
118</script>
118
119
120<!--Google Consent Default Config-->
121<script>
122  // Define dataLayer and the gtag function
123  window.dataLayer = window.dataLayer || [];
124  function gtag(){dataLayer.push(arguments);}
125
126  // Set default consent to 'granted' as a placeholder
127  if(localStorage.getItem('consentMode') === null){
128    gtag('consent', 'default', {
129      'ad_storage': 'granted',
130      'ad_user_data': 'granted',
131      'ad_personalization': 'granted',
132      'analytics_storage': 'granted',
133      'personalization_storage': 'granted',
134      'security_storage': 'granted',
135      'functionality_storage': 'granted',
136    });
137    // To further redact your ads data when ad_storage is denied, set ads_data_redaction to true
138    gtag('set', 'ads_data_redaction', true);
139  } else {
140    gtag('consent', 'default', JSON.parse(localStorage.getItem('consentMode')));
141  }
142</script>
142
143
144<style>
145/* 
146  Silktide Consent Manager - https://silktide.com/consent-manager/  
147*/
148
149/* --------------------------------
150  Global Styles - These elements exist in the main DOM and styling is limited to positioning and animation
151-------------------------------- */
152/* Wrapper (Global) */
153#silktide-wrapper {
154  position: fixed;
155  bottom: 0;
156  right: 0;
157  width: 100%;
158  height: 100%;
159  z-index: 99999;
160  pointer-events: none;
161  border: 0px;
162  display: flex;
163  justify-content: center;
164  align-items: center;
165  overscroll-behavior: contain;
166  overflow-y: auto;
167            }
168
169/* Backdrop (Global) */
170#silktide-backdrop-global {
171  position: fixed;
172  top: 0;
173  left: 0;
174  width: 100%;
175  height: 100%;
176  pointer-events: auto;
177  border: 0px;
178  display: none;
179}
180
181/* --------------------------------
182  Links
183-------------------------------- */
184#silktide-wrapper a {
185  all: unset;
186  display: inline-block;
187  color: var(--primaryColor);
188  text-decoration: underline;
189}
190
191#silktide-wrapper a:hover {
192  cursor: pointer;
193  color: var(--textColor);
194}
195
196/* --------------------------------
197  Focus Styles
198-------------------------------- */
199#silktide-wrapper a:focus,
200#silktide-wrapper #silktide-banner button:focus,
201#silktide-wrapper #silktide-modal button:focus,
202#silktide-wrapper #silktide-cookie-icon:focus {
203  outline: none;
204  box-shadow: var(--focus);
205  border-radius: 5px;
206}
207
208#silktide-wrapper #silktide-cookie-icon:focus {
209  border-radius: 50%;
210}
211
212/* --------------------------------
213  General Styles
214-------------------------------- */
215
216#silktide-wrapper .st-button {
217  color: var(--backgroundColor);
218  background-color: var(--primaryColor);
219  border: 2px solid var(--primaryColor);
220  padding: 10px 20px;
221  text-decoration: none;
222  text-align: center;
223  display: inline-block;
224  font-size: 16px;
225  line-height: 24px;
226  cursor: pointer;
227  border-radius: 5px;
228}
229
230#silktide-wrapper .st-button--primary {
231}
232
233#silktide-wrapper .st-button--primary:hover {
234  background-color: var(--backgroundColor);
235  color: var(--primaryColor);
236}
237
238#silktide-wrapper .st-button--secondary {
239  background-color: var(--backgroundColor);
240  color: var(--primaryColor);
241}
242
243#silktide-wrapper .st-button--secondary:hover {
244  background-color: var(--primaryColor);
245  color: var(--backgroundColor);
246}
247
248/* --------------------------------
249  Banner
250-------------------------------- */
251#silktide-banner {
252  font-family: var(--fontFamily);
253  color: var(--textColor);
254  background-color: var(--backgroundColor);
255  box-sizing: border-box;
256  padding: 32px;
257  border-radius: 5px;
258  pointer-events: auto;
259  border: 0px;
260  position: fixed;
261  bottom: 16px;
262  right: 16px;
263  width: 600px;
264  overflow: auto;
265  max-width: calc(100% - 32px);
266  max-height: calc(100vh - 32px);
267  transform: translate(0, -20px);
268  opacity: 0;
269  animation: silktide-slideInDown 350ms ease-out forwards;
270  animation-delay: 0.3s;
271  box-shadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;
272}
273
274#silktide-banner:focus {
275  border-radius: 50%;
276}
277
278#silktide-banner.center {
279  top: 50%;
280  left: 50%;
281  bottom: auto;
282  right: auto;
283  position: fixed;
284  transform: translate(-50%, calc(-50% - 20px));
285  animation: silktide-slideInDown-center 350ms ease-out forwards;
286}
287
288#silktide-banner.bottomLeft {
289  bottom: 16px;
290  left: 16px;
291  position: fixed;
292}
293
294#silktide-banner.bottomCenter {
295  bottom: 16px;
296  left: 50%;
297  position: fixed;
298  transform: translate(-50%, -20px);
299  animation: silktide-slideInDown-bottomCenter 350ms ease-out forwards;
300}
301
302#silktide-banner .preferences {
303  display: flex;
304  gap: 5px;
305  border: none;
306  padding: 15px 0px;
307  background-color: transparent;
308  color: var(--primaryColor);
309  cursor: pointer;
310  font-size: 16px;
311}
312
313#silktide-banner .preferences span {
314  display: block;
315  white-space: nowrap;
316  text-decoration: underline;
317}
318
319#silktide-banner .preferences span:hover {
320  color: var(--textColor);
321}
322
323#silktide-banner .preferences:after {
324  display: block;
325  content: '>';
326  text-decoration: none;
327}
328
329#silktide-banner p {
330  font-size: 16px;
331  line-height: 24px;
332  margin: 0px 0px 15px;
333}
334
335#silktide-banner a {
336  display: inline-block;
337  color: var(--primaryColor);
338  text-decoration: underline;
339  background-color: var(--backgroundColor);
340}
341
342#silktide-banner a:hover {
343  color: var(--textColor);
344}
345
346#silktide-banner a.silktide-logo {
347  display: flex;
348  align-items: center;
349  justify-content: center;
350  fill: var(--primaryColor); /* passed down to svg > path */
351  margin-left: auto;
352  width: 48px;
353  height: 48px;
354}
355
356
357#silktide-banner .actions {
358  display: flex;
359  gap: 16px;
360  flex-direction: column;
361  margin-top: 24px;
362}
363
364@media (min-width: 600px) {
365  #silktide-banner .actions {
366    flex-direction: row;
367    align-items: center;
368  }
369}
370
371#silktide-banner .actions-row {
372  display: flex;
373  gap: 16px;
374  flex-direction: row;
375  align-items: center;
376  justify-content: space-between;
377  flex-grow: 1;
378}
379
380/* --------------------------------
381  Modal
382-------------------------------- */
383#silktide-modal {
384  display: none;
385  pointer-events: auto;
386  overflow: auto;
387  width: 800px;
388  max-width: 100%;
389  max-height: 100%;
390  border: 0px;
391  transform: translate(0px, -20px);
392  opacity: 0;
393  animation: silktide-slideInUp-center 350ms ease-out forwards;
394  box-shadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;
395  font-family: var(--fontFamily);
396  color: var(--textColor);
397  flex-direction: column;
398  padding: 30px;
399  background-color: var(--backgroundColor);
400  border-radius: 5px;
401  box-sizing: border-box;
402}
403
404/* --------------------------------
405  Modal - Header
406-------------------------------- */
407#silktide-modal .silk-header {
408  display: flex;
409  justify-content: space-between;
410  align-items: center;
411  margin-bottom: 20px;
412  gap: 16px;
413}
414
415#silktide-modal h1 {
416  font-family: var(--fontFamily);
417  color: var(--textColor);
418  font-size: 24px;
419  font-weight: 500;
420  margin: 0px;
421}
422
423#silktide-modal .modal-close {
424  display: inline-flex;
425  border: none;
426  padding: 13px;
427  border: 0px;
428  cursor: pointer;
429  background: var(--backgroundColor);
430  color: var(--primaryColor);
431}
432
433#silktide-modal .modal-close svg {
434  fill: var(--primaryColor);
435}
436
437/* --------------------------------
438  Modal - Content
439-------------------------------- */
440
441#silktide-modal section {
442  flex: 1;
443  margin-top: 32px;
444}
445
446#silktide-modal section::-webkit-scrollbar {
447  display: block; /* Force scrollbars to show */
448  width: 5px; /* Width of the scrollbar */
449}
450
451#silktide-modal section::-webkit-scrollbar-thumb {
452  background-color: var(--textColor); /* Color of the scrollbar thumb */
453  border-radius: 10px; /* Rounded corners for the thumb */
454}
455
456#silktide-modal p {
457  font-size: 16px;
458  line-height: 24px;
459  color: var(--textColor);
460  margin: 0px 0px 15px;
461}
462
463#silktide-modal p:last-of-type {
464  margin: 0px;
465}
466
467#silktide-modal fieldset {
468  padding: 0px;
469  border: none;
470  margin: 0px 0px 32px;
471}
472
473#silktide-modal fieldset:last-of-type {
474  margin: 0px;
475}
476
477#silktide-modal legend {
478  padding: 0px;
479  margin: 0px 0px 10px;
480  font-weight: 700;
481  color: var(--textColor);
482  font-size: 16px;
483}
484
485#silktide-modal .cookie-type-content {
486  display: flex;
487  justify-content: space-between;
488  align-items: flex-start;
489  gap: 24px;  
490}
491
492/* --------------------------------
493  Modal - Switches
494-------------------------------- */
495#silktide-modal .switch {
496  flex-shrink: 0;
497  position: relative;
498  display: inline-block;
499  height: 34px;
500  width: 74px;
501  cursor: pointer;
502}
503
504#silktide-modal .switch:focus-within {
505  outline: none;
506  box-shadow: var(--focus);
507  border-radius: 25px;
508}
509
510#silktide-modal .switch input {
511  opacity: 0;
512  position: absolute;
513}
514
515/* Unchecked Switch Styles */
516#silktide-modal .switch__pill {
517  position: relative;
518  display: block;
519  height: 34px;
520  width: 74px;
521  background: var(--textColor);
522  border-radius: 25px;
523}
524
525#silktide-modal .switch__dot {
526  position: absolute;
527  top: 2px;
528  left: 2px;
529  display: block;
530  height: 30px;
531  width: 30px;
532  background: var(--backgroundColor);
533  border-radius: 50%;
534  transition: left 150ms ease-out;
535}
536
537#silktide-modal .switch__off,
538#silktide-modal .switch__on {
539  text-transform: uppercase;
540  font-size: 15px;
541  font-weight: 500;
542  color: var(--backgroundColor);
543  position: absolute;
544  top: 7px;
545  right: 8px;
546  transition: right 150ms ease-out, opacity 150ms ease-out;
547}
548
549#silktide-modal .switch__off {
550  opacity: 1;
551}
552
553#silktide-modal .switch__on {
554  opacity: 0;
555}
556
557/* Checked Switch Styles */
558#silktide-modal .switch input:checked + .switch__pill {
559  background: var(--primaryColor);
560}
561
562#silktide-modal .switch input:checked ~ .switch__dot {
563  left: calc(100% - 32px);
564}
565
566#silktide-modal .switch input:checked ~ .switch__off {
567  right: calc(100% - 32px);
568  opacity: 0;
569}
570
571#silktide-modal .switch input:checked ~ .switch__on {
572  right: calc(100% - 34px);
573  opacity: 1;
574}
575
576/* Disabled Switch Styles */
577#silktide-modal .switch input:disabled + .switch__pill {
578  opacity: 0.65;
579  cursor: not-allowed;
580}
581
582/* --------------------------------
583  Modal - Footer
584-------------------------------- */
585#silktide-modal .silk-footer {
586  display: flex;
587  flex-direction: column;
588  gap: 16px;
589  margin-top: 24px;
590}
591
592@media (min-width: 600px) {
593  #silktide-modal .silk-footer {
594    flex-direction: row;
595    align-items: center;
596  }
597}
598
599#silktide-modal .silk-footer a {
600  margin-left: auto;
601  padding: 14px 0px;
602}
603
604/* Cookie Icon */
605#silktide-cookie-icon {
606  display: none !important;
607  position: fixed;
608  bottom: 10px;
609  left: 10px;
610  justify-content: center;
611  align-items: center;
612  width: 60px;
613  height: 60px;
614  border-radius: 50%;
615  padding: 0px;
616  border: none;
617  background-color: var(--cookieIconColor);
618  cursor: pointer;
619  box-shadow: 0px 0px 6px 0px #0000001a;
620  pointer-events: auto;
621  animation: silktide-fadeIn 0.3s ease-in-out forwards;
622}
623
624#silktide-cookie-icon.bottomRight {
625  left: auto;
626  right: 10px;
627}
628
629#silktide-cookie-icon svg {
630  fill: var(--cookieIconBackgroundColor);
631}
632
633/* --------------------------------
634  Backdrop
635-------------------------------- */
636#silktide-backdrop {
637  display: none;
638  position: absolute;
639  top: 0;
640  left: 0;
641  width: 100%;
642  height: 100%;
643  background-color: var(--backdropBackgroundColor);
644  backdrop-filter: blur(var(--backdropBackgroundBlur));
645  pointer-events: all;
646}
647
648/* --------------------------------
649  Animations
650-------------------------------- */
651@keyframes silktide-fadeIn {
652  from {
653    opacity: 0;
654  }
655  to {
656    opacity: 1;
657  }
658}
659
660@keyframes silktide-slideInDown {
661  from {
662    opacity: 0;
663    transform: translateY(-20px);
664  }
665  to {
666    opacity: 1;
667    transform: translateY(0);
668  }
669}
670
671@keyframes silktide-slideInDown-center {
672  from {
673    opacity: 0;
674    transform: translate(-50%, calc(-50% - 20px));
675  }
676  to {
677    opacity: 1;
678    transform: translate(-50%, -50%);
679  }
680}
681
682@keyframes silktide-slideInDown-bottomCenter {
683  from {
684    opacity: 0;
685    transform: translate(-50%, -20px);
686  }
687  to {
688    opacity: 1;
689    transform: translate(-50%, 0);
690  }
691}
692
693@keyframes silktide-slideInUp-center {
694  from {
695    opacity: 0;
696    transform: translate(0px, 20px);
697  }
698  to {
699    opacity: 1;
700    transform: translate(0px, 0px);
701  }
702}
703
704</style>
705<script>
706// Silktide Consent Manager - https://silktide.com/consent-manager/  
707
708class SilktideCookieBanner {
709  constructor(config) {
710    this.config = config; // Save config to the instance
711
712    this.wrapper = null;
713    this.banner = null;
714    this.modal = null;
715    this.cookieIcon = null;
716    this.backdrop = null;
717
718    this.createWrapper();
719
720    if (this.shouldShowBackdrop()) {
721      this.createBackdrop();
722    }
723
724    this.createCookieIcon();
725    this.createModal();
726
727    if (this.shouldShowBanner()) {
728      this.createBanner();
729      this.showBackdrop();
730    } else {
731      this.showCookieIcon();
732    }
733
734    this.setupEventListeners();
735
736    if (this.hasSetInitialCookieChoices()) {
737      this.loadRequiredCookies();
738      this.runAcceptedCookieCallbacks();
739    }
740  }
741
742  destroyCookieBanner() {
743    // Remove all cookie banner elements from the DOM
744    if (this.wrapper && this.wrapper.parentNode) {
745      this.wrapper.parentNode.removeChild(this.wrapper);
746    }
747
748    // Restore scrolling
749    this.allowBodyScroll();
750
751    // Clear all references
752    this.wrapper = null;
753    this.banner = null;
754    this.modal = null;
755    this.cookieIcon = null;
756    this.backdrop = null;
757  }
758
759  // ----------------------------------------------------------------
760  // Wrapper
761  // ----------------------------------------------------------------
762  createWrapper() {
763    this.wrapper = document.createElement('div');
764    this.wrapper.id = 'silktide-wrapper';
765    document.body.insertBefore(this.wrapper, document.body.firstChild);
766  }
767
768  // ----------------------------------------------------------------
769  // Wrapper Child Generator
770  // ----------------------------------------------------------------
771  createWrapperChild(htmlContent, id) {
772    // Create child element
773    const child = document.createElement('div');
774    child.id = id;
775    child.innerHTML = htmlContent;
776
777    // Ensure wrapper exists
778    if (!this.wrapper || !document.body.contains(this.wrapper)) {
779      this.createWrapper();
780    }
781
782    // Append child to wrapper
783    this.wrapper.appendChild(child);
784    return child;
785  }
786
787  // ----------------------------------------------------------------
788  // Backdrop
789  // ----------------------------------------------------------------
790  createBackdrop() {
791    this.backdrop = this.createWrapperChild(null, 'silktide-backdrop');
792  }
793
794  showBackdrop() {
795    if (this.backdrop) {
796      this.backdrop.style.display = 'block';
797    }
798    // Trigger optional onBackdropOpen callback
799    if (typeof this.config.onBackdropOpen === 'function') {
800      this.config.onBackdropOpen();
801    }
802  }
803
804  hideBackdrop() {
805    if (this.backdrop) {
806      this.backdrop.style.display = 'none';
807    }
808
809    // Trigger optional onBackdropClose callback
810    if (typeof this.config.onBackdropClose === 'function') {
811      this.config.onBackdropClose();
812    }
813  }
814
815  shouldShowBackdrop() {
816    return this.config?.background?.showBackground || false;
817  }
818
819  // update the checkboxes in the modal with the values from localStorage
820  updateCheckboxState(saveToStorage = false) {
821    const preferencesSection = this.modal.querySelector('#cookie-preferences');
822    const checkboxes = preferencesSection.querySelectorAll('input[type="checkbox"]');
823
824    checkboxes.forEach((checkbox) => {
825      const [, cookieId] = checkbox.id.split('cookies-');
826      const cookieType = this.config.cookieTypes.find(type => type.id === cookieId);
827      
828      if (!cookieType) return;
829
830      if (saveToStorage) {
831        // Save the current state to localStorage and run callbacks
832        const currentState = checkbox.checked;
833        
834        if (cookieType.required) {
835          localStorage.setItem(
836            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,
837            'true'
838          );
839        } else {
840          localStorage.setItem(
841            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,
842            currentState.toString()
843          );
844          
845          // Run appropriate callback
846          if (currentState && typeof cookieType.onAccept === 'function') {
847            cookieType.onAccept();
848          } else if (!currentState && typeof cookieType.onReject === 'function') {
849            cookieType.onReject();
850          }
851        }
852      } else {
853        // When reading values (opening modal)
854        if (cookieType.required) {
855          checkbox.checked = true;
856          checkbox.disabled = true;
857        } else {
858          const storedValue = localStorage.getItem(
859            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`
860          );
861          
862          if (storedValue !== null) {
863            checkbox.checked = storedValue === 'true';
864          } else {
865            checkbox.checked = !!cookieType.defaultValue;
866          }
867        }
868      }
869    });
870  }
871
872  setInitialCookieChoiceMade() {
873    window.localStorage.setItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`, 1);
874  }
875
876  // ----------------------------------------------------------------
877  // Consent Handling
878  // ----------------------------------------------------------------
879  handleCookieChoice(accepted) {
880    // We set that an initial choice was made regardless of what it was so we don't show the banner again
881    this.setInitialCookieChoiceMade();
882
883    this.removeBanner();
884    this.hideBackdrop();
885    this.toggleModal(false);
886    this.showCookieIcon();
887
888    this.config.cookieTypes.forEach((type) => {
889      // Set localStorage and run accept/reject callbacks
890      if (type.required == true) {
891        localStorage.setItem(`silktideCookieChoice_${type.id}${this.getBannerSuffix()}`, 'true');
892        if (typeof type.onAccept === 'function') { type.onAccept() }
893      } else {
894        localStorage.setItem(
895          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,
896          accepted.toString(),
897        );
898
899        if (accepted) {
900          if (typeof type.onAccept === 'function') { type.onAccept(); }
901        } else {
902          if (typeof type.onReject === 'function') { type.onReject(); }
903        }
904      }
905    });
906
907    // Trigger optional onAcceptAll/onRejectAll callbacks
908    if (accepted && typeof this.config.onAcceptAll === 'function') {
909      if (typeof this.config.onAcceptAll === 'function') { this.config.onAcceptAll(); }
910    } else if (typeof this.config.onRejectAll === 'function') {
911      if (typeof this.config.onRejectAll === 'function') { this.config.onRejectAll(); }
912    }
913
914    // finally update the checkboxes in the modal with the values from localStorage
915    this.updateCheckboxState();
916  }
917
918  getAcceptedCookies() {
919    return (this.config.cookieTypes || []).reduce((acc, cookieType) => {
920      acc[cookieType.id] =
921        localStorage.getItem(`silktideCookieChoice_${cookieType.id}${this.getBannerSuffix()}`) ===
922        'true';
923      return acc;
924    }, {});
925  }
926
927  runAcceptedCookieCallbacks() {
928    if (!this.config.cookieTypes) return;
929
930    const acceptedCookies = this.getAcceptedCookies();
931    this.config.cookieTypes.forEach((type) => {
932      if (type.required) return; // we run required cookies separately in loadRequiredCookies
933      if (acceptedCookies[type.id] && typeof type.onAccept === 'function') {
934        if (typeof type.onAccept === 'function') { type.onAccept(); }
935      }
936    });
937  }
938
939  runRejectedCookieCallbacks() {
940    if (!this.config.cookieTypes) return;
941
942    const rejectedCookies = this.getRejectedCookies();
943    this.config.cookieTypes.forEach((type) => {
944      if (rejectedCookies[type.id] && typeof type.onReject === 'function') {
945        if (typeof type.onReject === 'function') { type.onReject(); }
946      }
947    });
948  }
949
950  /**
951   * Run through all of the cookie callbacks based on the current localStorage values
952   */
953  runStoredCookiePreferenceCallbacks() {
954    this.config.cookieTypes.forEach((type) => {
955      const accepted =
956        localStorage.getItem(`silktideCookieChoice_${type.id}${this.getBannerSuffix()}`) === 'true';
957      // Set localStorage and run accept/reject callbacks
958      if (accepted) {
959        if (typeof type.onAccept === 'function') { type.onAccept(); }
960      } else {
961        if (typeof type.onReject === 'function') { type.onReject(); }
962      }
963    });
964  }
965
966  loadRequiredCookies() {
967    if (!this.config.cookieTypes) return;
968    this.config.cookieTypes.forEach((cookie) => {
969      if (cookie.required && typeof cookie.onAccept === 'function') {
970        if (typeof cookie.onAccept === 'function') { cookie.onAccept(); }
971      }
972    });
973  }
974
975  // ----------------------------------------------------------------
976  // Banner
977  // ----------------------------------------------------------------
978  getBannerContent() {
979    const bannerDescription =
980      this.config.text?.banner?.description ||
981      "<p>We use cookies on our site to enhance your user experience, provide personalized content, and analyze our traffic.</p>";
982
983    // Accept button
984    const acceptAllButtonText = this.config.text?.banner?.acceptAllButtonText || 'Accept all';
985    const acceptAllButtonLabel = this.config.text?.banner?.acceptAllButtonAccessibleLabel;
986    const acceptAllButton = `<button class="accept-all st-button st-button--primary"${
987      acceptAllButtonLabel && acceptAllButtonLabel !== acceptAllButtonText 
988        ? ` aria-label="${acceptAllButtonLabel}"` 
989        : ''
990    }>${acceptAllButtonText}</button>`;
991    
992    // Reject button
993    const rejectNonEssentialButtonText = this.config.text?.banner?.rejectNonEssentialButtonText || 'Reject non-essential';
994    const rejectNonEssentialButtonLabel = this.config.text?.banner?.rejectNonEssentialButtonAccessibleLabel;
995    const rejectNonEssentialButton = `<button class="reject-all st-button st-button--primary"${
996      rejectNonEssentialButtonLabel && rejectNonEssentialButtonLabel !== rejectNonEssentialButtonText 
997        ? ` aria-label="${rejectNonEssentialButtonLabel}"` 
998        : ''
999    }>${rejectNonEssentialButtonText}</button>`;
1000
1001    // Preferences button
1002    const preferencesButtonText = this.config.text?.banner?.preferencesButtonText || 'Preferences';
1003    const preferencesButtonLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;
1004    const preferencesButton = `<button class="preferences"${
1005      preferencesButtonLabel && preferencesButtonLabel !== preferencesButtonText 
1006        ? ` aria-label="${preferencesButtonLabel}"` 
1007        : ''
1008    }><span>${preferencesButtonText}</span></button>`;
1009    
1010
1011    // Silktide logo link
1012    const silktideLogo = `
1013      <a class="silktide-logo" href="https://silktide.com/consent-manager" target="_blank" rel="noreferrer" aria-label="Visit the Silktide Consent Manager page">
1014        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="25" viewBox="0 0 24 25" fill="inherit">
1015          <path fill-rule="evenodd" clip-rule="evenodd" d="M14.1096 16.7745C13.8895 17.2055 13.3537 17.3805 12.9129 17.1653L8.28443 14.9055L2.73192 17.7651L11.1025 21.9814C11.909 22.3876 12.8725 22.3591 13.6524 21.9058L20.4345 17.9645C21.2845 17.4704 21.7797 16.5522 21.7164 15.5872L21.7088 15.4704C21.6487 14.5561 21.0962 13.7419 20.2579 13.3326L15.6793 11.0972L10.2283 13.9045L13.71 15.6043C14.1507 15.8195 14.3297 16.3434 14.1096 16.7745ZM8.2627 12.9448L13.7136 10.1375L10.2889 8.46543C9.84803 8.25021 9.66911 7.72629 9.88916 7.29524C10.1093 6.86417 10.6451 6.68921 11.0859 6.90442L15.6575 9.13647L21.2171 6.27325L12.8808 2.03496C12.0675 1.62147 11.0928 1.65154 10.3078 2.11432L3.54908 6.09869C2.70732 6.59492 2.21846 7.50845 2.28139 8.46761L2.29003 8.59923C2.35002 9.51362 2.9026 10.3278 3.7409 10.7371L8.2627 12.9448ZM6.31884 13.9458L2.94386 12.2981C1.53727 11.6113 0.610092 10.2451 0.509431 8.71094L0.500795 8.57933C0.3952 6.96993 1.21547 5.4371 2.62787 4.60447L9.38662 0.620092C10.7038 -0.156419 12.3392 -0.206861 13.7039 0.486938L23.3799 5.40639C23.4551 5.44459 23.5224 5.4918 23.5811 5.54596C23.7105 5.62499 23.8209 5.73754 23.897 5.87906C24.1266 6.30534 23.9594 6.83293 23.5234 7.05744L17.6231 10.0961L21.0549 11.7716C22.4615 12.4583 23.3887 13.8245 23.4893 15.3587L23.497 15.4755C23.6033 17.0947 22.7724 18.6354 21.346 19.4644L14.5639 23.4057C13.2554 24.1661 11.6386 24.214 10.2854 23.5324L0.621855 18.6649C0.477299 18.592 0.361696 18.4859 0.279794 18.361C0.210188 18.2968 0.150054 18.2204 0.10296 18.133C-0.126635 17.7067 0.0406445 17.1792 0.47659 16.9546L6.31884 13.9458Z" fill="inherit"/>
1016        </svg>
1017      </a>
1018    `;
1019
1020    const bannerContent = `
1021      ${bannerDescription}
1022      <div class="actions">                               
1023        ${acceptAllButton}
1024        ${rejectNonEssentialButton}
1025        <div class="actions-row">
1026          ${preferencesButton}
1027
1028        </div>
1029      </div>
1030    `;
1031
1032    return bannerContent;
1033  }
1034
1035  hasSetInitialCookieChoices() {
1036    return !!localStorage.getItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`);
1037  }
1038
1039  createBanner() {
1040    // Create banner element
1041    this.banner = this.createWrapperChild(this.getBannerContent(), 'silktide-banner');
1042
1043    // Add positioning class from config
1044    if (this.banner && this.config.position?.banner) {
1045      this.banner.classList.add(this.config.position.banner);
1046    }
1047
1048    // Trigger optional onBannerOpen callback
1049    if (this.banner && typeof this.config.onBannerOpen === 'function') {
1050      this.config.onBannerOpen();
1051    }
1052  }
1053
1054  removeBanner() {
1055    if (this.banner && this.banner.parentNode) {
1056      this.banner.parentNode.removeChild(this.banner);
1057      this.banner = null;
1058
1059      // Trigger optional onBannerClose callback
1060      if (typeof this.config.onBannerClose === 'function') {
1061        this.config.onBannerClose();
1062      }
1063    }
1064  }
1065
1066  shouldShowBanner() {
1067    if (this.config.showBanner === false) {
1068      return false;
1069    }
1070    return (
1071      localStorage.getItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`) === null
1072    );
1073  }
1074
1075  // ----------------------------------------------------------------
1076  // Modal
1077  // ----------------------------------------------------------------
1078  getModalContent() {
1079    const preferencesTitle =
1080      this.config.text?.preferences?.title || 'Customize your cookie preferences';
1081    
1082    const preferencesDescription =
1083      this.config.text?.preferences?.description ||
1084      "<p>We respect your right to privacy. You can choose not to allow some types of cookies. Your cookie preferences will apply across our website.</p>";
1085    
1086    // Preferences button
1087    const preferencesButtonLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;
1088
1089    const closeModalButton = `<button class="modal-close"${preferencesButtonLabel ? ` aria-label="${preferencesButtonLabel}"` : ''}>
1090      <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
1091          <path d="M19.4081 3.41559C20.189 2.6347 20.189 1.36655 19.4081 0.585663C18.6272 -0.195221 17.3591 -0.195221 16.5782 0.585663L10 7.17008L3.41559 0.59191C2.6347 -0.188974 1.36655 -0.188974 0.585663 0.59191C-0.195221 1.37279 -0.195221 2.64095 0.585663 3.42183L7.17008 10L0.59191 16.5844C-0.188974 17.3653 -0.188974 18.6335 0.59191 19.4143C1.37279 20.1952 2.64095 20.1952 3.42183 19.4143L10 12.8299L16.5844 19.4081C17.3653 20.189 18.6335 20.189 19.4143 19.4081C20.1952 18.6272 20.1952 17.3591 19.4143 16.5782L12.8299 10L19.4081 3.41559Z"/>
1092      </svg>
1093    </button>`;
1094    
1095
1096    const cookieTypes = this.config.cookieTypes || [];
1097    const acceptedCookieMap = this.getAcceptedCookies();
1098
1099    // Accept button
1100    const acceptAllButtonText = this.config.text?.banner?.acceptAllButtonText || 'Accept all';
1101    const acceptAllButtonLabel = this.config.text?.banner?.acceptAllButtonAccessibleLabel;
1102    const acceptAllButton = `<button class="preferences-accept-all st-button st-button--primary"${
1103      acceptAllButtonLabel && acceptAllButtonLabel !== acceptAllButtonText 
1104        ? ` aria-label="${acceptAllButtonLabel}"` 
1105        : ''
1106    }>${acceptAllButtonText}</button>`;
1107    
1108    // Reject button
1109    const rejectNonEssentialButtonText = this.config.text?.banner?.rejectNonEssentialButtonText || 'Reject non-essential';
1110    const rejectNonEssentialButtonLabel = this.config.text?.banner?.rejectNonEssentialButtonAccessibleLabel;
1111    const rejectNonEssentialButton = `<button class="preferences-reject-all st-button st-button--primary"${
1112      rejectNonEssentialButtonLabel && rejectNonEssentialButtonLabel !== rejectNonEssentialButtonText 
1113        ? ` aria-label="${rejectNonEssentialButtonLabel}"` 
1114        : ''
1115    }>${rejectNonEssentialButtonText}</button>`;
1116    
1117    // Credit link
1118    const creditLinkText = this.config.text?.preferences?.creditLinkText || '';
1119    const creditLinkAccessibleLabel = this.config.text?.preferences?.creditLinkAccessibleLabel;
1120    const creditLink = `<a href="https://silktide.com/consent-manager" target="_blank" rel="noreferrer"${
1121      creditLinkAccessibleLabel && creditLinkAccessibleLabel !== creditLinkText
1122        ? ` aria-label="${creditLinkAccessibleLabel}"`
1123        : ''
1124    }>${creditLinkText}</a>`;
1125    
1126    
1127
1128    const modalContent = `
1129      <div class="silk-header">
1130        <h1>${preferencesTitle}</h1>                    
1131        ${closeModalButton}
1132      </div>
1133      ${preferencesDescription}
1134      <section id="cookie-preferences">
1135        ${cookieTypes
1136          .map((type) => {
1137            const accepted = acceptedCookieMap[type.id];
1138            let isChecked = false;
1139
1140            // if it's accepted then show as checked
1141            if (accepted) {
1142              isChecked = true;
1143            }
1144
1145            // if nothing has been accepted / rejected yet, then show as checked if the default value is true
1146            if (!accepted && !this.hasSetInitialCookieChoices()) {
1147              isChecked = type.defaultValue;
1148            }
1149
1150            return `
1151            <fieldset>
1152                <legend>${type.name}</legend>
1153                <div class="cookie-type-content">
1154                    <div class="cookie-type-description">${type.description}</div>
1155                    <label class="switch" for="cookies-${type.id}">
1156                        <input type="checkbox" id="cookies-${type.id}" ${
1157              type.required ? 'checked disabled' : isChecked ? 'checked' : ''
1158            } />
1159                        <span class="switch__pill" aria-hidden="true"></span>
1160                        <span class="switch__dot" aria-hidden="true"></span>
1161                        <span class="switch__off" aria-hidden="true">Off</span>
1162                        <span class="switch__on" aria-hidden="true">On</span>
1163                    </label>
1164                </div>
1165            </fieldset>
1166        `;
1167          })
1168          .join('')}
1169      </section>
1170      <div class="silk-footer">
1171        ${acceptAllButton}
1172        ${rejectNonEssentialButton}
1173        ${creditLink}
1174      </div>
1175    `;
1176
1177    return modalContent;
1178  }
1179
1180  createModal() {
1181    // Create banner element
1182    this.modal = this.createWrapperChild(this.getModalContent(), 'silktide-modal');
1183  }
1184
1185  toggleModal(show) {
1186    if (!this.modal) return;
1187
1188    this.modal.style.display = show ? 'flex' : 'none';
1189
1190    if (show) {
1191      this.showBackdrop();
1192      this.hideCookieIcon();
1193      this.removeBanner();
1194      this.preventBodyScroll();
1195
1196      // Focus the close button
1197      const modalCloseButton = this.modal.querySelector('.modal-close');
1198      modalCloseButton.focus();
1199
1200      // Trigger optional onPreferencesOpen callback
1201      if (typeof this.config.onPreferencesOpen === 'function') {
1202        this.config.onPreferencesOpen();
1203      }
1204
1205      this.updateCheckboxState(false); // read from storage when opening
1206    } else {
1207      // Set that an initial choice was made when closing the modal
1208      this.setInitialCookieChoiceMade();
1209      
1210      // Save current checkbox states to storage
1211      this.updateCheckboxState(true);
1212
1213      this.hideBackdrop();
1214      this.showCookieIcon();
1215      this.allowBodyScroll();
1216
1217      // Trigger optional onPreferencesClose callback
1218      if (typeof this.config.onPreferencesClose === 'function') {
1219        this.config.onPreferencesClose();
1220      }
1221    }
1222  }
1223
1224  // ----------------------------------------------------------------
1225  // Cookie Icon
1226  // ----------------------------------------------------------------
1227  getCookieIconContent() {
1228    return `
1229      <svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
1230          <path d="M19.1172 1.15625C19.0547 0.734374 18.7344 0.390624 18.3125 0.328124C16.5859 0.0859365 14.8281 0.398437 13.2813 1.21875L7.5 4.30469C5.96094 5.125 4.71875 6.41406 3.95313 7.98437L1.08594 13.8906C0.320314 15.4609 0.0703136 17.2422 0.375001 18.9609L1.50781 25.4297C1.8125 27.1562 2.64844 28.7344 3.90625 29.9531L8.61719 34.5156C9.875 35.7344 11.4766 36.5156 13.2031 36.7578L19.6875 37.6719C21.4141 37.9141 23.1719 37.6016 24.7188 36.7812L30.5 33.6953C32.0391 32.875 33.2813 31.5859 34.0469 30.0078L36.9141 24.1094C37.6797 22.5391 37.9297 20.7578 37.625 19.0391C37.5547 18.625 37.2109 18.3125 36.7969 18.25C32.7734 17.6094 29.5469 14.5703 28.6328 10.6406C28.4922 10.0469 28.0078 9.59375 27.4063 9.5C23.1406 8.82031 19.7734 5.4375 19.1094 1.15625H19.1172ZM15.25 10.25C15.913 10.25 16.5489 10.5134 17.0178 10.9822C17.4866 11.4511 17.75 12.087 17.75 12.75C17.75 13.413 17.4866 14.0489 17.0178 14.5178C16.5489 14.9866 15.913 15.25 15.25 15.25C14.587 15.25 13.9511 14.9866 13.4822 14.5178C13.0134 14.0489 12.75 13.413 12.75 12.75C12.75 12.087 13.0134 11.4511 13.4822 10.9822C13.9511 10.5134 14.587 10.25 15.25 10.25ZM10.25 25.25C10.25 24.587 10.5134 23.9511 10.9822 23.4822C11.4511 23.0134 12.087 22.75 12.75 22.75C13.413 22.75 14.0489 23.0134 14.5178 23.4822C14.9866 23.9511 15.25 24.587 15.25 25.25C15.25 25.913 14.9866 26.5489 14.5178 27.0178C14.0489 27.4866 13.413 27.75 12.75 27.75C12.087 27.75 11.4511 27.4866 10.9822 27.0178C10.5134 26.5489 10.25 25.913 10.25 25.25ZM27.75 20.25C28.413 20.25 29.0489 20.5134 29.5178 20.9822C29.9866 21.4511 30.25 22.087 30.25 22.75C30.25 23.413 29.9866 24.0489 29.5178 24.5178C29.0489 24.9866 28.413 25.25 27.75 25.25C27.087 25.25 26.4511 24.9866 25.9822 24.5178C25.5134 24.0489 25.25 23.413 25.25 22.75C25.25 22.087 25.5134 21.4511 25.9822 20.9822C26.4511 20.5134 27.087 20.25 27.75 20.25Z" />
1231      </svg>
1232    `;
1233  }
1234
1235  createCookieIcon() {
1236    this.cookieIcon = document.createElement('button');
1237    this.cookieIcon.id = 'silktide-cookie-icon';
1238    this.cookieIcon.title = 'Manage your cookie preferences for this site';
1239    this.cookieIcon.innerHTML = this.getCookieIconContent();
1240
1241    if (this.config.text?.banner?.preferencesButtonAccessibleLabel) {
1242      this.cookieIcon.ariaLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;
1243    }
1244
1245    // Ensure wrapper exists
1246    if (!this.wrapper || !document.body.contains(this.wrapper)) {
1247      this.createWrapper();
1248    }
1249
1250    // Append child to wrapper
1251    this.wrapper.appendChild(this.cookieIcon);
1252
1253    // Add positioning class from config
1254    if (this.cookieIcon && this.config.cookieIcon?.position) {
1255      this.cookieIcon.classList.add(this.config.cookieIcon.position);
1256    }
1257
1258    // Add color scheme class from config
1259    if (this.cookieIcon && this.config.cookieIcon?.colorScheme) {
1260      this.cookieIcon.classList.add(this.config.cookieIcon.colorScheme);
1261    }
1262  }
1263
1264  showCookieIcon() {
1265    if (this.cookieIcon) {
1266      this.cookieIcon.style.display = 'flex';
1267    }
1268  }
1269
1270  hideCookieIcon() {
1271    if (this.cookieIcon) {
1272      this.cookieIcon.style.display = 'none';
1273    }
1274  }
1275
1276  /**
1277   * This runs if the user closes the modal without making a choice for the first time
1278   * We apply the default values and the necessary values as default
1279   */
1280  handleClosedWithNoChoice() {
1281    this.config.cookieTypes.forEach((type) => {
1282      let accepted = true;
1283      // Set localStorage and run accept/reject callbacks
1284      if (type.required == true || type.defaultValue) {
1285        localStorage.setItem(
1286          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,
1287          accepted.toString(),
1288        );
1289      } else {
1290        accepted = false;
1291        localStorage.setItem(
1292          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,
1293          accepted.toString(),
1294        );
1295      }
1296
1297      if (accepted) {
1298        if (typeof type.onAccept === 'function') { type.onAccept(); }
1299      } else {
1300        if (typeof type.onReject === 'function') { type.onReject(); }
1301      }
1302      // set the flag to say that the cookie choice has been made
1303      this.setInitialCookieChoiceMade();
1304      this.updateCheckboxState();
1305    });
1306  }
1307
1308  // ----------------------------------------------------------------
1309  // Focusable Elements
1310  // ----------------------------------------------------------------
1311  getFocusableElements(element) {
1312    return element.querySelectorAll(
1313      'button, a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
1314    );
1315  }
1316
1317  // ----------------------------------------------------------------
1318  // Event Listeners
1319  // ----------------------------------------------------------------
1320  setupEventListeners() {
1321    // Check Banner exists before trying to add event listeners
1322    if (this.banner) {
1323      // Get the buttons
1324      const acceptButton = this.banner.querySelector('.accept-all');
1325      const rejectButton = this.banner.querySelector('.reject-all');
1326      const preferencesButton = this.banner.querySelector('.preferences');
1327
1328      // Add event listeners to the buttons
1329      acceptButton?.addEventListener('click', () => this.handleCookieChoice(true));
1330      rejectButton?.addEventListener('click', () => this.handleCookieChoice(false));
1331      preferencesButton?.addEventListener('click', () => {
1332        this.showBackdrop();
1333        this.toggleModal(true);
1334      });
1335
1336      // Focus Trap
1337      const focusableElements = this.getFocusableElements(this.banner);
1338      const firstFocusableEl = focusableElements[0];
1339      const lastFocusableEl = focusableElements[focusableElements.length - 1];
1340
1341      // Add keydown event listener to handle tab navigation
1342      this.banner.addEventListener('keydown', (e) => {
1343        if (e.key === 'Tab') {
1344          if (e.shiftKey) {
1345            if (document.activeElement === firstFocusableEl) {
1346              lastFocusableEl.focus();
1347              e.preventDefault();
1348            }
1349          } else {
1350            if (document.activeElement === lastFocusableEl) {
1351              firstFocusableEl.focus();
1352              e.preventDefault();
1353            }
1354          }
1355        }
1356      });
1357
1358      // Set initial focus
1359      if (this.config.mode !== 'wizard') {
1360        acceptButton?.focus();
1361      }
1362    }
1363
1364    // Check Modal exists before trying to add event listeners
1365    if (this.modal) {
1366      const closeButton = this.modal.querySelector('.modal-close');
1367      const acceptAllButton = this.modal.querySelector('.preferences-accept-all');
1368      const rejectAllButton = this.modal.querySelector('.preferences-reject-all');
1369
1370      closeButton?.addEventListener('click', () => {
1371        this.toggleModal(false);
1372
1373        const hasMadeFirstChoice = this.hasSetInitialCookieChoices();
1374
1375        if (hasMadeFirstChoice) {
1376          // run through the callbacks based on the current localStorage state
1377          this.runStoredCookiePreferenceCallbacks();
1378        } else {
1379          // handle the case where the user closes without making a choice for the first time
1380          this.handleClosedWithNoChoice();
1381        }
1382      });
1383      acceptAllButton?.addEventListener('click', () => this.handleCookieChoice(true));
1384      rejectAllButton?.addEventListener('click', () => this.handleCookieChoice(false));
1385
1386      // Banner Focus Trap
1387      const focusableElements = this.getFocusableElements(this.modal);
1388      const firstFocusableEl = focusableElements[0];
1389      const lastFocusableEl = focusableElements[focusableElements.length - 1];
1390
1391      this.modal.addEventListener('keydown', (e) => {
1392        if (e.key === 'Tab') {
1393          if (e.shiftKey) {
1394            if (document.activeElement === firstFocusableEl) {
1395              lastFocusableEl.focus();
1396              e.preventDefault();
1397            }
1398          } else {
1399            if (document.activeElement === lastFocusableEl) {
1400              firstFocusableEl.focus();
1401              e.preventDefault();
1402            }
1403          }
1404        }
1405        if (e.key === 'Escape') {
1406          this.toggleModal(false);
1407        }
1408      });
1409
1410      closeButton?.focus();
1411
1412      // Update the checkbox event listeners
1413      const preferencesSection = this.modal.querySelector('#cookie-preferences');
1414      const checkboxes = preferencesSection.querySelectorAll('input[type="checkbox"]');
1415      
1416      checkboxes.forEach(checkbox => {
1417        checkbox.addEventListener('change', (event) => {
1418          const [, cookieId] = event.target.id.split('cookies-');
1419          const isAccepted = event.target.checked;
1420          const previousValue = localStorage.getItem(
1421            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`
1422          ) === 'true';
1423          
1424          // Only proceed if the value has actually changed
1425          if (isAccepted !== previousValue) {
1426            // Find the corresponding cookie type
1427            const cookieType = this.config.cookieTypes.find(type => type.id === cookieId);
1428            
1429            if (cookieType) {
1430              // Update localStorage
1431              localStorage.setItem(
1432                `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,
1433                isAccepted.toString()
1434              );
1435              
1436              // Run the appropriate callback only if the value changed
1437              if (isAccepted && typeof cookieType.onAccept === 'function') {
1438                cookieType.onAccept();
1439              } else if (!isAccepted && typeof cookieType.onReject === 'function') {
1440                cookieType.onReject();
1441              }
1442            }
1443          }
1444        });
1445      });
1446    }
1447
1448    // Check Cookie Icon exists before trying to add event listeners
1449    if (this.cookieIcon) {
1450
1451      this.cookieIcon.addEventListener('click', () => {
1452        // If modal is not found, create it
1453        if (!this.modal) {
1454          this.createModal();
1455          this.toggleModal(true);
1456          this.hideCookieIcon();
1457        }
1458        // If modal is hidden, show it
1459        else if (this.modal.style.display === 'none' || this.modal.style.display === '') {
1460          this.toggleModal(true);
1461          this.hideCookieIcon();
1462        }
1463        // If modal is visible, hide it
1464        else {
1465          this.toggleModal(false);
1466        }
1467      });
1468    }
1469  }
1470
1471  getBannerSuffix() {
1472    if (this.config.bannerSuffix) {
1473      return '_' + this.config.bannerSuffix;
1474    }
1475    return '';
1476  }
1477
1478  preventBodyScroll() {
1479    document.body.style.overflow = 'hidden';
1480    // Prevent iOS Safari scrolling
1481    document.body.style.position = 'fixed';
1482    document.body.style.width = '100%';
1483  }
1484
1485  allowBodyScroll() {
1486    document.body.style.overflow = '';
1487    document.body.style.position = '';
1488    document.body.style.width = '';
1489  }
1490}
1491
1492(function () {
1493  window.silktideCookieBannerManager = {};
1494
1495  let config = {};
1496  let cookieBanner;
1497
1498  function updateCookieBannerConfig(userConfig = {}) {
1499    config = {...config, ...userConfig};
1500
1501    // If cookie banner exists, destroy and recreate it with new config
1502    if (cookieBanner) {
1503      cookieBanner.destroyCookieBanner(); // We'll need to add this method
1504      cookieBanner = null;
1505    }
1506
1507    // Only initialize if document.body exists
1508    if (document.body) {
1509      initCookieBanner();
1510    } else {
1511      // Wait for DOM to be ready
1512      document.addEventListener('DOMContentLoaded', initCookieBanner, {once: true});
1513    }
1514  }
1515
1516  function initCookieBanner() {
1517    if (!cookieBanner) {
1518      cookieBanner = new SilktideCookieBanner(config); // Pass config to the CookieBanner instance
1519    }
1520  }
1521
1522  function injectScript(url, loadOption) {
1523    // Check if script with this URL already exists
1524    const existingScript = document.querySelector(`script[src="${url}"]`);
1525    if (existingScript) {
1526      return; // Script already exists, don't add it again
1527    }
1528
1529    const script = document.createElement('script');
1530    script.src = url;
1531
1532    // Apply the async or defer attribute based on the loadOption parameter
1533    if (loadOption === 'async') {
1534      script.async = true;
1535    } else if (loadOption === 'defer') {
1536      script.defer = true;
1537    }
1538
1539    document.head.appendChild(script);
1540  }
1541
1542  window.silktideCookieBannerManager.initCookieBanner = initCookieBanner;
1543  window.silktideCookieBannerManager.updateCookieBannerConfig = updateCookieBannerConfig;
1544  window.silktideCookieBannerManager.injectScript = injectScript;
1545
1546  if (document.readyState === 'loading') {
1547    document.addEventListener('DOMContentLoaded', initCookieBanner, {once: true});
1548  } else {
1549    initCookieBanner();
1550  }
1551})();
1552</script>
vendor: 1 bytes, line 1552
1552
1553<script>
1554silktideCookieBannerManager.updateCookieBannerConfig({
1555  showBanner: false, // <--- THIS HIDES THE POPUP ON LOAD
1556  background: {
1557    showBackground: true
1558  },
1559  cookieIcon: {
1560    position: "bottomLeft"
1561  },
1562  cookieTypes: [
1563    {
1564      id: "necessary",
1565      name: "Necessary",
1566      description: "<p>These cookies are necessary for the website to function properly and cannot be switched off. They help with things like logging in and setting your privacy preferences.</p>",
1567      required: true,
1568      onAccept: function() {
1569        //console.log('Add logic for the required Necessary here');
1570        //Remaining cookies
1571      }
1572    },
1573    {
1574      id: "analytics",
1575      name: "Analytics",
1576      description: "<p>These cookies help us improve the site by tracking which pages are most popular and how visitors move around the site.</p>",
1577      defaultValue: true,
1578      onAccept: function() {
1579        gtag('consent', 'update', {
1580          analytics_storage: 'granted',
1581        });
1582        // Dynamic Refresh: No IDs required
1583        if (window.google_tag_manager) {
1584            Object.keys(google_tag_manager).forEach(id => {
1585                if (id.startsWith('G-') || id.startsWith('GT-')) {
1586                    gtag('config', id, { 'update_config': true });
1587                }
1588            });
1589        }
1590        dataLayer.push({
1591          'event': 'consent_accepted_analytics',
1592        });
1593      },
1594      onReject: function() {
1595        gtag('consent', 'update', {
1596          analytics_storage: 'denied',
1597        });
1598      }
1599    },
1600    {
1601      id: "advertising",
1602      name: "Advertising",
1603      description: "<p>These cookies provide extra features and personalization to improve your experience. They may be set by us or by partners whose services we use.</p>",
1604      defaultValue: true,
1605      onAccept: function() {
1606        gtag('consent', 'update', {
1607          ad_storage: 'granted',
1608          ad_user_data: 'granted',
1609          ad_personalization: 'granted',
1610        });
1611        // Dynamic Refresh: No IDs required
1612        if (window.google_tag_manager) {
1613            Object.keys(google_tag_manager).forEach(id => {
1614                if (id.startsWith('G-') || id.startsWith('GT-')) {
1615                    gtag('config', id, { 'update_config': true });
1616                }
1617            });
1618        }
1619        dataLayer.push({
1620          'event': 'consent_accepted_advertising',
1621        });
1622      },
1623      onReject: function() {
1624        gtag('consent', 'update', {
1625          ad_storage: 'denied',
1626          ad_user_data: 'denied',
1627          ad_personalization: 'denied',
1628        });
1629      }
1630    }
1631  ],
1632  text: {
1633    banner: {
1634      description: "<p>We use cookies on our site to enhance your user experience, provide personalized content, and analyze our traffic. <a href=\"/privacy-policy/\" target=\"_blank\">Cookie Policy.</a></p>",
1635      acceptAllButtonText: "Accept all",
1636      acceptAllButtonAccessibleLabel: "Accept all cookies",
1637      rejectNonEssentialButtonText: "Reject non-essential",
1638      rejectNonEssentialButtonAccessibleLabel: "Reject non-essential",
1639      preferencesButtonText: "Preferences",
1640      preferencesButtonAccessibleLabel: "Toggle preferences"
1641    },
1642    preferences: {
1643      title: "Customize your cookie preferences",
1644      description: "<p>We respect your right to privacy. You can choose not to allow some types of cookies. Your cookie preferences will apply across our website.</p>",
1645      creditLinkText: "",
1646      creditLinkAccessibleLabel: ""
1647    }
1648  },
1649  position: {
1650    banner: "bottomLeft"
1651  }
1652});
1653</script>
1653
1654
1655<!-- Clarity (restricted)-->
1656<script>
1657window._MTS_ClarityProjectId = "wc67nnmzc4";
1658</script>
1658
1659 
1660<script>
1661
1662  var ClarityAllowedUsers = [2];
1663  var ClarityExcludedPaths = [
1664    /^\/news\/\d+\//,
1665    /^\/contact-us/
1666  ];
1667 
1668  var ClarityProjectId = window._MTS_ClarityProjectId || "";
1669 
1670  var ClarityIsExcluded = ClarityExcludedPaths.some(function (pattern) {
1671    return pattern.test(window.location.pathname);
1672  });
1673 
1674  if (
1675    ClarityProjectId &&
1676    typeof window._MTS_userId !== "undefined" &&
1677    window._MTS_userId > 0 &&
1678    (window._isAdmin === true || ClarityAllowedUsers.includes(window._MTS_userId)) &&
1679    !ClarityIsExcluded
1680  ) {
1681    var rawUrl = window._MTS_SITEURL || "UnknownSite";
1682    var siteUrl = rawUrl
1683      .replace(/^(https?:\/\/)?(www\.)?/, "")
1684      .split(".")[0]
1685      .substring(0, 16);
1686 
1687    var clarityUserId = window._MTS_userId.toString();
1688    var friendlyName = siteUrl + " - " + clarityUserId;
1689 
1690    (function (c, l, a, r, i, t, y) {
1691      c[a] = c[a] || function () {
1692        (c[a].q = c[a].q || []).push(arguments);
1693      };
1694      t = l.createElement(r);
1695      t.async = 1;
1696      t.src = "https://www.clarity.ms/tag/" + i;
1697      y = l.getElementsByTagName(r)[0];
1698      y.parentNode.insertBefore(t, y);
1699    })(window, document, "clarity", "script", ClarityProjectId);
1700 
1701    window.clarity("identify", clarityUserId, undefined, undefined, friendlyName);
1702    window.clarity("set", "site", siteUrl);
1703    window.clarity("set", "userId", clarityUserId);
1704    window.clarity("set", "isAdmin", window._isAdmin === true ? "true" : "false");
1705    window.clarity("set", "_MTS_userId", _MTS_userId);
1706  }
1707</script>
1707
1708
1709
1710
1711
1712<!-- Favicon -->
1713<link rel="icon" type="image/x-icon" href="https://d1gpmunylt23vy.cloudfront.net/360_SixRivers_Live/0/0/0/0/133/715/133715_original" />
1714
1715<!-- Apple Touch Icon -->
1716<link rel="apple-touch-icon" sizes="180x180" href="https://d1gpmunylt23vy.cloudfront.net/360_SixRivers_Live/0/0/0/0/133/715/133715_original" />
1717
1718
1719<!-- Android Chrome Icons -->
1720<link rel="icon" type="image/png" sizes="192x192" href="https://d1gpmunylt23vy.cloudfront.net/360_SixRivers_Live/0/0/0/0/133/715/133715_original" />
1721<link rel="icon" type="image/png" sizes="512x521" href="https://d1gpmunylt23vy.cloudfront.net/360_SixRivers_Live/0/0/0/0/133/715/133715_original" />
1722<style>
1723
1724.mailer{
1725display: none;
1726}
1727
1728html body {
1729    font-family: georgia, serif;
1730}
1731
1732#item_136 .navType:after {
1733    content: unset;
1734}
1735
1736.menuDropBgShow {
1737   box-shadow: 0px 0px 1px var(--six-main-black);
1738   margin-top: -1px;
1739   min-height: unset !important;
1740}
1741
1742.navigation_menu_widget .section_navigation_widget {
1743   background: var(--six-main-black);
1744}
1745
1746.navigation_menu_widget .section_navigation_widget a[title="Donate"] {
1747   background: var(--six-main-red) !important;
1748}
1749
1750.navigation_menu_widget .section_navigation_widget .sectionDropItem {
1751   color: var(--six-black);
1752   background: var(--six-white);
1753   font-size: 20px;
1754}
1755
1756.navigation_menu_widget .section_navigation_widget .sectionItem,
1757.navigation_menu_widget .section_navigation_widget .sectionLabel,
1758.navigation_menu_widget .section_navigation_widget .dropLink {
1759   background: var(--six-main-black) !important; 
1760   color: var(--six-white) !important;
1761   font-size: 20px;
1762   font-weight: 600;
1763}
1764
1765.header .headerMainItems {
1766   padding: 10px !important;
1767}
1768
1769#nextStoryTitle,
1770#previousStoryTitle {
1771   display: none !important;
1772}
1773
1774.adPlaceholder,
1775.adBannerPlaceholder {
1776    background: var(--six-black);
1777}
1778
1779.adPlaceholder {
1780    margin: 0px auto 20px auto;
1781    width: 300px;
1782    height: 250px;
1783}
1784
1785.adBannerPlaceholder {
1786    width: 728px;
1787    height: 90px;
1788    margin: 40px auto;
1789    max-width: 100%
1790}
1791
1792.navigation_menu_widget a.item, 
1793.navigation_menu_widget div.item,
1794body p {
1795    font-family: arial, sans-serif !important;
1796}
1797
1798body,
1799.masterMcWrap {
1800    background: var(--six-white);
1801}
1802
1803body .dropNavBtn i.fa-bars {
1804    text-align: center;
1805}
1806
1807body .mts_cc_heading {
1808    font-family: georgia, serif;
1809    font-size: 30px;
1810    font-weight: bold;
1811    color: var(--six-black);
1812    padding: 0px 0px 0px 0px;
1813    line-height: 1.125;    
1814}
1815
1816body .news_panel_widget #news .item .photoText .photoAuthor, 
1817body .news_panel_widget #news .item .photoTextw .photoAuthor, 
1818body .news_panel_widget #news .item .photoText .photoDate, 
1819body .news_panel_widget #news .item .photoTextw .photoDate {
1820    color: var(--six-main-black);
1821    font-family: arial;
1822}
1823
1824.trending_media_widget .trendingListCont {
1825   margin-top: 10px;
1826}
1827
1828a.trendingLink {
1829   font-size: 24px;
1830   display: flex;
1831   color: var(--six-black) !important; 
1832}
1833
1834.trendingCount {
1835   font-weight: bold;
1836   line-height: .875;
1837}
1838
1839.header .section_navigation_widget.showSecNav {
1840   position: absolute !important;
1841   left: 0 !important;
1842}
1843
1844.header .searchCtr {
1845   transform: translateY(0px);
1846   -webkit-transform: translateY(0px);
1847   -moz-transform: translateY(0px);
1848}
1849
1850.header .searchCtr.showSearch {
1851   transform: translateY(calc(100%));
1852   -webkit-transform: translateY(calc(100%));
1853   -moz-transform: translateY(calc(100%));
1854}
1855
1856body .section_navigation_widget .mts_cc_heading,
1857body .desktopNavSection .sectionLabel {
1858   display: none !important;
1859}
1860
1861body .navigation_menu_widget a.mdItem .dropDownElement .item, 
1862body .navigation_menu_widget .mdItem .dropDownElement .item {
1863   color: #000000;
1864}
1865
1866.sectionDropItem[title="Opinions Main"],
1867.sectionDropItem[title="News Main"],
1868.sectionDropItem[title="Living Main"],
1869.sectionDropItem[title="Sports Main"],
1870.sectionDropItem[title="Tri-Cities Scene Main"] {
1871   font-weight: bold;
1872}
1873
1874.backToTop {
1875   background: #eeeeee;
1876   border: solid 1px #000000;
1877   border-radius: 5px;
1878   position: sticky;
1879   bottom: 20px;
1880   left: calc(100% - 20px);
1881   z-index: 151;
1882   aspect-ratio: 1/1;
1883   display: flex;
1884   flex-direction: column;
1885   color: var(--six-main-black);
1886   align-items: center;
1887   justify-content: center;
1888   text-transform: uppercase;
1889   gap: 5px;
1890   padding: 10px;
1891   width: 48px;
1892   height: 48px;
1893   text-align: center;
1894   cursor: pointer;
1895   transition: background 250ms;
1896   margin-top: 20px;
1897}
1898
1899.backToTop:hover {
1900   background: #dddddd;
1901}
1902
1903.backToTop i {
1904   font-size: 20px;
1905}
1906
1907.backToTop span {
1908   font-family: arial, sans-serif;
1909   font-size: 14px;
1910   font-weight: 600;
1911   display: none;
1912}
1913
1914.srAd {
1915   margin: 0px auto 20px auto;
1916}
1917
1918@media (min-width: 768px) {
1919   .backToTop {
1920      width: 96px;
1921      height: 96px;
1922   }
1923
1924   .backToTop span {
1925      display: block;
1926   }
1927}
1928
1929@media (min-width: 1024px) {
1930   .header #navbar {
1931      align-self: center;
1932   }
1933
1934   .header .headerMainItems {
1935      padding: 5px !important;
1936   }
1937
1938   .mainNav,
1939   .navigation_menu_widget {
1940      height: calc(100%);
1941   }
1942
1943   .header .searchCtr.showSearch {
1944      transform: translateY(calc(100% + 14px)) !important;
1945      -webkit-transform: translateY(calc(100% + 14px)) !important;
1946      -moz-transform: translateY(calc(100% + 14px)) !important;
1947   }
1948}
1949</style>
1950
1951<script>
1952$(document).one('widgetsloaded', function() {
1953    const url = window.location.href;
1954    const targetPaths = ['/admin', '/layout-admin', '/news/editor', '/archive/search'];
1955
1956    if (targetPaths.some(path => url.includes(path))) {
1957        document.body.style.fontFamily = "roboto, sans-serif";
1958    }
1959
1960    let searchBtn = $(".searchBtn");
1961    searchBtn.on("click", function() {
1962
1963    });
1964
1965    let headerWidth = $("header").width();
1966    let navWidth = $(".navigationContainer").width();
1967    let navPos = $(".navigationContainer").scrollLeft();
1968    let leftVal = headerWidth - (navPos + navWidth);
1969
1970    // Wait until the element exists in the DOM
1971    function watchSectionNav() {
1972        const target = document.querySelector(".section_navigation_widget");
1973        if (!target) {
1974            requestAnimationFrame(watchSectionNav);
1975            return;
1976        }
1977
1978        // Create a MutationObserver
1979        const observer = new MutationObserver(mutations => {
1980            mutations.forEach(mutation => {
1981                if (mutation.attributeName === "class") {
1982                    if (target.classList.contains("showSecNav")) {
1983                        target.style.left = `${-leftVal}px`;
1984                    } else {
1985                        target.removeAttribute("style") // runs on removal too
1986                    }
1987                }
1988            });
1989        });
1990
1991        // Start observing class attribute changes
1992        observer.observe(target, { attributes: true, attributeFilter: ["class"] });
1993    }
1994
1995    watchSectionNav();
1996});
1997</script>
1997
1998
1999<script>
2000$(document).one('widgetsloaded', function() {
2001   //Set last visited page for URL redirect based on login
2002   if (!window.location.pathname.includes('/user/login'))
2003   {
2004      let urlQuery = `?target=${window.location.pathname + window.location.search + window.location.hash}`;
2005      localStorage.setItem('lastVisitedURL', urlQuery);
2006   }
2007
2008   let lastVisitedUrl = localStorage.getItem('lastVisitedURL');
2009   console.log(lastVisitedUrl);
2010   $("a[href='/user/login']").attr("href", `/user/login/${lastVisitedUrl}`);
2011
2012(function() {
2013  const targetSrc = "https://media-sixrivers.mynews360.com/noimage/block/213/";
2014
2015  function checkImages() {
2016    document.querySelectorAll('.blockImgCtr img').forEach(img => {
2017      if (img.src === targetSrc) {
2018        const parent = img.closest('.blockImgCtr');
2019        if (parent) parent.style.display = 'none';
2020      }
2021    });
2022  }
2023
2024  // Run immediately in case elements already exist
2025  checkImages();
2026
2027  // Watch for new elements being added to the DOM
2028  const observer = new MutationObserver(() => checkImages());
2029  observer.observe(document.body, { childList: true, subtree: true });
2030})();
2031});
2032</script>
2032
2033
2034<!-- GOOGLE ADS TAG (gtag.js) -->
vendor: 65 bytes, lines 2034-2035
2034 
2035<script async src="https://www.googletagmanager.com/gtag/js?id=
2035G-K9ZBRND062
vendor: 13 bytes, lines 2035-2036
2035"></script>
2036 
2036<script> 
vendor: 127 bytes, line 2036
2036window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '
2036G-K9ZBRND062
vendor: 4 bytes, line 2036
2036'); 
2036</script>
2036
2037
2038<!--//DIDNA AD CONFIGURATION-->
2039<script>
2040const url = window.location.href;
2041const targetPaths = ['/admin', '/layout-admin', '/news/editor', '/archive/search', '/manage', '/mtsAdmin', '/upload-ad', '/photos', '/mtsadmin'];
2042
2043var DIDNA_CONFIG = {
2044        pageTargeting: {
2045            pos: ['rectangle-one', 'cube-one', 'cube-two', 'sidebar-top']
2046        }
2047};
2048</script>
vendor: 1 bytes, line 2048
2048
2049<script async='async' type='text/javascript' src='https://storage.googleapis.com/didna_hb/six_rivers_media/johnsoncitypresscom/didna_config.js'></script>
2049
2050
2051<!--BROADSTREET AD-->
2052<style>
2053.broadstreet-dynamic-scrolling + broadstreet-zone-container {
2054   height: 0;
2055}
2056</style>
2057<script src="https://cdn.broadstreetads.com/init-2.min.js"></script>
vendor: 1 bytes, line 2057
2057
2058<script>broadstreet.watch({ networkId: 9387 })</script>
2058
2059
2060<script>
2061$(document).one("widgetsloaded", function() {
2062    if (!targetPaths.some(path => url.includes(path))) {
2063        let body = $("body");
2064        let mainContent = $(".masterMcWrap");
2065        let broadstreet = `<broadstreet-zone zone-id="170347" uri-keywords="true" soft-keywords="true"></broadstreet-zone>`;
2066
2067        $(broadstreet).prependTo(body);
2068
2069        let backToTop = `<div class="backToTop"><i class="fas fa-chevron-up"></i><span>Back to top</span></div>`;
2070        $(backToTop).appendTo(mainContent);
2071    }
2072
2073    $(".backToTop").on("click", function() {
2074        window.scrollTo({
2075             top : 0,
2076             behavior : "smooth"
2077        });
2078    });    
2079});
2080</script>
2080
2081
2082<script>
2083//User login / logout
2084$(document).one("widgetsloaded", function( ) {
2085   let user = _MTS_userId;
2086   let login = (user !== null  &&  user > -1 && user !== undefined ? `<a href="/signout.aspx" class="sectionItem">Logout</a>` : `<a href="/live-content/subscribe" class="sectionItem">Subscribe</a><a href="/user/login" class="sectionItem">Login</a>`);
2087   let dNav = $(".desktopNavSection").first();
2088   let mNav = $(".mobileNavSection").first();
2089   $(login).prependTo(dNav);
2090   $(login).prependTo(mNav);
2091});
2092</script>
2092
2093
2094<script>
2095$(document).one("widgetsloaded", function() {
2096function updateMenuHeight() {
2097    const menu = document.querySelector('.menuDropBgShow');
2098    const sportsList = document.querySelector('.sportsList');
2099    if (!menu || !sportsList) return;
2100
2101    const visibleSubLists = Array.from(sportsList.querySelectorAll('.subList'))
2102      .filter(el => el.offsetParent !== null); // visible only
2103
2104    // Set height based on number of visible subList items
2105    menu.style.height = `${visibleSubLists.length * 50}px`;
2106  }
2107
2108  // Observe DOM changes (for menuDropBgShow or subList updates)
2109  const observer = new MutationObserver(() => {
2110    updateMenuHeight();
2111  });
2112
2113  observer.observe(document.body, {
2114    childList: true,
2115    subtree: true,
2116    attributes: true,
2117    attributeFilter: ['style', 'class']
2118  });
2119
2120  // Run initially if elements are already present
2121  let match = window.matchMedia("(min-width: 1024px)").matches;
2122  if(match) {
2123      updateMenuHeight();
2124  }
2125
2126//ADJUST NAVIGATION HOVER TITLE TO REFLECT TARGET ATTRIBUTE
2127const cleanNonBlankNavTitles = () => {
2128  document.querySelectorAll('a.desktopNavItem:not([target="_blank"])').forEach(anchor => {
2129    if (anchor.title && /in new tab$/i.test(anchor.title)) {
2130      anchor.title = anchor.title.replace(/\s*in new tab$/i, '');
2131    }
2132  });
2133};
2134
2135// Run immediately
2136cleanNonBlankNavTitles();
2137
2138// Watch for dynamically added anchors
2139const titleObserver = new MutationObserver(() => cleanNonBlankNavTitles());
2140titleObserver.observe(document.body, { childList: true, subtree: true });
2141
2142   document.querySelectorAll('.sectionDropItem').forEach(el => {
2143     const href = el.getAttribute('href');
2144     if (href && (href.startsWith('http://') || href.startsWith('https://'))) {
2145       el.setAttribute('target', '_blank');
2146     }
2147   });
2148});
2149</script>
2149
2150
2151<script>
2152//SET PROPER URL TO "NOT A SUBSCRIBER" LINK ON LOGIN PAGE
2153$(document).one("widgetsloaded", function() {
2154if (window.location.href.includes('/user/login')) {
2155    const subObserver = new MutationObserver(() => {
2156        const subElement = document.querySelector('[title="Not a Subscriber"]');
2157        if (subElement) {
2158            subElement .setAttribute('href', '/live-content/subscribe');
2159            subObserver.disconnect(); // stop watching once done
2160        }
2161    });
2162
2163    subObserver.observe(document.body, {
2164        childList: true,
2165        subtree: true
2166    });
2167}
2168});
2169</script>
2169
2170
2171<script>
2172$(document).one("widgetsloaded", function() {
2173	let userProfileUpdate = window.location.href.includes("/user/edit");
2174	if (userProfileUpdate) {
2175	    let link = "https://sixrivers.newzware.com/ss70v2/sixrivers/common/template.jsp?autoLogout=N&nwmodule=main&nwpage=main&skin=jcp";
2176	    let modBtn = $("#newPasswordField a");
2177	    modBtn.attr("href", link).attr("target", "_blank").addClass("mts_cc_button button").css({"padding": "10px 20px"});
2178
2179	    let coverageContainer = $("#coverageContainer");
2180	    let parentRows = [
2181	    	"#changeEmail", 
2182	    	"#changeName", 
2183	    	"#changeTwoFactor", 
2184	    	"#changeGender",
2185	    	"#changeDOB",
2186	    	"#changeZip"
2187	    ];
2188
2189	    for(i = 0; i < parentRows.length; i++) {
2190		    $(`${parentRows[i]}`).closest(".setRow").hide();
2191		}
2192
2193	    coverageContainer.hide();
2194	}
2195});
2196</script>
2196
2197
2198
2199   
2200
2201
2202   
2203   <link rel="shortcut icon" href="https://media-sixrivers.mynews360.com/images/custom/213/favicon.ico" />
2204   
2205      <link rel="stylesheet" type="text/css" href="https://media-sixrivers.mynews360.com/css/?custom=true&pid=213" />
2206   
2207   <link rel="stylesheet" type="text/css" href="https://media-sixrivers.mynews360.com/css/oneColumn.css?v=1.14.5.35260" />
2208   <link rel="Stylesheet" type="text/css" href="https://media-sixrivers.mynews360.com/css/?v=1.14.5.35260&pid=213" />
2209
2210   
2210<script type="text/javascript">
2211      _MTS_cssList.push("css/jQueryExtensions/jquery-ui.css", "css/popUpDialog.css");
2212      _MTS_jsList.push("js/signin.js", "js/popUpDialog.js", "js/oneCol.js");
2213      var _timeout = 1140000;
2214      var _sessionTimeout = 1200000;
2215      var __redirectTo = "/news-category/news/local-news/1/6/";
2216      var _COMMON_isTablet = false;
2217      var _encodedPathAndQuery = "%2fnews-category%2fnews%2flocal-news%2f1%2f6%2f",
2218         _MTS_SEOALT = "Local News news on Johnson City Press.",
2219      _homePageUrl = "/";
2220   </script>
2220
2221   
2222   
2222<script type="text/javascript">
2223      
2224         _MTS_SEOALT = "Local News news on Johnson City Press.";
2225
2226      var _MTS_PHOTO_PER_AD = "";
2227      var _MTS_ITEM_ADS =
2228         [
2229         
2230      ];
2231   </script>
2231
2232
2233   
2234
2235<title>
2236	Johnson City Press | News | Local News News
2237</title><meta name="description" content="Get the latest Local News news on Johnson City Press" /></head>
2238
2239   
2240<body >
2241
2242   <div class="sitewideUserAlert">
2243      <p id="userAlertMessage"></p>
2244      <div class="sitewideUserAlertButtons">
2245         <button id="hideSiteWide">Okay</button>
2246         <button id="closeSiteWide">Close and Never Show Again</button>
2247      </div>
2248   </div>
2249   
2250   
2251
2252   
2253
2254   <div class="plBackground"></div>
2255   <div id="fb-root"></div>
2256
2257
2258
2259   <noscript>You must have javascript enabled to view this site.</noscript>
2260
2261   <div class="alwaysMobileBg"></div>
2262   
2263   <div class="busySpinnerBg">
2264      <div class="closeSpinner"><i class="fas fa-times"></i></div>
2265      <img class="busySpinner" src="https://media-sixrivers.mynews360.com/images/busySpinner.gif" alt="Loading" />
2266   </div>
2267
2268   
2269	<div class="navigation_admin_menu_widget">
2270		<input type="hidden" name="id" value="" />
2271		<input type="hidden" name="abovethefold" value="true" />
2272	</div>
2273   
2274         <div class="custom_header_widget">
2275		      <input type="hidden" name="abovethefold" value="true" />
2276         </div>
2277   
2278
2279<script type="text/javascript">
2280   _MTS_jsList.push("js/content/mobileSelectors.js");
2281</script>
2281
2282   <div class="emailRejected" style="display: none;">
2283      <div class="rejectTop">
2284         <div class="rejectedTitle">Email Rejected!</div>
2285         <div class="rejectHide">x</div>
2286      </div>
2287      <div class="rejectedInfo">
2288         We attempted to send a notification to your email address but we were unable to verify that you provided a valid email address.
2289         Please visit <a title="Link to my profile" class="emailLink" href="/user/edit/">my profile</a> to update your email address if you wish to receive notifications.
2290         Otherwise, <a title="Disable notifications" class="emailLink" href="javascript:fireEmailRejected()"> disable notifications</a> and hide this message.
2291      </div>
2292   </div>
2293
2294   
2295
2296   <div class="masterMcWrap"  role="main">
2297      <div id="logged_nav">
2298	      
2299
2300      </div>
2301      <div id="timeout">
2302         <div class="tText n">
2303            Your session was unable to be renewed and will be expiring in <span id="tTimer">0</span> seconds. 
2304            Click <span id="tRenew">here</span> to attempt to renew your session.
2305
2306            <div id="tStatus"></div>
2307         </div>
2308      </div>
2309
2310      
2311
2312      <div id='mts_r_0' class='widget_region' style='text-align:center'><input type='hidden' name='reg_width' value='100.00' /><input type='hidden' name='reg_margin_left' value='0.00' /><input type='hidden' name='reg_margin_right' value='0.00' /><input type='hidden' name='reg_width_med' value='100.00' /><input type='hidden' name='reg_margin_left_med' value='0.00' /><input type='hidden' name='reg_margin_right_med' value='0.00' /><input type='hidden' name='reg_width_tablet' value='100.00' /><input type='hidden' name='reg_margin_left_tablet' value='0.00' /><input type='hidden' name='reg_margin_right_tablet' value='0.00' /><input type='hidden' name='reg_pixel' value='False' /><input type='hidden' name='reg_innerSec' value='False' /><div id='mts_c_0' class='widget_column' style='display:inline-block;vertical-align:top;text-align:initial;'><input type='hidden' name='col_width' value='100.00' /><input type='hidden' name='col_margin_left' value='0.00' /><input type='hidden' name='col_margin_right' value='0.00' /><input type='hidden' name='col_width_med' value='100.00' /><input type='hidden' name='col_margin_left_med' value='0.00' /><input type='hidden' name='col_margin_right_med' value='0.00' /><input type='hidden' name='col_width_tablet' value='100.00' /><input type='hidden' name='col_margin_left_tablet' value='0.00' /><input type='hidden' name='col_margin_right_tablet' value='0.00' /><input type='hidden' name='col_pixel' value='False' /><div class='custom_break_widget'><style>
2313.news_panel_widget .item {
2314   padding: 20px 0px;
2315}
2316
2317@media (min-width: 1366px) {
2318    .masterMcWrap .innerSec {
2319       width: 1300px;
2320   }
2321}
2322</style></div><div class='custom_break_widget'><style>
2323html, body {visibility: hidden; opacity: 0;}
2324</style>
2325
2326<script>
2327$(document).one("widgetsloaded", function() {
2328	setTimeout(function() {
2329		$("html, body").css({"visibility": "visible", "opacity": "1"})
2330	}, 2)
2331})
2332</script>
2332</div><div class='custom_break_widget'><div id="ad-139731" style="margin: 20px auto 40px auto;"></div>
2333<script>
2334var didna = window.didna || {cmd: []};
2335didna.cmd.push(function(){
2336    didna.createAdUnits({
2337        id: "ad-139731",
2338        "adUnitPath": "/22870547579/johnsoncitypress.com",
2339        "size": [728, 90],
2340        "sizeMap": [
2341            [[1200, 0], [[1170, 90], [970, 250], [970, 90], [728, 90]]],
2342            [[992, 0],  [[970, 90], [728, 90]]],
2343            [[768, 0],  [[728, 90], [320, 50]]],
2344            [[320, 0],  [[320, 50]]]
2345        ],
2346        targeting:{'pos': "rectangle-one"}
2347    });
2348});
2349</script>
2349</div></div></div><div class='innerSec group'><div id='mts_r_1' class='widget_region' style='text-align:center'><input type='hidden' name='reg_width' value='100.00' /><input type='hidden' name='reg_margin_left' value='0.00' /><input type='hidden' name='reg_margin_right' value='0.00' /><input type='hidden' name='reg_width_med' value='100.00' /><input type='hidden' name='reg_margin_left_med' value='0.00' /><input type='hidden' name='reg_margin_right_med' value='0.00' /><input type='hidden' name='reg_width_tablet' value='100.00' /><input type='hidden' name='reg_margin_left_tablet' value='0.00' /><input type='hidden' name='reg_margin_right_tablet' value='0.00' /><input type='hidden' name='reg_pixel' value='False' /><input type='hidden' name='reg_innerSec' value='True' /><div id='mts_c_1' class='widget_column' style='display:inline-block;vertical-align:top;text-align:initial;'><input type='hidden' name='col_width' value='-320.00' /><input type='hidden' name='col_margin_left' value='0.00' /><input type='hidden' name='col_margin_right' value='0.00' /><input type='hidden' name='col_width_med' value='-320.00' /><input type='hidden' name='col_margin_left_med' value='0.00' /><input type='hidden' name='col_margin_right_med' value='0.00' /><input type='hidden' name='col_width_tablet' value='-320.00' /><input type='hidden' name='col_margin_left_tablet' value='0.00' /><input type='hidden' name='col_margin_right_tablet' value='0.00' /><input type='hidden' name='col_pixel' value='False' /><div class='news_panel_widget'><input type='hidden' name='type' value='7' /><input type='hidden' name='category' value='News' /><input type='hidden' name='subcategory' value='Local News' /><input type='hidden' name='itemCount' value='5' /><input type='hidden' name='showMore' value='Hidden' /></div><div class='custom_break_widget'><div id="ad-139732" style="margin: 20px auto 40px auto;"></div>
2350<script>
2351var didna = window.didna || {cmd: []};
2352        didna.cmd.push(function(){
2353        didna.createAdUnits({
2354            id: "ad-139732",
2355            "adUnitPath": "/22870547579/johnsoncitypress.com",
2356            "size": [728, 90],
2357            "sizeMap": [
2358                [[1200, 0], [[970, 250], [970, 90], [728, 90]]],
2359                [[992, 0],  [[970, 90], [728, 90]]],
2360                [[768, 0],  [[728, 90], [320, 50]]],
2361                [[320, 0],  [[320, 50]]]
2362            ],
2363            targeting:{'pos': "rectangle-two"}
2364        });
2365        });
2366</script>
2366</div><div class='news_panel_widget'><input type='hidden' name='type' value='7' /><input type='hidden' name='category' value='News' /><input type='hidden' name='subcategory' value='Local News' /><input type='hidden' name='itemStart' value='6' /><input type='hidden' name='itemCount' value='5' /><input type='hidden' name='hideHeader' value='true' /><input type='hidden' name='showMore' value='Hidden' /></div><div class='custom_break_widget'><div id="ad-1397313" style="margin: 20px auto 40px auto;"></div>
2367<script>
2368var didna = window.didna || {cmd: []};
2369didna.cmd.push(function(){
2370    didna.createAdUnits({
2371        id: "ad-1397313",
2372        "adUnitPath": "/22870547579/johnsoncitypress.com",
2373        "size": [728, 90],
2374        "sizeMap": [
2375            [[1200, 0], [[970, 250], [970, 90], [728, 90]]],
2376            [[992, 0],  [[970, 90], [728, 90]]],
2377            [[768, 0],  [[728, 90], [320, 50]]],
2378            [[320, 0],  [[320, 50]]]
2379        ],
2380        targeting:{'pos': "rectangle-three"}
2381    });
2382});
2383</script>
2383
2384
2385</div><div class='news_panel_widget'><input type='hidden' name='type' value='7' /><input type='hidden' name='category' value='News' /><input type='hidden' name='subcategory' value='Local News' /><input type='hidden' name='itemStart' value='11' /><input type='hidden' name='itemCount' value='5' /><input type='hidden' name='hideHeader' value='true' /><input type='hidden' name='showMore' value='Hidden' /></div><div class='custom_break_widget'><div id="ad-13973134" style="margin: 20px auto 40px auto;"></div>
2386<script>
2387var didna = window.didna || {cmd: []};
2388didna.cmd.push(function(){
2389    didna.createAdUnits({
2390        id: "ad-13973134",
2391        "adUnitPath": "/22870547579/johnsoncitypress.com",
2392        "size": [728, 90],
2393        "sizeMap": [
2394            [[1200, 0], [[970, 250], [970, 90], [728, 90]]],
2395            [[992, 0],  [[970, 90], [728, 90]]],
2396            [[768, 0],  [[728, 90], [320, 50]]],
2397            [[320, 0],  [[320, 50]]]
2398        ],
2399        targeting:{'pos': "rectangle-four"}
2400    });
2401});
2402</script>
2402</div><div class='news_panel_widget'><input type='hidden' name='type' value='7' /><input type='hidden' name='category' value='News' /><input type='hidden' name='subcategory' value='Local News' /><input type='hidden' name='itemStart' value='16' /><input type='hidden' name='itemCount' value='5' /><input type='hidden' name='hideHeader' value='true' /></div></div><div id='mts_c_2' class='widget_column' style='display:inline-block;vertical-align:top;text-align:initial;'><input type='hidden' name='col_width' value='300.00' /><input type='hidden' name='col_margin_left' value='20.00' /><input type='hidden' name='col_margin_right' value='0.00' /><input type='hidden' name='col_width_med' value='300.00' /><input type='hidden' name='col_margin_left_med' value='20.00' /><input type='hidden' name='col_margin_right_med' value='0.00' /><input type='hidden' name='col_width_tablet' value='300.00' /><input type='hidden' name='col_margin_left_tablet' value='20.00' /><input type='hidden' name='col_margin_right_tablet' value='0.00' /><input type='hidden' name='col_pixel' value='True' /><div class='custom_break_widget'><!--HALF PAGE AD CODE(300x600):-->
2403<div id="ad-1397311" class="srAd"></div>
2404<script>
2405var didna = window.didna || {cmd: []};
2406didna.cmd.push(function(){
2407    didna.createAdUnits({
2408        id: "ad-1397311",
2409        "adUnitPath": "/22870547579/johnsoncitypress.com/homepage",
2410        "size": [300, 600],
2411        "sizeMap": [
2412            [[1200, 0], [[300, 600]]],
2413            [[992, 0],  [[300, 600]]],
2414            [[768, 0],  [[300, 600]]],
2415            [[320, 0],  [[300, 600]]]
2416        ],
2417        targeting: { 'pos': "half-page" }
2418    });
2419});
2420</script>
2420</div><div class='trending_media_widget'><input type='hidden' name='types' value='NewsItem' /><input type='hidden' name='searchType' value='Views' /><input type='hidden' name='itemCount' value='5' /><input type='hidden' name='displayType' value='text' /><input type='hidden' name='renameHeader' value='Trending' /><input type='hidden' name='taggedTypes' value='Category' /></div><div class='custom_break_widget'><!--CUBE ONE AD CODE:-->
2421<div id="ad-1397309" style="margin: 20px auto;"></div>
2422<script>
2423var didna = window.didna || {cmd: []};
2424didna.cmd.push(function(){
2425    didna.createAdUnits({
2426        id: "ad-1397309",
2427        adUnitPath: "/22870547579/johnsoncitypress.com/homepage",
2428        size: [300, 250],
2429        sizeMap: [
2430            [[992, 0], [[300, 250]]],
2431            [[320, 0], [[300, 250]]]
2432        ],
2433        targeting: { pos: "cube-one" }
2434    });
2435});
2436</script>
2436</div><div class='custom_break_widget'><style>
2437.thingsToDo {
2438	font-family: arial, sans-serif;
2439	display: flex;
2440	gap: 10px;
2441	align-items: center;
2442	justify-content: center;
2443	padding: 20px;
2444}
2445
2446.ttdInfo {
2447	display: flex;
2448	flex-direction: column;
2449	gap: 5px;
2450}
2451
2452.ttdHeader {
2453	font-size: 20px;
2454	font-weight: 600;
2455}
2456
2457.thingsToDo p {
2458	margin: 0;
2459}
2460
2461.thingsToDo i {
2462	background: var(--six-main-black);
2463	color: var(--six-white);
2464	font-size: 48px;
2465	width: 50%;
2466	aspect-ratio: 1/1;
2467	display: flex;
2468	justify-content: center;
2469	align-items: center;
2470}
2471
2472.viewAllEvents {
2473	background: var(--six-black);
2474	color: var(--six-white);
2475	text-align: center;
2476	padding: 10px 20px;
2477	width: 100%;
2478	max-width: 150px;
2479	margin: 20px auto;
2480	display: block;
2481	font-family: arial, sans-serif;
2482}
2483
2484@media (min-width: 768px) {
2485	padding: 0px;
2486}
2487</style>
2488
2489<div class="thingsToDo">
2490	<i class="fas fa-calendar-alt"></i>
2491	<div class="ttdInfo">
2492		<div class="ttdHeader">Things to do</div>
2493		<p>Plan your week with our local event calendar</p>
2494	</div>
2495</div>
2496<a class="viewAllEvents" href="/live-content/local-events">View All</a>
2497</div><div class='custom_break_widget'><div id="ad-1397324" class="srAd"></div>
2498<script>
2499var didna = window.didna || {cmd: []};
2500didna.cmd.push(function(){
2501    didna.createAdUnits({
2502        id: "ad-1397324",
2503        "adUnitPath": "/22870547579/johnsoncitypress.com/news",
2504        "size": [300, 600],
2505        "sizeMap": [
2506            [[1200, 0], [[300, 600]]],
2507            [[992, 0],  [[300, 600]]],
2508            [[768, 0],  [[300, 600]]],
2509            [[320, 0],  [[300, 600]]]
2510        ],
2511        targeting: { 'pos': "sidebar-bottom" }
2512    });
2513});
2514</script>
2514</div><div class='custom_break_widget'>
2514<script>
2515//THIS SCRIPT WILL HANDLE ALL TRENDING NEWS WIDGETS ON THE PAGE, BUT MUST BE PLACED IMMEDIATELY AFTER THE LAST INSTANCE IN THE LAYOUT MANAGER
2516$(document).on("widgetsloaded", function() {
2517	//Add number list to trending widgets
2518	let trending = $(".trendingListCont");
2519	let item = trending.find(".trendingRow");
2520
2521	trending.each(function() {
2522		if ($(this).find(".trendingCount").length < 1) {
2523		let i = 0;
2524		$(this).find(item).each(function() {
2525			i += 1;
2526			$(this).find(".trendingLink").prepend(`<span class="trendingCount" style="margin-right: 10px; font-size: 24px;">${i}.</span>`);
2527		});  		
2528		i = 0
2529		}
2530	});
2531
2532});
2533</script>
2533</div></div></div></div>
2534   </div>
2535
2536
2537   
2538      <div class="fullAdView">
2539      </div>
2540      <div class="fullPageAd">
2541         
2542   
2543         <div class="adOptions">
2544            <div class="adCounter">
2545               <div class="loadingAd">Loading...</div> <img class="mts_lazy" width="324" height="20" data-original="https://media-sixrivers.mynews360.com/images/ajax-loader.gif" alt="" />
2546            </div>
2547            <div id="skipAd" class="adBtn">
2548               View Page in Progress
2549            </div>
2550         </div>
2551      </div>
2552   
2553   
2554   
2555   
2556   <h1 class="heading">
2557   The latest Local News news on Johnson City Press.
2558</h1>
2559
2560
2561
2562   <div id='mts_r_0' class='widget_region' style='text-align:center'><input type='hidden' name='reg_width' value='100.00' /><input type='hidden' name='reg_margin_left' value='0.00' /><input type='hidden' name='reg_margin_right' value='0.00' /><input type='hidden' name='reg_width_med' value='100.00' /><input type='hidden' name='reg_margin_left_med' value='0.00' /><input type='hidden' name='reg_margin_right_med' value='0.00' /><input type='hidden' name='reg_width_tablet' value='100.00' /><input type='hidden' name='reg_margin_left_tablet' value='0.00' /><input type='hidden' name='reg_margin_right_tablet' value='0.00' /><input type='hidden' name='reg_pixel' value='False' /><input type='hidden' name='reg_innerSec' value='False' /><div id='mts_c_0_3' class='widget_column' style='text-align: initial;'><input type='hidden' name='col_width' value='100.00' /><input type='hidden' name='col_margin_left' value='0.00' /><input type='hidden' name='col_margin_right' value='0.00' /><input type='hidden' name='col_width_med' value='100.00' /><input type='hidden' name='col_margin_left_med' value='0.00' /><input type='hidden' name='col_margin_right_med' value='0.00' /><input type='hidden' name='col_width_tablet' value='100.00' /><input type='hidden' name='col_margin_left_tablet' value='0.00' /><input type='hidden' name='col_margin_right_tablet' value='0.00' /><input type='hidden' name='col_pixel' value='False' /><div class='custom_break_widget'><style>
2563.customFooterInner {
2564	background: var(--six-main-black);
2565	color: var(--six-white);
2566	width: 100%;
2567	display: flex;
2568	flex-direction: column;
2569	justify-content: center;
2570	align-items: center;
2571	padding: 50px 30px;
2572	gap: 30px;
2573}
2574
2575.footerContent {
2576	max-width: 1280px;
2577	display: flex;
2578	flex-direction: column;
2579	gap: 40px;
2580}
2581
2582.footerBlock,
2583.footerInfoBlock,
2584.footerPubBlock {
2585	display: flex;
2586	flex-direction: column;
2587}
2588
2589.footerBlock {
2590	gap: 20px;		
2591}
2592
2593.footerInfoBlock {
2594	gap: 10px;
2595}
2596
2597.footerPubBlock {
2598	gap: 30px;
2599}
2600
2601.footerLogoMain {
2602	width: 300px;
2603	max-width: 100%;
2604}
2605
2606.footerLogoImage {
2607	width:100%;
2608}
2609
2610.footerShareInfo {
2611	display: flex;
2612	flex-direction: row;
2613	font-size: 24px;
2614	gap: 20px;
2615}
2616
2617.footerHeading {
2618	font-size: 32px;
2619	font-family: georgia, serif;
2620}
2621
2622.footerContent a.footerLink,
2623.footerContent a.fa-brands,
2624.footerContent a.sixRiversFooterLink {
2625	color: var(--six-white);
2626}
2627
2628.footerContent a.footerLink:hover,
2629.footerContent a.fa-brands:hover {
2630	color: var(--six-main-red);
2631}
2632
2633.borderTop {
2634	border-top: solid 1px var(--six-white);
2635	padding-top: 20px;
2636}
2637
2638.footerPubImage {
2639   max-width:100%;
2640}
2641
2642@media (min-width: 768px) {
2643	.customFooterInner {
2644		gap: 40px;
2645	}
2646
2647	.footerContent {
2648		flex-direction: row;
2649	}
2650
2651	.footerContent .footerBlock {
2652		width: calc(33.333% - 14px);
2653	}
2654}
2655
2656</style>
2657
2658<div class="customFooter">
2659	<div class="customFooterInner">
2660		<div class="footerContent">
2661			<div class="footerBlock">
2662				<a class="footerLogoMain" href="/">
2663					<img class="footerLogoImage" src="https://media-sixrivers.mynews360.com//images/custom/213/logo.png" alt="" />
2664				</a>
2665				<div class="footerInfoBlock">
2666					<span>Johnson City Press</span>
2667					<span>105 East Walnut Street Suite 10</span>
2668					<span>Johnson City, TN 37601</span>
2669					<span>Phone: <a class="mts_cc_text" href="tel:4237221330" title="Call Johnson City Phone Number">423-722-1330</a></span>
2670					<span>Email: <a class="mts_cc_text" href="mailto:[email protected]" title="E-mail Johnson city at [email protected]">[email protected]</a></span>					
2671				</div>
2672				<div class="footerShareInfo">
2673					<a class="fa-brands fa-facebook-f" href="https://www.facebook.com/JohnsonCityPress/" target="_blank"></a>
2674					<a class="fa-brands fa-x-twitter" href="http://twitter.com/jcpress/" target="_blank"></a>
2675					<a class="fa-brands fa-linkedin" href="https://www.linkedin.com/company/johnsoncitypress/" target="_blank"></a>
2676					<a class="fa-brands fa-youtube" href="https://www.youtube.com/channel/UCYZixCNzcgknXLPdHUXQPXw" target="_blank"></a>
2677					<a class="fa-brands fa-tiktok" href="https://www.tiktok.com/@johnsoncitypress" target="_blank"></a>
2678					<a class="fa-brands fa-instagram" href="https://www.instagram.com/johnson_city_press/" target="_blank"></a>
2679				</div>
2680			</div>
2681			<div class="footerBlock">
2682				<div class="footerHeading"><a class="sixRiversFooterLink" href="https://www.sixriversmedia.com/" target="_blank">Six Rivers Media LLC</a></div>
2683				<div class="footerPubBlock">
2684					<a class="footerPubLink" title="Johnson City Press link" href="https://www.timesnews.net/" target="_blank"><img class="footerPubImage" src="https://d1gpmunylt23vy.cloudfront.net/360_SixRivers_Live/0/0/0/0/118/575/118575_original" alt="Johnson City Press Logo" /></a>
2685					<a class="footerPubLink" title="The Tomahawk link" href="https://www.thetomahawk.com/" target="_blank"><img class="footerPubImage" src="https://d1gpmunylt23vy.cloudfront.net/360_SixRivers_Live/0/0/0/0/27/545/27545_original" alt="The Tomahawk Logo" /></a>
2686					<a class="footerPubLink" title="The Erwin Record link" href="https://www.erwinrecord.net/" target="_blank"><img class="footerPubImage" src="https://d1gpmunylt23vy.cloudfront.net/360_SixRivers_Live/0/0/0/0/27/543/27543_original" alt="The Erwin Logo" /></a>
2687				</div>
2688			</div>
2689			<div class="footerBlock">
2690				<div class="footerHeading">Quick Links:</div>
2691				<div class="footerInfoBlock">
2692					<a class="footerLink" href="/live-content/about us">About Us</a>
2693					<a class="footerLink" href="https://www.sixriversmedia.com/contact-us/#johnson_city_press" target="_blank">Contact Us</a>
2694					<!--<a class="footerLink" href="/live-content/archives">Archives</a>-->
2695					<a class="footerLink" href="https://sixrivers.newzware.com/myad/sixrivers/common/template.jsp" target="_blank">Advertise</a>
2696					<!--<a class="footerLink" href="/live-content/faq">FAQ</a>-->
2697					<a class="footerLink" href="/live-content/subscribe">Subscribe</a>
2698				</div>
2699			</div>
2700		</div>
2701		<div class="footerContent borderTop">
2702			<div class="copyright">
2703				&copy; 2025 Johnson City Press 105 East Walnut Street Suite 10 Johnson City, TN 37601 | <a class="footerLink" href="/live-content/terms of use">Terms of Use</a> | <a class="footerLink" href="/live-content/privacy policy">Privacy Policy</a> | <a class="footerLink" href="#" onclick="document.getElementById('silktide-cookie-icon').click(); return false;">Cookie Preferences
2704                                        </a>
2705			</div>
2706		</div>
2707	</div>
2708</div></div></div></div>
2709
2710   
2710<script type="text/javascript">
2711      _MTS_cssList.push("css/plugins/chosen/chosen.min.css");
2712      _MTS_jsList.push("js/ajax.js", "js/jQueryExtensions/jquery-ui.js", "js/jQueryExtensions/touch-punch.js", "js/jQueryExtensions/jquery.lazyload.js", "js/plugins/chosen/chosen.jquery.min.js", "js/common.js");
2713      
2714      _MTS_jsList.push("js/smartBanner.js");
2715      
2716      _imageSizes = {"SiteWideMxW":1280,"SiteWideMxH":720,"SlideShowMxW":864,"SlideShowMxH":486,"ThumbnailMxW":600,"ThumbnailMxH":337,"TeamLogoMxW":250,"TeamLogoMxH":250};
2717      var _MTS_adSlot = "";
2718      _MTS_VERSION = "1.14.5.35260";
2719
2720      
2721      
2722	</script>
2722
2723
2724
2725   
2725<script type="text/javascript" src="https://media-sixrivers.mynews360.com/js/widgets/main.js?v=1.14.5.35260&weburi=https://johnsoncitypress.com/&portalid=213&mediauri=https://media-sixrivers.mynews360.com/"></script>
2725
2726   
2727</body>
2728</html>
2729

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.