PageSourceSearch

https://krisp.ai/wp-content/themes/krisp-v4/js/pricing.js?ver=01.08.01.11

js krisp.ai collected 2026-10-01 08:30:52 UTC 8,975 bytes, 282 lines download raw bytes

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.