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&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=<%=_portal.Id %>&ie=1&v=<%=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'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'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. 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 \n\n \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. \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 \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–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. \nThe result is a single publishing workflow that supports both print and digital operations.\nDesigned for Collaboration\n\n\n\n\n \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. \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. Eighty Canadian publications represent another significant milestone with all of these papers transitioning within a 30-day window. \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, 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'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 …</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">© <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.