%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /snap/firefox/5014/usr/lib/firefox/browser/features/
Upload File :
Create Path :
Current File : //snap/firefox/5014/usr/lib/firefox/browser/features/formautofill@mozilla.org.xpi

�-PK
!<lC�0rr��Lapi.jsPK
!<�)�..���&chrome.manifestPK
!<:��--��='chrome/content/formautofill.cssPK
!<��ՊTT
���-background.jsPK
!<0�Z��$��&0chrome/content/addressFormLayout.mjsPK
!<|���( ( $���Hchrome/content/autofillEditForms.mjsPK
!<gL�JJ ��fichrome/content/editAddress.xhtmlPK
!<�q�{

#���qchrome/content/editCreditCard.xhtmlPK
!<2n��aa��<�chrome/content/editDialog.mjsPK
!<�iet��"��ؚchrome/content/formfill-anchor.svgPK
!<P+F���+����chrome/content/icon-credit-card-generic.svgPK
!<e�_�#����chrome/content/icon-credit-card.svgPK
!<�_
���$���chrome/content/manageAddresses.xhtmlPK
!<�o�b��&���chrome/content/manageCreditCards.xhtmlPK
!<p{a-AA��еchrome/content/manageDialog.cssPK
!<u�K77��N�chrome/content/manageDialog.mjsPK
!<5�|		#����chrome/content/skin/editAddress.cssPK
!<=�q��&���chrome/content/skin/editCreditCard.cssPK
!<{��v
v
)���chrome/content/skin/editDialog-shared.cssPK
!<�xli"���chrome/content/skin/editDialog.cssPK
!<�(O�+���chrome/content/third-party/cc-logo-amex.pngPK
!<�Ba		.��Achrome/content/third-party/cc-logo-amex@2x.pngPK
!<+�82��4���chrome/content/third-party/cc-logo-cartebancaire.pngPK
!<ۺ�''7���#chrome/content/third-party/cc-logo-cartebancaire@2x.pngPK
!<�u�+-��:0chrome/content/third-party/cc-logo-diners.svgPK
!<Ȋ+]]/���@chrome/content/third-party/cc-logo-discover.pngPK
!<�v�	�	2��LEchrome/content/third-party/cc-logo-discover@2x.pngPK
!<D���WW*��COchrome/content/third-party/cc-logo-jcb.svgPK
!<�^AEH
H
1���`chrome/content/third-party/cc-logo-mastercard.svgPK
!<�x���*��ynchrome/content/third-party/cc-logo-mir.svgPK
!<�}����/���rchrome/content/third-party/cc-logo-unionpay.svgPK
!<ZѨ���+��e�chrome/content/third-party/cc-logo-visa.svgPK
!<t����*����en-US/locale/en-US/formautofill.propertiesPK
!<d)�l��
����manifest.jsonPK
!<D�hp��d�schema.jsonPK##2PK
!<lC�0rrapi.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

/* globals ExtensionAPI, Services, XPCOMUtils */

const CACHED_STYLESHEETS = new WeakMap();

ChromeUtils.defineESModuleGetters(this, {
  FormAutofill: "resource://autofill/FormAutofill.sys.mjs",
  FormAutofillParent: "resource://autofill/FormAutofillParent.sys.mjs",
  FormAutofillStatus: "resource://autofill/FormAutofillParent.sys.mjs",
  AutoCompleteParent: "resource://gre/actors/AutoCompleteParent.sys.mjs",
});

XPCOMUtils.defineLazyServiceGetter(
  this,
  "resProto",
  "@mozilla.org/network/protocol;1?name=resource",
  "nsISubstitutingProtocolHandler"
);

const RESOURCE_HOST = "formautofill";

function insertStyleSheet(domWindow, url) {
  let doc = domWindow.document;
  let styleSheetAttr = `href="${url}" type="text/css"`;
  let styleSheet = doc.createProcessingInstruction(
    "xml-stylesheet",
    styleSheetAttr
  );

  doc.insertBefore(styleSheet, doc.documentElement);

  if (CACHED_STYLESHEETS.has(domWindow)) {
    CACHED_STYLESHEETS.get(domWindow).push(styleSheet);
  } else {
    CACHED_STYLESHEETS.set(domWindow, [styleSheet]);
  }
}

function ensureCssLoaded(domWindow) {
  if (CACHED_STYLESHEETS.has(domWindow)) {
    // This window already has autofill stylesheets.
    return;
  }

  insertStyleSheet(domWindow, "chrome://formautofill/content/formautofill.css");
}

this.formautofill = class extends ExtensionAPI {
  /**
   * Adjusts and checks form autofill preferences during startup.
   *
   * @param {boolean} addressAutofillAvailable
   * @param {boolean} creditCardAutofillAvailable
   */
  adjustAndCheckFormAutofillPrefs(
    addressAutofillAvailable,
    creditCardAutofillAvailable
  ) {
    // Reset the sync prefs in case the features were previously available
    // but aren't now.
    if (!creditCardAutofillAvailable) {
      Services.prefs.clearUserPref(
        "services.sync.engine.creditcards.available"
      );
    }
    if (!addressAutofillAvailable) {
      Services.prefs.clearUserPref("services.sync.engine.addresses.available");
    }

    if (!addressAutofillAvailable && !creditCardAutofillAvailable) {
      Services.prefs.clearUserPref("dom.forms.autocomplete.formautofill");
      Services.telemetry.scalarSet("formautofill.availability", false);
      return;
    }

    // This pref is used for web contents to detect the autocomplete feature.
    // When it's true, "element.autocomplete" will return tokens we currently
    // support -- otherwise it'll return an empty string.
    Services.prefs.setBoolPref("dom.forms.autocomplete.formautofill", true);
    Services.telemetry.scalarSet("formautofill.availability", true);

    // These "*.available" prefs determines whether the "addresses"/"creditcards" sync engine is
    // available (ie, whether it is shown in any UI etc) - it *does not* determine
    // whether the engine is actually enabled or not.
    if (FormAutofill.isAutofillAddressesAvailable) {
      Services.prefs.setBoolPref(
        "services.sync.engine.addresses.available",
        true
      );
    } else {
      Services.prefs.clearUserPref("services.sync.engine.addresses.available");
    }
    if (FormAutofill.isAutofillCreditCardsAvailable) {
      Services.prefs.setBoolPref(
        "services.sync.engine.creditcards.available",
        true
      );
    } else {
      Services.prefs.clearUserPref(
        "services.sync.engine.creditcards.available"
      );
    }
  }
  onStartup() {
    // We have to do this before actually determining if we're enabled, since
    // there are scripts inside of the core browser code that depend on the
    // FormAutofill JSMs being registered.
    let uri = Services.io.newURI("chrome/res/", null, this.extension.rootURI);
    resProto.setSubstitution(RESOURCE_HOST, uri);

    let aomStartup = Cc[
      "@mozilla.org/addons/addon-manager-startup;1"
    ].getService(Ci.amIAddonManagerStartup);
    const manifestURI = Services.io.newURI(
      "manifest.json",
      null,
      this.extension.rootURI
    );
    this.chromeHandle = aomStartup.registerChrome(manifestURI, [
      ["content", "formautofill", "chrome/content/"],
    ]);

    // Until we move to fluent (bug 1446164), we're stuck with
    // chrome.manifest for handling localization since its what the
    // build system can handle for localized repacks.
    if (this.extension.rootURI instanceof Ci.nsIJARURI) {
      this.autofillManifest = this.extension.rootURI.JARFile.QueryInterface(
        Ci.nsIFileURL
      ).file;
    } else if (this.extension.rootURI instanceof Ci.nsIFileURL) {
      this.autofillManifest = this.extension.rootURI.file;
    }

    if (this.autofillManifest) {
      Components.manager.addBootstrappedManifestLocation(this.autofillManifest);
    } else {
      console.error(
        "Cannot find formautofill chrome.manifest for registring translated strings"
      );
    }
    let addressAutofillAvailable = FormAutofill.isAutofillAddressesAvailable;
    let creditCardAutofillAvailable =
      FormAutofill.isAutofillCreditCardsAvailable;
    this.adjustAndCheckFormAutofillPrefs(
      addressAutofillAvailable,
      creditCardAutofillAvailable
    );
    if (!creditCardAutofillAvailable && !addressAutofillAvailable) {
      return;
    }
    // Listen for the autocomplete popup message
    // or the form submitted message (which may trigger a
    // doorhanger) to lazily append our stylesheets related
    // to the autocomplete feature.
    AutoCompleteParent.addPopupStateListener(ensureCssLoaded);
    FormAutofillParent.addMessageObserver(this);
    this.onFormSubmitted = (data, window) => ensureCssLoaded(window);

    FormAutofillStatus.init();

    ChromeUtils.registerWindowActor("FormAutofill", {
      parent: {
        esModuleURI: "resource://autofill/FormAutofillParent.sys.mjs",
      },
      child: {
        esModuleURI: "resource://autofill/FormAutofillChild.sys.mjs",
        events: {
          focusin: {},
          "form-submission-detected": { createActor: false },
        },
      },
      allFrames: true,
    });
  }

  onShutdown(isAppShutdown) {
    if (isAppShutdown) {
      return;
    }

    resProto.setSubstitution(RESOURCE_HOST, null);

    this.chromeHandle.destruct();
    this.chromeHandle = null;

    if (this.autofillManifest) {
      Components.manager.removeBootstrappedManifestLocation(
        this.autofillManifest
      );
    }

    ChromeUtils.unregisterWindowActor("FormAutofill");

    AutoCompleteParent.removePopupStateListener(ensureCssLoaded);
    FormAutofillParent.removeMessageObserver(this);

    for (let win of Services.wm.getEnumerator("navigator:browser")) {
      let cachedStyleSheets = CACHED_STYLESHEETS.get(win);

      if (!cachedStyleSheets) {
        continue;
      }

      while (cachedStyleSheets.length !== 0) {
        cachedStyleSheets.pop().remove();
      }
    }
  }
};
PK
!<�)�..chrome.manifestlocale formautofill en-US en-US/locale/en-US/
PK
!<:��--chrome/content/formautofill.css/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#PopupAutoComplete {
  &[resultstyles~="autofill"] {
    min-width: 150px !important;
  }

  > richlistbox > richlistitem {
    &[originaltype="autofill"] {
      display: block;
      margin: 0;
      padding: 0;
      height: auto;
      min-height: auto;

      /* Treat @collpased="true" as display: none similar to how it is for XUL elements.
      * https://developer.mozilla.org/en-US/docs/Web/CSS/visibility#Values */
      &[collapsed="true"] {
        display: none;
      }
    }

    &[disabled="true"] {
      opacity: 0.5;
    }
  }
}

/* Form Autofill Doorhanger */

#autofill-address-notification popupnotificationcontent > .desc-message-box,
#autofill-credit-card-notification popupnotificationcontent > .desc-message-box {
  margin-block-end: 12px;
}

#autofill-credit-card-notification popupnotificationcontent > .desc-message-box > image {
  -moz-context-properties: fill;
  fill: currentColor;
  width: auto;
  height: auto;
  list-style-image: url(chrome://formautofill/content/icon-credit-card-generic.svg);
}

#autofill-address-notification popupnotificationcontent > .desc-message-box > description,
#autofill-address-notification popupnotificationcontent > .desc-message-box > additional-description,
#autofill-credit-card-notification popupnotificationcontent > .desc-message-box > description {
  font-style: italic;
  margin-inline-start: 4px;
}
PK
!<��ՊTT
background.js/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

/* eslint-env webextensions */

"use strict";

browser.runtime.onUpdateAvailable.addListener(_details => {
  // By listening to but ignoring this event, any updates will
  // be delayed until the next browser restart.
  // Note that if we ever wanted to change this, we should make
  // sure we manually invalidate the startup cache using the
  // startupcache-invalidate notification.
});
PK
!<0�Z��$chrome/content/addressFormLayout.mjs/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
  FormAutofill: "resource://autofill/FormAutofill.sys.mjs",
  FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs",
});

// Defines template descriptors for generating elements in convertLayoutToUI.
const fieldTemplates = {
  commonAttributes(item) {
    return {
      id: item.fieldId,
      name: item.fieldId,
      required: item.required,
      value: item.value ?? "",
      // Conditionally add pattern attribute since pattern=""/false/undefined
      // results in weird behaviour.
      ...(item.pattern && { pattern: item.pattern }),
    };
  },
  input(item) {
    return {
      tag: "input",
      type: item.type ?? "text",
      ...this.commonAttributes(item),
    };
  },
  textarea(item) {
    return {
      tag: "textarea",
      ...this.commonAttributes(item),
    };
  },
  select(item) {
    return {
      tag: "select",
      children: item.options.map(({ value, text }) => ({
        tag: "option",
        selected: value === item.value,
        value,
        text,
      })),
      ...this.commonAttributes(item),
    };
  },
};

/**
 * Creates an HTML element with specified attributes and children.
 *
 * @param {string} tag - Tag name for the element to create.
 * @param {object} options - Options object containing attributes and children.
 * @param {object} options.attributes - Element's Attributes/Props (id, class, etc.)
 * @param {Array} options.children - Element's children (array of objects with tag and options).
 * @returns {HTMLElement} The newly created element.
 */
const createElement = (tag, { children = [], ...attributes }) => {
  const element = document.createElement(tag);

  for (let [attributeName, attributeValue] of Object.entries(attributes)) {
    if (attributeName in element) {
      element[attributeName] = attributeValue;
    } else {
      element.setAttribute(attributeName, attributeValue);
    }
  }

  for (let { tag: childTag, ...childRest } of children) {
    element.appendChild(createElement(childTag, childRest));
  }

  return element;
};

/**
 * Generator that creates UI elements from `fields` object, using localization from `l10nStrings`.
 *
 * @param {Array} fields - Array of objects as returned from `FormAutofillUtils.getFormLayout`.
 * @param {object} l10nStrings - Key-value pairs for field label localization.
 * @yields {HTMLElement} - A localized label element with constructed from a field.
 */
function* convertLayoutToUI(fields, l10nStrings) {
  for (const item of fields) {
    // eslint-disable-next-line no-nested-ternary
    const fieldTag = item.options
      ? "select"
      : item.multiline
      ? "textarea"
      : "input";

    const fieldUI = {
      label: {
        id: `${item.fieldId}-container`,
        class: `container ${item.newLine ? "new-line" : ""}`,
      },
      field: fieldTemplates[fieldTag](item),
      span: {
        class: "label-text",
        textContent: l10nStrings[item.l10nId] ?? "",
      },
    };

    const label = createElement("label", fieldUI.label);
    const { tag, ...rest } = fieldUI.field;
    const span = createElement("span", fieldUI.span);
    label.appendChild(span);
    const field = createElement(tag, rest);
    label.appendChild(field);
    yield label;
  }
}

/**
 * Retrieves the current form data from the current form element on the page.
 * NOTE: We are intentionally not using FormData here because on iOS we have states where
 *       selects are disabled and FormData ignores disabled elements. We want getCurrentFormData
 *       to always refelect the exact state of the form.
 *
 * @returns {object} An object containing key-value pairs of form data.
 */
export const getCurrentFormData = () => {
  const formData = {};
  for (const element of document.querySelector("form").elements) {
    formData[element.name] = element.value ?? "";
  }
  return formData;
};

/**
 * Checks if the form can be submitted based on the number of non-empty values.
 * TODO(Bug 1891734): Add address validation. Right now we don't do any validation. (2 fields mimics the old behaviour ).
 *
 * @returns {boolean} True if the form can be submitted
 */
export const canSubmitForm = () => {
  const formData = getCurrentFormData();
  const validValues = Object.values(formData).filter(Boolean);
  return validValues.length >= 2;
};

/**
 * Generates a form layout based on record data and localization strings.
 *
 * @param {HTMLFormElement} formElement - Target form element.
 * @param {object} record - Address record, includes at least country code defaulted to FormAutofill.DEFAULT_REGION.
 * @param {object} l10nStrings - Localization strings map.
 */
export const createFormLayoutFromRecord = (
  formElement,
  record = { country: lazy.FormAutofill.DEFAULT_REGION },
  l10nStrings = {}
) => {
  // Always clear select values because they are not persisted between countries.
  // For example from US with state NY, we don't want the address-level1 to be NY
  // when changing to another country that doesn't have state options
  const selects = formElement.querySelectorAll("select:not(#country)");
  for (const select of selects) {
    select.value = "";
  }

  // Get old data to persist before clearing form
  const formData = getCurrentFormData();
  record = {
    ...record,
    ...formData,
  };

  formElement.innerHTML = "";
  const fields = lazy.FormAutofillUtils.getFormLayout(record);

  const layoutGenerator = convertLayoutToUI(fields, l10nStrings);

  for (const fieldElement of layoutGenerator) {
    formElement.appendChild(fieldElement);
  }

  document.querySelector("#country").addEventListener(
    "change",
    ev =>
      // Allow some time for the user to type
      // before we set the new country and re-render
      setTimeout(() => {
        record.country = ev.target.value;
        createFormLayoutFromRecord(formElement, record, l10nStrings);
      }, 300),
    { once: true }
  );

  // Used to notify tests that the form has been updated and is ready
  window.dispatchEvent(new CustomEvent("FormReadyForTests"));
};
PK
!<|���( ( $chrome/content/autofillEditForms.mjs/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* eslint-disable mozilla/balanced-listeners */ // Not relevant since the document gets unloaded.

const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
  FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs",
});

class EditAutofillForm {
  constructor(elements) {
    this._elements = elements;
  }

  /**
   * Fill the form with a record object.
   *
   * @param  {object} [record = {}]
   */
  loadRecord(record = {}) {
    for (let field of this._elements.form.elements) {
      let value = record[field.id];
      value = typeof value == "undefined" ? "" : value;

      if (record.guid) {
        field.value = value;
      } else if (field.localName == "select") {
        this.setDefaultSelectedOptionByValue(field, value);
      } else {
        // Use .defaultValue instead of .value to avoid setting the `dirty` flag
        // which triggers form validation UI.
        field.defaultValue = value;
      }
    }
    if (!record.guid) {
      // Reset the dirty value flag and validity state.
      this._elements.form.reset();
    } else {
      for (let field of this._elements.form.elements) {
        this.updatePopulatedState(field);
        this.updateCustomValidity(field);
      }
    }
  }

  setDefaultSelectedOptionByValue(select, value) {
    for (let option of select.options) {
      option.defaultSelected = option.value == value;
    }
  }

  /**
   * Get a record from the form suitable for a save/update in storage.
   *
   * @returns {object}
   */
  buildFormObject() {
    let initialObject = {};
    if (this.hasMailingAddressFields) {
      // Start with an empty string for each mailing-address field so that any
      // fields hidden for the current country are blanked in the return value.
      initialObject = {
        "street-address": "",
        "address-level3": "",
        "address-level2": "",
        "address-level1": "",
        "postal-code": "",
      };
    }

    return Array.from(this._elements.form.elements).reduce((obj, input) => {
      if (!input.disabled) {
        obj[input.id] = input.value;
      }
      return obj;
    }, initialObject);
  }

  /**
   * Handle events
   *
   * @param  {DOMEvent} event
   */
  handleEvent(event) {
    switch (event.type) {
      case "change": {
        this.handleChange(event);
        break;
      }
      case "input": {
        this.handleInput(event);
        break;
      }
    }
  }

  /**
   * Handle change events
   *
   * @param  {DOMEvent} event
   */
  handleChange(event) {
    this.updatePopulatedState(event.target);
  }

  /**
   * Handle input events
   */
  handleInput(_e) {}

  /**
   * Attach event listener
   */
  attachEventListeners() {
    this._elements.form.addEventListener("input", this);
  }

  /**
   * Set the field-populated attribute if the field has a value.
   *
   * @param {DOMElement} field The field that will be checked for a value.
   */
  updatePopulatedState(field) {
    let span = field.parentNode.querySelector(".label-text");
    if (!span) {
      return;
    }
    span.toggleAttribute("field-populated", !!field.value.trim());
  }

  /**
   * Run custom validity routines specific to the field and type of form.
   *
   * @param {DOMElement} _field The field that will be validated.
   */
  updateCustomValidity(_field) {}
}

export class EditCreditCard extends EditAutofillForm {
  /**
   * @param {HTMLElement[]} elements
   * @param {object} record with a decrypted cc-number
   * @param {object} addresses in an object with guid keys for the billing address picker.
   */
  constructor(elements, record, addresses) {
    super(elements);

    this._addresses = addresses;
    Object.assign(this._elements, {
      ccNumber: this._elements.form.querySelector("#cc-number"),
      invalidCardNumberStringElement: this._elements.form.querySelector(
        "#invalidCardNumberString"
      ),
      month: this._elements.form.querySelector("#cc-exp-month"),
      year: this._elements.form.querySelector("#cc-exp-year"),
      billingAddress: this._elements.form.querySelector("#billingAddressGUID"),
      billingAddressRow:
        this._elements.form.querySelector(".billingAddressRow"),
    });

    this.attachEventListeners();
    this.loadRecord(record, addresses);
  }

  loadRecord(record, addresses, preserveFieldValues) {
    // _record must be updated before generateYears and generateBillingAddressOptions are called.
    this._record = record;
    this._addresses = addresses;
    this.generateBillingAddressOptions(preserveFieldValues);
    if (!preserveFieldValues) {
      // Re-generating the months will reset the selected option.
      this.generateMonths();
      // Re-generating the years will reset the selected option.
      this.generateYears();
      super.loadRecord(record);
    }
  }

  generateMonths() {
    const count = 12;

    // Clear the list
    this._elements.month.textContent = "";

    // Empty month option
    this._elements.month.appendChild(new Option());

    // Populate month list. Format: "month number - month name"
    let dateFormat = new Intl.DateTimeFormat(navigator.language, {
      month: "long",
    }).format;
    for (let i = 0; i < count; i++) {
      let monthNumber = (i + 1).toString();
      let monthName = dateFormat(new Date(1970, i));
      let option = new Option();
      option.value = monthNumber;
      // XXX: Bug 1446164 - Localize this string.
      option.textContent = `${monthNumber.padStart(2, "0")} - ${monthName}`;
      this._elements.month.appendChild(option);
    }
  }

  generateYears() {
    const count = 11;
    const currentYear = new Date().getFullYear();
    const ccExpYear = this._record && this._record["cc-exp-year"];

    // Clear the list
    this._elements.year.textContent = "";

    // Provide an empty year option
    this._elements.year.appendChild(new Option());

    if (ccExpYear && ccExpYear < currentYear) {
      this._elements.year.appendChild(new Option(ccExpYear));
    }

    for (let i = 0; i < count; i++) {
      let year = currentYear + i;
      let option = new Option(year);
      this._elements.year.appendChild(option);
    }

    if (ccExpYear && ccExpYear > currentYear + count) {
      this._elements.year.appendChild(new Option(ccExpYear));
    }
  }

  generateBillingAddressOptions(preserveFieldValues) {
    let billingAddressGUID;
    if (preserveFieldValues && this._elements.billingAddress.value) {
      billingAddressGUID = this._elements.billingAddress.value;
    } else if (this._record) {
      billingAddressGUID = this._record.billingAddressGUID;
    }

    this._elements.billingAddress.textContent = "";

    this._elements.billingAddress.appendChild(new Option("", ""));

    let hasAddresses = false;
    for (let [guid, address] of Object.entries(this._addresses)) {
      hasAddresses = true;
      let selected = guid == billingAddressGUID;
      let option = new Option(
        lazy.FormAutofillUtils.getAddressLabel(address),
        guid,
        selected,
        selected
      );
      this._elements.billingAddress.appendChild(option);
    }

    this._elements.billingAddressRow.hidden = !hasAddresses;
  }

  attachEventListeners() {
    this._elements.form.addEventListener("change", this);
    super.attachEventListeners();
  }

  handleInput(event) {
    // Clear the error message if cc-number is valid
    if (
      event.target == this._elements.ccNumber &&
      lazy.FormAutofillUtils.isCCNumber(this._elements.ccNumber.value)
    ) {
      this._elements.ccNumber.setCustomValidity("");
    }
    super.handleInput(event);
  }

  updateCustomValidity(field) {
    super.updateCustomValidity(field);

    // Mark the cc-number field as invalid if the number is empty or invalid.
    if (
      field == this._elements.ccNumber &&
      !lazy.FormAutofillUtils.isCCNumber(field.value)
    ) {
      let invalidCardNumberString =
        this._elements.invalidCardNumberStringElement.textContent;
      field.setCustomValidity(invalidCardNumberString || " ");
    }
  }
}
PK
!<gL�JJ chrome/content/editAddress.xhtml<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title data-l10n-id="autofill-add-address-title"></title>
    <link rel="localization" href="browser/preferences/formAutofill.ftl" />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/skin/editDialog-shared.css"
    />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/skin/editAddress.css"
    />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/skin/editDialog.css"
    />
    <script
      type="module"
      src="chrome://global/content/elements/moz-button-group.mjs"
    ></script>
  </head>
  <body>
    <form id="form" class="editAddressForm" autocomplete="off"></form>
    <div id="controls-container">
      <span
        id="country-warning-message"
        data-l10n-id="autofill-country-warning-message"
      />
      <moz-button-group>
        <button id="cancel" data-l10n-id="autofill-cancel-button" />
        <button id="save" class="primary" data-l10n-id="autofill-save-button" />
      </moz-button-group>
    </div>
    <!-- eslint-disable -->
    <script type="module">
      import { createFormLayoutFromRecord } from "chrome://formautofill/content/addressFormLayout.mjs";
      import { EditAddressDialog } from "chrome://formautofill/content/editDialog.mjs";

      const { record, noValidate, l10nStrings } = window.arguments?.[0] ?? {};
      const formElement = document.querySelector("form");
      formElement.noValidate = !!noValidate;
      createFormLayoutFromRecord(formElement, record, l10nStrings);

      new EditAddressDialog(
        {
          title: document.querySelector("title"),
          cancel: document.getElementById("cancel"),
          save: document.getElementById("save"),
        },
        record
      );
    </script>
    <!-- eslint-enable -->
  </body>
</html>
PK
!<�q�{

#chrome/content/editCreditCard.xhtml<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title data-l10n-id="autofill-add-card-title"></title>
    <link rel="localization" href="browser/preferences/formAutofill.ftl" />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/skin/editDialog-shared.css"
    />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/skin/editCreditCard.css"
    />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/skin/editDialog.css"
    />
  </head>
  <body>
    <form id="form" class="editCreditCardForm contentPane" autocomplete="off">
      <!--
        The <span class="label-text" …/> needs to be after the form field in the same element in
        order to get proper label styling with :focus and :user-invalid
      -->
      <label id="cc-number-container" class="container" role="none">
        <span
          id="invalidCardNumberString"
          hidden="hidden"
          data-l10n-id="autofill-card-invalid-number"
        ></span>
        <!-- Because there is text both before and after the input, a11y will
          include the value of the input in the label. Therefore, we override
          with aria-labelledby.
        -->
        <input
          id="cc-number"
          type="text"
          required="required"
          minlength="14"
          pattern="[\- 0-9]+"
          aria-labelledby="cc-number-label"
        />
        <span
          id="cc-number-label"
          data-l10n-id="autofill-card-number"
          class="label-text"
        />
      </label>
      <label id="cc-exp-month-container" class="container">
        <select id="cc-exp-month" required="required">
          <option />
        </select>
        <span data-l10n-id="autofill-card-expires-month" class="label-text" />
      </label>
      <label id="cc-exp-year-container" class="container">
        <select id="cc-exp-year" required="required">
          <option />
        </select>
        <span data-l10n-id="autofill-card-expires-year" class="label-text" />
      </label>
      <label id="cc-name-container" class="container">
        <input id="cc-name" type="text" required="required" />
        <span data-l10n-id="autofill-card-name-on-card" class="label-text" />
      </label>
      <label id="cc-csc-container" class="container" hidden="hidden">
        <!-- The CSC container will get filled in by forms that need a CSC (using csc-input.js) -->
      </label>
      <div
        id="billingAddressGUID-container"
        class="billingAddressRow container rich-picker"
      >
        <select id="billingAddressGUID" required="required"></select>
        <label
          for="billingAddressGUID"
          data-l10n-id="autofill-card-billing-address"
          class="label-text"
        />
      </div>
    </form>
    <div id="controls-container">
      <button id="cancel" data-l10n-id="autofill-cancel-button" />
      <button id="save" class="primary" data-l10n-id="autofill-save-button" />
    </div>

    <!-- eslint-disable -->
    <script type="module">
      import { EditCreditCardDialog } from "chrome://formautofill/content/editDialog.mjs";
      import { EditCreditCard } from "chrome://formautofill/content/autofillEditForms.mjs";
      const { record } = window.arguments?.[0] ?? {};

      const fieldContainer = new EditCreditCard(
        {
          form: document.getElementById("form"),
        },
        record,
        []
      );

      new EditCreditCardDialog(
        {
          title: document.querySelector("title"),
          fieldContainer,
          controlsContainer: document.getElementById("controls-container"),
          cancel: document.getElementById("cancel"),
          save: document.getElementById("save"),
        },
        record
      );
    </script>
    <!-- eslint-enable -->
  </body>
</html>
PK
!<2n��aachrome/content/editDialog.mjs/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* eslint-disable mozilla/balanced-listeners */ // Not relevant since the document gets unloaded.

import {
  getCurrentFormData,
  canSubmitForm,
} from "chrome://formautofill/content/addressFormLayout.mjs";

const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
  AutofillTelemetry: "resource://gre/modules/shared/AutofillTelemetry.sys.mjs",
  formAutofillStorage: "resource://autofill/FormAutofillStorage.sys.mjs",
});

class AutofillEditDialog {
  constructor(subStorageName, elements, record) {
    this._storageInitPromise = lazy.formAutofillStorage.initialize();
    this._subStorageName = subStorageName;
    this._elements = elements;
    this._record = record;
    this.localizeDocument();
    window.addEventListener("load", this, { once: true });
  }

  async init() {
    this.updateSaveButtonState();
    this.attachEventListeners();
    // For testing only: signal to tests that the dialog is ready for testing.
    // This is likely no longer needed since retrieving from storage is fully
    // handled in manageDialog.js now.
    window.dispatchEvent(new CustomEvent("FormReadyForTests"));
  }

  /**
   * Get storage and ensure it has been initialized.
   *
   * @returns {object}
   */
  async getStorage() {
    await this._storageInitPromise;
    return lazy.formAutofillStorage[this._subStorageName];
  }

  /**
   * Asks FormAutofillParent to save or update an record.
   *
   * @param  {object} record
   * @param  {string} guid [optional]
   */
  async saveRecord(record, guid) {
    let storage = await this.getStorage();
    if (guid) {
      await storage.update(guid, record);
    } else {
      await storage.add(record);
    }
  }

  /**
   * Handle events
   *
   * @param  {DOMEvent} event
   */
  handleEvent(event) {
    switch (event.type) {
      case "load": {
        this.init();
        break;
      }
      case "click": {
        this.handleClick(event);
        break;
      }
      case "input": {
        this.handleInput(event);
        break;
      }
      case "keypress": {
        this.handleKeyPress(event);
        break;
      }
      case "contextmenu": {
        if (
          !HTMLInputElement.isInstance(event.target) &&
          !HTMLTextAreaElement.isInstance(event.target)
        ) {
          event.preventDefault();
        }
        break;
      }
    }
  }

  /**
   * Handle click events
   *
   * @param  {DOMEvent} event
   */
  handleClick(event) {
    if (event.target == this._elements.cancel) {
      window.close();
    }
    if (event.target == this._elements.save) {
      this.handleSubmit();
    }
  }

  /**
   * Handle input events
   */
  handleInput(_e) {
    this.updateSaveButtonState();
  }

  /**
   * Handle key press events
   *
   * @param  {DOMEvent} event
   */
  handleKeyPress(event) {
    if (event.keyCode == KeyEvent.DOM_VK_ESCAPE) {
      window.close();
    }
  }

  updateSaveButtonState() {
    // Toggle disabled attribute on the save button based on
    // whether the form is filled or empty.
    if (!Object.keys(this._elements.fieldContainer.buildFormObject()).length) {
      this._elements.save.setAttribute("disabled", true);
    } else {
      this._elements.save.removeAttribute("disabled");
    }
  }

  /**
   * Attach event listener
   */
  attachEventListeners() {
    window.addEventListener("keypress", this);
    window.addEventListener("contextmenu", this);
    this._elements.save.addEventListener("click", this);
    this._elements.cancel.addEventListener("click", this);
    document.addEventListener("input", this);
  }

  // An interface to be inherited.
  localizeDocument() {}

  recordFormSubmit() {
    let method = this._record?.guid ? "edit" : "add";
    lazy.AutofillTelemetry.recordManageEvent(this.telemetryType, method);
  }
}

export class EditAddressDialog extends AutofillEditDialog {
  telemetryType = lazy.AutofillTelemetry.ADDRESS;

  constructor(elements, record) {
    super("addresses", elements, record);
    if (record) {
      lazy.AutofillTelemetry.recordManageEvent(
        this.telemetryType,
        "show_entry"
      );
    }
  }

  localizeDocument() {
    if (this._record?.guid) {
      document.l10n.setAttributes(
        this._elements.title,
        "autofill-edit-address-title"
      );
    }
  }

  updateSaveButtonState() {
    // Toggle disabled attribute on the save button based on
    // whether the form is filled or empty.
    if (!canSubmitForm()) {
      this._elements.save.setAttribute("disabled", true);
    } else {
      this._elements.save.removeAttribute("disabled");
    }
  }

  async handleSubmit() {
    await this.saveRecord(
      getCurrentFormData(),
      this._record ? this._record.guid : null
    );
    this.recordFormSubmit();

    window.close();
  }
}

export class EditCreditCardDialog extends AutofillEditDialog {
  telemetryType = lazy.AutofillTelemetry.CREDIT_CARD;

  constructor(elements, record) {
    elements.fieldContainer._elements.billingAddress.disabled = true;
    super("creditCards", elements, record);
    elements.fieldContainer._elements.ccNumber.addEventListener(
      "blur",
      this._onCCNumberFieldBlur.bind(this)
    );
    if (record) {
      lazy.AutofillTelemetry.recordManageEvent(
        this.telemetryType,
        "show_entry"
      );
    }
  }

  _onCCNumberFieldBlur() {
    let elem = this._elements.fieldContainer._elements.ccNumber;
    this._elements.fieldContainer.updateCustomValidity(elem);
  }

  localizeDocument() {
    if (this._record?.guid) {
      document.l10n.setAttributes(
        this._elements.title,
        "autofill-edit-card-title2"
      );
    }
  }

  async handleSubmit() {
    let creditCard = this._elements.fieldContainer.buildFormObject();
    if (!this._elements.fieldContainer._elements.form.reportValidity()) {
      return;
    }

    try {
      await this.saveRecord(
        creditCard,
        this._record ? this._record.guid : null
      );

      this.recordFormSubmit();

      window.close();
    } catch (ex) {
      console.error(ex);
    }
  }
}
PK
!<�iet��"chrome/content/formfill-anchor.svg<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity">
  <path d="M7.3 6h1.5c.1 0 .2-.1.2-.3V2c0-.5-.4-1-1-1s-1 .4-1 1v3.8c0 .1.1.2.3.2z"/>
  <path d="M13.5 3H11c-.6 0-1 .4-1 1s.4 1 1 1h2.5c.3 0 .5.2.5.5v7c0 .3-.2.5-.5.5h-11c-.3 0-.5-.3-.5-.5v-7c0-.3.2-.5.5-.5H5c.6 0 1-.4 1-1s-.4-1-1-1H2.5C1.1 3 0 4.1 0 5.5v7C0 13.8 1.1 15 2.5 15h11c1.4 0 2.5-1.1 2.5-2.5v-7C16 4.1 14.9 3 13.5 3z"/>
  <path d="M3.6 7h2.8c.3 0 .6.2.6.5v2.8c0 .4-.3.7-.6.7H3.6c-.3 0-.6-.3-.6-.6V7.5c0-.3.3-.5.6-.5zM9.5 8h3c.3 0 .5-.3.5-.5s-.2-.5-.5-.5h-3c-.3 0-.5.2-.5.5s.2.5.5.5zM9.5 9c-.3 0-.5.2-.5.5s.2.5.5.5h2c.3 0 .5-.2.5-.5s-.2-.5-.5-.5h-2z"/>
</svg>
PK
!<P+F���+chrome/content/icon-credit-card-generic.svg<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" fill="context-fill" viewBox="0 0 16 16">
  <path d="M4.5,9.4H3.2c-0.3,0-0.5,0.2-0.5,0.5s0.2,0.5,0.5,0.5h1.3c0.3,0,0.5-0.2,0.5-0.5S4.8,9.4,4.5,9.4z"/>
  <path d="M9.3,9.4H6.2c-0.3,0-0.5,0.2-0.5,0.5s0.2,0.5,0.5,0.5h3.2c0.3,0,0.5-0.2,0.5-0.5S9.6,9.4,9.3,9.4z"/>
  <path d="M14,2H2C0.9,2,0,2.9,0,4v8c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C16,2.9,15.1,2,14,2z M14,12H2V7.7h12V12z M14,6H2V4h12V6z"/>
</svg>
PK
!<e�_�#chrome/content/icon-credit-card.svg<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" fill="context-fill" fill-opacity="context-fill-opacity" viewBox="0 0 32 32">
  <path d="M9 22.2H6.4c-.6 0-1 .4-1 1s.4 1 1 1H9c.6 0 1-.4 1-1s-.4-1-1-1z"/>
  <path d="M28 7.6v8H4v-4h10v-4H4c-2.2 0-4 1.8-4 4v16c0 2.2 1.8 4 4 4h24c2.2 0 4-1.8 4-4v-16c0-2.2-1.8-4-4-4zm-24 20V19h24v8.6H4z"/>
  <path d="M19.2 22.2h-6.3c-.6 0-1 .4-1 1s.4 1 1 1h6.3c.6 0 1-.4 1-1s-.5-1-1-1zM16.3 7.9c-.4.4-.4 1 0 1.4l4 4c.4.4 1 .4 1.4 0l4-4c.4-.4.4-1 0-1.4s-1-.4-1.4 0L22 10.2v-9c0-.5-.4-1-1-1-.5 0-1 .4-1 1v9l-2.3-2.3c-.4-.4-1-.4-1.4 0z"/>
</svg>
PK
!<�_
���$chrome/content/manageAddresses.xhtml<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html
  xmlns="http://www.w3.org/1999/xhtml"
  data-l10n-id="autofill-manage-dialog"
  data-l10n-attrs="style"
>
  <head>
    <title data-l10n-id="autofill-manage-addresses-title"></title>
    <link rel="localization" href="browser/preferences/formAutofill.ftl" />
    <link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/manageDialog.css"
    />
  </head>
  <body>
    <fieldset>
      <legend data-l10n-id="autofill-manage-addresses-list-header" />
      <select id="addresses" size="9" multiple="multiple" />
    </fieldset>
    <div id="controls-container">
      <button
        id="remove"
        disabled="disabled"
        data-l10n-id="autofill-manage-remove-button"
      />
      <!-- Wrapper is used to properly compute the search tooltip position -->
      <div>
        <button id="add" data-l10n-id="autofill-manage-add-button" />
      </div>
      <button
        id="edit"
        disabled="disabled"
        data-l10n-id="autofill-manage-edit-button"
      />
    </div>
    <!-- eslint-disable -->
    <!-- For some reason eslint complains here about import only available for sourceType: "module" -->
    <!-- even though type is set to module.-->
    <script type="module">
      import { ManageAddresses } from "chrome://formautofill/content/manageDialog.mjs";

      new ManageAddresses({
        records: document.getElementById("addresses"),
        controlsContainer: document.getElementById("controls-container"),
        remove: document.getElementById("remove"),
        add: document.getElementById("add"),
        edit: document.getElementById("edit"),
      });
    </script>
    <!-- eslint-enable -->
  </body>
</html>
PK
!<�o�b��&chrome/content/manageCreditCards.xhtml<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html
  xmlns="http://www.w3.org/1999/xhtml"
  data-l10n-id="autofill-manage-dialog"
  data-l10n-attrs="style"
>
  <head>
    <title data-l10n-id="autofill-manage-payment-methods-title"></title>
    <link rel="localization" href="browser/preferences/formAutofill.ftl" />
    <link rel="localization" href="toolkit/formautofill/formAutofill.ftl" />
    <link rel="localization" href="toolkit/payments/payments.ftl" />
    <link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
    <link
      rel="stylesheet"
      href="chrome://formautofill/content/manageDialog.css"
    />
  </head>
  <body>
    <fieldset>
      <legend data-l10n-id="autofill-manage-cards-list-header" />
      <select id="credit-cards" size="9" multiple="multiple" />
    </fieldset>
    <div id="controls-container">
      <button
        id="remove"
        disabled="disabled"
        data-l10n-id="autofill-manage-remove-button"
      />
      <!-- Wrapper is used to properly compute the search tooltip position -->
      <div>
        <button id="add" data-l10n-id="autofill-manage-add-button" />
      </div>
      <button
        id="edit"
        disabled="disabled"
        data-l10n-id="autofill-manage-edit-button"
      />
    </div>
    <!-- eslint-disable -->
    <!-- For some reason eslint complains here about import only available for sourceType: "module" -->
    <!-- eventhough type is set to module -->
    <script type="module">
      import { ManageCreditCards } from "chrome://formautofill/content/manageDialog.mjs";

      new ManageCreditCards({
        records: document.getElementById("credit-cards"),
        controlsContainer: document.getElementById("controls-container"),
        remove: document.getElementById("remove"),
        add: document.getElementById("add"),
        edit: document.getElementById("edit"),
      });
    </script>
    <!-- eslint-enable -->
  </body>
</html>
PK
!<p{a-AAchrome/content/manageDialog.css/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

html {
  /* Prevent unnecessary horizontal scroll bar from showing */
  overflow-x: hidden;
}

div {
  display: flex;
}

button {
  padding-inline: 10px;
}

fieldset {
  margin: 0 4px;
  padding: 0;
  border: none;

  > legend {
    box-sizing: border-box;
    width: 100%;
    padding: 0.4em 0.7em;
    background-color: var(--in-content-box-background);
    border: 1px solid var(--in-content-box-border-color);
    border-radius: 2px 2px 0 0;
    user-select: none;
  }
}

option:nth-child(even) {
  background-color: var(--in-content-box-background-odd);
}

#addresses,
#credit-cards {
  width: 100%;
  height: 16.6em;
  margin: 0;
  padding-inline: 0;
  border-top: none;
  border-radius: 0 0 2px 2px;

  > option {
    display: flex;
    align-items: center;
    height: 1.6em;
    padding-inline-start: 0.6em;
  }
}

#controls-container {
  margin-top: 1em;
}

#remove {
  margin-inline-end: auto;
}

#credit-cards {
  > option::before {
    content: "";
    background: url("icon-credit-card-generic.svg") no-repeat;
    background-size: contain;
    float: inline-start;
    width: 16px;
    height: 16px;
    padding-inline-end: 10px;
    -moz-context-properties: fill;
    fill: currentColor;
  }

  /*
    We use .png / @2x.png images where we don't yet have a vector version of a logo
  */
  &.branded > option {
    &[cc-type="amex"]::before {
      background-image: url("third-party/cc-logo-amex.png");
    }

    &[cc-type="cartebancaire"]::before {
      background-image: url("third-party/cc-logo-cartebancaire.png");
    }

    &[cc-type="diners"]::before {
      background-image: url("third-party/cc-logo-diners.svg");
    }

    &[cc-type="discover"]::before {
      background-image: url("third-party/cc-logo-discover.png");
    }

    &[cc-type="jcb"]::before {
      background-image: url("third-party/cc-logo-jcb.svg");
    }

    &[cc-type="mastercard"]::before {
      background-image: url("third-party/cc-logo-mastercard.svg");
    }

    &[cc-type="mir"]::before {
      background-image: url("third-party/cc-logo-mir.svg");
    }

    &[cc-type="unionpay"]::before {
      background-image: url("third-party/cc-logo-unionpay.svg");
    }

    &[cc-type="visa"]::before {
      background-image: url("third-party/cc-logo-visa.svg");
    }

    @media (min-resolution: 1.1dppx) {
      &[cc-type="amex"]::before {
        background-image: url("third-party/cc-logo-amex@2x.png");
      }

      &[cc-type="cartebancaire"]::before {
        background-image: url("third-party/cc-logo-cartebancaire@2x.png");
      }

      &[cc-type="discover"]::before {
        background-image: url("third-party/cc-logo-discover@2x.png");
      }
    }
  }
}
PK
!<u�K77chrome/content/manageDialog.mjs/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const EDIT_ADDRESS_URL = "chrome://formautofill/content/editAddress.xhtml";
const EDIT_CREDIT_CARD_URL =
  "chrome://formautofill/content/editCreditCard.xhtml";

const { AppConstants } = ChromeUtils.importESModule(
  "resource://gre/modules/AppConstants.sys.mjs"
);
const { FormAutofill } = ChromeUtils.importESModule(
  "resource://autofill/FormAutofill.sys.mjs"
);
const { AutofillTelemetry } = ChromeUtils.importESModule(
  "resource://gre/modules/shared/AutofillTelemetry.sys.mjs"
);

const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
  CreditCard: "resource://gre/modules/CreditCard.sys.mjs",
  FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs",
  OSKeyStore: "resource://gre/modules/OSKeyStore.sys.mjs",
  formAutofillStorage: "resource://autofill/FormAutofillStorage.sys.mjs",
});

ChromeUtils.defineLazyGetter(lazy, "log", () =>
  FormAutofill.defineLogGetter(lazy, "manageAddresses")
);

ChromeUtils.defineLazyGetter(
  lazy,
  "l10n",
  () => new Localization(["	browser/preferences/formAutofill.ftl"], true)
);

class ManageRecords {
  constructor(subStorageName, elements) {
    this._storageInitPromise = lazy.formAutofillStorage.initialize();
    this._subStorageName = subStorageName;
    this._elements = elements;
    this._newRequest = false;
    this._isLoadingRecords = false;
    this.prefWin = window.opener;
    window.addEventListener("load", this, { once: true });
  }

  async init() {
    await this.loadRecords();
    this.attachEventListeners();
    // For testing only: Notify when the dialog is ready for interaction
    window.dispatchEvent(new CustomEvent("FormReadyForTests"));
  }

  uninit() {
    lazy.log.debug("uninit");
    this.detachEventListeners();
    this._elements = null;
  }

  /**
   * Get the selected options on the addresses element.
   *
   * @returns {Array<DOMElement>}
   */
  get _selectedOptions() {
    return Array.from(this._elements.records.selectedOptions);
  }

  /**
   * Get storage and ensure it has been initialized.
   *
   * @returns {object}
   */
  async getStorage() {
    await this._storageInitPromise;
    return lazy.formAutofillStorage[this._subStorageName];
  }

  /**
   * Load records and render them. This function is a wrapper for _loadRecords
   * to ensure any reentrant will be handled well.
   */
  async loadRecords() {
    // This function can be early returned when there is any reentrant happends.
    // "_newRequest" needs to be set to ensure all changes will be applied.
    if (this._isLoadingRecords) {
      this._newRequest = true;
      return;
    }
    this._isLoadingRecords = true;

    await this._loadRecords();

    // _loadRecords should be invoked again if there is any multiple entrant
    // during running _loadRecords(). This step ensures that the latest request
    // still is applied.
    while (this._newRequest) {
      this._newRequest = false;
      await this._loadRecords();
    }
    this._isLoadingRecords = false;

    // For testing only: Notify when records are loaded
    this._elements.records.dispatchEvent(new CustomEvent("RecordsLoaded"));
  }

  async _loadRecords() {
    let storage = await this.getStorage();
    let records = await storage.getAll();
    // Sort by last used time starting with most recent
    records.sort((a, b) => {
      let aLastUsed = a.timeLastUsed || a.timeLastModified;
      let bLastUsed = b.timeLastUsed || b.timeLastModified;
      return bLastUsed - aLastUsed;
    });
    await this.renderRecordElements(records);
    this.updateButtonsStates(this._selectedOptions.length);
  }

  /**
   * Render the records onto the page while maintaining selected options if
   * they still exist.
   *
   * @param  {Array<object>} records
   */
  async renderRecordElements(records) {
    let selectedGuids = this._selectedOptions.map(option => option.value);
    this.clearRecordElements();
    for (let record of records) {
      let { id, args, raw } = await this.getLabelInfo(record);
      let option = new Option(
        raw ?? "",
        record.guid,
        false,
        selectedGuids.includes(record.guid)
      );
      if (id) {
        document.l10n.setAttributes(option, id, args);
      }

      option.record = record;
      this._elements.records.appendChild(option);
    }
  }

  /**
   * Remove all existing record elements.
   */
  clearRecordElements() {
    const parentElement = this._elements.records;
    while (parentElement.lastChild) {
      parentElement.removeChild(parentElement.lastChild);
    }
  }

  /**
   * Remove records by selected options.
   *
   * @param  {Array<DOMElement>} options
   */
  async removeRecords(options) {
    let storage = await this.getStorage();
    // Pause listening to storage change event to avoid triggering `loadRecords`
    // when removing records
    Services.obs.removeObserver(this, "formautofill-storage-changed");

    for (let option of options) {
      storage.remove(option.value);
      option.remove();
    }
    this.updateButtonsStates(this._selectedOptions);

    // Resume listening to storage change event
    Services.obs.addObserver(this, "formautofill-storage-changed");
    // For testing only: notify record(s) has been removed
    this._elements.records.dispatchEvent(new CustomEvent("RecordsRemoved"));

    for (let i = 0; i < options.length; i++) {
      AutofillTelemetry.recordManageEvent(this.telemetryType, "delete");
    }
  }

  /**
   * Enable/disable the Edit and Remove buttons based on number of selected
   * options.
   *
   * @param  {number} selectedCount
   */
  updateButtonsStates(selectedCount) {
    lazy.log.debug("updateButtonsStates:", selectedCount);
    if (selectedCount == 0) {
      this._elements.edit.setAttribute("disabled", "disabled");
      this._elements.remove.setAttribute("disabled", "disabled");
    } else if (selectedCount == 1) {
      this._elements.edit.removeAttribute("disabled");
      this._elements.remove.removeAttribute("disabled");
    } else if (selectedCount > 1) {
      this._elements.edit.setAttribute("disabled", "disabled");
      this._elements.remove.removeAttribute("disabled");
    }
    this._elements.add.disabled = !Services.prefs.getBoolPref(
      `extensions.formautofill.${this._subStorageName}.enabled`
    );
  }

  /**
   * Handle events
   *
   * @param  {DOMEvent} event
   */
  handleEvent(event) {
    switch (event.type) {
      case "load": {
        this.init();
        break;
      }
      case "click": {
        this.handleClick(event);
        break;
      }
      case "change": {
        this.updateButtonsStates(this._selectedOptions.length);
        break;
      }
      case "unload": {
        this.uninit();
        break;
      }
      case "keypress": {
        this.handleKeyPress(event);
        break;
      }
      case "contextmenu": {
        event.preventDefault();
        break;
      }
    }
  }

  /**
   * Handle click events
   *
   * @param  {DOMEvent} event
   */
  handleClick(event) {
    if (event.target == this._elements.remove) {
      this.removeRecords(this._selectedOptions);
    } else if (event.target == this._elements.add) {
      this.openEditDialog();
    } else if (
      event.target == this._elements.edit ||
      (event.target.parentNode == this._elements.records && event.detail > 1)
    ) {
      this.openEditDialog(this._selectedOptions[0].record);
    }
  }

  /**
   * Handle key press events
   *
   * @param  {DOMEvent} event
   */
  handleKeyPress(event) {
    if (event.keyCode == KeyEvent.DOM_VK_ESCAPE) {
      window.close();
    }
    if (event.keyCode == KeyEvent.DOM_VK_DELETE) {
      this.removeRecords(this._selectedOptions);
    }
  }

  observe(_subject, topic, _data) {
    switch (topic) {
      case "formautofill-storage-changed": {
        this.loadRecords();
      }
    }
  }

  /**
   * Attach event listener
   */
  attachEventListeners() {
    window.addEventListener("unload", this, { once: true });
    window.addEventListener("keypress", this);
    window.addEventListener("contextmenu", this);
    this._elements.records.addEventListener("change", this);
    this._elements.records.addEventListener("click", this);
    this._elements.controlsContainer.addEventListener("click", this);
    Services.obs.addObserver(this, "formautofill-storage-changed");
  }

  /**
   * Remove event listener
   */
  detachEventListeners() {
    window.removeEventListener("keypress", this);
    window.removeEventListener("contextmenu", this);
    this._elements.records.removeEventListener("change", this);
    this._elements.records.removeEventListener("click", this);
    this._elements.controlsContainer.removeEventListener("click", this);
    Services.obs.removeObserver(this, "formautofill-storage-changed");
  }
}

export class ManageAddresses extends ManageRecords {
  telemetryType = AutofillTelemetry.ADDRESS;

  constructor(elements) {
    super("addresses", elements);
    elements.add.setAttribute(
      "search-l10n-ids",
      lazy.FormAutofillUtils.EDIT_ADDRESS_L10N_IDS.join(",")
    );
    AutofillTelemetry.recordManageEvent(this.telemetryType, "show");
  }

  static getAddressL10nStrings() {
    const l10nIds = [
      ...lazy.FormAutofillUtils.MANAGE_ADDRESSES_L10N_IDS,
      ...lazy.FormAutofillUtils.EDIT_ADDRESS_L10N_IDS,
    ];

    return l10nIds.reduce(
      (acc, id) => ({
        ...acc,
        [id]: lazy.l10n.formatValueSync(id),
      }),
      {}
    );
  }

  /**
   * Open the edit address dialog to create/edit an address.
   *
   * @param  {object} address [optional]
   */
  openEditDialog(address) {
    this.prefWin.gSubDialog.open(EDIT_ADDRESS_URL, undefined, {
      record: address,
      // Don't validate in preferences since it's fine for fields to be missing
      // for autofill purposes. For PaymentRequest addresses get more validation.
      noValidate: true,
      l10nStrings: ManageAddresses.getAddressL10nStrings(),
    });
  }

  getLabelInfo(address) {
    return { raw: lazy.FormAutofillUtils.getAddressLabel(address) };
  }
}

export class ManageCreditCards extends ManageRecords {
  telemetryType = AutofillTelemetry.CREDIT_CARD;

  constructor(elements) {
    super("creditCards", elements);
    elements.add.setAttribute(
      "search-l10n-ids",
      lazy.FormAutofillUtils.EDIT_CREDITCARD_L10N_IDS.join(",")
    );

    this._isDecrypted = false;
    AutofillTelemetry.recordManageEvent(this.telemetryType, "show");
  }

  /**
   * Open the edit address dialog to create/edit a credit card.
   *
   * @param  {object} creditCard [optional]
   */
  async openEditDialog(creditCard) {
    // Ask for reauth if user is trying to edit an existing credit card.
    if (creditCard) {
      const promptMessage = lazy.FormAutofillUtils.reauthOSPromptMessage(
        "autofill-edit-payment-method-os-prompt-macos",
        "autofill-edit-payment-method-os-prompt-windows",
        "autofill-edit-payment-method-os-prompt-other"
      );

      const verified = await lazy.FormAutofillUtils.verifyUserOSAuth(
        FormAutofill.AUTOFILL_CREDITCARDS_REAUTH_PREF,
        promptMessage
      );
      if (!verified) {
        return;
      }
    }
    let decryptedCCNumObj = {};
    if (creditCard && creditCard["cc-number-encrypted"]) {
      try {
        decryptedCCNumObj["cc-number"] = await lazy.OSKeyStore.decrypt(
          creditCard["cc-number-encrypted"]
        );
      } catch (ex) {
        if (ex.result == Cr.NS_ERROR_ABORT) {
          // User shouldn't be ask to reauth here, but it could happen.
          // Return here and skip opening the dialog.
          return;
        }
        // We've got ourselves a real error.
        // Recover from encryption error so the user gets a chance to re-enter
        // unencrypted credit card number.
        decryptedCCNumObj["cc-number"] = "";
        console.error(ex);
      }
    }
    let decryptedCreditCard = Object.assign({}, creditCard, decryptedCCNumObj);
    this.prefWin.gSubDialog.open(
      EDIT_CREDIT_CARD_URL,
      { features: "resizable=no" },
      {
        record: decryptedCreditCard,
      }
    );
  }

  /**
   * Get credit card display label. It should display masked numbers and the
   * cardholder's name, separated by a comma.
   *
   * @param {object} creditCard
   * @returns {Promise<string>}
   */
  async getLabelInfo(creditCard) {
    // The card type is displayed visually using an image. For a11y, we need
    // to expose it as text. We do this using aria-label. However,
    // aria-label overrides the text content, so we must include that also.
    // Since the text content is generated by Fluent, aria-label must be
    // generated by Fluent also.
    const type = creditCard["cc-type"];
    const typeL10nId = lazy.CreditCard.getNetworkL10nId(type);
    const typeName = typeL10nId
      ? await document.l10n.formatValue(typeL10nId)
      : type ?? ""; // Unknown card type
    return lazy.CreditCard.getLabelInfo({
      name: creditCard["cc-name"],
      number: creditCard["cc-number"],
      month: creditCard["cc-exp-month"],
      year: creditCard["cc-exp-year"],
      type: typeName,
    });
  }

  async renderRecordElements(records) {
    // Revert back to encrypted form when re-rendering happens
    this._isDecrypted = false;
    // Display third-party card icons when possible
    this._elements.records.classList.toggle(
      "branded",
      AppConstants.MOZILLA_OFFICIAL
    );
    await super.renderRecordElements(records);

    let options = this._elements.records.options;
    for (let option of options) {
      let record = option.record;
      if (record && record["cc-type"]) {
        option.setAttribute("cc-type", record["cc-type"]);
      } else {
        option.removeAttribute("cc-type");
      }
    }
  }

  updateButtonsStates(selectedCount) {
    super.updateButtonsStates(selectedCount);
  }

  handleClick(event) {
    super.handleClick(event);
  }
}
PK
!<5�|		#chrome/content/skin/editAddress.css/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

.editAddressForm {
  display: flex;
  flex-wrap: wrap;
  /* Use space-between so --grid-column-row-gap is in between the elements on a row */
  justify-content: space-between;
}

dialog:not([subdialog]) .editAddressForm {
  margin-inline: calc(var(--grid-column-row-gap) / -2);
}

.editAddressForm .container {
  /* !important is needed to override preferences.css's generic label rule. */
  margin-top: var(--grid-column-row-gap) !important;
  margin-inline: calc(var(--grid-column-row-gap) / 2);
  flex-grow: 1;

  &.new-line {
    flex: 0 1 100%;
  }

  input, textarea, select {
    width: 100%;
    margin: 0;
  }
}

#country-container {
  /* The country dropdown has a different intrinsic (content) width than the
     other fields which are <input>. */
  flex-basis: calc(50% - var(--grid-column-row-gap));
  flex-grow: 0;
  /* Country names can be longer than 50% which ruins the symmetry in the grid. */
  max-width: calc(50% - var(--grid-column-row-gap));
}

#street-address {
  resize: vertical;
}

#country-warning-message {
  box-sizing: border-box;
  font-size: 1rem;
  display: flex;
  align-items: center;
  text-align: start;
  opacity: .5;
  padding-inline-start: 1em;
  flex: 1;
}

dialog:not([subdialog]) #country-warning-message {
  display: none;
}

moz-button-group{
  margin-inline: 4px;
  margin-block-end: 4px;
}
PK
!<=�q��&chrome/content/skin/editCreditCard.css/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

.editCreditCardForm {
  display: grid;
  grid-template-areas:
    "cc-number          cc-exp-month       cc-exp-year"
    "cc-name            cc-csc             ."
    "billingAddressGUID billingAddressGUID billingAddressGUID";
  grid-template-columns: 4fr 2fr 2fr;
  grid-row-gap: var(--grid-column-row-gap);
  grid-column-gap: var(--grid-column-row-gap);
}

.editCreditCardForm label {
  /* Remove the margin on these labels since they are styled on top of
     the input/select element. */
  margin-inline-start: 0;
  margin-inline-end: 0;
}

.editCreditCardForm .container {
  display: flex;
}

#cc-number-container {
  grid-area: cc-number;
}

#cc-exp-month-container {
  grid-area: cc-exp-month;
}

#cc-exp-year-container {
  grid-area: cc-exp-year;
}

#cc-name-container {
  grid-area: cc-name;
}

#cc-csc-container {
  grid-area: cc-csc;
}

#billingAddressGUID-container {
  grid-area: billingAddressGUID;
}

#billingAddressGUID {
  grid-area: dropdown;
}
PK
!<{��v
v
)chrome/content/skin/editDialog-shared.css/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

:root {
  --in-field-label-size: .8em;
  --grid-column-row-gap: 8px;
  /* Use the animation-easing-function that is defined in xul.css. */
  --animation-easing-function: cubic-bezier(.07,.95,0,1);
}

dialog[subdialog] form {
  /* Add extra space to ensure invalid input box is displayed properly */
  padding: 2px;
}

/* The overly specific input attributes are required to override
   padding from common.css */
form input[type="email"],
form input[type="tel"],
form input[type="text"],
form textarea,
form select {
  flex-grow: 1;
  padding-top: calc(var(--in-field-label-size) + .4em);
}

form input[type="tel"] {
  text-align: match-parent;
}

select {
  margin: 0;
  padding-bottom: 5px;
}

form label[class="container"] select {
  min-width: 0;
}

form label,
form div {
  /* Positioned so that the .label-text and .error-text children will be
     positioned relative to this. */
  position: relative;
  display: block;
  line-height: 1em;
}

/* Reset margins for inputs and textareas, overriding in-content styles */
#form textarea,
#form input {
  margin: 0;
}

form :is(label, div) .label-text {
  position: absolute;
  opacity: .5;
  pointer-events: none;
  inset-inline-start: 10px;
  top: .2em;
  transition: top .2s var(--animation-easing-function),
              font-size .2s var(--animation-easing-function);
}

form :is(label, div):focus-within .label-text,
form :is(label, div) .label-text[field-populated] {
  top: 0;
  font-size: var(--in-field-label-size);
}

form :is(input, select, textarea):focus ~ .label-text {
  color: var(--in-content-item-selected);
  opacity: 1;
}

/* Focused error fields should get a darker text but not the blue one since it
 * doesn't look good with the red error outline. */
form :is(input, select, textarea):focus:user-invalid ~ .label-text {
  color: var(--in-content-text-color);
}

form div[required] > label .label-text::after,
form :is(label, div)[required] .label-text::after {
  content: attr(fieldRequiredSymbol);
}

.persist-checkbox label {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-block: var(--grid-column-row-gap);
}

dialog[subdialog] form {
  /* Match the margin-inline-start of the #controls-container buttons
     and provide enough padding at the top of the form so button outlines
     don't get clipped. */
  padding: 4px 4px 0;
}

#controls-container {
  display: flex;
  justify-content: end;
  margin: 1em 0 0;
}

#billingAddressGUID-container {
  display: none;
}
PK
!<�xli"chrome/content/skin/editDialog.css/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Linux specific rules */
dialog[subdialog] body {
  font-size: 0.85rem;
}
PK
!<�(O�+chrome/content/third-party/cc-logo-amex.png�PNG


IHDR;0���IDATx�WS�4I�m۶m���l��m۶m[c�m
�������ه�����Ddv�vfk˳�{���ؒ95��i��2
ZSwb@.���giM=�Zr	g��
�I���kB���$>������ӸvFc+.kuĺ�&V!;����z�$~�� �˄�sQ#�_'P����;���[!kQ���h������^��:����69ؕ7{��W�C\��xaP�5Q|26
���^�eyH-���Ò�������C3�@�AbF�۬,���IpU���w}�D|U[�\�p)S�YVg^5���6I�ZC*�_�bF{?�
z�+���>��͍;:����7�_���Ёk
�8�5W�v�B��32巬V5=}wd
�ꢸ��K�&�.e��ʼn�zxP�	���8�b{wD��?*�U\�΁��W�&Ck�6D|P�Lez
[ڱ/��<���c��!9�U�`�b\��tw\�/����&s��2@����JD�R�?&���l��~�7�'#�"f���M�A|51]���TO��=�hC�#�q;K�--������L�K�u<��'ם��.s�U)�l[j��.���J+#h�(�1(�TTEX�Th?��b8hլ������^ٻZ��׽R����{l�t(�kn65"�?	1��*�f��㷗��S��͔]�I;J0eo)�0���d��e.?�o,������w�3��'&>�h�$÷cӽ���e��0|K�Z��R�:7�V��tb�T�u�YI:v�'����Ik,�����><�ۃ�ꈤ�-%k�/{$��w����6Y{��W-�̞[��R�O{�ڨl�#Sx��V7���K����XSp�6�.�� .ma���ʶ1һ���Q�u�B[E=�Y�����gAf��1��r��f6iNj[�%kO���x�\��'���k����6���9!���f�R��g�|=���-��_ff��,nI!�饬$��9�t���<YeD5����L�]%�.�;4�����R�{���qe>Nk��n�BE-�Ÿ����mP��@8M�ר��-����SE�״q����Z[ g�i��D���"�G���{��g�t�z���,~�"z�{;3B�B�3:y�ub�|A`�3�@2�}��r�x���0v��p5�Vm�ͤt���Fzi�AbB^�N�8[z����<�e���8��A�8x��m_�-�&]r	�9������3���i���R��I������MIEND�B`�PK
!<�Ba		.chrome/content/third-party/cc-logo-amex@2x.png�PNG


IHDR<<:��r�IDATx�Zc�+Kͳm۶m���3��l۶m��0��m$�՞5����b���Zu0���]]��2���Z��>w���9SY�X-����,%^�X��#�Zr����ɒ[9��5X4888��
�ܜBo���ϩĵ���K�6������']Iu�;��Mx��\KK|�I+�W��V-����Hb�L�y�m`L~��j�w�Q*���O+�M��W|��L��t��޽Ś�9��)����2�随��RT���O��r�"��Ol����Y�Ѣ�tlM��v��JZT?D���a:���Ǣ�Q'����'�n�\��]�n�xġ�A���R�=FkW�&��R�Aޝ߅11v>�w�XsM/a# 7~ր�C�Pמ��� �!�.+���W��`�{1v�/����N��6�� H���{�
q��L
Z���^�4���F�5���!
��r�O-t,�#(aL\Z���eD��.���� 5Mô*Y��iI@�}�&�y�V����p����� >pW�LXbă��dt"Dc�aY4y^&�a���7EZ�I3���e5����އ p����Ž�&����M�D��s�=4I��v�<+g��������+�f�	�5d��oqG-rmĎu^`P��Њ9��Y��ن8N9&���C��jn�P�/w?���G�]	W�O��
?��K�����F����\��r&G����0Vq��j��0(^m��o�����R��}4!`x��3��
�R���xH;>���Y ��c�u�����q�[L2�H�N|�ؗ}ה0��sZ��O��/�>ś��ӊ�Ji�Γ�����}�A��E���,��1�$8u��DB����@'#n}���Xl��by�9�	�@��}��V�A���Z���0�#!`���?r��d�����jU�C�V���2�����' ��)1��>��HD�F��4220n��'x�/	*2��Hĸx��%�6ڊ�ܡg����禷�S��]�����?6�����}\�q��8�%oR��|o����n6�D�H��iEҁ���T�L��v�bc�U�HG �'�4��}6��q�n,�9����&�8O��҂�J!��-���_�n�T=r��7��]�׍F;	z:`�	N�c9�x@�8���F	�l�#�Հ	i��x��A�q����1��-=�/���_㉗߬�U6�aODlPi5��+����
s�Ơ���R�x�bW�T:�[L��R�x��1�j�L��;d�����U�!�)F�~|��	���Wᚚ[���Z�j��xH�g\✦�G��Cx�G<i�˭��T�^(�O�߄���W<� ]�I=�|�RN�Vz&�Wgw�
��!�>�w��ķ˻ţ��]�*F4'�.�҂�U�c�&k���h�#�|V�C�jc�x#ek��q@9�R0`ʿ�_�+��2��������h1���_Ej��މ/3�&��A
r*
�Ppj�d�����[s��河�S��hݢ����z!"s��h���,]����G=�V@�|����Ga]R�O�=�J��[�����,`L}������.�|�ތ�J�@����3mtc�P����jLX3����
����8���y�a�PDg>�>�u�	���;K��a��%�����Θȿ��W�����Hk��!�;��FF��0�7��n-�T���/ze����7�s2X��	/x@+7�ѿFw�(�(@i<�������1J���4���q����D�Bn~GmL���݀�����^�6�yM�q�T��1���D{?�W�Z�n�8��ZB�ɂ�q���a�j<1|��~ir]X?,�]�V fg���*�8��ݴ��1��3-hNz
j�:adX�pP�6ʋ3;���}2��2ǥѶ�C1�%ѹ̓o��A�8����/����.��܂o��y���7�<�O�e�cߙ
��i/{�G�Յ�5l9�c?��A��U=�)�-�)�xEð\/�^�;�W,��ykn��.-ퟥQ�ݐ�:E�] �~�N�ؐ�>���L������W�2����,2��RN%��Ck�4�wI��*�̿����l��,ų�/�}�t�jp�T�,��,�~���
���nqM��厏�-��h*+0�maHujwIEND�B`�PK
!<+�82��4chrome/content/third-party/cc-logo-cartebancaire.png�PNG


IHDR$˃+tRNSn���IDATx���X�H=o��R:�5�o_�@�!���������u'�qC��&�0�O��ϻ�qw���~㓤�?��彏{�^�'t���� ��-A(�7(�3��
�˩iD'v��*7m���qҔ��|�B*`m�8,Փ�b�ı���.�OLr��)	[�eچ���F�k��u����F���Ȍ�v���UX,��i[��ߌ���f���!���ڶm۶=���vT۶���6��l���?��)Y��Q�i)����wx`��8�b%H 4�6�!X$�f0[J�8���"I�b�9s-u�.���M��y�n`��
�<k��M�gndd�s����}��U�de�0;���?��}CN�L!�Y�3�φᖥ�/���.եX�L-�K�匝Z��B]I�-��8��дCK�i�}�̌h�/䁽�\��i��cZ۪<v�k��
&�Hű�o����F+�Z���a�ݼ�֛�"w�Siy^F�@J(-��9�)[6!
��3�ٶ�3�e=C#�tödX�����\�U����س�\I¨��
]������К�T`S`kA��xs⌏�̕R3��w�s�i}�f`���b�s���wv#�fCd
��	��!h�ٺ��V�#�����ܲ�v��D�y<��-h��{F /�|� h�@׀���6֦"'+Z�6L�W�mo]^���K}��UE�?���"���) i�w��tҀ�?�=�$!�4W��\"(IZ
���E[���~�A*>�9�%��H��LZ�PJ�"Y����3��Ì�3�����$�X�?4�����e�3�d"�?���s�{��m��ʫ�6ݎ����5�cąE��d�1�z��zL��e�0���ŀ&h$�t|ʱ2w��٩��./����t����:��B!�PUvv]n��QOH�Ɂ���=��#H����̧�l"{Y�ca�F��ճ���;�'3����f7d�@ɳs&%$׆ËJ�`�����y��B����P�͹3Z���A�f?eMȫƲ�f;���'�)-��2D�M�
��"V&�Ԫ FC�J?
;�>�4�9;�I�6�o��7U���+�֛��A	 ���jbk���?���Ǐ%��IEND�B`�PK
!<ۺ�''7chrome/content/third-party/cc-logo-cartebancaire@2x.png�PNG


IHDRH<J<k�tRNSn���IDATx�IDA�Ќ��ے��$.���}<�\�u]�[Ƭ6�:���8l�H)�c�H\�Y�C	lک�q���@�iju�Ը�?�):v�G'駅��&#�B?��nK�*J+�0�2�
��#������ox=�D��M���|]�	�	<P���Y�;�A�
9J�eQM�P�|��H�y��YR���ɺּ~�c�ef�A᪹
ӵ8m��nw8�Ā%HY
{��F�Q(�A@}l�H]2{qj����Y�&g�Ϛ���?�r� oUZ5��E��	�&��MRm'I��D�:7*��6|�߼�øa!'�sk^�"��Moe0���kI�;_3���aG���<��0\ߤ����"D`T��5��F����>��lA�c����<j��s´*&f�wkR�Q�ʦ�,_����������>f��
���z��	o�i͞tD��ш����)�Ll&��Z3b��WૐR���^-����\����	�� �]e|d�4t������K��0&]�٥z�`"=b$޳qLϟ���-�,F��~?�vT'����d�[�r�+��a˯��{�aN_�;��?-�%��Eὓt��s�l۶m۶��g۶m��sm�޻hz��r��:U=��oPIY�N��uĊ�:ȟ�BU�q)R���c���_�ſ�a�L��g�l,f���ZypͲ
5�k�kˌ��]��;'�=�=9�3ݙ��*��`� � �� ��N��!(�\,-�t����{��V*����l��F�����?Mnj��dɆʃVYb�U_up}E<�?�=���FNob[�/���BlSB���f��:A0��e�E����~��o���7���ɏ��;u'*�d o|FD �u+�l�~mœ��J'��BsU�1����1o�̃�_*4[.�w�A�(��cO���l�(+s���X0�c��G���g�R��;|0�%.5��w���]�樬�.$��Y�� �aۭ��#n}�s���c-<��+^$� ��ۜ�Ɉ��fhMJ���z��_@�J�R�/�k�!��9��W��|��w�S
b?4�.�L#��k�yj�-ݪJa�uWXЛ;�oD���[���7ӬR�0�b���E��$�������7]��i�Ϗ�����VZ����|QO�9� ��0�b̂�����*K�ܒ�R]��:�M����J�XyY|Q���e�B�<Px��;ק��*@D�J��Zc�G���RT${������(�@�L(�E��Z�Ɛ�
A��ֲ��0D�|7�=���prES���$l~�ŇčAԬ;�yh}傞"����}<�P���99�2���]o�`
U+��|f'�A�z��ϧ�3n`�'V�w>���C@��Dm
�6�~6���h�Ƽ������&�̸xE%a��y!a��0�&��?C����ۓg�
tN�AZ)��9W��d
����:��"p��Ks@�bߊ]ؓki[�Ք���=�ǁ�G	�(���7���A
 X.����Ny�S(��6~�\��1W}8
�E�
�wъ�Gvݧ���ӊX�VP���	��/�Ȭ�ܿ�r�o���}�����D����Lˬg�j�j	�Dؒߚz7��`��w��o_�ָ9#g�CQ�DA(��`R��kG/n�I�/9d��a8��3uƙ�.�P��z�=��\���ﮀ��r�U��>`	kmߌd��d�h�|��(����v���PCM:�T��Ղħ�N2��!��ms1td�&�O+è��񛮲�j��u%`Ej*�RWQ1	>)��󹳳����f^�Ͻ�Z��c6Z����(���ʀa��Hhj����ռY�,�"�	Ӡ�r"b��
�U�d�@�����\
p,�l�Cn����1����m�)� :*��D�Ԋ��ʉ�CX%�C�wfNyvҏ�����%��K���{К
 �"����Yh-.�����"@��Z9�Wk�Z��җv�W�ޟن��đ1�ma*�����8�����@�,L��֛>��_����J�ķ�}�caL�P"���Y��3��x��à�o� BM=a�]^z�mw�y�����e��ꇛ�L�F��$����s��ߛ�Ʉ�%�&��0J|�E���ՠ0nUL��N�3G����l�R�~�ޜ1��F��X�I}��$Z���}7}?�/&ۘ����0��:�/�(Z>�c�Y�-�_�6i�%��sٕ�2|XeuL�?��oZ*��ܹ/N��}�OBń	c��N%o͜=�����#�tE���S��&{s-�S��i��(6�BR蒸�PĐ�>&�t�h�h�`SE��5�K�6������^ߟߛ�ו��J��tg=Jk�X���g�4d=�<o�ZF�P�K[hQm���d�$� �����3^�1@�&��s����`�$�|�=;�����/8=9PNz��A�8�a?���������<Daus�{�>�GL�-�0�6��6�@�
