{"version":3,"file":"product-faqs-accordion-section.min.js","mappings":"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","sources":["webpack://lange/../node_modules/uuid/dist/rng.js","webpack://lange/../node_modules/uuid/dist/stringify.js","webpack://lange/../node_modules/uuid/dist/v4.js","webpack://lange/../node_modules/@integrabeauty/assert/src/index.ts","webpack://lange/./lib/decorate-error.ts","webpack://lange/./sections/product-faqs-accordion/yotpo-question-create/yotpo-create-question.ts","webpack://lange/./sections/product-faqs-accordion/yotpo-question-create/index.ts","webpack://lange/./sections/product-faqs-accordion/index.ts"],"sourcesContent":["const rnds8 = new Uint8Array(16);\nexport default function rng() {\n    return crypto.getRandomValues(rnds8);\n}\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n    byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n    return (byteToHex[arr[offset + 0]] +\n        byteToHex[arr[offset + 1]] +\n        byteToHex[arr[offset + 2]] +\n        byteToHex[arr[offset + 3]] +\n        '-' +\n        byteToHex[arr[offset + 4]] +\n        byteToHex[arr[offset + 5]] +\n        '-' +\n        byteToHex[arr[offset + 6]] +\n        byteToHex[arr[offset + 7]] +\n        '-' +\n        byteToHex[arr[offset + 8]] +\n        byteToHex[arr[offset + 9]] +\n        '-' +\n        byteToHex[arr[offset + 10]] +\n        byteToHex[arr[offset + 11]] +\n        byteToHex[arr[offset + 12]] +\n        byteToHex[arr[offset + 13]] +\n        byteToHex[arr[offset + 14]] +\n        byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n    const uuid = unsafeStringify(arr, offset);\n    if (!validate(uuid)) {\n        throw TypeError('Stringified UUID is invalid');\n    }\n    return uuid;\n}\nexport default stringify;\n","import rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n    if (!buf && !options && crypto.randomUUID) {\n        return crypto.randomUUID();\n    }\n    return _v4(options, buf, offset);\n}\nfunction _v4(options, buf, offset) {\n    options = options || {};\n    const rnds = options.random ?? options.rng?.() ?? rng();\n    if (rnds.length < 16) {\n        throw new Error('Random bytes length must be >= 16');\n    }\n    rnds[6] = (rnds[6] & 0x0f) | 0x40;\n    rnds[8] = (rnds[8] & 0x3f) | 0x80;\n    if (buf) {\n        offset = offset || 0;\n        if (offset < 0 || offset + 16 > buf.length) {\n            throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n        }\n        for (let i = 0; i < 16; ++i) {\n            buf[offset + i] = rnds[i];\n        }\n        return buf;\n    }\n    return unsafeStringify(rnds);\n}\nexport default v4;\n","/**\n * Throws an assertion error if the given condition is falsy.\n *\n * @param expression any expression, although one that evaluates to true or false is preferred by\n * convention\n * @param message optional error text\n */\nexport function assert(expression: unknown, message?: string) {\n  if (!expression) {\n    throw new AssertionError(message);\n  }\n}\n\nexport class AssertionError extends Error {\n  constructor(message = 'Assertion error') {\n    super(message);\n    this.name = this.constructor.name;\n  }\n}\n","/**\n * Copies a single piece of supplementary context onto an error before it is thrown or reported.\n *\n * Use this when decorating a value the calling code did not construct, such as a caught value or an\n * error handed in by another module. An error the caller just built with new is always writable, so\n * plain assignment is fine there. A value from elsewhere may be a foreign object this code does not\n * own. Such a value can carry a non-writable property, such as a DOMException whose code is a read-\n * only accessor, or be frozen outright, and assigning to it then throws. Attaching context must\n * never itself fail, so a rejected assignment is swallowed and the remaining context is still\n * attempted. Guarding each property in isolation means a single read-only slot, the common case,\n * costs only that one property rather than all of them.\n *\n * In practice the value that triggers this is almost always a DOMException that reached the caller\n * from a fetch the browser cut short, such as an abort when an in-flight request is interrupted.\n * The platform defines a DOMException's code, name, and message as read-only attributes, so\n * assigning a code onto one throws under the strict mode that all bundled module code runs in. It\n * surfaces from Safari far more than elsewhere for two reasons. The reported wording, attempted to\n * assign to readonly property, is JavaScriptCore's phrasing for this failure, so the same bug in\n * another engine is worded differently and groups as a separate report, which makes this one look\n * Safari specific even though the read-only rule is not. And iOS Safari abandons in-flight fetches\n * aggressively when a tab is backgrounded or a connection drops, which is when such a DOMException\n * tends to be produced and handed to code that assumed an ordinary writable error.\n *\n * A swallowed failure is logged at a level low enough that it is recorded as a breadcrumb for\n * monitoring rather than escalated into its own captured event. That keeps the lost context visible\n * alongside the eventual report without adding fresh noise of its own. The breadcrumb names the\n * property that could not be attached, the kind of value that rejected it, and why, which is enough\n * to recognize a read-only or frozen caught value after the fact.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Read-only\n * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMException\n * @see https://webidl.spec.whatwg.org/#dfn-read-only\n */\nexport function decorateError(error: any, key: string, value: unknown) {\n  try {\n    error[key] = value;\n  } catch (assignmentError) {\n    let reason: string;\n    if (assignmentError instanceof Error) {\n      reason = assignmentError.message;\n    } else {\n      reason = `${assignmentError}`;\n    }\n\n    console.log('Failed to assign error property', {\n      key,\n      name: error?.name,\n      tag: Object.prototype.toString.call(error),\n      reason\n    });\n  }\n}\n","import { assert } from '@integrabeauty/assert';\nimport { decorateError } from '../../../lib/decorate-error.js';\n\nexport interface Input {\n  appkey: string;\n\n  /**\n   * The customer's name\n   */\n  display_name: string;\n\n  /**\n   * The customer's email\n   */\n  email: string;\n\n  /**\n   * Prevents sending of two identical questions. It is recommended to set this to true.\n   */\n  prevent_duplicate_review?: boolean;\n\n  /**\n   * The description of the product\n   */\n  product_description?: string;\n\n  /**\n   * The URL of the image of the product\n   */\n  product_image_url?: string;\n\n  /**\n   * The tag you apply to a product in Custom Questions. This can only be a single string. Products\n   * can accept one tag per product and may not contain commas.\n   */\n  product_tags?: string;\n\n  /**\n   * The name of the product\n   */\n  product_title: string;\n\n  /**\n   * The URL of the product\n   */\n  product_url: string;\n\n  /**\n   * The question the customer asks\n   */\n  review_content: string;\n\n  /**\n   * The id of the product to which the new question should be attached. This may be a SKU.\n   */\n  sku: string;\n}\n\n/**\n * Create and send a Question which requires email confirmation.\n *\n * * The sku parameter only supports alphanumeric (a...z, A...Z, 0...9), \"_\" and \"-\" characters.\n * * Products can accept one tag per product and may not contain commas (,)\n * * Adding more than one product tag per product will result in a failed request (400 Error). As a\n *   result, no new question will be created.\n *\n * It is possible to allow questions without using a confirmation email. This function only supports\n * the \"with confirmation email\" requirement.\n *\n * @see https://apidocs.yotpo.com/reference/send-question-confirmation-mail\n */\nexport async function createQuestion(input: Partial<Input>) {\n  assert(input.appkey, 'Invalid app key');\n\n  const url = new URL('/questions/send_confirmation_mail', 'https://api.yotpo.com');\n\n  let response;\n  try {\n    response = await fetch(url, {\n      headers: {\n        'Content-Type': 'application/json'\n      },\n      body: JSON.stringify(input),\n      method: 'POST',\n      mode: 'cors'\n    });\n  } catch (error) {\n    decorateError(error, 'url', url.href);\n    throw error;\n  }\n\n  if (!response.ok) {\n    const error: any = new Error('Received non-200 status code creating question');\n    error.code = response.status;\n    error.url = response.url;\n    throw error;\n  }\n\n  // We are not using response.json() because it obscures errors.\n\n  let responseText;\n  try {\n    responseText = await response.text();\n  } catch (error) {\n    decorateError(error, 'code', response.status);\n    decorateError(error, 'url', response.url);\n    throw error;\n  }\n\n  // We are not hard-casting the object to its type here. Instead, we are leaving the type as\n  // unknown initially, and then later proving the type using a type assertion.\n\n  let body;\n  try {\n    body = JSON.parse(responseText);\n  } catch (error) {\n    decorateError(error, 'body', responseText);\n    decorateError(error, 'code', response.status);\n    decorateError(error, 'url', response.url);\n    throw error;\n  }\n\n  if (!isResponseBody(body)) {\n    const error: any = new Error('Malformed response body creating question');\n    error.body = body;\n    error.code = response.status;\n    error.url = response.url;\n    throw error;\n  }\n\n  if (body.status.code > 399) {\n    const error: any = new Error('Nested response status code is not ok when creating question');\n    error.body = body;\n    error.code = response.status;\n    error.url = response.url;\n    throw error;\n  }\n\n  return body;\n}\n\nexport interface ResponseBody {\n  status: {\n    code: number;\n    message: string;\n  };\n}\n\nexport function isResponseBody(value: any): value is ResponseBody {\n  return typeof value === 'object' && value !== null && typeof value.status === 'object' &&\n    value.status !== null;\n}\n","import type { CustomElement } from '@integrabeauty/custom-elements';\nimport { v4 as uuidv4 } from 'uuid';\nimport html from './index.html';\nimport styles from './index.scss';\nimport { createQuestion, type Input } from './yotpo-create-question.js';\n\n/**\n * Renders a Yotpo \"Ask question\" button and question form in a slide-in drawer. This is the v2\n * redesign of the question-create element, following the same drawer UI pattern as the review-\n * create-v2 element while keeping the question-specific form fields and Yotpo question API.\n */\nclass YotpoQuestionCreate extends HTMLElement implements CustomElement {\n  public static get observedAttributes() {\n    return ['data-modal-state'];\n  }\n\n  declare readonly dataset: {\n    /**\n     * Shopify customer id of currently logged in user\n     */\n    customerId: string;\n\n    /**\n     * Whether the drawer is shown, as \"open\". Anything else, or no value at all, means closed. A\n     * change only takes effect while the element is on the page. For now the element sets this\n     * itself. Later the modal manager sets it instead.\n     */\n    modalState: string;\n\n    /**\n     * Shopify product id to which the question will pertain\n     */\n    productId: string;\n\n    /**\n     * Shopify product title to which the question will pertain\n     */\n    productTitle: string;\n\n    /**\n     * Shopify product url to which the question will pertain\n     */\n    productUrl: string;\n\n    /**\n     * Yotpo API app key\n     */\n    yotpoAppKey: string;\n  };\n\n  private onAskQuestionButtonClickedBound = this.onAskQuestionButtonClicked.bind(this);\n  private onSubmitButtonClickedBound = this.onSubmitButtonClicked.bind(this);\n  private onCloseButtonClickedBound = this.onCloseButtonClicked.bind(this);\n  private onModalDismissRequestedBound = this.onModalDismissRequested.bind(this);\n\n  public connectedCallback() {\n    this.initializeShadowRoot();\n\n    const askQuestionButton = this.shadowRoot.querySelector<HTMLButtonElement>('.ask-question');\n    askQuestionButton?.addEventListener('click', this.onAskQuestionButtonClickedBound);\n\n    const submitButton = this.shadowRoot.querySelector<HTMLButtonElement>('button[type=\"submit\"]');\n    submitButton?.addEventListener('click', this.onSubmitButtonClickedBound);\n\n    const closeButton = this.shadowRoot.querySelector('close-button');\n    closeButton?.addEventListener('click', this.onCloseButtonClickedBound);\n  }\n\n  public disconnectedCallback() {\n    const askQuestionButton = this.shadowRoot.querySelector<HTMLButtonElement>('.ask-question');\n    askQuestionButton?.removeEventListener('click', this.onAskQuestionButtonClickedBound);\n\n    const submitButton = this.shadowRoot.querySelector<HTMLButtonElement>('button[type=\"submit\"]');\n    submitButton?.removeEventListener('click', this.onSubmitButtonClickedBound);\n\n    const closeButton = this.shadowRoot.querySelector('close-button');\n    closeButton?.removeEventListener('click', this.onCloseButtonClickedBound);\n  }\n\n  public attributeChangedCallback(name: string, oldValue: string, newValue: string) {\n    if (!this.isConnected || oldValue === newValue) {\n      return;\n    }\n\n    if (name === 'data-modal-state') {\n      if (newValue === 'open') {\n        this.openDrawer();\n      } else if (oldValue === 'open') {\n        this.closeDrawer();\n      }\n    }\n  }\n\n  private initializeShadowRoot() {\n    if (!this.shadowRoot) {\n      this.attachShadow({ mode: 'open' });\n      this.shadowRoot.innerHTML = `<style>${styles}</style>${html}`;\n    }\n  }\n\n  private onSubmitButtonClicked(event: PointerEvent) {\n    event.preventDefault();\n\n    const submitButton = event.currentTarget;\n    if (!(submitButton instanceof HTMLButtonElement)) {\n      return;\n    }\n\n    const form = this.shadowRoot.querySelector('form');\n\n    const isValid = form.checkValidity();\n    if (!isValid) {\n      for (const element of form.elements) {\n        if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement)) {\n          continue;\n        }\n\n        if (!element.checkValidity()) {\n          element.parentElement.classList.add('error');\n          const invalidField = form.querySelector<HTMLElement>(':invalid');\n          invalidField.focus({ focusVisible: true });\n        } else {\n          element.parentElement.classList.remove('error');\n        }\n      }\n\n      const errorSummary = this.shadowRoot.querySelector<HTMLElement>('.error-summary');\n      errorSummary.hidden = false;\n\n      return;\n    }\n\n    const errorSummary = this.shadowRoot.querySelector<HTMLElement>('.error-summary');\n    errorSummary.hidden = true;\n\n    const formData = new FormData(form);\n    const displayName = formData.get('display_name');\n    const email = formData.get('email');\n    const reviewContent = formData.get('review_content');\n\n    const createQuestionInput: Partial<Input> = {\n      appkey: this.dataset.yotpoAppKey,\n      display_name: isString(displayName) ? displayName : '',\n      email: isString(email) ? email : '',\n      product_title: this.dataset.productTitle,\n      product_url: this.dataset.productUrl,\n      review_content: isString(reviewContent) ? reviewContent : '',\n      sku: this.dataset.productId\n    };\n\n    const loader = this.shadowRoot.querySelector('loading-indicator');\n    submitButton.disabled = true;\n    loader.hidden = false;\n\n    createQuestion(createQuestionInput).then(() => {\n      submitButton.disabled = false;\n      loader.hidden = true;\n      form.reset();\n      this.dataset.modalState = 'closed';\n\n      type Detail = WindowEventMap['yotpo-question-created']['detail'];\n      const createdEvent = new CustomEvent<Detail>('yotpo-question-created', {\n        bubbles: true,\n        composed: true,\n        detail: {\n          body: isString(reviewContent) ? reviewContent : '',\n          customer_id: parseInt(this.dataset.customerId, 10),\n          email: createQuestionInput.email,\n          event_id: uuidv4(),\n          name: createQuestionInput.display_name,\n          product_title: this.dataset.productTitle,\n          product_url: this.dataset.productUrl\n        }\n      });\n      this.dispatchEvent(createdEvent);\n\n      const detail: WindowEventMap['identity-captured']['detail'] = {\n        email: createQuestionInput.email\n      };\n\n      // The display_name field may contain a full name. Attempt to parse it into first and last\n      // name by splitting on space. If there is only one part, treat it as the first name. If there\n      // are two parts, treat the first as the first name and the second as the last name. If there\n      // are more than two parts, treat the last part as the last name and the rest as the first\n      // name.\n      const parts = isString(displayName) && displayName.split(' ');\n      if (parts.length === 1) {\n        detail.first_name = parts[0];\n      } else if (parts.length === 2) {\n        detail.first_name = parts[0];\n        detail.last_name = parts[1];\n      } else {\n        detail.last_name = parts.pop();\n        detail.first_name = parts.join(' ');\n      }\n\n      type IdentityCapturedEvent = WindowEventMap['identity-captured'];\n\n      const identityEvent = new CustomEvent<IdentityCapturedEvent['detail']>('identity-captured', {\n        bubbles: true,\n        composed: true,\n        detail\n      });\n      this.dispatchEvent(identityEvent);\n    }).catch(error => {\n      submitButton.disabled = false;\n      loader.hidden = true;\n      errorSummary.textContent = 'Sorry we are having temporary problems, please try again later.';\n      errorSummary.parentElement.classList.add('error');\n      errorSummary.hidden = false;\n\n      console.error(error, createQuestionInput);\n    });\n  }\n\n  /**\n   * Opens the ask a question form drawer when the button is clicked.\n   */\n  private onAskQuestionButtonClicked(event: PointerEvent) {\n    if (!(event.target instanceof HTMLButtonElement)) {\n      return;\n    }\n\n    event.target.setAttribute('aria-expanded', 'true');\n\n    // Claim focus return before opening. Without this the modal manager has nothing of ours on its\n    // focus stack, so closing the drawer reaches down to whichever opener an earlier modal left\n    // there, and focusing that one scrolls the page away to wherever it sits.\n    const focusEvent = new Event('focus-stack-push-requested', {\n      bubbles: true,\n      composed: true\n    });\n    event.target.dispatchEvent(focusEvent);\n\n    // The modal manager leaves the FAQ section active while the drawer is open, so the button would\n    // stay reachable by Tab behind it. The section's script inerts the rest of the section.\n    event.target.inert = true;\n\n    this.dataset.modalState = 'open';\n  }\n\n  /**\n   * Handles the click event on the close button of the drawer.\n   */\n  private onCloseButtonClicked(_event: PointerEvent) {\n    this.dataset.modalState = 'closed';\n  }\n\n  /**\n   * Handles the event sent when clicking on the modal backdrop or pressing the Escape key. The\n   * event is sent by modal-manager.\n   */\n  private onModalDismissRequested(_event: Event) {\n    this.dataset.modalState = 'closed';\n  }\n\n  private openDrawer() {\n    const drawer = this.shadowRoot.querySelector<HTMLElement>('#drawer');\n    drawer.inert = false;\n\n    addEventListener('modal-dismiss-requested', this.onModalDismissRequestedBound);\n\n    const modalShowEvent = new Event('modal-open-requested', { bubbles: true, composed: true });\n    this.dispatchEvent(modalShowEvent);\n\n    const closeButton = drawer.querySelector('close-button');\n    closeButton.focus({ focusVisible: true });\n  }\n\n  private closeDrawer() {\n    const drawer = this.shadowRoot.querySelector<HTMLElement>('#drawer');\n    drawer.inert = true;\n\n    const askQuestion = this.shadowRoot.querySelector('.ask-question');\n    askQuestion.setAttribute('aria-expanded', 'false');\n\n    // This has to happen before the close request goes out, since the modal manager puts focus back\n    // on this button when it hears it, and a focus call into an inert subtree does nothing.\n    if (askQuestion instanceof HTMLElement) {\n      askQuestion.inert = false;\n    }\n\n    removeEventListener('modal-dismiss-requested', this.onModalDismissRequestedBound);\n\n    const event = new Event('modal-close-requested', { bubbles: true, composed: true });\n    this.dispatchEvent(event);\n  }\n}\n\nfunction isString(value: any): value is string {\n  return typeof value === 'string';\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'yotpo-question-create': YotpoQuestionCreate;\n  }\n}\n\nif (!customElements.get('yotpo-question-create')) {\n  customElements.define('yotpo-question-create', YotpoQuestionCreate);\n}\n","import './yotpo-question-create/index.js';\n\n/**\n * The modal manager inerts every section but the one holding the open modal, so while the ask a\n * question drawer is open, the FAQ heading and the accordion stay reachable by Tab behind it. The\n * question element inerts its own button, and we inert the parts of the section beside it. The\n * header is left alone since the drawer sits inside it.\n *\n * Only the modal manager is meant to act on this request. We listen for it here only because it\n * comes from our own child element, and we run before the manager's listener on the window.\n */\nfunction onModalOpenRequested(event: GlobalEventHandlersEventMap['modal-open-requested']) {\n  if (!(event.currentTarget instanceof HTMLElement)) {\n    return;\n  }\n\n  const parts = event.currentTarget.querySelectorAll<HTMLElement>(\n    'header > div, accordion-element');\n  for (const part of parts) {\n    part.inert = true;\n  }\n}\n\n/**\n * Takes the section's parts back out of inert. We run before the modal manager's listener on the\n * window puts focus back on the button that opened the drawer, and a focus call into an inert\n * subtree does nothing.\n */\nfunction onModalCloseRequested(event: GlobalEventHandlersEventMap['modal-close-requested']) {\n  if (!(event.currentTarget instanceof HTMLElement)) {\n    return;\n  }\n\n  const parts = event.currentTarget.querySelectorAll<HTMLElement>(\n    'header > div, accordion-element');\n  for (const part of parts) {\n    part.inert = false;\n  }\n}\n\n// Each FAQ section on the page carries its own copy of this script, and every copy runs, so we skip\n// the sections an earlier copy already set up.\nconst sections = document.querySelectorAll<HTMLElement>('.product-faqs:not([data-initialized])');\nfor (const section of sections) {\n  section.addEventListener('modal-open-requested', onModalOpenRequested);\n  section.addEventListener('modal-close-requested', onModalCloseRequested);\n  section.dataset.initialized = 'true';\n}\n"],"names":["rnds8","Uint8Array","byteToHex","i","push","toString","slice","unsafeStringify","arr","offset","toLowerCase","dist_v4","options","buf","crypto","randomUUID","_ref","_options$random","rnds","random","rng","getRandomValues","length","Error","RangeError","_v4","AssertionError","constructor","message","super","this","name","decorateError","error","key","value","assignmentError","reason","console","log","tag","Object","prototype","call","async","createQuestion","input","expression","assert","appkey","url","URL","response","responseText","body","fetch","headers","JSON","stringify","method","mode","href","ok","code","status","text","parse","YotpoQuestionCreate","HTMLElement","observedAttributes","onAskQuestionButtonClickedBound","onAskQuestionButtonClicked","bind","onSubmitButtonClickedBound","onSubmitButtonClicked","onCloseButtonClickedBound","onCloseButtonClicked","onModalDismissRequestedBound","onModalDismissRequested","connectedCallback","initializeShadowRoot","askQuestionButton","shadowRoot","querySelector","addEventListener","submitButton","closeButton","disconnectedCallback","removeEventListener","attributeChangedCallback","oldValue","newValue","isConnected","openDrawer","closeDrawer","attachShadow","innerHTML","event","preventDefault","currentTarget","HTMLButtonElement","form","checkValidity","element","elements","HTMLInputElement","HTMLTextAreaElement","parentElement","classList","remove","add","focus","focusVisible","hidden","errorSummary","formData","FormData","displayName","get","email","reviewContent","createQuestionInput","dataset","yotpoAppKey","display_name","isString","product_title","productTitle","product_url","productUrl","review_content","sku","productId","loader","disabled","then","reset","modalState","createdEvent","CustomEvent","bubbles","composed","detail","customer_id","parseInt","customerId","event_id","dispatchEvent","parts","split","first_name","last_name","pop","join","identityEvent","catch","textContent","target","setAttribute","focusEvent","Event","inert","_event","drawer","modalShowEvent","askQuestion","onModalOpenRequested","querySelectorAll","part","onModalCloseRequested","customElements","define","sections","document","section","initialized"],"sourceRoot":""}