PageSourceSearch

https://airshopapp.com/js/cal-embed.js

js airshopapp.com collected 2026-10-05 19:23:47 UTC 4,100 bytes, 146 lines download raw bytes

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.