�`��~�� f�R?T�M����ί�����;�+TTB��F�*8E�?L8$_L�$E����$�׿�IWM*Ք|"�T���A(y�#UQRy#���Pr���DV�*M��_���P��w9P&�<�j"�`8��q�2�1��.�I�e���@�`���3��&`7�38���~���Q��I����*������w+J�T���4Eɉ���8�D?	E"��?f��Q�������|!�R�J�G4��2�L]�gȉ,�Au@E��D����'���T���_%���81��T�LEя�E����LrY�t��i[��(:AQ��R^O��D)RO]Vz�oL���,T��ٵ	d������T3�/c�Z���N��l���@T�%$>
�P���:��c���o���_ԁ����BIEND�B`�PK
!<�u�+-chrome/content/third-party/cc-logo-diners.svg<svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><path d="M19.863 20.068c4.698.022 8.987-3.839 8.987-8.536 0-5.137-4.289-8.688-8.987-8.686h-4.044c-4.755-.002-8.669 3.55-8.669 8.686 0 4.698 3.914 8.559 8.669 8.536h4.044z" fill="#4186CD"/><path d="M15.76 3.535a7.923 7.923 0 0 0 0 15.844 7.923 7.923 0 0 0 0-15.844zm-4.821 7.75c.004-2.122 1.288-3.931 3.1-4.65v9.3c-1.812-.719-3.096-2.527-3.1-4.65zm6.544 4.65v-9.3c1.811.717 3.097 2.527 3.1 4.65-.003 2.123-1.289 3.931-3.1 4.65z" fill="#FFF"/><g fill="#211E1F"><path d="M.65 22.925c0-.71-.375-.663-.733-.671v-.205c.31.015.63.015.94.015.336 0 .79-.015 1.381-.015 2.065 0 3.19 1.365 3.19 2.763 0 .782-.462 2.748-3.286 2.748-.407 0-.782-.016-1.157-.016-.358 0-.71.008-1.068.016v-.205c.478-.048.71-.064.733-.6v-3.83zm.644 3.636c0 .586.437.654.825.654 1.713 0 2.275-1.24 2.275-2.373 0-1.422-.951-2.449-2.48-2.449-.326 0-.476.022-.62.03v4.138zM5.428 27.364h.152c.225 0 .387 0 .387-.25v-2.041c0-.332-.121-.378-.419-.528v-.12c.378-.107.83-.249.861-.272a.301.301 0 0 1 .145-.038c.04 0 .057.046.057.106v2.893c0 .25.177.25.402.25h.137v.196c-.274 0-.556-.015-.845-.015-.29 0-.58.007-.877.015v-.196zm.689-4.627a.36.36 0 0 1-.345-.35c0-.177.169-.338.345-.338.182 0 .344.148.344.337 0 .19-.155.351-.344.351zM7.993 25.117c0-.278-.084-.353-.438-.496v-.143c.325-.106.634-.204.996-.363.022 0 .045.016.045.076v.49c.43-.309.8-.566 1.307-.566.64 0 .867.468.867 1.055v1.944c0 .25.166.25.377.25h.136v.196c-.265 0-.528-.015-.8-.015s-.544.007-.815.015v-.196h.136c.211 0 .362 0 .362-.25v-1.95c0-.43-.263-.642-.694-.642-.241 0-.626.196-.876.362v2.23c0 .25.166.25.378.25h.136v.196c-.264 0-.529-.015-.8-.015-.272 0-.544.007-.816.015v-.196h.137c.21 0 .362 0 .362-.25v-1.997zM11.943 25.569c-.017.072-.017.192 0 .465.049.762.553 1.388 1.212 1.388.453 0 .809-.24 1.113-.537l.115.113c-.38.489-.849.906-1.525.906-1.31 0-1.575-1.236-1.575-1.75 0-1.573 1.089-2.039 1.665-2.039.668 0 1.386.41 1.394 1.26 0 .05 0 .097-.008.145l-.074.049h-2.317zm1.514-.42c.212 0 .237-.077.237-.147 0-.3-.264-.542-.742-.542-.52 0-.877.264-.98.689h1.485zM14.383 27.364h.191c.198 0 .34 0 .34-.25v-2.117c0-.233-.262-.279-.368-.339v-.113c.516-.234.799-.43.863-.43.042 0 .063.023.063.099v.678h.015c.176-.294.474-.777.905-.777.176 0 .402.128.402.4 0 .203-.133.385-.331.385-.22 0-.22-.182-.468-.182-.12 0-.516.174-.516.626v1.77c0 .25.142.25.34.25h.395v.196c-.389-.008-.684-.015-.99-.015-.289 0-.586.007-.84.015v-.196zM17.282 26.668c.102.53.418.98.996.98.465 0 .64-.29.64-.57 0-.948-1.724-.643-1.724-1.935 0-.45.357-1.028 1.226-1.028.252 0 .592.073.9.234l.056.818h-.182c-.079-.505-.355-.795-.862-.795-.316 0-.616.185-.616.53 0 .94 1.834.65 1.834 1.91 0 .53-.42 1.092-1.36 1.092a2.06 2.06 0 0 1-.964-.272l-.087-.924.143-.04zM26.431 23.625h-.192c-.147-.94-.786-1.318-1.649-1.318-.886 0-2.173.618-2.173 2.548 0 1.626 1.11 2.792 2.296 2.792.763 0 1.395-.547 1.55-1.392l.176.048-.177 1.175c-.323.21-1.194.426-1.703.426-1.802 0-2.942-1.214-2.942-3.024 0-1.649 1.41-2.831 2.92-2.831.623 0 1.224.21 1.817.427l.077 1.15zM26.783 27.36h.153c.226 0 .387 0 .387-.253v-4.268c0-.498-.12-.514-.427-.598v-.123c.322-.099.66-.237.83-.33.087-.045.152-.084.176-.084.05 0 .065.046.065.108v5.295c0 .254.177.254.403.254h.136v.199c-.273 0-.555-.016-.845-.016-.29 0-.58.008-.878.016v-.2zM31.775 27.032c0 .136.084.143.214.143.092 0 .206-.007.305-.007v.159c-.328.03-.955.188-1.1.233l-.038-.023v-.61c-.458.37-.81.633-1.353.633-.412 0-.84-.264-.84-.897v-1.93c0-.196-.03-.384-.457-.422v-.143c.275-.007.885-.053.984-.053.085 0 .085.053.085.219v1.944c0 .226 0 .874.664.874.26 0 .604-.195.924-.458v-2.029c0-.15-.366-.233-.64-.309v-.135c.686-.046 1.115-.106 1.19-.106.062 0 .062.053.062.136v2.78zM33.372 24.72c.323-.27.76-.572 1.206-.572.94 0 1.505.804 1.505 1.671 0 1.042-.776 2.085-1.935 2.085-.599 0-.914-.191-1.125-.278l-.243.182-.169-.087a9.26 9.26 0 0 0 .113-1.416v-3.422c0-.518-.122-.534-.43-.621v-.128c.325-.103.664-.246.834-.342.09-.048.154-.088.18-.088.047 0 .064.048.064.112v2.905zm-.044 2.032c0 .301.291.808.834.808.868 0 1.232-.831 1.232-1.535 0-.854-.664-1.565-1.296-1.565-.3 0-.552.19-.77.372v1.92z"/></g></g></svg>PK
!<Ȋ+]]/chrome/content/third-party/cc-logo-discover.png�PNG


IHDR%�#�m$IDATxb�`���GDD��‘���.y{{?��b//�����y@C�D������䨶��:��YH�:G��յ�+�8Y� ��k�<{f�m۶m���<۶m۶m�w��}�'k��Oݺ��'8��ݻ�L�P+W�dܸq�X����X�l9���t�R̕+W]�v����3p�@>|���χG�f�p�@�ہח��_���� Dׯ_g���l߾�q��X,nܸ��)S�Z�\�|�{�*=z�X��>SNj�F�9�ڵ+�7�\�r\�x�\�r�@�y�l�X�x1{����ٳdȐ)`�ȑ�>~����j"�4Lλf���l!o��lܸQ͚5�4iժU�U�V�=w��M�4i0�͘L&.]�������*X� B/*S��D�%X�v-��ٳgH�ڵ�<y2�͑�<���/�|�jħo:\�3o�(j֪���/Ȝ93_�~E��mۖ�r��!��͋�/P<%'��ׯO�N�(T�v�����S�V-�t���_�t`�'ç��aF�l����U��/�>��֭�*U��Dž�S�r��a�&MJ�D��9sf�L	T�ܹY�|9���#k֬�۷�<y�z�j�Je�f�BΕ6�:u�;g��;� ��R�LM�:;	΃�ⶾ�q��MDɑ�r��1Ĉ�c�J���`P0�Wz.��ӧOr�bŊ�,YRr��+��c���w���ط5���4��}Ђ�#�8��r�H2(ϐNH>���+0�oߞ�G��@�����x�m��#�JT��=���K��	cNi^�p���j�S���J�{����)�PF'�fIG�"?�����i�PF%G��lСq�ix�\űg ����O�Bi�p]߀}Uc�I�&N�4����^��t�(cR���7P�������uV1���Cr%v�4�ϫ�8��ž�%��<(cR�	�&�#%k�i“3���=:���T�Z�U�E�ј��Ʀ�fN'��8�:�o3�[� %%�ؽy�����q��J�����}e��@�龇�}OuN ��P�z$+���0��([#0�"��QIEND�B`�PK
!<�v�	�	2chrome/content/third-party/cc-logo-discover@2x.png�PNG


IHDRJ<��,�	nIDATx�pd[�3�c��l�۶m#�c�m�5����d�� ���^�YՓ[AϳsWծ\|g�}v�n+Y�dɒ%��r������N8::�7����)1�x[[[�_a��֏��V��S�._FRR�l�l<<<���J����eYd��/N�"(��eYd��%��AɠdP2�)2�_���}���ruu]!��e��ˠdP"(�V�;w���۠ݻ���|�UFFx���8q���݋�wc`Iz��ϟ���e��/�ш�R�d"�^�\�1;� ��u�J�q��M��Ĕ{������J��rƹ�ݘ�X�Z�8�źu���Ҟ��x��Q�ZuXYY�J�*�T(0h� $$$�X����Q�F�
�ҥKx��w�whU�VE��푙��b9r��9�KV�fM�Y�ź�yv6x�?zQ_Z�68�7�{C�����8;;�v�ڈ��DY
0իW����q��e�Q̥Z�>�u���B����Y麧�'|}}���ƾ}���ƍ �Y�f��������K
]�x���xmĈ(**�G}�� ����O���j���U���|�aÆ�o߾[�@���0�x�\�猇�H�@J7R�{"����(�F��}�v�~I���@��?�c�s�<�Z�h��-[�6{�lz��lo�^�v�$h3f�Ç����Ӡ*U��^x��R�D�F��F�{�=�t:�����cƌAbb"=���P,1ɛ�6��Ϗ7�Ŋ��C�3H�y	;>���&� �d(����S��>
dP ���[�#2�,'HȥB޼y`�~�-���h�w�AY���Bj#00|��テ�����E�,�7>6t��a����ǣF��s������>}:��g�}·�H�!8��
!���z@���
d�P g�'�^�!K�/��lsѢE��~
^[�z5���(��_gN�wӸP<�@�}�ʕ���|��oE1��C+,<<f.��|���Y:t�իWA1W�:W̒��8��;ķt1{P/�
@���^��@�$�}��9�NbɊ5`�_~�%(�ʕ+3=0�J�����ۃH������5;0Gn޼�֭��/�,���2l��),,�(��`�ӻx�+v��u�i�<�5k,I��!�˗H��f4@�@�(/�NP o��@a��0'�bw!3'gB`�d�1y�dP%Aƛo����z�0aZ�$omm��Æq޿�SɵI�(Iw��9�O�0�&M�{��'�ʘvH�挬!�h�4��@A��Գ���1�<(��v[�j��aľˁ"$�7��E/{��g��FTN�$���b͟?���%L�,J�:y�dɺ�۫�3�;w��rPb���k��<$�^���논��0+. ���*���
�ֺ�A��+�%�hݺ5��~6�3M��b�Y���b��k� ܊U�V�k׮�h��ɜ�����c�֭�.Կ��ܿ?�,Q*��M<������8�3Kl�&�i�͐?���L5]�#-�v�tK�`T�A�L&�֫�v9>�k��Ν;�{�nЮ�YYYR2ONNf9�c��f��]�����A1$����Y�H��{��D���޽�ŶCCCAe=�zEs�B����\7h�A����/��r��ƍ%��o%u��i���mۖ9�`x^\HK%���˖��2��zʔ)�����Աc���u�b�Fxu��E�������աC���[OxB�&M���߿I�B���nwg���F0DO�)�,�аaC�X�e�����m۶
����	G*��+˞�'��EH�RX���)6����\����A�*�xn�߂�3�eP)��Y�
Z��Ƹ��j2��2e&@�k4T�
����
�D�Xw�� �caP��
�T��<����J�ʆ>r>�3>yȝ�h2(3�,�B=�3 _���dP��d�O͂z�g���Z�ʘ�A?�#�/�A2(c�NC�uTA�>�A w0Å��,knN�ގ�.F�ؠ���n�D��}h���l@Eeʌ�>j4K�pb�ë"���e���uݠ~���ELL
��ʔ���-�n�u�;-aN�rO�e2˜q��]ߝ�Z�\�\�@�4�(J���h�y�
z�E�%8�^
c�
�5+���ꙟ��sʅUEe��xE�Y	ݶ!��*��9�r����|�èr�@�!OL�aCw�f.:V@��h6?7h�9���<���Y�{�4�w���ƃ�P.덄�o7�ečrD�[čt@�h�:n\��)ǻ#j�+����_C[omm��|U���ZJ��VJ�j����Z��6����ͺV凕+[�	PV���!ȠdP2(���e��3^�uIEND�B`�PK
!<D���WW*chrome/content/third-party/cc-logo-jcb.svg<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg"><defs><path d="M3.622.575C1.734.575.009 2.278.009 4.188c0 1.051 0 5.212-.002 9.348.346.217 2.01.752 2.68.799 1.466.103 2.375-.381 2.515-1.603l-.007-4.538h3.243v4.434c-.17 2.54-2.399 3.057-5.79 2.887-.877-.046-2.07-.27-2.64-.42L.004 22.94H5.65c1.54 0 3.544-1.439 3.544-3.627V.575H3.622z" id="a"/><linearGradient x1="-.003%" y1="49.999%" x2="100.002%" y2="49.999%" id="b"><stop stop-color="#313477" offset="0%"/><stop stop-color="#0077BC" offset="100%"/></linearGradient><path d="M0 1.564l.007.001V.007L0 .002v1.562z" id="d"/><linearGradient x1="0%" y1="50.019%" x2="1.21%" y2="50.019%" id="e"><stop stop-color="#313477" offset="0%"/><stop stop-color="#0077BC" offset="100%"/></linearGradient><path d="M3.976.575C2.088.575.363 2.278.363 4.188v4.945c1.132-.885 2.958-1.319 5.281-1.14 1.322.102 2.3.286 2.834.445v1.57c-.588-.294-1.748-.73-2.715-.8-2.191-.158-3.342.868-3.342 2.528 0 1.494.888 2.773 3.331 2.602.806-.056 2.148-.525 2.719-.797l.007 1.523c-.492.155-2.02.488-3.458.5-2.165.017-3.694-.443-4.659-1.189L.36 22.941h5.643c1.54 0 3.546-1.439 3.546-3.627V.575H3.976z" id="g"/><linearGradient x1=".004%" y1="49.999%" x2="99.996%" y2="49.999%" id="h"><stop stop-color="#753136" offset="0%"/><stop stop-color="#ED1746" offset="100%"/></linearGradient><path d="M.123.448L.119 2.424l2.21.007c.43 0 .97-.368.97-1.01a.97.97 0 0 0-.967-.973c-.308.003-.8.001-1.245 0L.375.446C.26.446.17.446.123.448" id="j"/><linearGradient x1="0%" y1="50.008%" x2="99.996%" y2="50.008%" id="k"><stop stop-color="#008049" offset="0%"/><stop stop-color="#62BA44" offset="100%"/></linearGradient><path d="M.115.473l-.008 1.8 2.089.014c.346-.007.834-.325.834-.882 0-.567-.426-.95-.88-.939-.296.008-.702.005-1.078.002L.52.465C.333.465.187.467.115.473" id="m"/><linearGradient x1=".022%" y1="49.994%" x2="100.012%" y2="49.994%" id="n"><stop stop-color="#008049" offset="0%"/><stop stop-color="#62BA44" offset="100%"/></linearGradient><path d="M3.694.575C1.806.575.08 2.278.08 4.188L.08 8.164h5.365c1.067 0 2.324.457 2.324 1.754 0 .696-.37 1.485-1.706 1.74v.03c.78 0 2.132.457 2.132 1.833 0 1.423-1.46 1.817-2.243 1.817l-5.873.006-.001 7.597H5.72c1.54 0 3.544-1.439 3.544-3.627V.575H3.694z" id="p"/><linearGradient x1="-.007%" y1="49.999%" x2="100.004%" y2="49.999%" id="q"><stop stop-color="#008049" offset="0%"/><stop stop-color="#62BA44" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><g transform="translate(0 3.013)"><mask id="c" fill="#fff"><use href="#a"/></mask><path d="M3.622.575C1.734.575.009 2.278.009 4.188c0 1.051 0 5.212-.002 9.348.346.217 2.01.752 2.68.799 1.466.103 2.375-.381 2.515-1.603l-.007-4.538h3.243v4.434c-.17 2.54-2.399 3.057-5.79 2.887-.877-.046-2.07-.27-2.64-.42L.004 22.94H5.65c1.54 0 3.544-1.439 3.544-3.627V.575H3.622z" fill="url(#b)" mask="url(#c)"/></g><g transform="translate(0 16.543)"><mask id="f" fill="#fff"><use href="#d"/></mask><path d="M0 1.564l.007.001V.007L0 .002v1.562z" fill="url(#e)" mask="url(#f)"/></g><g transform="translate(10 3.013)"><mask id="i" fill="#fff"><use href="#g"/></mask><path d="M3.976.575C2.088.575.363 2.278.363 4.188v4.945c1.132-.885 2.958-1.319 5.281-1.14 1.322.102 2.3.286 2.834.445v1.57c-.588-.294-1.748-.73-2.715-.8-2.191-.158-3.342.868-3.342 2.528 0 1.494.888 2.773 3.331 2.602.806-.056 2.148-.525 2.719-.797l.007 1.523c-.492.155-2.02.488-3.458.5-2.165.017-3.694-.443-4.659-1.189L.36 22.941h5.643c1.54 0 3.546-1.439 3.546-3.627V.575H3.976z" fill="url(#h)" mask="url(#i)"/></g><g transform="translate(22.353 14.778)"><mask id="l" fill="#fff"><use href="#j"/></mask><path d="M.123.448L.119 2.424l2.21.007c.43 0 .97-.368.97-1.01a.97.97 0 0 0-.967-.973c-.308.003-.8.001-1.245 0L.375.446C.26.446.17.446.123.448" fill="url(#k)" mask="url(#l)"/></g><g transform="translate(22.353 11.837)"><mask id="o" fill="#fff"><use href="#m"/></mask><path d="M.115.473l-.008 1.8 2.089.014c.346-.007.834-.325.834-.882 0-.567-.426-.95-.88-.939-.296.008-.702.005-1.078.002L.52.465C.333.465.187.467.115.473" fill="url(#n)" mask="url(#o)"/></g><g transform="translate(20.588 3.013)"><mask id="r" fill="#fff"><use href="#p"/></mask><path d="M3.694.575C1.806.575.08 2.278.08 4.188L.08 8.164h5.365c1.067 0 2.324.457 2.324 1.754 0 .696-.37 1.485-1.706 1.74v.03c.78 0 2.132.457 2.132 1.833 0 1.423-1.46 1.817-2.243 1.817l-5.873.006-.001 7.597H5.72c1.54 0 3.544-1.439 3.544-3.627V.575H3.694z" fill="url(#q)" mask="url(#r)"/></g></g></svg>PK
!<�^AEH
H
1chrome/content/third-party/cc-logo-mastercard.svg<svg width="38" height="30" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><path d="M7.485 29.258v-1.896a1.125 1.125 0 0 0-1.188-1.2 1.17 1.17 0 0 0-1.061.537 1.109 1.109 0 0 0-.999-.537.998.998 0 0 0-.885.448v-.373h-.657v3.021h.664v-1.662a.708.708 0 0 1 .74-.802c.435 0 .656.284.656.796v1.68h.664v-1.674a.71.71 0 0 1 .74-.802c.448 0 .663.284.663.796v1.68l.663-.012zm9.817-3.02h-1.08v-.917h-.664v.916h-.6v.6h.613v1.391c0 .701.271 1.119 1.049 1.119.29 0 .575-.08.821-.234l-.19-.563a1.213 1.213 0 0 1-.58.17c-.317 0-.437-.201-.437-.505v-1.377h1.074l-.006-.6zm5.605-.076a.891.891 0 0 0-.796.442v-.367h-.65v3.021h.656v-1.693c0-.5.215-.778.632-.778.14-.002.28.024.411.076l.202-.632a1.406 1.406 0 0 0-.467-.082l.012.013zm-8.474.316a2.26 2.26 0 0 0-1.232-.316c-.765 0-1.264.366-1.264.966 0 .493.367.797 1.043.891l.316.045c.36.05.53.145.53.316 0 .234-.24.366-.688.366-.361.01-.715-.1-1.005-.316l-.316.512a2.18 2.18 0 0 0 1.308.392c.872 0 1.378-.41 1.378-.986 0-.575-.398-.809-1.056-.904l-.316-.044c-.284-.038-.511-.095-.511-.297 0-.202.214-.354.575-.354.333.004.659.093.947.26l.291-.531zm17.602-.316a.891.891 0 0 0-.796.442v-.367h-.65v3.021h.656v-1.693c0-.5.215-.778.632-.778.14-.002.28.024.411.076l.202-.632a1.406 1.406 0 0 0-.467-.082l.012.013zm-8.467 1.58a1.526 1.526 0 0 0 1.611 1.58 1.58 1.58 0 0 0 1.087-.36l-.316-.532a1.327 1.327 0 0 1-.79.272.97.97 0 0 1 0-1.934c.286.003.563.099.79.272l.316-.53a1.58 1.58 0 0 0-1.087-.361 1.526 1.526 0 0 0-1.611 1.58v.012zm6.155 0v-1.505h-.658v.367a1.147 1.147 0 0 0-.948-.442 1.58 1.58 0 0 0 0 3.16c.37.013.722-.152.948-.443v.366h.658v-1.504zm-2.446 0a.913.913 0 1 1 .916.966.907.907 0 0 1-.916-.967zm-7.93-1.58a1.58 1.58 0 1 0 .044 3.16c.454.023.901-.124 1.254-.411l-.316-.487c-.25.2-.559.311-.878.316a.837.837 0 0 1-.904-.74h2.243v-.252c0-.948-.587-1.58-1.434-1.58l-.01-.006zm0 .587a.749.749 0 0 1 .764.733h-1.58a.777.777 0 0 1 .803-.733h.012zm16.464.999v-2.724h-.632v1.58a1.147 1.147 0 0 0-.948-.442 1.58 1.58 0 0 0 0 3.16c.369.013.722-.152.948-.443v.366h.632v-1.497zm1.096 1.07a.316.316 0 0 1 .218.086.294.294 0 0 1-.098.487.297.297 0 0 1-.12.025.316.316 0 0 1-.284-.183.297.297 0 0 1 .066-.329.316.316 0 0 1 .228-.085h-.01zm0 .535a.224.224 0 0 0 .165-.07.234.234 0 0 0 0-.316.234.234 0 0 0-.165-.07.237.237 0 0 0-.167.07.234.234 0 0 0 0 .316.234.234 0 0 0 .076.05c.032.015.066.021.101.02h-.01zm.02-.376a.126.126 0 0 1 .082.025c.02.016.03.041.028.066a.076.076 0 0 1-.022.057.11.11 0 0 1-.066.029l.091.104h-.072l-.086-.104h-.028v.104h-.06v-.278l.132-.003zm-.07.054v.075h.07a.066.066 0 0 0 .037 0 .032.032 0 0 0 0-.028.032.032 0 0 0 0-.028.066.066 0 0 0-.038 0l-.07-.02zm-3.476-1.283a.913.913 0 1 1 .917.967.907.907 0 0 1-.917-.967zm-22.19 0v-1.51h-.657v.366a1.147 1.147 0 0 0-.948-.442 1.58 1.58 0 1 0 0 3.16c.369.013.722-.152.948-.443v.366h.657v-1.497zm-2.445 0a.913.913 0 1 1 .916.967.907.907 0 0 1-.922-.967h.006z" fill="#231F20"/><path fill="#FF5F00" d="M14.215 3.22h9.953v17.886h-9.953z"/><path d="M14.847 12.165a11.356 11.356 0 0 1 4.345-8.945 11.375 11.375 0 1 0 0 17.886 11.356 11.356 0 0 1-4.345-8.941z" fill="#EB001B"/><path d="M37.596 12.165a11.375 11.375 0 0 1-18.404 8.941 11.375 11.375 0 0 0 0-17.886 11.375 11.375 0 0 1 18.404 8.941v.004zM36.51 19.265v-.412h.148v-.085h-.376v.085h.161v.412h.066zm.73 0v-.497h-.115l-.132.355-.133-.355h-.101v.497h.082v-.373l.123.323h.086l.123-.323v.376l.066-.003z" fill="#F79E1B"/></g></svg>PK
!<�x���*chrome/content/third-party/cc-logo-mir.svg<svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="100%" y1="312.751%" x2=".612%" y2="312.751%" id="a"><stop stop-color="#1E5CD8" offset="0%"/><stop stop-color="#02AFFF" offset="100%"/></linearGradient></defs><g fill-rule="nonzero" fill="none"><path d="M7.812 11.313l-1.326 4.593h-.227l-1.326-4.594A1.823 1.823 0 0 0 3.18 10H0v10h3.184v-5.91h.227L5.234 20H7.51l1.819-5.91h.226V20h3.185V10H9.56c-.81 0-1.522.535-1.75 1.313zM25.442 20h3.204v-2.957h3.223c1.686 0 3.122-.953 3.677-2.293H25.442V20zm-5.676-8.945l-2.241 4.855h-.227V10h-3.184v10h2.703c.712 0 1.357-.414 1.654-1.055l2.242-4.851h.227V20h3.184V10H21.42c-.712 0-1.358.414-1.655 1.055z" fill="#006848"/><path d="M32.186 0c.92 0 1.752.352 2.382.93a3.49 3.49 0 0 1 1.146 2.59c0 .21-.023.417-.058.62H29.74a4.478 4.478 0 0 1-4.272-3.124c-.007-.02-.011-.043-.02-.067-.015-.054-.027-.113-.042-.168A4.642 4.642 0 0 1 25.293 0h6.893z" fill="url(#a)" transform="translate(0 10)"/></g></svg>PK
!<�}����/chrome/content/third-party/cc-logo-unionpay.svg<svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><defs><path id="a" d="M0 .04h17.771v22.433H0z"/><path id="c" d="M.134.04h18.093v22.433H.134z"/><path id="e" d="M.202.04h17.77v22.433H.202z"/></defs><g fill="none" fill-rule="evenodd"><g transform="translate(0 3.179)"><mask id="b" fill="#fff"><use href="#a"/></mask><path d="M7.023.04h8.952C17.225.04 18 1.057 17.71 2.31l-4.168 17.893c-.294 1.25-1.545 2.269-2.795 2.269h-8.95c-1.248 0-2.027-1.02-1.736-2.269l4.17-17.893C4.52 1.058 5.771.04 7.022.04" fill="#E21837" mask="url(#b)"/></g><g transform="translate(8.073 3.179)"><mask id="d" fill="#fff"><use href="#c"/></mask><path d="M7.157.04h10.294c1.25 0 .686 1.018.392 2.271l-4.167 17.893c-.292 1.25-.201 2.269-1.453 2.269H1.93c-1.252 0-2.026-1.02-1.732-2.269L4.363 2.311C4.66 1.058 5.907.04 7.157.04" fill="#00457C" mask="url(#d)"/></g><g transform="translate(17.89 3.179)"><mask id="f" fill="#fff"><use href="#e"/></mask><path d="M7.224.04h8.952c1.251 0 2.028 1.018 1.734 2.271l-4.166 17.893c-.295 1.25-1.547 2.269-2.798 2.269H2c-1.252 0-2.028-1.02-1.735-2.269L4.432 2.311C4.723 1.058 5.972.04 7.224.04" fill="#007B84" mask="url(#f)"/></g><path d="M26.582 16.428L25.49 20.04h.295l-.228.746h-.292l-.069.23h-1.038l.07-.23H22.12l.21-.69h.215l1.106-3.667.22-.739h1.06l-.111.373s.282-.203.55-.272c.266-.07 1.801-.096 1.801-.096l-.227.734h-.362zm-1.866 0l-.28.923s.315-.142.484-.189c.174-.046.434-.061.434-.061l.203-.673h-.841zm-.42 1.38l-.29.96s.321-.163.492-.215c.174-.039.438-.072.438-.072l.205-.673h-.845zm-.675 2.24h.844l.242-.81h-.841l-.245.81z" fill="#FEFEFE"/><path d="M27.05 15.694h1.13l.012.42c-.008.072.054.106.186.106h.23l-.21.695h-.612c-.528.038-.73-.19-.715-.445l-.022-.776zM27.2 18.993H26.12l.185-.619h1.232l.175-.566h-1.216l.207-.698h3.384l-.21.698h-1.135l-.178.566h1.139l-.19.619h-1.229l-.219.26h.5l.121.78c.014.078.014.13.04.162.025.028.175.042.262.042h.152l-.231.759h-.385c-.058 0-.147-.005-.27-.01-.114-.01-.195-.077-.273-.116a.367.367 0 0 1-.202-.265l-.12-.778-.56.766c-.177.243-.417.428-.824.428h-.782l.205-.677h.3a.484.484 0 0 0 .218-.063.336.336 0 0 0 .166-.138l.816-1.15zM15.397 17.298h2.855l-.211.68H16.9l-.179.581h1.168l-.213.702h-1.167l-.284.945c-.034.104.278.117.39.117l.584-.08-.235.778H15.65c-.106 0-.185-.015-.299-.04a.312.312 0 0 1-.209-.153c-.048-.077-.122-.14-.071-.305l.378-1.25H14.8l.215-.714h.65l.173-.581h-.648l.207-.68zM17.317 16.074h1.171l-.212.712h-1.6l-.173.15c-.075.072-.1.042-.198.094-.09.045-.28.136-.525.136h-.513l.207-.684h.154c.13 0 .219-.012.264-.04a.617.617 0 0 0 .171-.222l.296-.535h1.163l-.205.389zM18.991 15.694h.997l-.146.502s.316-.252.536-.343c.22-.081.716-.154.716-.154l1.615-.01-.55 1.832a2.139 2.139 0 0 1-.269.608.7.7 0 0 1-.271.251 1.02 1.02 0 0 1-.375.126c-.106.008-.27.01-.496.014h-1.556l-.437 1.447c-.042.144-.061.213-.034.252a.18.18 0 0 0 .148.073l.686-.065-.235.794h-.766c-.245 0-.422-.006-.547-.015-.118-.01-.242 0-.325-.063-.07-.063-.18-.147-.177-.231.007-.078.04-.209.09-.389l1.396-4.63zm2.117 1.848h-1.634l-.1.33h1.414c.167-.02.202.004.216-.004l.104-.326zm-1.545-.297s.32-.292.867-.387c.124-.023.9-.015.9-.015l.119-.392h-1.647l-.24.794z" fill="#FEFEFE"/><path d="M21.899 18.648l-.093.44c-.04.137-.073.24-.177.328-.11.093-.237.19-.536.19l-.554.023-.005.497c-.005.14.032.126.054.149.026.025.049.035.073.045l.175-.01.529-.03-.22.726h-.606c-.425 0-.74-.01-.842-.091-.103-.065-.116-.146-.115-.286l.04-1.938h.968l-.014.397h.233c.08 0 .134-.008.167-.03a.175.175 0 0 0 .065-.1l.097-.31h.76zM8.082 8.932c-.033.158-.655 3.024-.656 3.026-.134.58-.231.993-.562 1.26a1 1 0 0 1-.66.23c-.409 0-.646-.203-.687-.587l-.007-.132.124-.781s.652-2.611.769-2.957l.01-.039c-1.27.011-1.495 0-1.51-.02-.009.028-.04.19-.04.19l-.666 2.943-.057.25-.11.816c0 .242.047.44.142.607.303.53 1.168.609 1.657.609.63 0 1.222-.134 1.622-.378.694-.41.875-1.051 1.037-1.62l.075-.293s.672-2.712.786-3.065c.004-.02.006-.03.012-.039-.92.01-1.192 0-1.28-.02M11.798 14.319c-.45-.008-.61-.008-1.135.02l-.02-.04c.045-.2.095-.398.14-.6l.065-.275c.097-.425.191-.92.202-1.072.01-.09.042-.317-.218-.317-.109 0-.223.053-.339.107-.063.226-.19.863-.252 1.153-.13.61-.138.681-.197.983l-.038.041a12.946 12.946 0 0 0-1.159.02l-.024-.046c.089-.362.178-.728.263-1.091.224-.986.278-1.362.338-1.863l.044-.03c.52-.073.647-.088 1.21-.202l.048.053-.087.313c.096-.057.187-.114.283-.163.266-.13.562-.17.724-.17.248 0 .518.069.63.355.107.254.036.567-.104 1.184l-.072.316c-.144.686-.168.812-.25 1.283l-.052.041zM13.627 14.319c-.272-.002-.448-.008-.617-.002-.17.002-.335.01-.588.022l-.013-.022-.016-.024c.069-.26.106-.35.14-.443a3.13 3.13 0 0 0 .128-.449c.08-.345.128-.586.16-.797.037-.204.057-.378.085-.58l.02-.015.02-.02c.27-.037.442-.062.618-.09.177-.023.355-.06.635-.113l.01.024.008.025c-.052.214-.105.427-.156.643-.05.217-.103.43-.15.643-.101.453-.142.623-.166.745-.024.115-.03.178-.069.412l-.025.021-.024.02zM17.67 12.768c.159-.692.036-1.015-.119-1.212-.234-.3-.648-.396-1.078-.396-.258 0-.873.025-1.354.468-.345.32-.505.754-.6 1.17-.098.423-.21 1.186.492 1.47.216.093.528.118.73.118.513 0 1.04-.141 1.436-.561.305-.341.445-.848.494-1.057m-1.18-.05c-.022.117-.124.551-.262.736-.097.136-.21.219-.337.219-.037 0-.26 0-.264-.332-.002-.163.031-.33.072-.512.119-.524.258-.964.616-.964.28 0 .3.328.175.853M28.677 14.365c-.544-.004-.7-.004-1.202.017l-.031-.04c.135-.517.272-1.032.393-1.554.158-.678.194-.966.245-1.363l.041-.033c.54-.077.69-.099 1.252-.203l.016.047c-.103.426-.203.85-.304 1.278-.206.893-.281 1.346-.36 1.813l-.05.038z" fill="#FEFEFE"/><path d="M28.935 12.83c.158-.688-.479-.062-.58-.289-.154-.354-.058-1.072-.683-1.312-.24-.095-.804.027-1.29.469-.34.315-.504.747-.597 1.161-.098.418-.21 1.18.488 1.452.222.095.422.123.624.113.702-.038 1.236-1.098 1.633-1.516.305-.333.358.124.405-.079m-1.074-.05c-.027.112-.13.549-.268.732-.092.13-.311.211-.437.211-.036 0-.257 0-.264-.325a2.225 2.225 0 0 1 .073-.512c.12-.515.258-.95.616-.95.28 0 .4.316.28.843M20.746 14.319a12.427 12.427 0 0 0-1.134.02l-.02-.04c.046-.2.097-.398.144-.6l.061-.275c.099-.425.194-.92.203-1.072.01-.09.042-.317-.216-.317-.113 0-.225.053-.341.107-.062.226-.192.863-.255 1.153-.126.61-.136.681-.193.983l-.04.041a12.904 12.904 0 0 0-1.156.02l-.024-.046c.088-.362.177-.728.262-1.091.224-.986.276-1.362.339-1.863l.04-.03c.52-.073.648-.088 1.212-.202l.043.053-.08.313a4.81 4.81 0 0 1 .281-.163c.264-.13.562-.17.724-.17.244 0 .516.069.632.355.105.254.033.567-.108 1.184l-.07.316c-.15.686-.17.812-.25 1.283l-.054.041zM25.133 10.61c-.079.359-.312.66-.61.806-.247.124-.549.134-.86.134h-.201l.015-.08.37-1.608.011-.082.005-.063.149.015.782.067c.302.117.426.418.34.81m-.487-1.68l-.375.003c-.974.012-1.364.008-1.524-.011l-.04.197-.348 1.618-.874 3.597c.85-.01 1.199-.01 1.345.006.034-.161.23-1.121.232-1.121 0 0 .168-.704.178-.73 0 0 .053-.073.106-.102h.078c.732 0 1.56 0 2.209-.477.441-.328.743-.81.877-1.398.035-.144.061-.315.061-.487 0-.225-.045-.447-.176-.62-.33-.464-.99-.472-1.75-.476M33.124 11.185l-.043-.05c-.556.113-.656.131-1.167.2l-.038.038-.005.024-.002-.009c-.38.877-.37.688-.679 1.378l-.003-.084-.077-1.497-.05-.05c-.581.113-.595.131-1.133.2l-.041.038c-.006.017-.006.037-.01.059l.004.007c.067.344.05.267.118.809.032.266.073.533.105.796.053.44.083.656.147 1.327-.363.6-.449.826-.798 1.352l.022.049c.524-.02.646-.02 1.035-.02l.084-.096c.294-.633 2.531-4.47 2.531-4.47M14.12 11.556c.298-.207.335-.493.085-.641-.254-.15-.7-.102-1 .105-.3.203-.333.49-.08.642.25.146.697.103.994-.106" fill="#FEFEFE"/><path d="M30.554 15.709l-.437.75c-.139.256-.395.447-.803.448l-.696-.012.203-.674h.137c.07 0 .121-.003.16-.023.036-.012.062-.04.09-.08l.258-.409h1.088z" fill="#FEFEFE"/></g></svg>PK
!<ZѨ���+chrome/content/third-party/cc-logo-visa.svg<svg width="44" height="30" xmlns="http://www.w3.org/2000/svg"><defs><path d="M22.8 9.786c-.025-1.96 1.765-3.053 3.113-3.703 1.385-.667 1.85-1.095 1.845-1.691-.01-.913-1.105-1.316-2.13-1.332-1.787-.027-2.826.478-3.652.86L21.332.938c.83-.378 2.364-.708 3.956-.722 3.735 0 6.18 1.824 6.193 4.653.014 3.59-5.02 3.79-4.985 5.395.012.486.481 1.005 1.51 1.138.508.066 1.914.117 3.506-.609l.626 2.884a9.623 9.623 0 0 1-3.329.605c-3.516 0-5.99-1.85-6.01-4.497m15.347 4.248a1.621 1.621 0 0 1-1.514-.998L31.296.428h3.733l.743 2.032h4.561l.431-2.032h3.29l-2.87 13.606h-3.038m.522-3.675l1.077-5.11h-2.95l1.873 5.11m-20.394 3.675L15.33.428h3.557l2.942 13.606h-3.556m-8.965-9.26L7.81 12.648c-.176.879-.87 1.386-1.64 1.386H.116l-.084-.395c1.242-.267 2.654-.697 3.51-1.157.523-.282.672-.527.844-1.196L7.224.428h3.76l5.763 13.606H13.01L9.31 4.774z" id="a"/><linearGradient x1="16.148%" y1="34.401%" x2="85.832%" y2="66.349%" id="b"><stop stop-color="#222357" offset="0%"/><stop stop-color="#254AA5" offset="100%"/></linearGradient></defs><g transform="matrix(1 0 0 -1 0 22.674)" fill="none" fill-rule="evenodd"><mask id="c" fill="#fff"><use href="#a"/></mask><path fill="url(#b)" fill-rule="nonzero" mask="url(#c)" d="M-4.669 12.849l44.237 16.12L49.63 1.929 5.395-14.19"/></g></svg>PK
!<t����*en-US/locale/en-US/formautofill.properties
insecureFieldWarningDescription = %S has detected an insecure site. Form Autofill is temporarily disabled.

learnMoreLabel = Learn more

autofillReauthOSDialogMac = change the authentication settings
autofillReauthOSDialogWin = To change the authentication settings, enter your Windows login credentials.
autofillReauthOSDialogLin = To change the authentication settings, enter your Linux login credentials.
PK
!<d)�l��
manifest.json{
  "manifest_version": 2,
  "name": "Form Autofill",
  "version": "1.0.1",

  "browser_specific_settings": {
    "gecko": {
      "id": "formautofill@mozilla.org"
    }
  },

  "background": {
    "scripts": ["background.js"]
  },

  "experiment_apis": {
    "formautofill": {
      "schema": "schema.json",
      "parent": {
        "scopes": ["addon_parent"],
        "script": "api.js",
        "events": ["startup"]
      }
    }
  }
}
PK
!<D�hpschema.json[]
PK##2

Zerion Mini Shell 1.0