1/** 2 * Cal.com popup-on-click embed for demo CTAs. 3 * Opens scheduler in modal instead of new tab. 4 * GA4 events: demo_cta_click (open), demo_booking_completed, demo_booking_rescheduled, demo_booking_cancelled. 5 * 6 * On pages that only link to the demo calendar (e.g. Shopboard), use: 7 * <script src=".../cal-embed.js" data-cal-variant="demo-only"></script> 8 * to skip the Donuts namespace and preloads, which avoids loading unused Cal chunks. 9 */ 10var calEmbedVariant = (function () { 11 var s = document.currentScript; 12 return s ? s.getAttribute('data-cal-variant') || '' : ''; 13})(); 14 15(function (C, A, L) { 16 var p = function (a, ar) { 17 a.q.push(ar); 18 }; 19 var d = C.document; 20 C.Cal = 21 C.Cal || 22 function () { 23 var cal = C.Cal; 24 var ar = arguments; 25 if (!cal.loaded) { 26 cal.ns = {}; 27 cal.q = cal.q || []; 28 d.head.appendChild(d.createElement('script')).src = A; 29 cal.loaded = true; 30 } 31 if (ar[0] === L) { 32 var api = function () { 33 p(api, arguments); 34 }; 35 var ns = ar[1]; 36 api.q = api.q || []; 37 if (typeof ns === 'string') { 38 cal.ns[ns] = cal.ns[ns] || api; 39 p(cal.ns[ns], ar); 40 p(cal, ['initNamespace', ns]); 41 } else { 42 p(cal, ar); 43 } 44 return; 45 } 46 p(cal, ar); 47 }; 48})(window, 'https://app.cal.com/embed/embed.js', 'init'); 49 50Cal('init', 'demo', { origin: 'https://cal.com' }); 51Cal.ns['demo']('ui', { 52 theme: 'dark', 53 styles: { branding: { brandColor: '#FF5918' } }, 54}); 55if (calEmbedVariant !== 'demo-only') { 56 Cal.ns['demo']('preload', { calLink: 'airshop/demo' }); 57 Cal('init', 'donuts', { origin: 'https://cal.com' }); 58 Cal.ns['donuts']('ui', { 59 theme: 'dark', 60 styles: { branding: { brandColor: '#FF5918' } }, 61 }); 62 Cal.ns['donuts']('preload', { calLink: 'airshop/donuts' }); 63} 64 65function fireCalEvent(eventName, eventLabel, eventParams) { 66 if (typeof gtag === 'function') { 67 var isLocal = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; 68 var params = { 69 event_category: 'engagement', 70 event_label: eventLabel, 71 value: 1, 72 send_to: 'G-LPM80C117C', 73 debug_mode: isLocal, 74 }; 75 if (eventParams) {
76 for (var k in eventParams) params[k] = eventParams[k]; 77 } 78 gtag('event', eventName, params); 79 } 80} 81 82Cal.ns['demo']('on', { 83 action: 'bookingSuccessfulV2', 84 callback: function (e) { 85 var d = e.detail && e.detail.data; 86 fireCalEvent('demo_booking_completed', 'demo', d && d.startTime ? { booking_start: d.startTime } : null); 87 }, 88}); 89 90Cal.ns['demo']('on', { 91 action: 'rescheduleBookingSuccessfulV2', 92 callback: function (e) { 93 fireCalEvent('demo_booking_rescheduled', 'demo'); 94 }, 95}); 96 97Cal.ns['demo']('on', { 98 action: 'bookingCancelled', 99 callback: function () { 100 fireCalEvent('demo_booking_cancelled', 'demo'); 101 }, 102}); 103 104document.addEventListener( 105 'click', 106 function (e) { 107 var el = e.target.closest('[data-cal-link]'); 108 if (el) { 109 e.preventDefault(); 110 var label = (el.getAttribute('aria-label') || el.textContent || '').trim().slice(0, 50) || 'cal_demo'; 111 if (typeof gtag === 'function') { 112 var isLocal = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; 113 gtag('event', 'demo_cta_click', { 114 event_category: 'engagement', 115 event_label: label, 116 value: 1, 117 send_to: 'G-LPM80C117C', 118 debug_mode: isLocal, 119 }); 120 } else if (typeof window.dataLayer !== 'undefined') { 121 window.dataLayer.push({ 122 event: 'demo_cta_click', 123 event_category: 'engagement', 124 event_label: label, 125 value: 1, 126 }); 127 } 128 } 129 }, 130 true 131); 132 133/** Enter / Space on demo triggers (href="#" links) */ 134document.addEventListener('keydown', function (e) { 135 if (e.key !== 'Enter' && e.key !== ' ') { 136 return; 137 } 138 var el = e.target.closest('[data-cal-link]'); 139 if (!el) { 140 return; 141 } 142 if (e.key === ' ') { 143 e.preventDefault(); 144 } 145 el.click(); 146});
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.