PageSourceSearch

https://presteligence.com/news/250922/how-carpenter-media-group-bu…n-publishing-workflow-for-today-and-beyond/

html presteligence.com collected 2026-10-01 15:00:46 UTC 126,924 bytes, 3,517 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.myteamscoop.com/css/smartBanner.css?v=1.14.5.35260" media="screen" />
19   <link rel="stylesheet" type="text/css" href="https://media.myteamscoop.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.myteamscoop.com/css/fontawesome/fontawesome.min.css?v=1.14.5.35260" />
22   <link rel="stylesheet" type="text/css" href="https://media.myteamscoop.com/css/fontawesome/brands.min.css?v=1.14.5.35260" />
23   
24
25   
25<script type="text/javascript" src="https://media.myteamscoop.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://myteamscoop.com/",
31         _webUri = "https://presteligence.com",
32         _mediaUrl = "https://media.myteamscoop.com/",
33         _logoTemplate = "https://media.myteamscoop.com/logo/%%TEAM_ID%%/24",
34         _schoolTemplate = "https://media.myteamscoop.com/logo/%%SCHOOL_ID%%/school/%%SPORT_ID%%/24",
35         _MTS_PHOTO_TEMPLATE = "https://media.myteamscoop.com/image/%%IMG_ID%%/%%SIZE%%/%%TEAM_ID%%/%%USER_ID%%/%%TYPE%%/24",
36         _portalId = 24,
37         _portalName = "Presteligence",
38         _portalUrl = "https://presteligence.com/",
39         _twitterName = "",
40         _facebookName = "",
41         _region = "Presteligence",
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 = "~/PortalNews.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 = "How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond. | Presteligence";
68   var _ga_sport = "";
69   var _ga_school = "";
70   var _ga_guid = "250922";
71   var _ga_author = "Denise Franken";
72   var _ga_pagetype = "portalnews";
73   var _ga_tags = "My News 360,Automated page building,Web CMS,News";
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<script>
87window._MTS_ClarityProjectId = "w9jos14ihs";
88
89window.loadClarity = function () {
90  var projectId = window._MTS_ClarityProjectId || "";
91  if (!projectId || window.__clarityLoaded) return;
92
93  window.__clarityLoaded = true;
94
95  (function (c, l, a, r, i, t, y) {
96    c[a] = c[a] || function () {
97      (c[a].q = c[a].q || []).push(arguments);
98    };
99    t = l.createElement(r);
100    t.async = 1;
101    t.src = "https://www.clarity.ms/tag/" + i;
102    y = l.getElementsByTagName(r)[0];
103    y.parentNode.insertBefore(t, y);
104  })(window, document, "clarity", "script", projectId);
105};
106
107window.identifyClarityUser = function () {
108    var rawUrl = window._MTS_SITEURL || "UnknownSite";
109    var siteUrl = rawUrl
110      .replace(/^(https?:\/\/)?(www\.)?/, "")
111      .split(".")[0]
112      .substring(0, 16);
113
114    var clarityUserId = String(window._MTS_userId);
115    var friendlyName = siteUrl + " - " + clarityUserId;
116
117    window.clarity("identify", clarityUserId, undefined, undefined, friendlyName);
118    window.clarity("set", "site", siteUrl);
119    window.clarity("set", "userId", clarityUserId);
120    window.clarity("set", "isAdmin", window._isAdmin === true ? "true" : "false");
121};
122
123$(document).one("widgetsloaded", function () {
124  if (localStorage.getItem("silktideCookieChoice_analytics") === "true") {
125    window.loadClarity();
126    window.identifyClarityUser();
127  }
128});
129</script>
129
130
131<script>
132  // Initialize the dataLayer
133  window.dataLayer = window.dataLayer || [];
134
135  // Create the gtag function that pushes to the dataLayer
136  function gtag() {
137    dataLayer.push(arguments);
138  }
139
140  // Set consent defaults
141  gtag('consent', 'default', {
142    analytics_storage: localStorage.getItem('silktideCookieChoice_analytics') === 'true' ? 'granted' : 'denied',
143    ad_storage: localStorage.getItem('silktideCookieChoice_marketing') === 'true' ? 'granted' : 'denied',
144    ad_user_data: localStorage.getItem('silktideCookieChoice_marketing') === 'true' ? 'granted' : 'denied',
145    ad_personalization: localStorage.getItem('silktideCookieChoice_marketing') === 'true' ? 'granted' : 'denied',
146    functionality_storage: localStorage.getItem('silktideCookieChoice_necessary') === 'true' ? 'granted' : 'denied',
147    security_storage: localStorage.getItem('silktideCookieChoice_necessary') === 'true' ? 'granted' : 'denied'
148  });
149</script>
149
150
151<!--Google Consent Default Config-->
152<script>
153  // Define dataLayer and the gtag function
154  window.dataLayer = window.dataLayer || [];
155  function gtag(){dataLayer.push(arguments);}
156
157  // Set default consent to 'denied' as a placeholder
158  if(localStorage.getItem('consentMode') === null){
159    gtag('consent', 'default', {
160      'ad_storage': 'denied',
161      'ad_user_data': 'denied',
162      'ad_personalization': 'denied',
163      'analytics_storage': 'denied',
164      'personalization_storage': 'denied',
165      'security_storage': 'denied',
166      'functionality_storage': 'denied',
167    });
168    // To further redact your ads data when ad_storage is denied, set ads_data_redaction to true
169    gtag('set', 'ads_data_redaction', true);
170  } else {
171    gtag('consent', 'default', JSON.parse(localStorage.getItem('consentMode')));
172  }
173</script>
173
174
175<style>
176/* 
177  Silktide Consent Manager - https://silktide.com/consent-manager/  
178*/
179
180/* --------------------------------
181  Global Styles - These elements exist in the main DOM and styling is limited to positioning and animation
182-------------------------------- */
183/* Wrapper (Global) */
184#silktide-wrapper {
185              --focus: 0 0 0 2px #ffffff, 0 0 0 4px #000000, 0 0 0 6px #ffffff;
186              --boxShadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;
187              --fontFamily: Helvetica Neue, Segoe UI, Arial, sans-serif;
188              --primaryColor: #F9D000;
189              --backgroundColor: #050505;
190              --textColor: #F4F0DF;
191              --backdropBackgroundColor: #00000033;
192              --backdropBackgroundBlur: 0px;
193              --cookieIconColor: #F9D000;
194              --cookieIconBackgroundColor: #050505;
195              position: fixed;
196  bottom: 0;
197  right: 0;
198  width: 100%;
199  height: 100%;
200  z-index: 99999;
201  pointer-events: none;
202  border: 0px;
203  display: flex;
204  justify-content: center;
205  align-items: center;
206  overscroll-behavior: contain;
207  overflow-y: auto;
208            }
209
210/* Backdrop (Global) */
211#silktide-backdrop-global {
212  position: fixed;
213  top: 0;
214  left: 0;
215  width: 100%;
216  height: 100%;
217  pointer-events: auto;
218  border: 0px;
219  display: none;
220}
221
222/* --------------------------------
223  Links
224-------------------------------- */
225#silktide-wrapper a {
226  all: unset;
227  display: inline-block;
228  color: var(--primaryColor);
229  text-decoration: underline;
230}
231
232#silktide-wrapper a:hover {
233  cursor: pointer;
234  color: var(--textColor);
235}
236
237/* --------------------------------
238  Focus Styles
239-------------------------------- */
240#silktide-wrapper a:focus,
241#silktide-wrapper #silktide-banner button:focus,
242#silktide-wrapper #silktide-modal button:focus,
243#silktide-wrapper #silktide-cookie-icon:focus {
244  outline: none;
245  box-shadow: var(--focus);
246  border-radius: 5px;
247}
248
249#silktide-wrapper #silktide-cookie-icon:focus {
250  border-radius: 50%;
251}
252
253/* --------------------------------
254  General Styles
255-------------------------------- */
256
257#silktide-wrapper .st-button {
258  color: var(--backgroundColor);
259  background-color: var(--primaryColor);
260  border: 2px solid var(--primaryColor);
261  padding: 10px 20px;
262  text-decoration: none;
263  text-align: center;
264  display: inline-block;
265  font-size: 16px;
266  line-height: 24px;
267  cursor: pointer;
268  border-radius: 5px;
269}
270
271#silktide-wrapper .st-button--primary {
272}
273
274#silktide-wrapper .st-button--primary:hover {
275  background-color: var(--backgroundColor);
276  color: var(--primaryColor);
277}
278
279#silktide-wrapper .st-button--secondary {
280  background-color: var(--backgroundColor);
281  color: var(--primaryColor);
282}
283
284#silktide-wrapper .st-button--secondary:hover {
285  background-color: var(--primaryColor);
286  color: var(--backgroundColor);
287}
288
289/* --------------------------------
290  Banner
291-------------------------------- */
292#silktide-banner {
293  font-family: var(--fontFamily);
294  color: var(--textColor);
295  background-color: var(--backgroundColor);
296  box-sizing: border-box;
297  padding: 32px;
298  border-radius: 5px;
299  pointer-events: auto;
300  border: 0px;
301  position: fixed;
302  bottom: 16px;
303  right: 16px;
304  width: 600px;
305  overflow: auto;
306  max-width: calc(100% - 32px);
307  max-height: calc(100vh - 32px);
308  transform: translate(0, -20px);
309  opacity: 0;
310  animation: silktide-slideInDown 350ms ease-out forwards;
311  animation-delay: 0.3s;
312  box-shadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;
313}
314
315#silktide-banner:focus {
316  border-radius: 50%;
317}
318
319#silktide-banner.center {
320  top: 50%;
321  left: 50%;
322  bottom: auto;
323  right: auto;
324  position: fixed;
325  transform: translate(-50%, calc(-50% - 20px));
326  animation: silktide-slideInDown-center 350ms ease-out forwards;
327}
328
329#silktide-banner.bottomLeft {
330  bottom: 16px;
331  left: 16px;
332  position: fixed;
333}
334
335#silktide-banner.bottomCenter {
336  bottom: 16px;
337  left: 50%;
338  position: fixed;
339  transform: translate(-50%, -20px);
340  animation: silktide-slideInDown-bottomCenter 350ms ease-out forwards;
341}
342
343#silktide-banner .preferences {
344  display: flex;
345  gap: 5px;
346  border: none;
347  padding: 15px 0px;
348  background-color: transparent;
349  color: var(--primaryColor);
350  cursor: pointer;
351  font-size: 16px;
352}
353
354#silktide-banner .preferences span {
355  display: block;
356  white-space: nowrap;
357  text-decoration: underline;
358}
359
360#silktide-banner .preferences span:hover {
361  color: var(--textColor);
362}
363
364#silktide-banner .preferences:after {
365  display: block;
366  content: '>';
367  text-decoration: none;
368}
369
370#silktide-banner p {
371  font-size: 16px;
372  line-height: 24px;
373  margin: 0px 0px 15px;
374}
375
376#silktide-banner a {
377  display: inline-block;
378  color: var(--primaryColor);
379  text-decoration: underline;
380  background-color: var(--backgroundColor);
381}
382
383#silktide-banner a:hover {
384  color: var(--textColor);
385}
386
387#silktide-banner a.silktide-logo {
388  display: flex;
389  align-items: center;
390  justify-content: center;
391  fill: var(--primaryColor); /* passed down to svg > path */
392  margin-left: auto;
393  width: 48px;
394  height: 48px;
395}
396
397
398#silktide-banner .actions {
399  display: flex;
400  gap: 16px;
401  flex-direction: column;
402  margin-top: 24px;
403}
404
405@media (min-width: 600px) {
406  #silktide-banner .actions {
407    flex-direction: row;
408    align-items: center;
409  }
410}
411
412#silktide-banner .actions-row {
413  display: flex;
414  gap: 16px;
415  flex-direction: row;
416  align-items: center;
417  justify-content: space-between;
418  flex-grow: 1;
419}
420
421/* --------------------------------
422  Modal
423-------------------------------- */
424#silktide-modal {
425  display: none;
426  pointer-events: auto;
427  overflow: auto;
428  width: 800px;
429  max-width: 100%;
430  max-height: 100%;
431  border: 0px;
432  transform: translate(0px, -20px);
433  opacity: 0;
434  animation: silktide-slideInUp-center 350ms ease-out forwards;
435  box-shadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;
436  font-family: var(--fontFamily);
437  color: var(--textColor);
438  flex-direction: column;
439  padding: 30px;
440  background-color: var(--backgroundColor);
441  border-radius: 5px;
442  box-sizing: border-box;
443}
444
445/* --------------------------------
446  Modal - Header
447-------------------------------- */
448#silktide-modal header {
449  display: flex;
450  justify-content: space-between;
451  align-items: center;
452  margin-bottom: 20px;
453  gap: 16px;
454}
455
456#silktide-modal h1 {
457  font-family: var(--fontFamily);
458  color: var(--textColor);
459  font-size: 24px;
460  font-weight: 500;
461  margin: 0px;
462}
463
464#silktide-modal .modal-close {
465  display: inline-flex;
466  border: none;
467  padding: 13px;
468  border: 0px;
469  cursor: pointer;
470  background: var(--backgroundColor);
471  color: var(--primaryColor);
472}
473
474#silktide-modal .modal-close svg {
475  fill: var(--primaryColor);
476}
477
478/* --------------------------------
479  Modal - Content
480-------------------------------- */
481
482#silktide-modal section {
483  flex: 1;
484  margin-top: 32px;
485}
486
487#silktide-modal section::-webkit-scrollbar {
488  display: block; /* Force scrollbars to show */
489  width: 5px; /* Width of the scrollbar */
490}
491
492#silktide-modal section::-webkit-scrollbar-thumb {
493  background-color: var(--textColor); /* Color of the scrollbar thumb */
494  border-radius: 10px; /* Rounded corners for the thumb */
495}
496
497#silktide-modal p {
498  font-size: 16px;
499  line-height: 24px;
500  color: var(--textColor);
501  margin: 0px 0px 15px;
502}
503
504#silktide-modal p:last-of-type {
505  margin: 0px;
506}
507
508#silktide-modal fieldset {
509  padding: 0px;
510  border: none;
511  margin: 0px 0px 32px;
512}
513
514#silktide-modal fieldset:last-of-type {
515  margin: 0px;
516}
517
518#silktide-modal legend {
519  padding: 0px;
520  margin: 0px 0px 10px;
521  font-weight: 700;
522  color: var(--textColor);
523  font-size: 16px;
524}
525
526#silktide-modal .cookie-type-content {
527  display: flex;
528  justify-content: space-between;
529  align-items: flex-start;
530  gap: 24px;  
531}
532
533/* --------------------------------
534  Modal - Switches
535-------------------------------- */
536#silktide-modal .switch {
537  flex-shrink: 0;
538  position: relative;
539  display: inline-block;
540  height: 34px;
541  width: 74px;
542  cursor: pointer;
543}
544
545#silktide-modal .switch:focus-within {
546  outline: none;
547  box-shadow: var(--focus);
548  border-radius: 25px;
549}
550
551#silktide-modal .switch input {
552  opacity: 0;
553  position: absolute;
554}
555
556/* Unchecked Switch Styles */
557#silktide-modal .switch__pill {
558  position: relative;
559  display: block;
560  height: 34px;
561  width: 74px;
562  background: var(--textColor);
563  border-radius: 25px;
564}
565
566#silktide-modal .switch__dot {
567  position: absolute;
568  top: 2px;
569  left: 2px;
570  display: block;
571  height: 30px;
572  width: 30px;
573  background: var(--backgroundColor);
574  border-radius: 50%;
575  transition: left 150ms ease-out;
576}
577
578#silktide-modal .switch__off,
579#silktide-modal .switch__on {
580  text-transform: uppercase;
581  font-size: 15px;
582  font-weight: 500;
583  color: var(--backgroundColor);
584  position: absolute;
585  top: 7px;
586  right: 8px;
587  transition: right 150ms ease-out, opacity 150ms ease-out;
588}
589
590#silktide-modal .switch__off {
591  opacity: 1;
592}
593
594#silktide-modal .switch__on {
595  opacity: 0;
596}
597
598/* Checked Switch Styles */
599#silktide-modal .switch input:checked + .switch__pill {
600  background: var(--primaryColor);
601}
602
603#silktide-modal .switch input:checked ~ .switch__dot {
604  left: calc(100% - 32px);
605}
606
607#silktide-modal .switch input:checked ~ .switch__off {
608  right: calc(100% - 32px);
609  opacity: 0;
610}
611
612#silktide-modal .switch input:checked ~ .switch__on {
613  right: calc(100% - 34px);
614  opacity: 1;
615}
616
617/* Disabled Switch Styles */
618#silktide-modal .switch input:disabled + .switch__pill {
619  opacity: 0.65;
620  cursor: not-allowed;
621}
622
623/* --------------------------------
624  Modal - Footer
625-------------------------------- */
626#silktide-modal footer {
627  display: flex;
628  flex-direction: column;
629  gap: 16px;
630  margin-top: 24px;
631}
632
633@media (min-width: 600px) {
634  #silktide-modal footer {
635    flex-direction: row;
636    align-items: center;
637  }
638}
639
640#silktide-modal footer a {
641  margin-left: auto;
642  padding: 14px 0px;
643}
644
645/* Cookie Icon */
646#silktide-cookie-icon {
647  display: none;
648  position: fixed;
649  bottom: 10px;
650  left: 10px;
651  justify-content: center;
652  align-items: center;
653  width: 48px;
654  height: 48px;
655  border-radius: 50%;
656  padding: 0px;
657  border: none;
658  background-color: var(--cookieIconColor);
659  cursor: pointer;
660  box-shadow: 0px 0px 6px 0px #0000001a;
661  pointer-events: auto;
662  animation: silktide-fadeIn 0.3s ease-in-out forwards;
663}
664
665#silktide-cookie-icon.bottomRight {
666  left: auto;
667  right: 10px;
668}
669
670#silktide-cookie-icon svg {
671  fill: var(--cookieIconBackgroundColor);
672  width: 24px;
673  height: 24px;
674}
675
676/* --------------------------------
677  Backdrop
678-------------------------------- */
679#silktide-backdrop {
680  display: none;
681  position: absolute;
682  top: 0;
683  left: 0;
684  width: 100%;
685  height: 100%;
686  background-color: var(--backdropBackgroundColor);
687  backdrop-filter: blur(var(--backdropBackgroundBlur));
688  pointer-events: all;
689}
690
691/* --------------------------------
692  Animations
693-------------------------------- */
694@keyframes silktide-fadeIn {
695  from {
696    opacity: 0;
697  }
698  to {
699    opacity: 1;
700  }
701}
702
703@keyframes silktide-slideInDown {
704  from {
705    opacity: 0;
706    transform: translateY(-20px);
707  }
708  to {
709    opacity: 1;
710    transform: translateY(0);
711  }
712}
713
714@keyframes silktide-slideInDown-center {
715  from {
716    opacity: 0;
717    transform: translate(-50%, calc(-50% - 20px));
718  }
719  to {
720    opacity: 1;
721    transform: translate(-50%, -50%);
722  }
723}
724
725@keyframes silktide-slideInDown-bottomCenter {
726  from {
727    opacity: 0;
728    transform: translate(-50%, -20px);
729  }
730  to {
731    opacity: 1;
732    transform: translate(-50%, 0);
733  }
734}
735
736@keyframes silktide-slideInUp-center {
737  from {
738    opacity: 0;
739    transform: translate(0px, 20px);
740  }
741  to {
742    opacity: 1;
743    transform: translate(0px, 0px);
744  }
745}
746
747</style>
748<script>
749// Silktide Consent Manager - https://silktide.com/consent-manager/  
750
751class SilktideCookieBanner {
752  constructor(config) {
753    this.config = config; // Save config to the instance
754
755    this.wrapper = null;
756    this.banner = null;
757    this.modal = null;
758    this.cookieIcon = null;
759    this.backdrop = null;
760
761    this.createWrapper();
762
763    if (this.shouldShowBackdrop()) {
764      this.createBackdrop();
765    }
766
767    this.createCookieIcon();
768    this.createModal();
769
770    if (this.shouldShowBanner()) {
771      this.createBanner();
772      this.showBackdrop();
773    } else {
774      this.showCookieIcon();
775    }
776
777    this.setupEventListeners();
778
779    if (this.hasSetInitialCookieChoices()) {
780      this.loadRequiredCookies();
781      this.runAcceptedCookieCallbacks();
782    }
783  }
784
785  destroyCookieBanner() {
786    // Remove all cookie banner elements from the DOM
787    if (this.wrapper && this.wrapper.parentNode) {
788      this.wrapper.parentNode.removeChild(this.wrapper);
789    }
790
791    // Restore scrolling
792    this.allowBodyScroll();
793
794    // Clear all references
795    this.wrapper = null;
796    this.banner = null;
797    this.modal = null;
798    this.cookieIcon = null;
799    this.backdrop = null;
800  }
801
802  // ----------------------------------------------------------------
803  // Wrapper
804  // ----------------------------------------------------------------
805  createWrapper() {
806    this.wrapper = document.createElement('div');
807    this.wrapper.id = 'silktide-wrapper';
808    document.body.insertBefore(this.wrapper, document.body.firstChild);
809  }
810
811  // ----------------------------------------------------------------
812  // Wrapper Child Generator
813  // ----------------------------------------------------------------
814  createWrapperChild(htmlContent, id) {
815    // Create child element
816    const child = document.createElement('div');
817    child.id = id;
818    child.innerHTML = htmlContent;
819
820    // Ensure wrapper exists
821    if (!this.wrapper || !document.body.contains(this.wrapper)) {
822      this.createWrapper();
823    }
824
825    // Append child to wrapper
826    this.wrapper.appendChild(child);
827    return child;
828  }
829
830  // ----------------------------------------------------------------
831  // Backdrop
832  // ----------------------------------------------------------------
833  createBackdrop() {
834    this.backdrop = this.createWrapperChild(null, 'silktide-backdrop');
835  }
836
837  showBackdrop() {
838    if (this.backdrop) {
839      this.backdrop.style.display = 'block';
840    }
841    // Trigger optional onBackdropOpen callback
842    if (typeof this.config.onBackdropOpen === 'function') {
843      this.config.onBackdropOpen();
844    }
845  }
846
847  hideBackdrop() {
848    if (this.backdrop) {
849      this.backdrop.style.display = 'none';
850    }
851
852    // Trigger optional onBackdropClose callback
853    if (typeof this.config.onBackdropClose === 'function') {
854      this.config.onBackdropClose();
855    }
856  }
857
858  shouldShowBackdrop() {
859    return this.config?.background?.showBackground || false;
860  }
861
862  // update the checkboxes in the modal with the values from localStorage
863  updateCheckboxState(saveToStorage = false) {
864    const preferencesSection = this.modal.querySelector('#cookie-preferences');
865    const checkboxes = preferencesSection.querySelectorAll('input[type="checkbox"]');
866
867    checkboxes.forEach((checkbox) => {
868      const [, cookieId] = checkbox.id.split('cookies-');
869      const cookieType = this.config.cookieTypes.find(type => type.id === cookieId);
870      
871      if (!cookieType) return;
872
873      if (saveToStorage) {
874        // Save the current state to localStorage and run callbacks
875        const currentState = checkbox.checked;
876        
877        if (cookieType.required) {
878          localStorage.setItem(
879            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,
880            'true'
881          );
882        } else {
883          localStorage.setItem(
884            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,
885            currentState.toString()
886          );
887          
888          // Run appropriate callback
889          if (currentState && typeof cookieType.onAccept === 'function') {
890            cookieType.onAccept();
891          } else if (!currentState && typeof cookieType.onReject === 'function') {
892            cookieType.onReject();
893          }
894        }
895      } else {
896        // When reading values (opening modal)
897        if (cookieType.required) {
898          checkbox.checked = true;
899          checkbox.disabled = true;
900        } else {
901          const storedValue = localStorage.getItem(
902            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`
903          );
904          
905          if (storedValue !== null) {
906            checkbox.checked = storedValue === 'true';
907          } else {
908            checkbox.checked = !!cookieType.defaultValue;
909          }
910        }
911      }
912    });
913  }
914
915  setInitialCookieChoiceMade() {
916    window.localStorage.setItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`, 1);
917  }
918
919  // ----------------------------------------------------------------
920  // Consent Handling
921  // ----------------------------------------------------------------
922  handleCookieChoice(accepted) {
923    // We set that an initial choice was made regardless of what it was so we don't show the banner again
924    this.setInitialCookieChoiceMade();
925
926    this.removeBanner();
927    this.hideBackdrop();
928    this.toggleModal(false);
929    this.showCookieIcon();
930
931    this.config.cookieTypes.forEach((type) => {
932      // Set localStorage and run accept/reject callbacks
933      if (type.required == true) {
934        localStorage.setItem(`silktideCookieChoice_${type.id}${this.getBannerSuffix()}`, 'true');
935        if (typeof type.onAccept === 'function') { type.onAccept() }
936      } else {
937        localStorage.setItem(
938          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,
939          accepted.toString(),
940        );
941
942        if (accepted) {
943          if (typeof type.onAccept === 'function') { type.onAccept(); }
944        } else {
945          if (typeof type.onReject === 'function') { type.onReject(); }
946        }
947      }
948    });
949
950    // Trigger optional onAcceptAll/onRejectAll callbacks
951    if (accepted && typeof this.config.onAcceptAll === 'function') {
952      if (typeof this.config.onAcceptAll === 'function') { this.config.onAcceptAll(); }
953    } else if (typeof this.config.onRejectAll === 'function') {
954      if (typeof this.config.onRejectAll === 'function') { this.config.onRejectAll(); }
955    }
956
957    // finally update the checkboxes in the modal with the values from localStorage
958    this.updateCheckboxState();
959  }
960
961  getAcceptedCookies() {
962    return (this.config.cookieTypes || []).reduce((acc, cookieType) => {
963      acc[cookieType.id] =
964        localStorage.getItem(`silktideCookieChoice_${cookieType.id}${this.getBannerSuffix()}`) ===
965        'true';
966      return acc;
967    }, {});
968  }
969
970  runAcceptedCookieCallbacks() {
971    if (!this.config.cookieTypes) return;
972
973    const acceptedCookies = this.getAcceptedCookies();
974    this.config.cookieTypes.forEach((type) => {
975      if (type.required) return; // we run required cookies separately in loadRequiredCookies
976      if (acceptedCookies[type.id] && typeof type.onAccept === 'function') {
977        if (typeof type.onAccept === 'function') { type.onAccept(); }
978      }
979    });
980  }
981
982  runRejectedCookieCallbacks() {
983    if (!this.config.cookieTypes) return;
984
985    const rejectedCookies = this.getRejectedCookies();
986    this.config.cookieTypes.forEach((type) => {
987      if (rejectedCookies[type.id] && typeof type.onReject === 'function') {
988        if (typeof type.onReject === 'function') { type.onReject(); }
989      }
990    });
991  }
992
993  /**
994   * Run through all of the cookie callbacks based on the current localStorage values
995   */
996  runStoredCookiePreferenceCallbacks() {
997    this.config.cookieTypes.forEach((type) => {
998      const accepted =
999        localStorage.getItem(`silktideCookieChoice_${type.id}${this.getBannerSuffix()}`) === 'true';
1000      // Set localStorage and run accept/reject callbacks
1001      if (accepted) {
1002        if (typeof type.onAccept === 'function') { type.onAccept(); }
1003      } else {
1004        if (typeof type.onReject === 'function') { type.onReject(); }
1005      }
1006    });
1007  }
1008
1009  loadRequiredCookies() {
1010    if (!this.config.cookieTypes) return;
1011    this.config.cookieTypes.forEach((cookie) => {
1012      if (cookie.required && typeof cookie.onAccept === 'function') {
1013        if (typeof cookie.onAccept === 'function') { cookie.onAccept(); }
1014      }
1015    });
1016  }
1017
1018  // ----------------------------------------------------------------
1019  // Banner
1020  // ----------------------------------------------------------------
1021  getBannerContent() {
1022    const bannerDescription =
1023      this.config.text?.banner?.description ||
1024      "<p>We use cookies on our site to enhance your user experience, provide personalized content, and analyze our traffic.</p>";
1025
1026    // Accept button
1027    const acceptAllButtonText = this.config.text?.banner?.acceptAllButtonText || 'Accept all';
1028    const acceptAllButtonLabel = this.config.text?.banner?.acceptAllButtonAccessibleLabel;
1029    const acceptAllButton = `<button class="accept-all st-button st-button--primary"${
1030      acceptAllButtonLabel && acceptAllButtonLabel !== acceptAllButtonText 
1031        ? ` aria-label="${acceptAllButtonLabel}"` 
1032        : ''
1033    }>${acceptAllButtonText}</button>`;
1034    
1035    // Reject button
1036    const rejectNonEssentialButtonText = this.config.text?.banner?.rejectNonEssentialButtonText || 'Reject non-essential';
1037    const rejectNonEssentialButtonLabel = this.config.text?.banner?.rejectNonEssentialButtonAccessibleLabel;
1038    const rejectNonEssentialButton = `<button class="reject-all st-button st-button--primary"${
1039      rejectNonEssentialButtonLabel && rejectNonEssentialButtonLabel !== rejectNonEssentialButtonText 
1040        ? ` aria-label="${rejectNonEssentialButtonLabel}"` 
1041        : ''
1042    }>${rejectNonEssentialButtonText}</button>`;
1043
1044    // Preferences button
1045    const preferencesButtonText = this.config.text?.banner?.preferencesButtonText || 'Preferences';
1046    const preferencesButtonLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;
1047    const preferencesButton = `<button class="preferences"${
1048      preferencesButtonLabel && preferencesButtonLabel !== preferencesButtonText 
1049        ? ` aria-label="${preferencesButtonLabel}"` 
1050        : ''
1051    }><span>${preferencesButtonText}</span></button>`;
1052    
1053
1054    // Silktide logo link
1055    const silktideLogo = `
1056      <a class="silktide-logo" href="https://silktide.com/consent-manager" target="_blank" rel="noreferrer" aria-label="Visit the Silktide Consent Manager page">
1057        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="25" viewBox="0 0 24 25" fill="inherit">
1058          <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"/>
1059        </svg>
1060      </a>
1061    `;
1062
1063    const bannerContent = `
1064      ${bannerDescription}
1065      <div class="actions">                               
1066        ${acceptAllButton}
1067        ${rejectNonEssentialButton}
1068        <div class="actions-row">
1069          ${preferencesButton}
1070
1071        </div>
1072      </div>
1073    `;
1074
1075    return bannerContent;
1076  }
1077
1078  hasSetInitialCookieChoices() {
1079    return !!localStorage.getItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`);
1080  }
1081
1082  createBanner() {
1083    // Create banner element
1084    this.banner = this.createWrapperChild(this.getBannerContent(), 'silktide-banner');
1085
1086    // Add positioning class from config
1087    if (this.banner && this.config.position?.banner) {
1088      this.banner.classList.add(this.config.position.banner);
1089    }
1090
1091    // Trigger optional onBannerOpen callback
1092    if (this.banner && typeof this.config.onBannerOpen === 'function') {
1093      this.config.onBannerOpen();
1094    }
1095  }
1096
1097  removeBanner() {
1098    if (this.banner && this.banner.parentNode) {
1099      this.banner.parentNode.removeChild(this.banner);
1100      this.banner = null;
1101
1102      // Trigger optional onBannerClose callback
1103      if (typeof this.config.onBannerClose === 'function') {
1104        this.config.onBannerClose();
1105      }
1106    }
1107  }
1108
1109  shouldShowBanner() {
1110    if (this.config.showBanner === false) {
1111      return false;
1112    }
1113    return (
1114      localStorage.getItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`) === null
1115    );
1116  }
1117
1118  // ----------------------------------------------------------------
1119  // Modal
1120  // ----------------------------------------------------------------
1121  getModalContent() {
1122    const preferencesTitle =
1123      this.config.text?.preferences?.title || 'Customize your cookie preferences';
1124    
1125    const preferencesDescription =
1126      this.config.text?.preferences?.description ||
1127      "<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>";
1128    
1129    // Preferences button
1130    const preferencesButtonLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;
1131
1132    const closeModalButton = `<button class="modal-close"${preferencesButtonLabel ? ` aria-label="${preferencesButtonLabel}"` : ''}>
1133      <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
1134          <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"/>
1135      </svg>
1136    </button>`;
1137    
1138
1139    const cookieTypes = this.config.cookieTypes || [];
1140    const acceptedCookieMap = this.getAcceptedCookies();
1141
1142    // Accept button
1143    const acceptAllButtonText = this.config.text?.banner?.acceptAllButtonText || 'Accept all';
1144    const acceptAllButtonLabel = this.config.text?.banner?.acceptAllButtonAccessibleLabel;
1145    const acceptAllButton = `<button class="preferences-accept-all st-button st-button--primary"${
1146      acceptAllButtonLabel && acceptAllButtonLabel !== acceptAllButtonText 
1147        ? ` aria-label="${acceptAllButtonLabel}"` 
1148        : ''
1149    }>${acceptAllButtonText}</button>`;
1150    
1151    // Reject button
1152    const rejectNonEssentialButtonText = this.config.text?.banner?.rejectNonEssentialButtonText || 'Reject non-essential';
1153    const rejectNonEssentialButtonLabel = this.config.text?.banner?.rejectNonEssentialButtonAccessibleLabel;
1154    const rejectNonEssentialButton = `<button class="preferences-reject-all st-button st-button--primary"${
1155      rejectNonEssentialButtonLabel && rejectNonEssentialButtonLabel !== rejectNonEssentialButtonText 
1156        ? ` aria-label="${rejectNonEssentialButtonLabel}"` 
1157        : ''
1158    }>${rejectNonEssentialButtonText}</button>`;
1159    
1160    // Credit link
1161    const creditLinkText = this.config.text?.preferences?.creditLinkText || '';
1162    const creditLinkAccessibleLabel = this.config.text?.preferences?.creditLinkAccessibleLabel;
1163    const creditLink = `<a href="https://silktide.com/consent-manager" target="_blank" rel="noreferrer"${
1164      creditLinkAccessibleLabel && creditLinkAccessibleLabel !== creditLinkText
1165        ? ` aria-label="${creditLinkAccessibleLabel}"`
1166        : ''
1167    }>${creditLinkText}</a>`;
1168    
1169    
1170
1171    const modalContent = `
1172      <header>
1173        <h1>${preferencesTitle}</h1>                    
1174        ${closeModalButton}
1175      </header>
1176      ${preferencesDescription}
1177      <section id="cookie-preferences">
1178        ${cookieTypes
1179          .map((type) => {
1180            const accepted = acceptedCookieMap[type.id];
1181            let isChecked = false;
1182
1183            // if it's accepted then show as checked
1184            if (accepted) {
1185              isChecked = true;
1186            }
1187
1188            // if nothing has been accepted / rejected yet, then show as checked if the default value is true
1189            if (!accepted && !this.hasSetInitialCookieChoices()) {
1190              isChecked = type.defaultValue;
1191            }
1192
1193            return `
1194            <fieldset>
1195                <legend>${type.name}</legend>
1196                <div class="cookie-type-content">
1197                    <div class="cookie-type-description">${type.description}</div>
1198                    <label class="switch" for="cookies-${type.id}">
1199                        <input type="checkbox" id="cookies-${type.id}" ${
1200              type.required ? 'checked disabled' : isChecked ? 'checked' : ''
1201            } />
1202                        <span class="switch__pill" aria-hidden="true"></span>
1203                        <span class="switch__dot" aria-hidden="true"></span>
1204                        <span class="switch__off" aria-hidden="true">Off</span>
1205                        <span class="switch__on" aria-hidden="true">On</span>
1206                    </label>
1207                </div>
1208            </fieldset>
1209        `;
1210          })
1211          .join('')}
1212      </section>
1213      <footer>
1214        ${acceptAllButton}
1215        ${rejectNonEssentialButton}
1216        ${creditLink}
1217      </footer>
1218    `;
1219
1220    return modalContent;
1221  }
1222
1223  createModal() {
1224    // Create banner element
1225    this.modal = this.createWrapperChild(this.getModalContent(), 'silktide-modal');
1226  }
1227
1228  toggleModal(show) {
1229    if (!this.modal) return;
1230
1231    this.modal.style.display = show ? 'flex' : 'none';
1232
1233    if (show) {
1234      this.showBackdrop();
1235      this.hideCookieIcon();
1236      this.removeBanner();
1237      this.preventBodyScroll();
1238
1239      // Focus the close button
1240      const modalCloseButton = this.modal.querySelector('.modal-close');
1241      modalCloseButton.focus();
1242
1243      // Trigger optional onPreferencesOpen callback
1244      if (typeof this.config.onPreferencesOpen === 'function') {
1245        this.config.onPreferencesOpen();
1246      }
1247
1248      this.updateCheckboxState(false); // read from storage when opening
1249    } else {
1250      // Set that an initial choice was made when closing the modal
1251      this.setInitialCookieChoiceMade();
1252      
1253      // Save current checkbox states to storage
1254      this.updateCheckboxState(true);
1255
1256      this.hideBackdrop();
1257      this.showCookieIcon();
1258      this.allowBodyScroll();
1259
1260      // Trigger optional onPreferencesClose callback
1261      if (typeof this.config.onPreferencesClose === 'function') {
1262        this.config.onPreferencesClose();
1263      }
1264    }
1265  }
1266
1267  // ----------------------------------------------------------------
1268  // Cookie Icon
1269  // ----------------------------------------------------------------
1270  getCookieIconContent() {
1271    return `
1272      <svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
1273          <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" />
1274      </svg>
1275    `;
1276  }
1277
1278  createCookieIcon() {
1279    this.cookieIcon = document.createElement('button');
1280    this.cookieIcon.id = 'silktide-cookie-icon';
1281    this.cookieIcon.title = 'Manage your cookie preferences for this site';
1282    this.cookieIcon.innerHTML = this.getCookieIconContent();
1283
1284    if (this.config.text?.banner?.preferencesButtonAccessibleLabel) {
1285      this.cookieIcon.ariaLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;
1286    }
1287
1288    // Ensure wrapper exists
1289    if (!this.wrapper || !document.body.contains(this.wrapper)) {
1290      this.createWrapper();
1291    }
1292
1293    // Append child to wrapper
1294    this.wrapper.appendChild(this.cookieIcon);
1295
1296    // Add positioning class from config
1297    if (this.cookieIcon && this.config.cookieIcon?.position) {
1298      this.cookieIcon.classList.add(this.config.cookieIcon.position);
1299    }
1300
1301    // Add color scheme class from config
1302    if (this.cookieIcon && this.config.cookieIcon?.colorScheme) {
1303      this.cookieIcon.classList.add(this.config.cookieIcon.colorScheme);
1304    }
1305  }
1306
1307  showCookieIcon() {
1308    if (this.cookieIcon) {
1309      this.cookieIcon.style.display = 'flex';
1310    }
1311  }
1312
1313  hideCookieIcon() {
1314    if (this.cookieIcon) {
1315      this.cookieIcon.style.display = 'none';
1316    }
1317  }
1318
1319  /**
1320   * This runs if the user closes the modal without making a choice for the first time
1321   * We apply the default values and the necessary values as default
1322   */
1323  handleClosedWithNoChoice() {
1324    this.config.cookieTypes.forEach((type) => {
1325      let accepted = true;
1326      // Set localStorage and run accept/reject callbacks
1327      if (type.required == true || type.defaultValue) {
1328        localStorage.setItem(
1329          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,
1330          accepted.toString(),
1331        );
1332      } else {
1333        accepted = false;
1334        localStorage.setItem(
1335          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,
1336          accepted.toString(),
1337        );
1338      }
1339
1340      if (accepted) {
1341        if (typeof type.onAccept === 'function') { type.onAccept(); }
1342      } else {
1343        if (typeof type.onReject === 'function') { type.onReject(); }
1344      }
1345      // set the flag to say that the cookie choice has been made
1346      this.setInitialCookieChoiceMade();
1347      this.updateCheckboxState();
1348    });
1349  }
1350
1351  // ----------------------------------------------------------------
1352  // Focusable Elements
1353  // ----------------------------------------------------------------
1354  getFocusableElements(element) {
1355    return element.querySelectorAll(
1356      'button, a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
1357    );
1358  }
1359
1360  // ----------------------------------------------------------------
1361  // Event Listeners
1362  // ----------------------------------------------------------------
1363  setupEventListeners() {
1364    // Check Banner exists before trying to add event listeners
1365    if (this.banner) {
1366      // Get the buttons
1367      const acceptButton = this.banner.querySelector('.accept-all');
1368      const rejectButton = this.banner.querySelector('.reject-all');
1369      const preferencesButton = this.banner.querySelector('.preferences');
1370
1371      // Add event listeners to the buttons
1372      acceptButton?.addEventListener('click', () => this.handleCookieChoice(true));
1373      rejectButton?.addEventListener('click', () => this.handleCookieChoice(false));
1374      preferencesButton?.addEventListener('click', () => {
1375        this.showBackdrop();
1376        this.toggleModal(true);
1377      });
1378
1379      // Focus Trap
1380      const focusableElements = this.getFocusableElements(this.banner);
1381      const firstFocusableEl = focusableElements[0];
1382      const lastFocusableEl = focusableElements[focusableElements.length - 1];
1383
1384      // Add keydown event listener to handle tab navigation
1385      this.banner.addEventListener('keydown', (e) => {
1386        if (e.key === 'Tab') {
1387          if (e.shiftKey) {
1388            if (document.activeElement === firstFocusableEl) {
1389              lastFocusableEl.focus();
1390              e.preventDefault();
1391            }
1392          } else {
1393            if (document.activeElement === lastFocusableEl) {
1394              firstFocusableEl.focus();
1395              e.preventDefault();
1396            }
1397          }
1398        }
1399      });
1400
1401      // Set initial focus
1402      if (this.config.mode !== 'wizard') {
1403        acceptButton?.focus();
1404      }
1405    }
1406
1407    // Check Modal exists before trying to add event listeners
1408    if (this.modal) {
1409      const closeButton = this.modal.querySelector('.modal-close');
1410      const acceptAllButton = this.modal.querySelector('.preferences-accept-all');
1411      const rejectAllButton = this.modal.querySelector('.preferences-reject-all');
1412
1413      closeButton?.addEventListener('click', () => {
1414        this.toggleModal(false);
1415
1416        const hasMadeFirstChoice = this.hasSetInitialCookieChoices();
1417
1418        if (hasMadeFirstChoice) {
1419          // run through the callbacks based on the current localStorage state
1420          this.runStoredCookiePreferenceCallbacks();
1421        } else {
1422          // handle the case where the user closes without making a choice for the first time
1423          this.handleClosedWithNoChoice();
1424        }
1425      });
1426      acceptAllButton?.addEventListener('click', () => this.handleCookieChoice(true));
1427      rejectAllButton?.addEventListener('click', () => this.handleCookieChoice(false));
1428
1429      // Banner Focus Trap
1430      const focusableElements = this.getFocusableElements(this.modal);
1431      const firstFocusableEl = focusableElements[0];
1432      const lastFocusableEl = focusableElements[focusableElements.length - 1];
1433
1434      this.modal.addEventListener('keydown', (e) => {
1435        if (e.key === 'Tab') {
1436          if (e.shiftKey) {
1437            if (document.activeElement === firstFocusableEl) {
1438              lastFocusableEl.focus();
1439              e.preventDefault();
1440            }
1441          } else {
1442            if (document.activeElement === lastFocusableEl) {
1443              firstFocusableEl.focus();
1444              e.preventDefault();
1445            }
1446          }
1447        }
1448        if (e.key === 'Escape') {
1449          this.toggleModal(false);
1450        }
1451      });
1452
1453      closeButton?.focus();
1454
1455      // Update the checkbox event listeners
1456      const preferencesSection = this.modal.querySelector('#cookie-preferences');
1457      const checkboxes = preferencesSection.querySelectorAll('input[type="checkbox"]');
1458      
1459      checkboxes.forEach(checkbox => {
1460        checkbox.addEventListener('change', (event) => {
1461          const [, cookieId] = event.target.id.split('cookies-');
1462          const isAccepted = event.target.checked;
1463          const previousValue = localStorage.getItem(
1464            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`
1465          ) === 'true';
1466          
1467          // Only proceed if the value has actually changed
1468          if (isAccepted !== previousValue) {
1469            // Find the corresponding cookie type
1470            const cookieType = this.config.cookieTypes.find(type => type.id === cookieId);
1471            
1472            if (cookieType) {
1473              // Update localStorage
1474              localStorage.setItem(
1475                `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,
1476                isAccepted.toString()
1477              );
1478              
1479              // Run the appropriate callback only if the value changed
1480              if (isAccepted && typeof cookieType.onAccept === 'function') {
1481                cookieType.onAccept();
1482              } else if (!isAccepted && typeof cookieType.onReject === 'function') {
1483                cookieType.onReject();
1484              }
1485            }
1486          }
1487        });
1488      });
1489    }
1490
1491    // Check Cookie Icon exists before trying to add event listeners
1492    if (this.cookieIcon) {
1493
1494      this.cookieIcon.addEventListener('click', () => {
1495        // If modal is not found, create it
1496        if (!this.modal) {
1497          this.createModal();
1498          this.toggleModal(true);
1499          this.hideCookieIcon();
1500        }
1501        // If modal is hidden, show it
1502        else if (this.modal.style.display === 'none' || this.modal.style.display === '') {
1503          this.toggleModal(true);
1504          this.hideCookieIcon();
1505        }
1506        // If modal is visible, hide it
1507        else {
1508          this.toggleModal(false);
1509        }
1510      });
1511    }
1512  }
1513
1514  getBannerSuffix() {
1515    if (this.config.bannerSuffix) {
1516      return '_' + this.config.bannerSuffix;
1517    }
1518    return '';
1519  }
1520
1521  preventBodyScroll() {
1522    document.body.style.overflow = 'hidden';
1523    // Prevent iOS Safari scrolling
1524    document.body.style.position = 'fixed';
1525    document.body.style.width = '100%';
1526  }
1527
1528  allowBodyScroll() {
1529    document.body.style.overflow = '';
1530    document.body.style.position = '';
1531    document.body.style.width = '';
1532  }
1533}
1534
1535(function () {
1536  window.silktideCookieBannerManager = {};
1537
1538  let config = {};
1539  let cookieBanner;
1540
1541  function updateCookieBannerConfig(userConfig = {}) {
1542    config = {...config, ...userConfig};
1543
1544    // If cookie banner exists, destroy and recreate it with new config
1545    if (cookieBanner) {
1546      cookieBanner.destroyCookieBanner(); // We'll need to add this method
1547      cookieBanner = null;
1548    }
1549
1550    // Only initialize if document.body exists
1551    if (document.body) {
1552      initCookieBanner();
1553    } else {
1554      // Wait for DOM to be ready
1555      document.addEventListener('DOMContentLoaded', initCookieBanner, {once: true});
1556    }
1557  }
1558
1559  function initCookieBanner() {
1560    if (!cookieBanner) {
1561      cookieBanner = new SilktideCookieBanner(config); // Pass config to the CookieBanner instance
1562    }
1563  }
1564
1565  function injectScript(url, loadOption) {
1566    // Check if script with this URL already exists
1567    const existingScript = document.querySelector(`script[src="${url}"]`);
1568    if (existingScript) {
1569      return; // Script already exists, don't add it again
1570    }
1571
1572    const script = document.createElement('script');
1573    script.src = url;
1574
1575    // Apply the async or defer attribute based on the loadOption parameter
1576    if (loadOption === 'async') {
1577      script.async = true;
1578    } else if (loadOption === 'defer') {
1579      script.defer = true;
1580    }
1581
1582    document.head.appendChild(script);
1583  }
1584
1585  window.silktideCookieBannerManager.initCookieBanner = initCookieBanner;
1586  window.silktideCookieBannerManager.updateCookieBannerConfig = updateCookieBannerConfig;
1587  window.silktideCookieBannerManager.injectScript = injectScript;
1588
1589  if (document.readyState === 'loading') {
1590    document.addEventListener('DOMContentLoaded', initCookieBanner, {once: true});
1591  } else {
1592    initCookieBanner();
1593  }
1594})();
1595</script>
vendor: 1 bytes, line 1595
1595
1596<script>
1597silktideCookieBannerManager.updateCookieBannerConfig({
1598  background: {
1599    showBackground: true
1600  },
1601  cookieIcon: {
1602    position: "bottomLeft"
1603  },
1604  cookieTypes: [
1605    {
1606      id: "necessary",
1607      name: "Necessary",
1608      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>",
1609      required: true,
1610      onAccept: function() {
1611        //console.log('Add logic for the required Necessary here');
1612        //Remaining cookies
1613      }
1614    },
1615    {
1616  id: "analytics",
1617  name: "Analytics",
1618  description: "<p>These cookies help us improve the site by tracking which pages are most popular and how visitors move around the site.</p>",
1619  defaultValue: true,
1620  onAccept: function() {
1621    gtag('consent', 'update', {
1622      analytics_storage: 'granted',
1623    });
1624
1625    if (window.google_tag_manager) {
1626      Object.keys(google_tag_manager).forEach(id => {
1627        if (id.startsWith('G-') || id.startsWith('GT-')) {
1628          gtag('config', id, { 'update_config': true });
1629        }
1630      });
1631    }
1632
1633    window.loadClarity();
1634    window.identifyClarityUser();
1635
1636    dataLayer.push({
1637      event: 'consent_accepted_analytics',
1638    });
1639  },
1640  onReject: function() {
1641    gtag('consent', 'update', {
1642      analytics_storage: 'denied',
1643    });
1644  }
1645},
1646  ],
1647  text: {
1648    banner: {
1649      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>",
1650      acceptAllButtonText: "Accept all",
1651      acceptAllButtonAccessibleLabel: "Accept all cookies",
1652      rejectNonEssentialButtonText: "Reject non-essential",
1653      rejectNonEssentialButtonAccessibleLabel: "Reject non-essential",
1654      preferencesButtonText: "Preferences",
1655      preferencesButtonAccessibleLabel: "Toggle preferences"
1656    },
1657    preferences: {
1658      title: "Customize your cookie preferences",
1659      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>",
1660      creditLinkText: "",
1661      creditLinkAccessibleLabel: ""
1662    }
1663  },
1664  position: {
1665    banner: "bottomLeft"
1666  }
1667});
1668</script>
vendor: 1 bytes, line 1668
1668
1669<script>
1670(function () {
1671  // Normalize trailing slash
1672  var path = location.pathname.replace(/\/+$/, '/') || '/';
1673
1674  if (path === '/live-content/tutorials/') {
1675    var head = document.head || document.getElementsByTagName('head')[0];
1676
1677    function addMeta(name, content) {
1678      var m = document.createElement('meta');
1679      m.setAttribute('name', name);
1680      m.setAttribute('content', content);
1681      head.insertBefore(m, head.firstChild);
1682    }
1683
1684    addMeta('robots', 'noindex, nofollow, noarchive');
1685    addMeta('googlebot', 'noindex, nofollow, noarchive');
1686  }
1687})();
1688</script>
vendor: 1 bytes, line 1688
1688
1689<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
1689
1690<link rel="stylesheet" type="text/css" href="https://media.myteamscoop.com//css/swiper/swiper-bundle.css" />
1691
1692<link rel="stylesheet" href="https://use.typekit.net/poc3djh.css">
1693
1694<style>
1695ul li {
1696   line-height: 1.5 !important;
1697   margin-bottom: 10px;
1698}
1699
1700.itemCategory {
1701   margin-bottom: 5px;
1702   color: #666666;
1703   font-size: 14px;
1704   font-weight: bold;
1705}
1706
1707[thumbslider] {
1708	margin-bottom: 40px;
1709}
1710
1711video {
1712    -webkit-mask-image: -webkit-radial-gradient(white, black);
1713    -webkit-backface-visibility: hidden;
1714    -moz-backface-visibility: hidden;
1715}
1716
1717.boldLink {font-weight: 900; text-decoration: underline !important;}
1718ul.overlayListDark,
1719ul.overlayList {
1720	list-style-type: none;
1721	position: relative;
1722	padding: 20px 0px;
1723	text-align: left;
1724	margin: 0;
1725}
1726
1727ul.overlayListDark {
1728	background: rgba(0,0,0,.5);
1729	border-radius: 10px;
1730	color: #ffffff;
1731	padding: 30px;
1732}
1733
1734ul.overlayListDark li,
1735ul.overlayList li {
1736	margin-bottom: 10px;
1737	position: relative;
1738	padding-left: 30px;
1739	font-size: 18px;
1740}
1741
1742ul.overlayListDark li:before,
1743ul.overlayList li:before {
1744	content: "\f00c";
1745	font-family: 'Font Awesome 5 Pro Solid';
1746	font-size: 18px;
1747	color: var(--pres-yellow);
1748	position: absolute;
1749	left: 0px;
1750}
1751
1752.navigation_menu_widget .mainNav {
1753   display: block;
1754}
1755
1756.menuDropBg {
1757   display: none;
1758}
1759
1760.menuDropBg.menuDropBgShow {
1761   display: block;
1762}
1763
1764:root {
1765	--pres-dark-gray: #707070;
1766	--pres-light-gray: #f2f3f5;
1767	--pres-yellow: #ffe000;
1768}
1769
1770p {
1771   line-height: 1.5;
1772}
1773
1774.largeHeading,
1775.largeHeadingLeft {
1776   font-size: 48px;
1777   font-weight: 900;
1778   letter-spacing: -.025em;
1779   text-align: center;
1780   max-width: 1170px;
1781   margin: auto;
1782}
1783
1784.largeHeadingLeft {
1785   text-align: left;
1786}
1787
1788.smallHeading {
1789   font-size: 32px;
1790   font-weight: 900;
1791   letter-spacing: -.025em;
1792}
1793
1794.menuDropBg, .menuDropBgShow {
1795   z-index: 152;
1796}
1797
1798body .mts_cc_button {
1799   border-radius: 30px !important;
1800   padding: 0px 20px !important;
1801}
1802
1803.custom_header_widget .navigationContainer {
1804      height: 110px;
1805}
1806
1807#logo, #logoA {
1808      vertical-align: top;
1809}
1810
1811.custom_header_widget .dropNavBtn {
1812   width: 30px;
1813   height: 30px;
1814   line-height: 30px;
1815}
1816
1817/*VERTICAL SLIDER INFO*/
1818.toolsContentCtr {
1819	position: relative;
1820	clear: both;
1821	width: 100%;
1822	text-align: left;
1823	margin: 40px auto 0px auto;
1824	max-width: 768px;
1825}
1826
1827.tcItem {
1828   position: absolute;
1829   width: 100%;
1830   top: 0px;
1831   left: 0px;
1832   transform: translateY(100%);
1833   opacity: 0;
1834   transition: transform 500ms, opacity 250ms;
1835   -webkit-transition: transform 500ms, opacity 250ms;
1836   -moz-transition: transform 500ms, opacity 250ms;
1837   display: flex;
1838   flex-direction: column;
1839   gap: 10px;
1840}
1841
1842.tcShow {
1843   opacity: 1;
1844   transform: translateY(0px);
1845}
1846
1847.tcDrop {
1848   background: #fee000;
1849   color: #ffffff;
1850   border-radius: 5px;
1851   padding: 0px 10px;
1852   line-height: 30px;
1853   text-align: center;
1854   display: inline-block;
1855   margin: 10px 0px;
1856   cursor: pointer;
1857}
1858
1859.tcLeft {
1860	display: inline-block;
1861	vertical-align: top;
1862	clear: both;
1863	width: 100%;
1864}
1865
1866.tcHeader {
1867	margin: 0px 0px 10px 0px;
1868	line-height: 40px;
1869}
1870
1871.tcCat {
1872   float: left;
1873   margin-right: 5px;
1874   margin-bottom: 5px;
1875   text-transform: capitalize;
1876   font-size: 14px;
1877    padding: 10px;
1878   background: #fee000;
1879   color: #222222;
1880   border-radius: 5px;
1881   text-align: center;
1882   cursor: pointer;
1883}
1884
1885.tcRight {
1886	display: inline-block;
1887	vertical-align: top;	
1888	position: relative;
1889	clear: both;
1890	width: 100%;
1891	z-index: 1;
1892	margin-top: 20px;
1893	overflow: hidden;
1894}
1895
1896.tcItemIcon {
1897   width: 52px;
1898   height: 52px;
1899   color: #fee000;
1900   text-align: center;
1901   line-height: 52px;
1902   font-size: 52px;
1903}
1904
1905.tcItemLabel {
1906   font-weight: 700;
1907   float: left;
1908   clear: both;
1909   width: 100%;
1910   margin: 0px 0px 0px 0px;
1911   font-size: 24px;
1912   text-align: left;
1913}
1914
1915.tcLeft .tcItemLabel {
1916   margin-bottom: 10px;
1917}
1918
1919.tcItemText {
1920   line-height: 25px;
1921   float: left;
1922   clear: both;
1923   width: 100%;
1924}
1925
1926.downArrowLine {
1927	margin: 0px auto;
1928	display: block;
1929}
1930
1931@media (min-width: 768px) {
1932	.largeHeading {
1933		padding: 0px;
1934	}
1935
1936	.tcLeft {
1937		width: 196px;
1938		border-right: solid 1px #bbbbbb;
1939		margin-right: 40px;
1940	}
1941
1942	.tcCat {
1943		float: left;
1944		clear: both;
1945		width: 100%;
1946		color: #222222;
1947		background: unset;
1948		text-align: left;
1949		font-size: .9em;
1950		padding: 10px 0px 10px 15px;
1951		position: relative;
1952		margin-right: 0px;
1953		transition: background 250ms;
1954		border-radius: 0px;
1955	}
1956
1957	.tcCat:hover {
1958		background: #eeeeee;
1959	}
1960
1961	.tcBorder {
1962		height: 0px;
1963		width: 4px;
1964		background: #fee000;
1965		position: absolute;
1966		left: 0px;
1967		top: 50%;
1968		transform: translateY(-50%);
1969		transition: height 250ms;
1970	}
1971
1972	.tcbShow {
1973		height: 100%;
1974	}
1975
1976	.tcRight {
1977		clear: none;
1978		margin-top: 0px;
1979		width: calc(100% - 240px);
1980	}
1981}
1982
1983@media all and (min-width: 1024px) {
1984   .largeHeading {
1985      font-size: 72px;
1986   }
1987
1988   .custom_header_widget .navigationContainer {
1989      height: 70px;
1990      padding: 0px;
1991      border: none;
1992      outline: solid 10px #fee000;
1993   }
1994
1995   .custom_header_widget .navigationContainer .innerHeadCtr {
1996      padding: 0px 0px 0px 20px;
1997   }
1998
1999   .custom_header_widget .navigation_menu_widget {
2000      padding: 20px 0px 20px 0px;
2001   }
2002
2003   .custom_header_widget .section_navigation_widget {
2004      left: 0px;
2005      top: 100% !important;
2006      border-top: solid 10px #fee000;
2007   }
2008
2009   .custom_header_widget .searchBar {
2010      padding: 19px;
2011   }
2012}
2013</style>
2014
2015<style>
2016    #register #loginContainer {border: solid 1px #dddddd; margin: 0px 0px 50px 0px; border-radius: 3px; }
2017    i.toggleDemo {display: none !important;}
2018   .quoteToggleClose, .demoToggleClose {margin-left: 5px;}
2019   [data-holder] {display: none !important;}
2020   .navigation_menu_widget .mainNav {display: block;}
2021   li:before {font-family: "font awesome 5 pro solid";}
2022   .atDescription {overflow-y: auto;}
2023   .button, .mts_cc_button {display: inline-block;}
2024   @media all and (min-width: 768px) {
2025      .atDescription {padding: 20px !important;}
2026   }
2027</style>
2028
2029<!--ZOHO WEB FORMS-->
2030<!-- Do not remove this code. -->
2031<style>
2032   html,
2033   body {
2034   margin: 0px;
2035   }
2036   .toggleForm {
2037   position: fixed;
2038   bottom: 20px;
2039   right: 78px;
2040   cursor: pointer;
2041   border-radius: 50%;
2042   background: #fee000;
2043   color: #333;
2044   text-align: center;
2045   width: 48px;
2046   height: 48px;
2047   line-height: 48px;
2048   display: inline-block;
2049   vertical-align: baseline;
2050   padding: 0 10px;
2051   text-transform: uppercase;
2052   transition: transform 250ms;
2053   z-index: 12;
2054   font-size:24px;
2055   }
2056   #demoToggle {
2057   right: 20px;
2058   }
2059   .zcwf_lblLeft {
2060   width: 100%;
2061   padding: 20px;
2062   margin: 0 auto;
2063   box-sizing: border-box;
2064   }
2065   .zcwf_lblLeft * {
2066   box-sizing: border-box;
2067   }
2068   .crmWebToEntityForm {
2069   z-index: 12;
2070   background: #fff;
2071   border-top: solid 5px #fee000;
2072   box-shadow: 0 0 1px #444;
2073   text-align: left;
2074   overflow-y: auto;   
2075   background: #ffffff;
2076   max-width: 480px;           
2077   }
2078   .crmWebToEntityForm * {
2079   direction: ltr;
2080   }
2081   .zcwf_lblLeft .zcwf_title {
2082   word-wrap: break-word;
2083   padding: 0px;
2084   font-weight: bold;
2085   font-size: 1.5em;
2086   }
2087   .zcwf_lblLeft .zcwf_col_fld input[type=text] {
2088   width: 100%;
2089   }
2090   .zcwf_lblLeft .zcwf_col_fld textarea {
2091   width: 100%;
2092   min-width: 100%;
2093   max-width: 100%;
2094   }
2095   .zcwf_lblLeft .zcwf_col_lab {
2096   width: 100%;
2097   word-break: break-word;
2098   display: inline-block;
2099   font-size: 14px;
2100   }
2101   .zcwf_lblLeft .zcwf_col_fld {
2102   float: left;
2103   width: 100%;
2104   position: relative;
2105   }
2106   .cap_img, .cap_reload {
2107   display: inline-block;
2108   vertical-align: middle;
2109   margin-right: 20px;
2110   }
2111   .zcwf_lblLeft .zcwf_privacy {
2112   padding: 6px;
2113   }
2114   .zcwf_lblLeft .wfrm_fld_dpNn {
2115   display: none;
2116   }
2117   .dIB {
2118   display: inline-block;
2119   }
2120   .zcwf_lblLeft .zcwf_col_fld_slt {
2121   width: 60%;
2122   border: 1px solid #ccc;
2123   background: #fff;
2124   border-radius: 4px;
2125   font-size: 12px;
2126   float: left;
2127   resize: vertical;
2128   }
2129   .zcwf_lblLeft .zcwf_col_help {
2130   float: left;
2131   margin-left: 7px;
2132   font-size: 12px;
2133   max-width: 35%;
2134   word-break: break-word;
2135   }
2136   .zcwf_lblLeft .zcwf_help_icon {
2137   cursor: pointer;
2138   width: 16px;
2139   height: 16px;
2140   display: inline-block;
2141   background: #fff;
2142   border: 1px solid #ccc;
2143   color: #ccc;
2144   text-align: center;
2145   font-size: 11px;
2146   line-height: 16px;
2147   font-weight: bold;
2148   border-radius: 50%;
2149   }
2150   .zcwf_lblLeft .zcwf_row {
2151   margin: 0px 0px 5px 0px;
2152   }
2153   .zcwf_lblLeft .formsubmit {
2154   margin-right: 5px;
2155   cursor: pointer;
2156   color: #333;
2157   font-size: 12px;
2158   }
2159   .zcwf_lblLeft .zcwf_privacy_txt {
2160   color: rgb(0, 0, 0);
2161   font-size: 12px;
2162   display: inline-block;
2163   vertical-align: top;
2164   color: #333;
2165   padding-top: 2px;
2166   margin-left: 6px;
2167   }
2168   .zcwf_lblLeft .zcwf_button {
2169   font-family: unset;
2170   font-size: unset;
2171   margin-bottom:10px;
2172   }
2173   .zcwf_lblLeft .zcwf_tooltip_over {
2174   position: relative;
2175   }
2176   .zcwf_lblLeft .zcwf_tooltip_ctn {
2177   position: absolute;
2178   background: #dedede;
2179   padding: 3px 6px;
2180   top: 3px;
2181   border-radius: 4px;
2182   word-break: break-all;
2183   min-width: 50px;
2184   max-width: 150px;
2185   color: #333;
2186   }
2187   .zcwf_lblLeft .zcwf_ckbox {
2188   float: left;
2189   }
2190   .zcwf_lblLeft .zcwf_file {
2191   width: 55%;
2192   box-sizing: border-box;
2193   float: left;
2194   }
2195   @media all and (max-width: 768px) {
2196   .zcwf_lblLeft .zcwf_col_lab,
2197   .zcwf_lblLeft .zcwf_col_fld {
2198   width: auto;
2199   float: none !important;
2200   }
2201   .zcwf_lblLeft .zcwf_col_help {
2202   width: 40%;
2203   }
2204   }
2205</style>
2206
2207
2208<script type="text/javascript">
2209if(window.location.href.indexOf("/layout-admin/") < 0 && window.location.href.indexOf("/admin/") < 0 && window.location.href.indexOf("/news/editor/") < 0) {
2210    var demoTag = '<a href="/live-content/request demo" id="demoToggle" class="far fa-envelope-open-text toggleForm" title="Request Demo" target="_blank"></a>';
2211    var body = $("body");
2212    $(demoTag).appendTo(body);
2213}
2214
2215//BUTTON CLICK TO TOGGLE QUOTE FORMS
2216$(document).one("widgetsloaded", function() {
2217    var quoteForm = $(".quoteForm");
2218    var demoForm = $(".demoForm")
2219    var formToggle = $("#quoteToggle, #pageDemo_2, .quoteToggleClose, #quoteToggleCorner");
2220    var demoToggle = $("#demoToggle, #pageDemo_1, .demoToggleClose");
2221
2222    formToggle.on("click", function () {
2223        var height = quoteForm.outerHeight();
2224        quoteForm.toggleClass("showEfw");
2225    });
2226});
2227</script>
2227
2228
2229<!-- Google Tag Manager -->
vendor: 64 bytes, lines 2229-2230
2229
2230<script async src="https://www.googletagmanager.com/gtag/js?id=
2230AW-1024102851
vendor: 12 bytes, line 2230
2230"></script>
2231<script>
2232  
vendor: 134 bytes, lines 2232-2236
2232window.dataLayer = window.dataLayer || [];
2233  function gtag(){dataLayer.push(arguments);}
2234  gtag('js', new Date());
2235
2236  gtag('config', '
2236AW-1024102851
vendor: 4 bytes, line 2236
2236');
2237</script>
2237
2238
2239<!-- Event snippet for Request Demo conversion page
2240In your html page, add the snippet and call gtag_report_conversion when someone clicks on the chosen link or button. -->
2241<script>
2242function gtag_report_conversion(url) {
2243  var callback = function () {
2244    if (typeof(url) != 'undefined') {
2245      window.location = url;
2246    }
2247  };
2248  gtag('event', 'conversion', {
2249      'send_to': 'AW-1024102851/1w4NCLi2urUDEMOjqugD',
2250      'event_callback': callback
2251  });
2252  return false;
2253}
2254</script>
2254
2255
2256
2257<script>
2258$(document).one("widgetsloaded", function() {
2259   var detach = $(".followCtr").detach();
2260   detach.prependTo(".section_navigation_widget");
2261});
2262</script>
2262
2263
2264
2265
2266   
2267   <!-- Facebook Metadata -->
2268   
2269   <meta property="og:image" content="http://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/810/40810_1" />
2270   <meta property="og:image:secure_url" content="https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/810/40810_1" />
2271   <meta property="og:image:width" content="500" />
2272   <meta property="og:image:height" content="261" />
2273   <meta property="og:type" content="article" />
2274   <meta property="fb:app_id" content="309214499646406" />
2275   <meta property="og:url" content="https://presteligence.com/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/" />
2276   <meta property="og:title" content="How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond." />
2277   <meta property="og:description" content="Carpenter Media Group&#39;s implementation of Dynamic Production has cut production timelines by 60 to 80 minutes ahead of deadline. The platform allows existing staff to take on smaller publications previously outsourced to external designers, creating new revenue while reducing end-of-day pressure on production teams." />
2278
2279   <!-- Twitter Metadata -->
2280   
2281   <meta name="twitter:card" content="summary_large_image" />
2282   <meta name="twitter:site" content="@" />
2283   <meta name="twitter:title" content="How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond." />
2284   <meta name="twitter:description" content="Carpenter Media Group&#39;s implementation of Dynamic Production has cut production timelines by 60 to 80 minutes ahead of deadline. The platform allows existing staff to take on smaller publications previously outsourced to external designers, creating new revenue while reducing end-of-day pressure on production teams." />
2285   <meta name="twitter:image" content="https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/810/40810_1" />
2286   <meta name="twitter:image:alt" content="" />
2287   
2288   
2289   <!-- SEO Metadata -->
2290   <meta name="description" content="Carpenter Media Group's implementation of Dynamic Production has cut production timelines by 60 to 80 minutes ahead of deadline. The platform allows existing staff to take on smaller publications previously outsourced to external designers, creating new revenue while reducing end-of-day pressure on production teams." />
2291   <meta name="keywords" content="multi-platform publishing strategy, content distribution workflow, editorial team efficiency, local newspaper production" />
2292   <meta name="robots" content="index, follow">
2293   <link rel="canonical" href="https://presteligence.com/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/" />
2294   
2295   <!-- Google+ Metadata -->
2296   <meta itemprop="name" content="How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond." />
2297   <meta itemprop="description" content="Carpenter Media Group's implementation of Dynamic Production has cut production timelines by 60 to 80 minutes ahead of deadline. The platform allows existing staff to take on smaller publications previously outsourced to external designers, creating new revenue while reducing end-of-day pressure on production teams.">
2298   <meta itemprop="image" content="https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/810/40810_1">
2299   
2300
2301
2302   
2303   <link rel="shortcut icon" href="https://media.myteamscoop.com/images/custom/24/favicon.ico" />
2304   
2305      <link rel="stylesheet" type="text/css" href="https://media.myteamscoop.com/css/?custom=true&pid=24" />
2306   
2307   <link rel="stylesheet" type="text/css" href="https://media.myteamscoop.com/css/oneColumn.css?v=1.14.5.35260" />
2308   <link rel="Stylesheet" type="text/css" href="https://media.myteamscoop.com/css/?v=1.14.5.35260&pid=24" />
2309
2310   
2310<script type="text/javascript">
2311      _MTS_cssList.push("css/jQueryExtensions/jquery-ui.css", "css/popUpDialog.css");
2312      _MTS_jsList.push("js/signin.js", "js/popUpDialog.js", "js/oneCol.js");
2313      var _timeout = 1140000;
2314      var _sessionTimeout = 1200000;
2315      var __redirectTo = "/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/";
2316      var _COMMON_isTablet = false;
2317      var _encodedPathAndQuery = "%2fnews%2f250922%2fhow-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond%2f",
2318         _MTS_SEOALT = "How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.",
2319      _homePageUrl = "/";
2320   </script>
2320
2321    
2322   <!-- structured article data -->
2323   
2323<script type="application/ld+json">
2324      {
2325  "@context": "https://schema.org",
2326  "@type": "NewsArticle",
2327  "headline": "How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.",
2328  "image": [
2329    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/810/40810_1",
2330    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/808/40808_1",
2331    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/809/40809_1",
2332    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/811/40811_1",
2333    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/812/40812_1",
2334    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/813/40813_1",
2335    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/815/40815_1",
2336    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/816/40816_1",
2337    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/817/40817_1",
2338    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/818/40818_1",
2339    "https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence/0/0/0/0/40/819/40819_1"
2340  ],
2341  "datePublished": "2026-09-22T14:20:00-05:00",
2342  "author": {
2343    "@type": "Person",
2344    "name": "",
2345    "url": ""
2346  },
2347  "description": "Carpenter Media Group's implementation of Dynamic Production has cut production timelines by 60 to 80 minutes ahead of deadline. The platform allows existing staff to take on smaller publications previously outsourced to external designers, creating new revenue while reducing end-of-day pressure on production teams.",
2348  "articleBody": "\n\n\n\n\n\n\nWhen Carpenter Media Group (CMG) began evaluating its print production workflow, they determined that streamlining editorial processes and systems across the group was a primary goal.&nbsp; The company wanted a more consistent way to produce newspapers for their growing portfolio of publications while making life easier for local editors and production teams.\nDownload Carpenter Case Study Summary\nTo accomplish this, Carpenter Media Group partnered with Presteligence to implement Dynamic Production, Presteligence's automated page building platform including its content management system. They determined The Daily News (Bowling, Kentucky) and nine other newspapers spanning Kentucky, Ohio, and Tennessee would be the first to deploy.\nBefore anyone started building pages in the new system; however, Carpenter Media Group focused on something more important: establishing common standards.\nBuilding the Framework\n\n\n\n\n&nbsp;\n\n&nbsp;\n\n\n\n\nOne of the first steps of this project for CMG was to create a unified design approach that could be adapted across the group's diverse portfolio of newspapers. Representatives from editorial, production, and corporate teams worked together to standardize page templates, typography, section fronts, and other design elements while still accommodating the unique characteristics of individual publications, including both broadsheet and tabloid formats. The effort required significant planning upfront, but it simplified future deployments, streamlined production, and provided greater consistency across publications.\nAfter these standards were finalized, Presteligence converted the master files into Dynamic Production page templates and story templates, utilizing their requested paragraph styles and fonts.&nbsp;\nThe planning invested during this phase would ultimately pay dividends throughout the rollout and beyond, creating a scalable foundation for replication across regions.\nLearning the System in Real Time\n\n\n\n\n\n\n\nEvery successful implementation has champions, and for the initial rollout, that champion was Joe Imel, Regional Publisher of the Central Kentucky group.\nAs a hands-on learner, Joe embraced the opportunity to work directly with the system and help refine workflows that best fit his team's editorial process, while keeping in mind best practices for the entire organization. Presteligence worked alongside the group through weekly implementation meetings, regular training sessions, and day-to-day support whenever questions arose.\nTogether, the teams developed a workflow that felt natural to editors and designers.\nStories move through an 'Edited' folder before advancing to a 'Ready for Print' folder, giving editors clear visibility and control of budgeting content. Once stories are placed on pages, automation moves them into archive folders, keeping active workspaces clean and organized without requiring manual maintenance.\nAs this workflow progressed, the transition accelerated dramatically. From that point forward, Joe and his team embraced the system with confidence.\nWorking Smarter, Not Harder\nToday, Joe's group regularly completes production ahead of deadline. What once required significant manual effort has become a streamlined production workflow that allows editorial teams to spend less time building pages and more time producing quality journalism.\n\n\"We are building pages faster, beating old deadlines by 60-80 minutes.\"\n-Joe Imel, Regional Publisher, Central Kentucky Group&nbsp;\n\nSince implementing Dynamic Production, Carpenter Media Group has transformed the way its production teams operate. The results were immediate and measurable:\n\nDeadlines are no longer a daily challenge. Publications are consistently completed 60&ndash;80 minutes ahead of schedule, giving production teams more flexibility and significantly reducing end-of-day pressure.\nExisting staff have become a growth opportunity. Rather than adding designers, Carpenter Media Group has leveraged its current production team to take on smaller newsp
2348apers that previously outsourced page design to a higher-cost provider. This has created a new revenue stream while maximizing existing resources.\nTraining and scaling have become dramatically easier. With Dynamic Production integrated into the production workflow, even designers with no prior newspaper experience can quickly become productive. The intuitive platform enables teams to collaborate seamlessly and produce high-quality pages while consistently meeting—and often exceeding—production deadlines.\n\nWhile the measurable improvements are significant, perhaps the greatest benefit has been giving newsroom staff more time to focus on journalism instead of repetitive production tasks.\nOne Story. One Workflow. Multiple Platforms.\n\n\n\n\n\n\nCMS output to Print and Wordpress\n\n\n\nAs the implementation progressed, Carpenter Media Group identified another opportunity to simplify operations.\nHistorically, editorial staff often published stories separately for print and then copied the same content into their websites—a repetitive process that introduced unnecessary duplication.\nTo eliminate that extra work, Presteligence developed a custom WordPress integration that allows content to originate entirely within the Presteligence CMS and export it for web.\nStories are automatically delivered to the appropriate publication websites based on categories, tags, and publication assignments, eliminating duplicate entry while ensuring each site maintains its unique organizational structure. Although Carpenter Media Group manages its websites centrally, individual publications retain the flexibility to organize content in ways that best serve their readers.&nbsp;\nThe result is a single publishing workflow that supports both print and digital operations.\nDesigned for Collaboration\n\n\n\n\n&nbsp;\n\n\n\n\nAs more publications prepared to join the platform, another opportunity emerged.\nOriginally, all publications shared a common portal. As adoption expanded, Presteligence worked with CMG to organize publications into regional portals, allowing newsroom staff to more easily share stories and collaborate with the publications they work with most frequently.\nCorporate administrators continue to maintain organization-wide access, providing flexibility to share content across all publications whenever needed.\nThis balance between regional collaboration and centralized oversight has become an important component of Carpenter Media Group's long-term publishing strategy.&nbsp;\nBuilding Momentum\nThe success of the Central Kentucky rollout quickly demonstrated that the model could scale.\nFollowing the initial implementation, Carpenter Media Group expanded Dynamic Production to an additional ten newspapers in Oregon. &nbsp;Eighty Canadian publications represent another significant milestone with all of these papers transitioning within a 30-day window.&nbsp; &nbsp;\nEach rollout benefits from the lessons learned during previous implementations, making every deployment more efficient than the last.\nA Partnership Built for Growth\nLarge-scale implementations are rarely about software alone.\nThey require thoughtful planning, open communication, and a willingness to adapt as organizations evolve. Throughout the implementation, Presteligence and Carpenter Media Group worked side by side to refine workflows, answer questions, and ensure the platform aligned with the needs of editorial, production, and corporate teams alike.\n\n\"Large-scale implementations are about much more than software—they're about people, processes, and establishing standards that can support long-term growth. Presteligence partnered with us throughout that journey, and together we've built a publishing environment that's more efficient today and well-positioned for the continued expansion of Carpenter Media Group.\"\n-Lisa Griffin, Chief Technology Officer,&nbsp;Carpenter Media Group\n\nTogether, the organizations have created more than an automated production workflow. They have built a scalable publishing platform capable of supporting continued growth across Carpenter Media Group's expanding portfolio of publications.\nLooking Ahead\nWhat began with ten newspapers in Kentucky has become the blueprint for an enterprise-wide transformation.\nAs additional regions come online and new publications join the platform, Carpe
2348nter Media Group continues to build upon a standardized workflow that simplifies production, streamlines digital publishing, and gives newsroom staff more time to focus on creating the local journalism their communities depend on.\nFor Presteligence, the project represents more than a successful implementation. It demonstrates what is possible when technology is paired with collaboration, thoughtful planning, and a shared commitment to continuous improvement.\nView more:\nDynamic Production CMS Request Demo",
2349  "isAccessibleForFree": true,
2350  "hasPart": {
2351    "@type": "WebPageElement",
2352    "isAccessibleForFree": true,
2353    "cssSelector": ".storyWrapper"
2354  },
2355  "publisher": {
2356    "@type": "Organization",
2357    "name": "Presteligence",
2358    "logo": {
2359      "@type": "ImageObject",
2360      "url": "https://media.myteamscoop.com/images/custom/24/logo.png"
2361    }
2362  }
2363}
2364   </script>
2364
2365
2366   
2366<script type="text/javascript">
2367      _returnPageLink = "/";
2368      
2369      var _isTablet = _COMMON_isTablet;
2370      var _portalId = 24;
2371   </script>
2371
2372
2373   
2374
2375<title>
2376	How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond. | Presteligence
2377</title><meta name="description" content="Carpenter Media Group&#39;s implementation of Dynamic Production has cut production timelines by 60 to 80 minutes ahead of deadline. The platform allows existing staff to take on smaller publications previously outsourced to external designers, creating new revenue while reducing end-of-day pressure on production teams." /></head>
2378
2379   
2380<body >
2381
2382   <div class="sitewideUserAlert">
2383      <p id="userAlertMessage"></p>
2384      <div class="sitewideUserAlertButtons">
2385         <button id="hideSiteWide">Okay</button>
2386         <button id="closeSiteWide">Close and Never Show Again</button>
2387      </div>
2388   </div>
2389   
2390   
2390<script>window.$zoho=window.$zoho || {};$zoho.salesiq=$zoho.salesiq||{ready:function(){}}</script>
2390<script id="zsiqscript" src="
2391https://salesiq.zohopublic.com/widget?wc=siq4da4a189f7a5291071a5fc131ccbfb3bf8e329825be07d67de56e6e36fdfd5f3"
2392defer></script>
2392
2393
2394
2395<div class="solutionsNav">
2396   <div class="followCtr group">
2397      <a class="navHomeLink" href="/"><i class="fas fa-home"></i></a>
2398      <i id="twitterConnect" class="fab fa-twitter appIcons mainItem"></i>
2399      <i id="facebookConnect" class="fab fa-facebook-f appIcons mainItem"></i>
2400   </div>
2401   <div class="solNavHeading">solutions <a href="/live-content/solutions" class="mts_cc_text viewAll">View All</a></div>
2402   <i class="fas fa-times solNavClose"></i>
2403   <div class="solCol">
2404      <img class="solutionIcon" src="https://5eae8a408f205e9a3b5c-a40225aaada983bb85dafa9064686193.ssl.cf1.rackcdn.com/0/0/0/0/0/173/173_original" alt=""/>
2405      <a class="mainNavItem" href="/live-content/myNews">my news 360</a>
2406      <a class="mainNavItem indent" href="/live-content/eEdition">e-edition</a>
2407      <a class="mainNavItem indent" href="/live-content/apps">apps</a>
2408      <a class="mainNavItem indent" href="/live-content/webcms">content management</a>
2409      <a class="mainNavItem indent" href="/live-content/editorial system">editorial</a>
2410      <a class="mainNavItem indent" href="/live-content/automated page layout">automated page layout</a>
2411      <a class="mainNavItem indent" href="/live-content/website hosting">website hosting</a>
2412   </div>
2413   <div class="solCol">
2414      <img class="solutionIcon" src="https://5eae8a408f205e9a3b5c-a40225aaada983bb85dafa9064686193.ssl.cf1.rackcdn.com/0/0/0/0/0/174/174_original" alt=""/>
2415      <a class="mainNavItem" href="/live-content/myTeamScoop">my team scoop</a>
2416      <a class="mainNavItem indent" href="/live-content/myTeamScoop">high school sports</a>
2417   </div>
2418   <div class="solCol">
2419      <img class="solutionIcon" src="https://5eae8a408f205e9a3b5c-a40225aaada983bb85dafa9064686193.ssl.cf1.rackcdn.com/0/0/0/0/0/172/172_original" alt=""/>
2420      <a class="mainNavItem" href="/live-content/nxt cloud">newsxtreme</a>
2421      <a class="mainNavItem indent" href="/live-content/nxt cloud">prepress workflow</a>
2422      <a class="mainNavItem indent" href="/live-content/commercial portal">commercial portal</a>
2423      <a class="mainNavItem indent" href="/live-content/ink optimization">ink optimization</a>
2424      <a class="mainNavItem indent" href="/live-content/xtreme inking">ink presetting</a>
2425      <a class="mainNavItem indent" href="/live-content/pdf corrector">pdf corrector</a>
2426      <a class="mainNavItem indent" href="/live-content/black magic">color calibrated proofing</a>
2427   </div>
2428   <div class="solCol">
2429      <img class="solutionIcon" src="https://5eae8a408f205e9a3b5c-a40225aaada983bb85dafa9064686193.ssl.cf1.rackcdn.com/0/0/0/0/0/171/171_original" alt=""/>
2430      <a class="mainNavItem" href="/live-content/e-tearsheets">adinfinitum</a>
2431      <a class="mainNavItem indent" href="/live-content/e-tearsheets">e-tearsheets</a>
2432   </div>
2433</div>
2434
2435
2436   
2437
2438   <div class="plBackground"></div>
2439   <div id="fb-root"></div>
2440
2441
2442
2443   <noscript>You must have javascript enabled to view this site.</noscript>
2444
2445   <div class="alwaysMobileBg"></div>
2446   
2447   <div class="busySpinnerBg">
2448      <div class="closeSpinner"><i class="fas fa-times"></i></div>
2449      <img class="busySpinner" src="https://media.myteamscoop.com/images/busySpinner.gif" alt="Loading" />
2450   </div>
2451
2452   
2453	<div class="navigation_admin_menu_widget">
2454		<input type="hidden" name="id" value="" />
2455		<input type="hidden" name="abovethefold" value="true" />
2456	</div>
2457   
2458         <div class="custom_header_widget">
2459		      <input type="hidden" name="abovethefold" value="true" />
2460         </div>
2461   
2462
2463<script type="text/javascript">
2464   _MTS_jsList.push("js/content/mobileSelectors.js");
2465</script>
2465
2466   <div class="emailRejected" style="display: none;">
2467      <div class="rejectTop">
2468         <div class="rejectedTitle">Email Rejected!</div>
2469         <div class="rejectHide">x</div>
2470      </div>
2471      <div class="rejectedInfo">
2472         We attempted to send a notification to your email address but we were unable to verify that you provided a valid email address.
2473         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.
2474         Otherwise, <a title="Disable notifications" class="emailLink" href="javascript:fireEmailRejected()"> disable notifications</a> and hide this message.
2475      </div>
2476   </div>
2477
2478   
2479
2480   <div class="masterMcWrap"  role="main">
2481      <div id="logged_nav">
2482	      
2483
2484      </div>
2485      <div id="timeout">
2486         <div class="tText n">
2487            Your session was unable to be renewed and will be expiring in <span id="tTimer">0</span> seconds. 
2488            Click <span id="tRenew">here</span> to attempt to renew your session.
2489
2490            <div id="tStatus"></div>
2491         </div>
2492      </div>
2493
2494      
2495   
2496
2497   <div id="newsItem" class="innerSec group">
2498      
2499
2500<script>_MTS_jsList.push("js/tracking.js");</script>
2500
2501
2502<script type="text/javascript">
2503   _rated = false;
2504   _rating = 0;
2505   _articleId = 250922;
2506   _articleTitle = "How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.";
2507   _featureImageId = 0;
2508   _isFeatured = false;
2509
2510   
2511
2512   _selectedAlbum = {"images":[{"id":40810,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":0,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304440,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"},{"tagName":"News","tagType":90,"tagId":304454,"linkId":8,"writerId":1,"href":"/news-category/news/8/"}]},{"id":40808,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":1,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304456,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304439,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40809,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":2,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304458,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304441,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40811,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":3,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304460,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304442,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40812,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":4,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304462,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304443,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40813,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":5,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304464,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304444,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40815,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","
2512imageId":-1,"cheers":0,"cheered":"false","position":6,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304466,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304446,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40816,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":7,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304468,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304447,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40817,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":8,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304470,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304448,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40818,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":9,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304472,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304449,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]},{"id":40819,"uploaderName":"Jeff Pawlowski","uploaderId":2,"title":"","summ":"","credit":"","featuredUntil":"","description":"","imageId":-1,"cheers":0,"cheered":"false","position":10,"teamId":0,"container":"24","inCloud":"true","webActiveVersion":1,"links":[{"tagName":"News","tagType":90,"tagId":304474,"linkId":8,"writerId":1,"href":"/news-category/news/8/"},{"tagName":"How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.","tagType":230,"tagId":304450,"linkId":250922,"writerId":2,"href":"/news/250922/how-carpenter-media-group-built-the-foundation-for-a-modern-publishing-workflow-for-today-and-beyond/"}]}]};
2513   var _activeContainer = {"portals":[{"id":24,"url":"https://d1gmbian9wasdl.cloudfront.net/MTS_Live_Presteligence","domain":""}]};
2514
2515</script>
2515
2516
2517
2518      <div id="previousStoryTitle" class="ns_250923" title="Website Updates and Patch Notes 9/2/2026">
2519         <input type="hidden" id="nsUrl_250923" value="news/250923/website-updates-and-patch-notes-922026/" />
2520         <img src="https://media.myteamscoop.com/images/whiteLeftArrow.png" alt="Previous" />
2521         <div class="mStoryTitle">Website Updates and Patch Notes 9/2/2026</div>
2522      </div>
2523   <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='-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='custom_break_widget'><style>
2524iframe .custom_header_widget {
2525   display: none;
2526}
2527
2528.kbWrapper {
2529   margin-bottom: 20px;
2530}
2531
2532.masterMcWrap,
2533.innerSec {
2534    padding: 0px;
2535}
2536
2537blockquote {
2538    background: #f9f9f9;
2539    margin: 40px 0px;
2540    padding: 40px;
2541    width: 100%;
2542    border-left: solid 10px #fee000;
2543    text-indent: -0.333em;
2544}
2545
2546blockquote p {
2547   display: block;
2548}
2549
2550.storyWrapper p a {
2551   color: #000000;
2552   text-decoration: underline;
2553   font-weight: bold;
2554}
2555
2556.body img {
2557    max-width: 100%;
2558}
2559
2560blockquote:before {
2561    content: none;
2562    margin: 0px;
2563    font-size: 0px;
2564    vertical-align: 0px;
2565}
2566
2567.masterMcWrap {
2568    background: #eeeeee;
2569}
2570
2571.fileList .fileHeader {
2572font-weight: bold;
2573width:100%;
2574margin: 0px 0px 10px 0px;
2575}
2576
2577.fileList .file {
2578width:100%;
2579margin: 0px 0px 1px 0px;
2580background: #333333;
2581clear: both;
2582float: left;
2583padding: 10px;
2584font-size: .9em;
2585}
2586
2587.storyWrapper {
2588  padding: 20px;
2589}
2590
2591.dateTimeStory {
2592   display: none;
2593}
2594
2595@media all and (min-width: 768px) {
2596  .masterMcWrap {
2597     padding: 30px;
2598  }
2599
2600  .storyWrapper {
2601     padding: 40px;
2602  }
2603
2604  .storyWrapper .title {
2605     font-size: 2.5em;
2606     line-height: 1.25;
2607  }
2608
2609  .innerSec {
2610    padding-top: 10px;
2611    margin: auto;
2612  }
2613}
2614</style>
2615
2616<script>
2617$(document).one("widgetsloaded", function() {
2618$(".fileList").last().find("a").each(function() {
2619   $(this).attr("target", "_blank");
2620});
2621});
2622</script>
2622</div><div class='news_content_widget'><input type='hidden' name='id' value='250922' /></div><div class='custom_break_widget'>
2622<script>
2623$(document).one("widgetsloaded", function(){
2624
2625	let recentStory = document.querySelectorAll(".recentStoryMain")
2626	let kbCat = _ga_tags
2627	let kbWrap = 
2628	`<div class="recentKbHeading">Latest Knowledge Base</div>
2629	<div class="kbWrapper" data-mtsrest="/api/v3/portal/news/all/?portal_id=24&from=1&to=1&category=Knowledge Base&filter_id=11&filter_type=category">	
2630		<!--SQUARE IMAGE STORY-->
2631		<div class="recentStoryItem">
2632			<a data-holder="0_Link" style="margin-bottom: 20px;">
2633				<div class="recentImageContainer mts_collapse">
2634					<img class="recentStoryImage"  data-holder="0_MediaList_0_ImgLink" />
2635				</div>
2636				<div class="recentTextContainer">
2637					<div data-holder="0_TagList_0_getTitle" mts-collapse="" class="recentCategory"></div>
2638					<div data-holder="0_Title" mts-collapse="" class="recentTitle"></div>
2639				</div>
2640			</a>
2641			<a class="mts_cc_button button" style="width: 100%; margin-bottom: 20px;" href="/live-content/knowledge base">View Knowledge Base</a>
2642		</div>
2643	</div>`
2644
2645	if(kbCat.includes("Knowledge Base"))
2646		$(kbWrap).insertBefore(recentStory)
2647})
2648</script>
2648</div></div><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='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='250.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'><style>
2649.recentStoryMain {
2650	display: inline-block;
2651	vertical-align: top;
2652	width: 100%;
2653}
2654
2655.recentKbHeading,
2656.recentStoryHeading {
2657	margin: 0px 0px 20px 0px;
2658	width: 100%;
2659	display: inline-block;
2660	font-size: 24px;
2661	font-weight: bold;
2662}
2663.recentStoryWrapper {
2664	width: 100%;
2665	display: flex;
2666	flex-direction: column;
2667	gap: 20px;
2668}
2669
2670.recentStoryItem,
2671.recentImageContainer,
2672.recentStoryImage,
2673.recentTextContainer {
2674	width: 100%;
2675	display: inlie-block;
2676	vertical-align: top;
2677}
2678
2679.recentStoryItem {
2680	background: #ffffff;
2681}
2682
2683.recentStoryItem a {
2684	color: #000000;
2685	display: flex;
2686	flex-direction: column;
2687	gap: 5px;
2688}
2689
2690.recentImageContainer {
2691	width: 100%;
2692	position: relative;
2693}
2694
2695.recentImage {
2696	max-width: 100%;
2697}
2698
2699.recentTextContainer {
2700	padding: 10px;
2701}
2702
2703.recentImageContainer + .recentTextContainer {
2704	width: calc(100%);
2705}
2706
2707.recentTitle {
2708	font-weight: bold;
2709}
2710</style>
2711
2712<div class="recentStoryMain">
2713	<div class="recentStoryHeading" href="/live-content/sports-main">Recent Stories</div>
2714</div>
2715
2716<script>
2717
2718$(document).one("widgetsloaded", function() {
2719	let cat = _ga_tags == "Blog" ? "Blog" : "News" 
2720	let id = cat == "Blog" ? 13 : 8
2721	let wrapper = `<div class="recentStoryWrapper" mts-collapse="" data-mtsrest="/api/v3/portal/news/all/?portal_id=24&from=1&to=6&category=${cat}&filter_id=${id}&filter_type=category">		
2722		<!--SQUARE IMAGE STORY-->
2723		<div class="recentStoryItem">
2724			<a data-holder="0_Link">
2725				<div class="recentImageContainer mts_collapse">
2726					<img class="recentStoryImage"  data-holder="0_MediaList_0_ImgLink" />
2727				</div>
2728				<div class="recentTextContainer">
2729					<div data-holder="0_TagList_0_getTitle" mts-collapse="" class="recentCategory"></div>
2730					<div data-holder="0_Title" mts-collapse="" class="recentTitle"></div>
2731				</div>
2732			</a>
2733		</div>
2734		<!--SQUARE IMAGE STORY-->
2735		<div class="recentStoryItem">
2736			<a data-holder="1_Link">
2737				<div class="recentImageContainer mts_collapse">
2738					<img class="recentStoryImage" data-holder="1_MediaList_0_ImgLink">
2739				</div>
2740				<div class="recentTextContainer">
2741					<div data-holder="1_TagList_0_getTitle" mts-collapse="" class="recentCategory"></div>
2742					<div data-holder="1_Title" mts-collapse="" class="recentTitle"></div>
2743				</div>
2744			</a>
2745		</div>
2746		<!--SQUARE IMAGE STORY-->
2747		<div class="recentStoryItem">
2748			<a data-holder="2_Link">
2749				<div class="recentImageContainer mts_collapse">
2750					<img class="recentStoryImage" data-holder="2_MediaList_0_ImgLink">
2751				</div>
2752				<div class="recentTextContainer">
2753					<div data-holder="2_TagList_0_getTitle" mts-collapse="" class="recentCategory"></div>
2754					<div data-holder="2_Title" mts-collapse="" class="recentTitle"></div>
2755				</div>
2756			</a>
2757		</div>
2758		<!--SQUARE IMAGE STORY-->
2759		<div class="recentStoryItem">
2760			<a data-holder="3_Link">
2761				<div class="recentImageContainer mts_collapse">
2762					<img class="recentStoryImage" data-holder="3_MediaList_0_ImgLink">
2763				</div>
2764				<div class="recentTextContainer">
2765					<div data-holder="3_TagList_0_getTitle" mts-collapse="" class="recentCategory"></div>
2766					<div data-holder="3_Title" mts-collapse="" class="recentTitle"></div>
2767				</div>
2768			</a>
2769		</div>
2770		<!--SQUARE IMAGE STORY-->
2771		<div class="recentStoryItem">
2772			<a data-holder="4_Link">
2773				<div class="recentImageContainer mts_collapse">
2774					<img class="recentStoryImage" data-holder="4_MediaList_0_ImgLink">
2775				</div>
2776				<div class="recentTextContainer">
2777					<div data-holder="4_TagList_0_getTitle" mts-collapse="" class="recentCategory"></div>
2778					<div data-holder="4_Title" mts-collapse="" class="recentTitle"></div>
2779				</div>
2780			</a>
2781		</div>
2782		<!--SQUARE IMAGE STORY-->
2783		<div class="recentStoryItem">
2784			<a data-holder="5_Link">
2785				<div class="recentImageContainer mts_collapse">
2786					<img class="recentStoryImage" data-holder="5_MediaList_0_ImgLink">
2787				</div>
2788				<div class="recentTextContainer">
2789					<div data-holder="5_TagList_0_getTitle" mts-collapse="" class="recentCategory"></div>
2790					<div data-holder="5_Title" mts-collapse="" class="recentTitle"></div>
2791				</div>
2792			</a>
2793		</div>
2794	</div>`
2795
2796	$(wrapper).insertAfter(".recentStoryHeading")
2797})
2798</script>
2798
2799</div></div></div>
2800      <div class="borderBox">
2801         <div id="back" class="mts_cc_button borderBtn">Back</div>
2802      </div>
2803   </div>
2804
2805   
2806 
2807 
2807<script type="text/javascript"> _selectAlbum = "";
2808    _selectImage = "";
2809    var _featurePhotos = false;
2810    _MTS_jsList.push("js/tracking.js");
2811</script>
2811
2812
2813<script type="text/javascript">
2814   var _mediaUrl = "https://media.myteamscoop.com/";
2815</script>
2815
2816
2817<div id="whiteBox" class="whiteBox" style="display: none;">
2818
2819   <div class="imageInfoWrapper">
2820      <div id="whiteCaptionRow" class="mediaTools">
2821         <div class="mediaToolPop">
2822         
2823         </div>
2824
2825         <i class="fas fa-chevron-left imageBackBtn" title="Back"></i>
2826
2827         <div id="whiteCheerButton"></div>
2828
2829         <div class="shareCtr">
2830            <a id="twitterPhotoShare" class="fa-brands fa-x-twitter photoOptIcon" title="Share Via Twitter"></a>
2831            <i id="fbPhotoShare" class="fab fa-facebook-f photoOptIcon" title="Share Via Facebook"></i>
2832            <input type="hidden" id="fbTitle" value="" />
2833            <input type="hidden" id="fbImgDefault" value="" />
2834            <input type="hidden" id="fbLink" value="" />
2835            <i id="mailPhotoShare" class="fas fa-envelope photoOptIcon" title="Share Via Email"></i>
2836            <i id="buyPhoto" class="fas fa-dollar-sign photoOptIcon" title="Buy Photo"></i>
2837               
2838         </div>
2839
2840         <i class="fas fa-expand-alt toggleCaption" title="Show/Hide Photo Options And Details"></i>
2841
2842         
2843
2844         <div class="cropImgOptions" id="cropImgOpts">
2845            <div id="saveCrop" class="mts_cc_button submitEdit">
2846               Crop
2847            </div>
2848            <div id="cancelCrop" class="mts_cc_button submitEdit">
2849               Undo / Cancel
2850            </div>
2851         </div>
2852
2853      </div>
2854
2855      <div class="mediaControlsContainer" style="display: none;">
2856         <div class="mediaControlLeft"></div>
2857         <div class="mediaControlStop"></div>
2858         <div class="mediaControlPlay"></div>
2859         <div class="mediaControlPause"></div>
2860         <div class="mediaControlRight"></div>
2861      </div>
2862   </div>
2863
2864   <div id="whiteLoader" class="whiteLoader">
2865      <div class="whiteCenter">
2866         <div class="whiteLoaderImage">
2866<img src="https://media.myteamscoop.com/images/loading.gif" title="Loading..." alt="[Loading...]" /></div>
2867         <div class="whiteLoaderText">Loading...</div>
2868      </div>
2869   </div>
2870
2871   <div class="white group">
2872
2873      <div id="whiteImage">
2874         <div class="whiteLeftArrow"></div>
2875      </div>
2876
2877      <div class="titleBuy">
2878         <div class="titleBuyCtr">
2879            <div class="whiteText">
2880               <div class="whiteAlbumTitle"></div>
2881               <p id="whiteTitle"></p>
2882               <p id="whiteCredit" class="bold"></p>
2883            </div>
2884         </div>
2885      </div>
2886      <!--LEFT SIDE-->
2887      <div class="rightSideCtr">
2888         <div id="whiteCaptionRapper" class="leftGalInfo">
2889            <div class="editImgInfo" id="editImgShowBtn">
2890               Edit Photo Info
2891            </div>
2892            <div class="editImgCtr">
2893               <div class="wlbl">
2894                  Edit Title
2895               </div>
2896               <textarea class="editImgInput" id="whiteTitleNewValue"></textarea>
2897               <div id="editCaptionWrap">
2898                  <div class="wlbl">
2899                     Edit Caption
2900                  </div>
2901                  <textarea id="whiteSummaryNewValue" maxlength="1024" class="eiTextarea"></textarea>
2902               </div>
2903               <div class="wlbl">
2904                  Credit Source(s)
2905               </div>
2906               <textarea class="editImgInput" id="whiteCreditEditText"></textarea>
2907               <div class="btnCtr">
2908                  <div class="submitEdit mts_cc_button" id="editImgSave">
2909                     Save
2910                  </div>
2911                  <div class="submitEdit mts_cc_button" id="editImgCancel">
2912                     Cancel
2913                  </div>
2914               </div>
2915            </div>
2916         </div>
2917   
2918         <div class="miscPhotoInfo">
2919            <div id="whiteSummary"></div>
2920            <div id="whiteUploader" class="whiteUploader"></div>
2921            <div id="featureDate">
2922               Featured photo until: 
2923               
2924               <span class="mts_cc_text" id="photoEditFeatLink"></span>
2925               
2926               <div id="featApply" style="display: none;">
2927                  <div>Applying &hellip;</div>
2928                  <img src="https://media.myteamscoop.com/images/ajax-loader.gif" alt="Applying ..." />
2929               </div>
2930               <div id="fdError" style="display: none;"></div>
2931            </div>
2932   
2933            <div id="tagContainer" class="whiteTagContainer tagContainer"></div>
2934         </div>
2935      </div>
2936            <!--END LEFT SIDE-->
2937   </div>
2938
2939   <!--ALBUM SCROLLER-->
2940   <div class="asCtr">
2941      <div class="albumScroller">
2942      </div>
2943   </div>
2944
2945   <div class="photo_upload_widget">
2946      <input type="hidden" name="abovethefold" value="true" />
2947      <input type="hidden" name="uploadType" value="Photo" />
2948   </div>
2949   
2950
2951
2952   
2953         <div class="uploadTagWrapper">
2954            
2955
2956<script type="text/javascript"> 
2957   var _iPad = navigator.userAgent.toLowerCase().search(/ipad/) > 0; 
2958   var _hasJQuery = false; 
2959   var _hasCal = false; 
2960   var _hasAjax = false; 
2961   var _isPortalTag = true; 
2962   var _loadedCat = ['typePortalVideos'];
2963   var _startedWithMTSJQuery = typeof _MTS_JQUERY != "undefined";
2964   var _MTS_JQUERY = _startedWithMTSJQuery ? _MTS_JQUERY : undefined;
2965   var _MTS_SITEURL = "https://presteligence.com/";
2966   var _MTS_SEARCH_TYPE = "tag";
2967   var _DoNotSuggestRelated = false; 
2968   _MTS_jsList.push("js/mce/tagSel.js");
2969   _MTS_cssList.push("css/plugins/chosen/chosen.min.css", "css/mce/tagList.css", "css/mce/imageSel.css", "css/miniCalendar.css");
2970   _imageSizes = {"SiteWideMxW":1280,"SiteWideMxH":720,"SlideShowMxW":864,"SlideShowMxH":486,"ThumbnailMxW":600,"ThumbnailMxH":337,"TeamLogoMxW":250,"TeamLogoMxH":250};
2971   if (typeof(_MTS_urlRegex) === 'undefined')
2972      _MTS_urlRegex = new RegExp("[|+<>\\\\*%&:\\\\?\\\\/\\\\\\\\\\\'.\\\"\\\\r\\\\n#]", "g");
2973
2974   window.onload = function ()
2975   {
2976      determineInit();
2977   };
2978
2979   function determineInit()
2980   {
2981      if (typeof jQuery == "undefined")
2982      { 
2983         var js = document.createElement("script"); 
2984         js.type = "text/javascript"; 
2985         js.src = "https://media.myteamscoop.com/js/jquery.js?v=1.14.5.35260"; 
2986         js.onload = function () { _hasJQuery = true; initChosen(); if (!_startedWithMTSJQuery) { _MTS_JQUERY = jQuery; } startTag(); }; 
2987         document.getElementsByTagName("head")[0].appendChild(js); 
2988      } else { _hasJQuery = true; if (!_startedWithMTSJQuery) { _MTS_JQUERY = jQuery; } } 
2989      
2990      if (typeof _cal == "undefined")
2991      {
2992         var js = document.createElement("script"); 
2993         js.type = "text/javascript"; 
2994         js.src = "https://media.myteamscoop.com/js/miniCalendar.js?v=1.14.5.35260"; 
2995         js.onload = function () { _hasCal = true; startTag(); }; 
2996         document.getElementsByTagName("head")[0].appendChild(js); 
2997      } else { _hasCal = true; } 
2998      
2999      if (typeof ajax == "undefined") {
3000         var js = document.createElement("script"); 
3001         js.type = "text/javascript"; 
3002         js.src = "https://media.myteamscoop.com/js/ajax.js?v=1.14.5.35260"; 
3003         js.onload = function () { _hasAjax = true; startTag(); }; 
3004         document.getElementsByTagName("head")[0].appendChild(js); 
3005      } else { _hasAjax = true; } 
3006      
3007      if (_hasJQuery && _hasCal) { startTag(); }
3008   }
3009
3010   function initChosen()
3011   { 
3012      if (typeof _MTS_JQUERY == "undefined" || typeof _MTS_JQUERY().chosen == "undefined") 
3013      { 
3014         var js = document.createElement("script"); 
3015         js.type = "text/javascript"; 
3016         js.src = "https://media.myteamscoop.com/js/plugins/chosen/chosen.jquery.min.js?v=1.14.5.35260"; 
3017         js.onload = function () { _hasAjax = true; startTag(); }; 
3018         document.getElementsByTagName("head")[0].appendChild(js);
3019      } 
3020   } 
3021
3022   function startTag()
3023   {
3024      if (typeof(_MTS_JQUERY) != "undefined" && typeof(initTag) != "undefined")
3025      {
3026         if (_MTS_widgetsReady)
3027         {
3028            reallyStartTag();
3029         }
3030         else
3031         {
3032            _MTS_JQUERY(document).one("widgetsloaded", function ()
3033            {
3034               reallyStartTag();
3035            });
3036         }
3037      }
3038      else
3039      {
3040         setTimeout(startTag, 500);
3041      }
3042   }
3043
3044   function reallyStartTag()
3045   {
3046      initTag();
3047      // Same url regex that is done on server side for seo purposes - usage: $.urlName(url)
3048      (function ($)
3049      {
3050         $.urlName = (function (url)
3051         {
3052            return url.replace(_MTS_urlRegex, "-").replace(/ /g, "-").replace(/\-+/g, "-");
3053         })
3054      })(jQuery);
3055   }
3056</script>
3056
3057
3058<div class="search_widget">
3059   <input type="hidden" name="excluded" value="250" />
3060   <input type="hidden" name="searchType" value="Tag" />
3061   <input type="hidden" name="searchCallback" value="highlightLightboxTags" />
3062   <input type="hidden" name="abovethefold" value="true" />
3063   <input type="hidden" name="recentData" value="False" />
3064   <input type="hidden" name="frequent" value="False" />
3065</div>
3066         </div>
3067   
3068</div>
3069
3070
3071
3072   </div>
3073
3074
3075   
3076      <div class="fullAdView">
3077      </div>
3078      <div class="fullPageAd">
3079         
3080   
3081         <div class="adOptions">
3082            <div class="adCounter">
3083               <div class="loadingAd">Loading...</div> <img class="mts_lazy" width="324" height="20" data-original="https://media.myteamscoop.com/images/ajax-loader.gif" alt="" />
3084            </div>
3085            <div id="skipAd" class="adBtn">
3086               View Page in Progress
3087            </div>
3088         </div>
3089      </div>
3090   
3091   
3092   
3093   
3094   <h1 class="heading">
3095   How Carpenter Media Group Built the Foundation for a Modern Publishing Workflow for today and beyond.
3096</h1>
3097
3098
3099
3100   <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>
3101/*FOOTER MOBILE*/
3102.footerCtr {
3103	background: #212533;
3104}
3105
3106.footerInner {
3107	width: 100%;
3108	padding: 30px;
3109}
3110 
3111.footerCol {
3112	width: 100%;
3113	float: left;
3114	padding: 0px;
3115	border-bottom: dotted 1px #fee000;
3116}
3117
3118.footerLinkCtr {
3119	padding: 15px 0px;
3120	float: left;
3121	width: 100%;
3122	position: relative;
3123}
3124
3125.footerLink {
3126	color: #fee000;
3127	font-size: 1em;
3128	float: left;
3129	clear: both;
3130	text-decoration: none;
3131	line-height: 1em;
3132	margin-bottom: 5px;
3133	position: relative;
3134	z-index: 1;
3135	text-transform: capitalize;
3136	font-weight: bold;
3137}
3138
3139.footerCategory {
3140	font-size: 1em;
3141	float: left;
3142	clear: both;
3143	text-decoration: none;
3144	line-height: .9em;
3145	position: relative;
3146	z-index: 1;
3147	text-transform: capitalize;
3148	font-weight: bold;
3149	color: #ffffff;
3150}
3151
3152.footerHeader {
3153	font-size: 2em;
3154	text-transform: capitalize;
3155	font-weight: bold;
3156	width: 100%;
3157	float: left;
3158	clear: both;
3159	line-height: 3em;
3160	color: #ffffff;
3161}
3162
3163.mfExpand {
3164	position: absolute;
3165	right: 10px;
3166	z-index: 2;
3167	transform: rotate(0deg);
3168	-webkit-transform: rotate(0deg);
3169	-moz-transform: rotate(0deg);
3170	transition: transform 250ms;
3171	-webkit-transition: -webkit-transform 250ms;
3172	-moz-transition: -moz-transform 250ms;
3173	color: #fee000;
3174	font-size: 1em;
3175}
3176
3177.mfRotate {
3178	transform: rotate(180deg);
3179	-webkit-transform: rotate(180deg);
3180	-moz-transform: rotate(180deg);
3181	transition: transform 250ms;
3182	-webkit-transition: -webkit-transform 250ms;
3183	-moz-transition: -moz-transform 250ms;
3184}
3185
3186.footerSubCtr {
3187	float: left;
3188	clear: both;
3189	width: 100%;
3190	overflow: hidden;
3191	height: 0px;
3192	transition: height 250ms;
3193	-webkit-transition: height 250ms;
3194}
3195
3196.subOpen {
3197	transition: height 250ms;
3198	-webkit-transition: height 250ms;
3199}
3200
3201.footerSubLink {
3202	color: #ffffff;
3203	font-size: .8em;
3204	float: left;
3205	clear: both;
3206	padding: 5px 0px;
3207	text-decoration: none;
3208	border-bottom: solid 1px #212533;
3209	transition: border-bottom 125ms;
3210	-webkit-transition: border-bottom 125ms;
3211	-moz-transition: border-bottom 125ms;
3212	line-height: 1.25em;
3213	text-transform: capitalize;
3214	font-weight: bold;
3215}
3216
3217.logoSml {
3218	height: 20px;
3219	position: relative;
3220	margin: -3px 10px 0px 10px;
3221	vertical-align: middle;
3222}
3223
3224.copyright {
3225	width: 100%;
3226	color: #ffffff;
3227	padding: 20px;
3228	display: inline-block;
3229	vertical-align: middle;
3230}
3231
3232.footerShareTwitter, .footerShareFacebook {
3233	display: inline-block;
3234	vertical-align: middle;
3235}
3236
3237.footerShareTwitter {
3238	width: 25px;
3239	margin-top: -3px;
3240}
3241
3242.footerShareFacebook {
3243	width: 15px;
3244	margin-top: -5px;
3245	margin-left: 10px;
3246}
3247
3248@media all and (min-width: 768px) {
3249.copyright {text-align: center;}
3250}
3251
3252/*END FOOTER MOBILE*/
3253
3254.footerCtr {text-align: left !important;}
3255.mfExpand {font-size: 1em; color: #fee000; height: 24px; width: 24px; text-align:center; line-height: 24px;}
3256.copyright, .copyrightText,
3257.copyright a {display: inline-block;vertical-align: middle;line-height: 22px;}
3258.copyright a.footerShare {color: #ffffff; font-family: 'font awesome 5 pro brands'; margin-right: 10px; line-height: 22px;}
3259.logoSml {height: 22px; display: inline-block;vertical-align: top;margin: 0px 10px;}
3260
3261@media all and (min-width: 1024px) {
3262	/*FOOTER*/
3263
3264	.footerInner {
3265		width: 960px;
3266	}
3267
3268	.footerInner {
3269		margin: auto;
3270		height: 600px;
3271		position: relative;
3272		border-bottom: dotted 1px #fee000;
3273		padding: 50px 0px 0px 0px;
3274	}
3275
3276	.footerLinkCtr {
3277		padding: 0px;
3278	}
3279
3280	.footerCol {
3281		width: 14.2857%;
3282		padding: 0px 10px 0px 0px;
3283		border-bottom: none;
3284	}
3285
3286	.footerLink {
3287		border: none;
3288		border-bottom: solid 1px #212533;
3289		transition: border-bottom 125ms;
3290		-webkit-transition: border-bottom 125ms;
3291		-moz-transition: border-bottom 125ms;
3292		width: auto;
3293		padding: 5px 0px;
3294	}
3295
3296	.footerSubCtr {
3297		overflow: visible;
3298		height: auto;
3299	}
3300
3301	.footerSubLink {
3302		border: none;
3303		border-bottom: solid 1px #212533;
3304		transition: border-bottom 125ms;
3305		-webkit-transition: border-bottom 125ms;
3306		-moz-transition: border-bottom 125ms;
3307		width: auto;
3308	}
3309
3310	.footerLink:hover {
3311		border: none;
3312		border-bottom: solid 1px #fee000;
3313		transition: border-bottom 125ms;
3314		-webkit-transition: border-bottom 125ms;
3315		-moz-transition: border-bottom 125ms;
3316	}
3317
3318	.footerSubLink:hover {
3319		border: none;
3320		border-bottom: solid 1px #ffffff;
3321		transition: border-bottom 125ms;
3322		-webkit-transition: border-bottom 125ms;
3323		-moz-transition: border-bottom 125ms;
3324	}
3325
3326	.mfExpand {
3327		display: none !important;
3328	}
3329
3330}
3331
3332@media all and (min-width: 1367px) {
3333	.footerInner {
3334		width: 1170px;
3335	}
3336}
3337</style>
3338
3339<div class="footerCtr group">
3340   <div class="footerInner">
3341      <div class="footerHeader">
3342         Main
3343      </div>
3344      <div class="footerCol">
3345         <div class="footerLinkCtr">
3346            <a class="footerLink" href="/">
3347               Home
3348            </a>
3349         </div>
3350      </div>
3351      <div class="footerCol">
3352         <div class="footerLinkCtr">
3353            <a class="footerLink" href="/live-content/solutions">
3354               Solutions
3355            </a>
3356         </div>
3357      </div>
3358      <div class="footerCol">
3359         <div class="footerLinkCtr">
3360            <a class="footerLink" href="/news-category/news/8/">
3361               News
3362            </a>
3363         </div>
3364      </div>
3365      <div class="footerCol">
3366         <div class="footerLinkCtr">
3367            <a class="footerLink" href="/live-content/blog">
3368               Blog
3369            </a>
3370         </div>
3371      </div>
3372      <div class="footerCol">
3373         <div class="footerLinkCtr">
3374            <a class="footerLink" href="/live-content/about">
3375               About
3376            </a>
3377         </div>
3378      </div>
3379      <div class="footerCol">
3380         <div class="footerLinkCtr">
3381            <a class="footerLink" href="/live-content/careers">
3382               Careers
3383            </a>
3384         </div>
3385      </div>
3386      <div class="footerCol">
3387         <div class="footerLinkCtr">
3388            <a class="footerLink" href="/live-content/contact">
3389               Contact
3390            </a>
3391         </div>
3392      </div>
3393
3394      <div class="footerHeader">
3395         products
3396      </div>
3397      <div class="footerCol">
3398         <div class="footerLinkCtr">
3399            <a class="footerLink" href="/live-content/myNews">
3400               my news 360
3401            </a>
3402            <i class="fas fa-chevron-down mfExpand"></i>
3403         </div>
3404         <div class="footerSubCtr">
3405            <a class="footerSubLink" href="/live-content/eedition">
3406               e-edition
3407            </a>
3408            <a class="footerSubLink" href="/live-content/apps">
3409               apps
3410            </a>
3411            <a class="footerSubLink" href="/live-content/webcms">
3412               content management
3413            </a>
3414            <a class="footerSubLink" href="/live-content/editorial system">
3415               editorial
3416            </a>
3417            <a class="footerSubLink" href="/live-content/automated page layout">
3418               automated page layout
3419            </a>
3420         </div>
3421      </div>
3422      <div class="footerCol">
3423         <div class="footerLinkCtr">
3424            <a class="footerLink" href="/live-content/myTeamScoop">
3425               my Team Scoop
3426            </a>
3427            <i class="fas fa-chevron-down mfExpand"></i>
3428         </div>
3429         <div class="footerSubCtr">
3430            <a class="footerSubLink" href="/live-content/myTeamScoop">
3431               high school sports
3432            </a>
3433         </div>
3434      </div>
3435      <div class="footerCol">
3436         <div class="footerLinkCtr">
3437            <a class="footerLink" href="/live-content/nxt cloud">
3438               newsxtreme
3439            </a>
3440            <i class="fas fa-chevron-down mfExpand"></i>
3441         </div>
3442         <div class="footerSubCtr">
3443            <a class="footerSubLink" href="/live-content/nxt cloud">
3444               prepress workflow
3445            </a>
3446            <a class="footerSubLink" href="/live-content/commercial portal">
3447               commercial portal
3448            </a>
3449            <a class="footerSubLink" href="/live-content/ink optimization">
3450               ink optimization
3451            </a>
3452            <a class="footerSubLink" href="/live-content/xtreme inking">
3453               ink presetting
3454            </a>
3455            <a class="footerSubLink" href="/live-content/pdf corrector">
3456               PDF Corrector
3457            </a>
3458            <a class="footerSubLink" href="/live-content/black magic">
3459               Color Calibrated Proofing
3460            </a>
3461         </div>
3462      </div>
3463      <div class="footerCol">
3464         <div class="footerLinkCtr">
3465            <a class="footerLink" href="/live-content/e-tearsheets">
3466               adinfinitum
3467            </a>
3468            <i class="fas fa-chevron-down mfExpand"></i>
3469         </div>
3470         <div class="footerSubCtr">
3471            <a class="footerSubLink" href="/live-content/e-tearsheets">
3472               e-tearsheets
3473            </a>
3474         </div>
3475      </div>
3476   </div>
3477   <div class="copyright">
3478      <div class="copyrightText">&copy; <span id="footerYear"></span> </div>
3479      <a href="/">
3480         <img class="logoSml" src="https://media.myteamscoop.com/images/custom/24/logoSml.png" alt="Presteligence"/>
3481      </a>
3482      <a class="footerShare" href="https://www.linkedin.com/company/presteligence" title="Share Via LinkedIn"><i class="fab fa-linkedin"></i></a>
3483      <a class="footerShare" href="https://www.facebook.com/presteligence" title="Share Via Facebook"><i class="fab fa-facebook-square"></i></a>
3484      <a style="color: #ffffff;" href="/live-content/privacy policy">Privacy Policy</a>
3485   </div>
3486</div>
3487
3488<script>
3489var year = new Date().getFullYear();
3490document.getElementById("footerYear").innerHTML = year;
3491</script>
3491</div></div></div>
3492
3493   
3493<script type="text/javascript">
3494      _MTS_cssList.push("css/plugins/chosen/chosen.min.css");
3495      _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");
3496      
3497      _MTS_jsList.push("js/smartBanner.js");
3498      
3499         _MTS_cssList.push("css/portrait.css");
3500      
3501      _imageSizes = {"SiteWideMxW":1280,"SiteWideMxH":720,"SlideShowMxW":864,"SlideShowMxH":486,"ThumbnailMxW":600,"ThumbnailMxH":337,"TeamLogoMxW":250,"TeamLogoMxH":250};
3502      var _MTS_adSlot = "";
3503      _MTS_VERSION = "1.14.5.35260";
3504
3505      
3506      
3507         _MTS_jsList.push("js/custom/24/script.js");
3508         _MTS_jsList.push("js/custom/24/transition.js");
3509      
3510	</script>
3510
3511
3512
3513   
3513<script type="text/javascript" src="https://media.myteamscoop.com/js/widgets/main.js?v=1.14.5.35260&weburi=https://presteligence.com/&portalid=24&mediauri=https://media.myteamscoop.com/"></script>
3513
3514   
3515</body>
3516</html>
3517

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.