1$(document).ready(async function () { 2 const { isMobileOrTablet } = UiHelpers; 3 const { sendEvent } = AnalyticsHelpers; 4 5 const getCountry = async () => { 6 try { 7 const response = await fetch( 8 theme_url + "/includes/controller/get-location.php", 9 { 10 method: "GET", 11 headers: new Headers({ 12 Authorization: "Basic " + btoa("admin" + ":" + "admin"), 13 }), 14 }, 15 ); 16 17 if (!response.ok) { 18 throw new Error(`HTTP error! status: ${response.status}`); 19 } 20 21 const data = await response.json(); 22 country = data.location; 23 return country; 24 } catch (error) { 25 console.error("Error:", error); 26 return null; 27 } 28 }; 29 30 // (async () => { 31 // let country = await getCountry(); 32 // if (country === 'PH') { 33 // $('.plan_holder.pro.ai_meeting_assistant') 34 // .children() 35 // .find('.price.yearly') 36 // .text('$6'); 37 // } 38 // })(); 39 40 $(".price_checkbox").on("change", function () { 41 let isYearly = $(this).is(":checked"); 42 $(".price_checkbox").prop("checked", isYearly); 43 togglePricing(isYearly); 44 }); 45 46 const fetchPrice = async () => { 47 try { 48 const data = await window.fetchExperiment("without-freemium"); 49 if (Object.keys(data).length !== 0 && data?.value !== "control") { 50 return "variant"; 51 } else { 52 return "control"; 53 } 54 } catch (error) { 55 return "error"; 56 } 57 }; 58 59 // whenAvailable('amplitude', async function () { 60 // if (!isMobileOrTablet()) { 61 // const mode = await fetchPrice(); 62 // if (mode === 'variant') { 63 // $('.plan_holder.ai_meeting_assistant.free') 64 // .addClass('hide') 65 // .removeClass('loading'); 66 // $('.plan_holder.ai_meeting_assistant.free_trial').addClass('show'); 67 // } else { 68 // $('.plan_holder.ai_meeting_assistant.free').removeClass('hide loading'); 69 // $('.plan_holder.ai_meeting_assistant.free_trial').removeClass('show'); 70 // } 71 // } else { 72 // $('.plan_holder.ai_meeting_assistant.free').removeClass('loading'); 73 // } 74 // }); 75 76 const $section = $("#pricing_comparison_table"); 77 const $table = $section.find(".comparison_table"); 78 const $sticky = $section.find(".comparison_sticky_header"); 79 80 const OFFSET = 50; 81 82 let tableTop = 0, 83 tableBottom = 0, 84 stickyH = 0; 85 86 function measure() { 87 const off = $table.offset(); 88 tableTop = off ? off.top : 0; 89 tableBottom = tableTop + $table.outerHeight(); 90 stickyH = $sticky.outerHeight() || 0; 91 } 92 93 function onScroll() { 94 const y = window.scrollY || $(window).scrollTop(); 95 96 const within = y >= tableTop + OFFSET && y < tableBottom - stickyH; 97 $sticky.toggleClass("show", within); 98 } 99 100 $(window).on("scroll", onScroll); 101 102 // initial measure (and again after layout settles) 103 measure(); 104 onScroll(); 105 setTimeout(function () { 106 measure(); 107 onScroll(); 108 }, 0); 109 110 $(".see_all").on("click", function () { 111 $("html, body").animate({ 112 scrollTop: $section.offset().top - 120, 113 }); 114 }); 115 116 const applyBillingPeriod = (isYearly) => { 117 $(".yearly").toggleClass("show", isYearly).toggleClass("hidden", !isYearly); 118 $(".monthly").toggleClass("show", !isYearly).toggleClass("hidden", isYearly); 119 }; 120 121 // Legacy checkbox switcher, still rendered by template-partners-referral.php. 122 $("#price_toggle").on("change", function () { 123 applyBillingPeriod($(this).is(":checked")); 124 }); 125 126 const $billingToggle = $(".switcher_wrapper .switch_inner.billing_toggle"); 127 const $billingPill = $billingToggle.find(".billing_active_pill"); 128 129 const moveBillingPill = () => { 130 const option = $billingToggle.find(".billing_option.active")[0]; 131 if (!option) return; 132 $billingPill.css({ 133 width: option.offsetWidth + "px", 134 transform: "translateX(" + option.offsetLeft + "px)", 135 }); 136 }; 137 138 moveBillingPill(); 139 requestAnimationFrame(() => $billingToggle.addClass("pill_ready")); 140 $(window).on("load resize", moveBillingPill); 141 if (document.fonts && document.fonts.ready) { 142 document.fonts.ready.then(moveBillingPill); 143 } 144 145 $billingToggle.on("click", ".billing_option", function () { 146 const $option = $(this); 147 if ($option.hasClass("active")) return; 148 $billingToggle 149 .find(".billing_option") 150 .removeClass("active") 151 .attr("aria-selected", "false"); 152 $option.addClass("active").attr("aria-selected", "true"); 153 moveBillingPill(); 154 applyBillingPeriod($option.data("period") === "yearly"); 155 }); 156 157 const setProductQueryParam = (productId) => { 158 if (!productId || !window.history || !window.history.replaceState) return; 159 160 const url = new URL(window.location.href); 161 url.searchParams.set("product", productId); 162 window.history.replaceState({}, "", url.toString()); 163 }; 164 165 const getAllProductClasses = () => { 166 return $(".pricing_navigation_container .nav_item a") 167 .map(function () { 168 return $(this).data("product-id"); 169 }) 170 .get() 171 .filter(Boolean) 172 .join(" "); 173 }; 174 175 const openDetailModal = (id) => { 176 $(`.pricing_detail_modal[data-modal='${id}']`).addClass("show"); 177 $("html, body").addClass("freeze"); 178 }; 179 180 $(document).on("keydown", ".pricing_detail_trigger", function (e) { 181 if (e.key !== "Enter" && e.key !== " ") return; 182 e.preventDefault(); 183 openDetailModal($(this).data("modal-opener")); 184 }); 185 186 const filterModalItems = ($modal, term) => { 187 const query = term.trim().toLowerCase(); 188 let visible = 0; 189 $modal.find(".pdm_item").each(function () { 190 const name = ($(this).attr("data-name") || "").toLowerCase(); 191 const match = name.indexOf(query) !== -1; 192 $(this).toggleClass("hidden", !match); 193 if (match) visible++; 194 }); 195 $modal.find(".pdm_group").each(function () { 196 $(this).toggleClass("hidden", $(this).find(".pdm_item:not(.hidden)").length === 0); 197 }); 198 $modal.find(".pdm_empty").prop("hidden", visible !== 0); 199 }; 200 201 $(document).on("input", ".pdm_search_input", function () { 202 filterModalItems($(this).closest(".pricing_detail_modal"), $(this).val()); 203 }); 204 205 $(document).on("click", ".pricing_detail_modal .modal_close", function () { 206 const $modal = $(this).closest(".pricing_detail_modal"); 207 $modal.find(".pdm_search_input").val(""); 208 filterModalItems($modal, ""); 209 }); 210 211 const $navInner = $(".pricing_navigation_container .navigation_inner"); 212 const $navPill = $navInner.find(".nav_active_pill"); 213 214 const getActiveNavItem = () =>
215 $navInner.find(".nav_item a.active").closest(".nav_item")[0]; 216 217 const moveNavPill = (bounce) => { 218 const item = getActiveNavItem(); 219 if (!item) return; 220 $navPill.css({ 221 width: item.offsetWidth + "px", 222 transform: "translateX(" + item.offsetLeft + "px)", 223 }); 224 if (!bounce) return; 225 // Replay the squash: drop the class and force a reflow so a second 226 // click mid-travel restarts the keyframes instead of being ignored. 227 $navPill.removeClass("is_moving"); 228 void $navPill[0].offsetWidth; 229 $navPill.addClass("is_moving"); 230 }; 231 232 // Once the track overflows (phones), keep the selected tab in view. 233 const revealActiveNavItem = (behavior) => { 234 const item = getActiveNavItem(); 235 const scroller = $navInner.closest(".navigation_scroller")[0]; 236 if (!item || !scroller || scroller.scrollWidth <= scroller.clientWidth) 237 return; 238 item.scrollIntoView({ 239 behavior: behavior || "smooth", 240 block: "nearest", 241 inline: "center", 242 }); 243 }; 244 245 moveNavPill(); 246 // Enable the slide only after the first measurement lands. 247 requestAnimationFrame(() => { 248 $navInner.addClass("pill_ready"); 249 // A tab preselected by ?product= can start off-screen on phones. 250 revealActiveNavItem("auto"); 251 }); 252 $(window).on("load resize", moveNavPill); 253 if (document.fonts && document.fonts.ready) { 254 document.fonts.ready.then(moveNavPill); 255 } 256 257 $(".pricing_navigation_container .nav_item a").on("click", function () { 258 $(".pricing_navigation_container .nav_item a").removeClass("active"); 259 let elem = $(this); 260 $(this).addClass("active"); 261 moveNavPill(true); 262 revealActiveNavItem(); 263 const dataProduct = $(this).data("product-id"); 264 setProductQueryParam(dataProduct); 265 const selector = `[data-product="${dataProduct}"]`; 266 $("[data-product]").removeClass("active"); 267 $(selector).addClass("active"); 268 $(".pricing_page_wrapper") 269 .removeClass(getAllProductClasses()) 270 .addClass(dataProduct); 271 // The billing toggle lives inside the Meeting AI panel, which is 272 // display:none until its tab is active. Measured while hidden it reports 273 // zero, so landing on another product left the pill invisible - reading as 274 // though neither period were selected. Re-measure now that it has a box. 275 moveBillingPill(); 276 sendEvent("ui_visited_pricing", { 277 data: { 278 produc: elem.text().trim(), 279 }, 280 }); 281 }); 282});
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.