(() => {
  // application/scripts/height_equaler.js
  var height_equaler = class {
    #to;
    #from;
    constructor(from, to) {
      this.#from = from;
      this.#to = to;
      this.#set_styles();
      new ResizeObserver(() => {
        this.#update();
      }).observe(from);
      setTimeout(() => {
        this.#update();
      }, 100);
    }
    get height() {
      return this.#from.offsetHeight;
    }
    #set_styles() {
      this.#to.style.height = "0px";
      this.#to.style.transition = "height 0.5s";
    }
    #update() {
      this.#to.style.height = this.height + "px";
    }
  };

  // application/scripts/product.js
  var product = class _product {
    name;
    description;
    author;
    image;
    stock_count;
    barcode;
    thumbnail;
    on_stock;
    constructor(target) {
      this.name = null;
      this.description = null;
      this.author = null;
      this.image = null;
      this.stock_count = null;
      this.barcode = null;
      this.thumbnail = null;
      this.on_stock = null;
      if ("name" in target) this.name = target["name"];
      if ("description" in target) this.description = target["description"];
      if ("author" in target) this.author = target["author"];
      if ("image" in target) this.image = target["image"];
      if ("stock_count" in target) this.stock_count = target["stock_count"];
      if ("barcode" in target) this.barcode = target["barcode"];
      if ("thumbnail" in target) this.thumbnail = target["thumbnail"];
      if ("on_stock" in target) this.on_stock = target["on_stock"];
      try {
        this.stock_count = Number(this.stock_count);
      } catch {
        this.stock_count = 0;
      }
      try {
        this.on_stock = Number(this.on_stock);
      } catch {
        this.on_stock = 0;
      }
    }
    get dump() {
      const dumped = {
        "name": new String(this.name),
        "description": new String(this.description),
        "author": new String(this.author),
        "image": new String(this.image),
        "barcode": new String(this.barcode),
        "thumbnail": new String(this.thumbnail),
        "stock_count": new String(this.stock_count)
      };
      if (this.on_stock !== null) {
        dumped["on_stock"] = new String(this.on_stock);
      }
      return dumped;
    }
    get ready() {
      if (this.name === null || this.description === null) return false;
      if (this.author === null || this.image === null) return false;
      if (this.stock_count === null || this.barcode === null) return false;
      if (this.thumbnail === null) return false;
      return true;
    }
    copy() {
      return new _product(this.dump);
    }
  };

  // application/scripts/products_loader.js
  var products_loader = class _products_loader {
    static async all() {
      const request2 = await fetch("/products/");
      const response = await request2.json();
      return _products_loader.#response_to_collection(response);
    }
    static #response_to_collection(response) {
      if (response.result !== "success") {
        return new Array();
      }
      if ("collection" in response) {
        return this.#list_response_to_collection(response);
      }
      return this.#single_response_to_collection(response);
    }
    static #single_response_to_collection(response) {
      const result = new Array();
      result.push(new product(response.product));
      return result;
    }
    static #list_response_to_collection(response) {
      const result = new Array();
      response.collection.forEach((serialized) => {
        result.push(new product(serialized));
      });
      return result;
    }
    static async search_name(name) {
      return await _products_loader.#search(
        "/product/search/name",
        name
      );
    }
    static async search_author(author) {
      return await _products_loader.#search(
        "/product/search/author",
        author
      );
    }
    static async search_barcode(barcode) {
      return await _products_loader.#search(
        "/product/get/barcode",
        barcode
      );
    }
    static async #search(path, parameter) {
      const coded = encodeURI(parameter);
      const request2 = await fetch(path + "/" + coded);
      const response = await request2.json();
      return _products_loader.#response_to_collection(response);
    }
  };

  // application/scripts/fullscreen.js
  var fullscreen = class {
    #node;
    constructor() {
      this.#node = null;
    }
    get visible() {
      return this.#node !== null;
    }
    _build_node() {
      throw new TypeError("This is virtual method!");
    }
    get #opacity() {
      if (!this.visible) {
        throw new TypeError("Can not change opacity of not existed.");
      }
      return Number(this.#node.style.opacity);
    }
    set #opacity(target) {
      if (!this.visible) {
        throw new TypeError("Can not change opacity of not existed.");
      }
      this.#node.style.opacity = String(target);
    }
    get_query(selector) {
      if (!this.visible) {
        throw new TypeError("Can not get item from not visible.");
      }
      return this.#node.querySelector(selector);
    }
    #prepare() {
      const container = document.createElement("div");
      container.classList.add("fullscreen-viewer");
      container.style.transition = "opacity 0.5s";
      container.appendChild(this._build_node());
      return container;
    }
    hide() {
      if (!this.visible) {
        return;
      }
      this.#opacity = 0;
      setTimeout(() => {
        if (!this.visible) {
          return;
        }
        this.#node.remove();
        this.#node = null;
      }, 500);
    }
    show() {
      if (this.visible) {
        return;
      }
      this.#node = this.#prepare();
      this.#opacity = 0;
      document.querySelector("body").appendChild(this.#node);
      setTimeout(() => {
        this.#opacity = 1;
      }, 100);
    }
  };

  // application/scripts/product_fullscreen.js
  var product_fullscreen = class extends fullscreen {
    #target;
    constructor(target) {
      super();
      this.#target = target;
    }
    get target() {
      return this.#target;
    }
    _build_node() {
      const container = document.createElement("div");
      container.classList.add("product-fullscreen-viewer");
      const image = document.createElement("div");
      image.style.backgroundImage = 'url("' + this.target.image + '")';
      image.classList.add("image");
      container.appendChild(image);
      const title = document.createElement("div");
      title.classList.add("title");
      container.appendChild(title);
      const title_content = document.createElement("h1");
      title_content.innerText = this.target.name;
      title.appendChild(title_content);
      const bottom = document.createElement("div");
      bottom.classList.add("bottom-side");
      container.appendChild(bottom);
      const bottom_header = document.createElement("div");
      bottom_header.classList.add("bottom-header");
      bottom.appendChild(bottom_header);
      const barcode_icon = document.createElement("span");
      barcode_icon.classList.add("material-icons");
      barcode_icon.innerText = "qr_code_scanner";
      const barcode_content = document.createElement("span");
      barcode_content.innerText = this.target.barcode;
      barcode_content.classList.add("numbers");
      const barcode = document.createElement("p");
      barcode.appendChild(barcode_icon);
      barcode.appendChild(barcode_content);
      bottom_header.appendChild(barcode);
      const author_icon = document.createElement("span");
      author_icon.classList.add("material-icons");
      author_icon.innerText = "attribution";
      const author_content = document.createElement("span");
      author_content.innerText = this.target.author;
      const author = document.createElement("p");
      author.appendChild(author_icon);
      author.appendChild(author_content);
      bottom_header.appendChild(author);
      const description = document.createElement("div");
      description.classList.add("description");
      bottom.appendChild(description);
      const description_content = document.createElement("p");
      description_content.innerText = this.target.description;
      description.appendChild(description_content);
      const close_button = document.createElement("button");
      close_button.classList.add("material-icons");
      close_button.classList.add("close");
      close_button.innerText = "close";
      container.appendChild(close_button);
      close_button.addEventListener("click", () => {
        this.hide();
      });
      return container;
    }
  };

  // application/scripts/user.js
  var user = class {
    #nick;
    #apikey;
    constructor(nick, apikey) {
      this.#nick = nick;
      this.#apikey = apikey;
    }
    get nick() {
      return this.#nick;
    }
    get apikey() {
      return this.#apikey;
    }
  };

  // application/scripts/login_manager.js
  var login_manager = class {
    get apikey() {
      return localStorage.getItem("apikey");
    }
    get logged_in() {
      return localStorage.getItem("apikey") !== null;
    }
    #create_request(data) {
      return {
        method: "POST",
        body: JSON.stringify(data),
        headers: {
          "Content-Type": "application/json"
        }
      };
    }
    async get_user() {
      if (!this.logged_in) {
        return null;
      }
      const request_data = this.#create_request({
        apikey: this.apikey
      });
      const request2 = await fetch("/user", request_data);
      const response = await request2.json();
      if (response.result !== "success") {
        return null;
      }
      return new user(
        response.nick,
        response.apikey
      );
    }
    async login(nick, password) {
      const request_data = this.#create_request({
        nick,
        password
      });
      const request2 = await fetch("/user/login", request_data);
      const response = await request2.json();
      if (response.result !== "success") {
        return false;
      }
      localStorage.setItem("apikey", response.apikey);
      return true;
    }
    logout() {
      localStorage.removeItem("apikey");
    }
  };

  // application/scripts/confirm_action.js
  var confirm_action = class {
    #node;
    #action;
    constructor() {
      this.#node = null;
      this.#action = true;
    }
    get _description() {
      throw new TypeError("It must be overwriten.");
    }
    get _title() {
      return _("you-must-confirm-it");
    }
    _action() {
      throw new TypeError("It must be overwriten.");
    }
    get _info() {
      return false;
    }
    show() {
      if (this.#node !== null) {
        return;
      }
      this.#action = true;
      this.#node = this.#create_window();
      document.querySelector("body").appendChild(this.#node);
      setTimeout(() => {
        this.#node.style.opacity = "1";
      }, 100);
    }
    hide() {
      if (this.#node === null) {
        return;
      }
      this.#action = false;
      this.#node.style.opacity = "0";
      setTimeout(() => {
        if (this.#node === null) {
          return;
        }
        this.#node.remove();
        this.#node = null;
      }, 500);
    }
    #create_window() {
      const container = document.createElement("div");
      container.classList.add("confirm-window");
      container.style.transition = "opacity 0.5s";
      container.style.opacity = "0";
      const center = document.createElement("div");
      center.classList.add("center");
      container.appendChild(center);
      const title = document.createElement("div");
      title.classList.add("title");
      center.appendChild(title);
      const title_text = document.createElement("h3");
      title_text.innerText = this._title;
      title.appendChild(title_text);
      const description = document.createElement("div");
      description.classList.add("description");
      center.appendChild(description);
      const description_text = document.createElement("p");
      description_text.innerText = this._description;
      description.appendChild(description_text);
      const buttons = document.createElement("div");
      buttons.classList.add("buttons");
      center.appendChild(buttons);
      const cancel_button = document.createElement("button");
      cancel_button.classList.add("cancel");
      cancel_button.classList.add("material-icons");
      cancel_button.innerText = "close";
      buttons.appendChild(cancel_button);
      cancel_button.addEventListener("click", () => {
        this.hide();
      });
      if (!this._info) {
        const confirm_button = document.createElement("button");
        confirm_button.classList.add("confirm");
        confirm_button.classList.add("material-icons");
        confirm_button.innerText = "send";
        buttons.appendChild(confirm_button);
        confirm_button.addEventListener("click", () => {
          if (this.#action === false) {
            return;
          }
          this._action();
          this.hide();
        });
      }
      return container;
    }
  };

  // application/scripts/request.js
  var request = class {
    get settings() {
      const settings = {
        "method": this.method,
        "headers": this.headers
      };
      if (this.method === "GET" || this.method === "HEAD") {
        return settings;
      }
      if (this.body === null) {
        return settings;
      }
      settings.body = this.body;
      return settings;
    }
    get _apikey() {
      const manager = new login_manager();
      if (manager.logged_in) {
        return manager.apikey;
      }
      throw new Error(_("user-must-be-logged-in"));
    }
    get method() {
      throw new TypeError("It must be overwrite.");
    }
    get url() {
      throw new TypeError("It must be overwrite.");
    }
    get headers() {
      if (this.method === "GET" || this.method === "HEAD") {
        return {};
      }
      if (typeof this.data === "string") {
        return {
          "Content-Type": "text/plain"
        };
      }
      return {
        "Content-Type": "application/json"
      };
    }
    get body() {
      if (this.data === null) {
        return null;
      }
      if (typeof this.data === "string") {
        return this.data;
      }
      return JSON.stringify(this.data);
    }
    get _response() {
      throw new TypeError("It must be overwrite.");
    }
    async connect() {
      const request2 = await fetch(this.url, this.settings);
      if (!request2.ok) {
        throw new Error(_("fail-when-request-__url__").format({
          url: this.url
        }));
      }
      const response = await request2.json();
      if (!("result" in response)) {
        throw new Error(_("bad-response-not-contain-result"));
      }
      return new this._response(response);
    }
    get data() {
      throw new TypeError("This must be overwrite.");
    }
  };

  // application/scripts/bool_response.js
  var bool_response = class {
    #result;
    #cause;
    constructor(target) {
      this.#result = target.result === "success";
      this.#cause = null;
      if (!this.result) {
        this.#cause = target.cause;
      }
    }
    get cause() {
      return this.#cause;
    }
    get result() {
      return this.#result;
    }
  };

  // application/scripts/delete_request.js
  var delete_request = class extends request {
    #product;
    constructor(product2) {
      super();
      this.#product = product2;
    }
    get _response() {
      return bool_response;
    }
    get data() {
      return {
        "apikey": this._apikey
      };
    }
    get url() {
      return "/product/barcode/" + this.#product.barcode;
    }
    get method() {
      return "DELETE";
    }
  };

  // application/scripts/product_containers.js
  var product_containers = class {
    #content;
    #where;
    #inserted;
    #counter;
    #count;
    #next_button;
    #previous_button;
    constructor(where) {
      this.#counter = 0;
      this.#count = 24;
      this.#content = new Array();
      this.#inserted = new Array();
      this.#where = document.createElement("div");
      this.#where.classList.add("products-list");
      this.#next_button = document.createElement("input");
      this.#next_button.type = "button";
      this.#next_button.value = _("show-next");
      this.#previous_button = document.createElement("input");
      this.#previous_button.type = "button";
      this.#previous_button.value = _("show-previous");
      this.#next_button.addEventListener("click", () => {
        this.#next();
      });
      this.#previous_button.addEventListener("click", () => {
        this.#previous();
      });
      where.appendChild(this.#previous_button);
      where.appendChild(this.#where);
      where.appendChild(this.#next_button);
    }
    add_list(target) {
      target.forEach((count) => {
        this.add(count);
      });
      return this;
    }
    add(target) {
      const current = new product_container(target);
      this.#content.push(current);
      return this;
    }
    clean() {
      this.#counter = 0;
      this.#content = new Array();
      return this;
    }
    #update_buttons() {
      if (this.previous_avairable) {
        this.#previous_button.style.opacity = "1";
      } else {
        this.#previous_button.style.opacity = "0";
      }
      if (this.next_avairable) {
        this.#next_button.style.opacity = "1";
      } else {
        this.#next_button.style.opacity = "0";
      }
    }
    update() {
      this.#update_buttons();
      this.#hide();
      setTimeout(() => {
        const first = this.#counter;
        const last = this.#counter + this.#count;
        const current = this.#content.slice(first, last);
        current.forEach((count) => {
          this.#show_sigle(count);
        });
      }, 500);
      return this;
    }
    get next_avairable() {
      return this.#counter + this.#count <= this.#content.length;
    }
    get previous_avairable() {
      return this.#counter >= this.#count;
    }
    #next() {
      if (!this.next_avairable) return;
      this.#counter += this.#count;
      this.update();
    }
    #previous() {
      if (!this.previous_avairable) return;
      this.#counter -= this.#count;
      this.#counter = this.#counter < 0 ? 0 : this.#counter;
      this.update();
    }
    #show_sigle(target) {
      this.#inserted.push(target);
      target.add(this.#where);
    }
    #hide() {
      this.#inserted.forEach((count) => {
        count.drop();
      });
      this.#inserted = new Array();
      return this;
    }
  };

  // application/scripts/searcher.js
  var searcher = class _searcher {
    #input;
    #category;
    #manager;
    #result;
    #counter;
    static #instances;
    static #add(instance) {
      if (typeof _searcher.#instances !== "object") {
        _searcher.#instances = new Array();
      }
      _searcher.#instances.push(instance);
    }
    static reload() {
      if (typeof _searcher.#instances !== "object") {
        return;
      }
      _searcher.#instances.forEach((instance) => {
        instance.update();
      });
    }
    constructor(search_form, manager, result, counter) {
      this.#input = search_form.querySelector('input[type="text"]');
      this.#category = search_form.querySelector("select");
      this.#manager = manager;
      this.#result = result;
      this.#counter = counter;
      this.#selector_complete();
      search_form.addEventListener("submit", (target) => {
        target.preventDefault();
        this.update();
      });
      _searcher.#add(this);
    }
    get categories() {
      return {
        "name": _("name-category"),
        "author": _("author-category"),
        "barcode": _("barcode-category")
      };
    }
    #selector_complete() {
      const category = this.#category;
      const categories = this.categories;
      Object.keys(categories).forEach((name) => {
        const option = document.createElement("option");
        option.value = name;
        option.innerText = categories[name];
        category.appendChild(option);
      });
    }
    get #loader() {
      return {
        "name": products_loader.search_name,
        "author": products_loader.search_author,
        "barcode": products_loader.search_barcode
      }[this.category];
    }
    get category() {
      return this.#category.value;
    }
    get phrase() {
      return this.#input.value.trim();
    }
    get #result_title() {
      return this.#result.innerText;
    }
    set #result_title(target) {
      this.#result.innerText = target;
    }
    async update() {
      if (this.phrase.length === 0) {
        this.show_all();
        return;
      }
      this.#insert(await this.#loader(this.phrase));
    }
    set #how_many(target) {
      this.#counter.innerText = _("found-count") + target;
    }
    get #how_many() {
      return this.#counter.innerText;
    }
    #insert(list) {
      if (list.length === 0) {
        this.#result_title = _("not-found-anything");
      } else {
        this.#result_title = _("browse-our-products");
      }
      this.#how_many = list.length;
      this.#manager.clean().add_list(list).update();
    }
    async show_all() {
      this.#insert(await products_loader.all());
    }
  };

  // application/scripts/delete_product_window.js
  var delete_product_window = class extends confirm_action {
    #target;
    constructor(target) {
      super();
      this.#target = target;
    }
    get _title() {
      return _("do-you-want-to-remove-it");
    }
    get _description() {
      let content = _("you-try-to-remove-__name__").format({
        name: this.#target.name
      });
      return content;
    }
    async _action() {
      new delete_request(this.#target).connect();
      searcher.reload();
    }
  };

  // application/scripts/formscreen.js
  var formscreen = class extends fullscreen {
    #form;
    #result;
    constructor() {
      super();
      this.#form = null;
      this.#result = null;
    }
    get _name() {
      throw new TypeError("This is virtual getter!");
    }
    _process() {
      this._error = "This is abstract, and must be overwriten.";
    }
    _build_form() {
      throw new TypeError("This is virtual method!");
    }
    _get_input(name) {
      return this.get_query('input[name="' + name + '"]');
    }
    get _has_submit() {
      return true;
    }
    _build_node() {
      const center = document.createElement("div");
      center.classList.add("center");
      const title = document.createElement("div");
      title.classList.add("title");
      center.appendChild(title);
      const title_content = document.createElement("h3");
      title_content.innerText = this._name;
      title.appendChild(title_content);
      const form = document.createElement("form");
      center.appendChild(form);
      form.addEventListener("change", () => {
        this._clear_results();
      });
      this.#form = document.createElement("div");
      this.#form.classList.add("content");
      form.appendChild(this.#form);
      this.#result = document.createElement("div");
      this.#result.classList.add("result");
      form.appendChild(this.#result);
      const bottom = document.createElement("div");
      bottom.classList.add("bottom");
      form.appendChild(bottom);
      const close_button = document.createElement("button");
      close_button.classList.add("close");
      close_button.classList.add("material-icons");
      close_button.innerText = "close";
      close_button.type = "button";
      bottom.appendChild(close_button);
      if (this._has_submit) {
        const send_button = document.createElement("button");
        send_button.classList.add("send");
        send_button.classList.add("material-icons");
        send_button.innerText = "send";
        send_button.type = "submit";
        bottom.appendChild(send_button);
      }
      close_button.addEventListener("click", () => {
        this.hide();
      });
      form.addEventListener("submit", (target) => {
        target.preventDefault();
        this._process();
      });
      this._refresh();
      return center;
    }
    _refresh() {
      while (this.#form.lastChild) {
        this.#form.lastChild.remove();
      }
      this._build_form();
    }
    _create_input(name, label_text, placeholder, worker = null) {
      const container = document.createElement("div");
      container.classList.add("input-container");
      container.classList.add("input-" + name);
      const label = document.createElement("label");
      label.htmlFor = name;
      label.innerText = label_text;
      container.appendChild(label);
      const input = document.createElement("input");
      input.type = "text";
      input.placeholder = placeholder;
      input.name = name;
      input.id = name;
      container.appendChild(input);
      if (worker !== null) {
        worker(input);
      }
      if (!this.#form) {
        throw new Error("Screen is not visible yet!");
      }
      this._append_child(container);
      return (target = null) => {
        if (target !== null) {
          input.value = target;
        }
        return input.value;
      };
    }
    _append_child(target) {
      this.#form.appendChild(target);
    }
    _clear_results() {
      if (!this.#result) {
        return;
      }
      while (this.#result.lastChild) {
        this.#result.lastChild.remove();
      }
    }
    set _info(target) {
      this._clear_results();
      const info = document.createElement("p");
      info.classList.add("info");
      info.innerText = target;
      if (this.#result) {
        this.#result.appendChild(info);
      }
    }
    set _error(target) {
      this._clear_results();
      const info = document.createElement("p");
      info.classList.add("error");
      info.innerText = target;
      if (this.#result) {
        this.#result.appendChild(info);
      }
    }
    set _success(target) {
      this._clear_results();
      const info = document.createElement("p");
      info.classList.add("success");
      info.innerText = target;
      if (this.#result) {
        this.#result.appendChild(info);
      }
    }
  };

  // application/scripts/product_base.js
  var product_base = class {
    name;
    description;
    author;
    barcode;
    stock_count;
    constructor(target = null) {
      this.name = this._extract(target, "name");
      this.description = this._extract(target, "description");
      this.author = this._extract(target, "author");
      this.barcode = this._extract(target, "barcode");
      this.stock_count = this._extract(target, "stock_count");
      if (this.stock_count !== null) {
        try {
          this.stock_count = Number(this.stock_count);
        } catch {
          this.stock_count = 0;
        }
      }
    }
    get dump() {
      return {
        "name": new String(this.name),
        "description": new String(this.description),
        "author": new String(this.author),
        "barcode": new String(this.barcode),
        "stock_count": new String(this.stock_count)
      };
    }
    _extract(dict, name) {
      if (dict === null) {
        return null;
      }
      if (name in dict) {
        return dict[name];
      }
      return null;
    }
    get avairable() {
      return this.stock_count > 0;
    }
  };

  // application/scripts/edit_request.js
  var edit_request = class extends request {
    #target;
    #updated;
    constructor(target, updated) {
      super();
      this.#target = target;
      this.#updated = updated;
    }
    get _response() {
      return bool_response;
    }
    get data() {
      return Object.assign(this.#updated.dump, {
        "apikey": this._apikey
      });
    }
    get method() {
      return "POST";
    }
    get url() {
      return "/product/update/barcode/" + this.#target.barcode;
    }
  };

  // application/scripts/edit_image_request.js
  var edit_image_request = class extends request {
    #image;
    #target;
    constructor(target, image) {
      super();
      this.#target = target;
      this.#image = image;
    }
    get _response() {
      return bool_response;
    }
    get data() {
      return {
        "image": this.#image,
        "apikey": this._apikey
      };
    }
    get method() {
      return "POST";
    }
    get url() {
      return "/product/update/image/barcode/" + this.#target.barcode;
    }
  };

  // application/scripts/product_editor.js
  var product_editor = class extends formscreen {
    #target;
    #name;
    #description;
    #author;
    #barcode;
    #stock_count;
    #image;
    #loaded_image_type;
    #loaded_image;
    #image_preview;
    constructor(target) {
      super();
      this.#target = target;
    }
    get target() {
      return this.#target;
    }
    get _name() {
      return _("product-editor");
    }
    _build_form() {
      this.#loaded_image = null;
      this.#loaded_image_type = null;
      this.#name = this._create_input(
        "name",
        _("name-prompt"),
        _("name-sample"),
        (input) => {
          input.value = this.#target.name;
        }
      );
      this.#description = this._create_input(
        "description",
        _("description-prompt"),
        _("description-sample"),
        (input) => {
          input.value = this.#target.description;
        }
      );
      this.#author = this._create_input(
        "author",
        _("author-prompt"),
        _("author-sample"),
        (input) => {
          input.value = this.#target.author;
        }
      );
      this.#barcode = this._create_input(
        "barcode",
        _("barcode-prompt"),
        _("barcode-sample"),
        (input) => {
          input.type = "number";
          input.value = this.#target.barcode;
        }
      );
      this.#stock_count = this._create_input(
        "stock_count",
        _("stock-count-prompt"),
        _("stock-count-sample"),
        (input) => {
          input.type = "number";
          input.value = this.#target.stock_count;
        }
      );
      this._create_input(
        "image",
        _("change-product-image"),
        "",
        (input) => {
          this.#image = input;
          input.type = "file";
          input.accept = "image/*";
          input.addEventListener("change", () => {
            this.#load_image_from_file();
          });
        }
      );
      this.#image_preview = document.createElement("img");
      this.#image_preview.style.opacity = "1";
      this.#image_preview.src = this.#target.image;
      this._append_child(this.#image_preview);
    }
    get #ready_image() {
      return this.#loaded_image;
    }
    #update_image_preview() {
      this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;
      this.#image_preview.style.opacity = "1";
    }
    #reset_image() {
      this.#loaded_image = null;
      this.#loaded_image_type = null;
      this.#image_preview.style.opacity = "0";
      this.#image_preview.src = "";
    }
    async #load_image_from_file() {
      if (this.#image.files.length === 0) {
        this.#reset_image();
      }
      const file = this.#image.files.item(0);
      const buffer = await file.arrayBuffer();
      let as_string = new String();
      new Uint8Array(buffer).forEach((letter) => {
        as_string += String.fromCharCode(letter);
      });
      this.#loaded_image = btoa(as_string);
      this.#loaded_image_type = file.type;
      this.#update_image_preview();
    }
    async #submit() {
      const copy = this.#target.copy();
      copy.name = this.#name();
      copy.description = this.#description();
      copy.author = this.#author();
      copy.barcode = this.#barcode();
      copy.stock_count = this.#stock_count();
      const request2 = new edit_request(this.#target, copy);
      const response = await request2.connect();
      if (!response.result) {
        throw new Error(response.cause);
      }
      this.#target = copy;
    }
    async #image_submit() {
      const image = await this.#ready_image;
      if (image === null) {
        return;
      }
      const request2 = new edit_image_request(this.#target, image);
      const response = await request2.connect();
      if (!response.result) {
        throw new Error(response.cause);
      }
    }
    async _process() {
      try {
        this._info = _("updating-product-data");
        await this.#submit();
        this._info = _("processing-image");
        await this.#image_submit();
        this._success = _("uploaded-successfull");
        searcher.reload();
        setTimeout(() => {
          this.hide();
        }, 500);
      } catch (error) {
        this._error = new String(error);
      }
    }
  };

  // application/scripts/rents_screen.js
  var rents_screen = class extends formscreen {
    #target;
    #email;
    #phone;
    get _email() {
      return this.#email();
    }
    get _phone() {
      return this.#phone();
    }
    constructor(target) {
      super();
      this.#target = target;
    }
    get _target() {
      return this.#target;
    }
    _build_form() {
      this.#email = this._create_input(
        "email",
        _("email-prompt"),
        _("email-sample"),
        (input) => {
          input.type = "email";
        }
      );
      this.#phone = this._create_input(
        "phone",
        _("phone-number-prompt"),
        _("phone-number-sample"),
        (input) => {
          input.type = "tel";
          const add_prefix = () => {
            if (input.value.length === 0) {
              input.value = "+48 ";
            }
          };
          input.addEventListener("click", add_prefix);
          input.addEventListener("focus", add_prefix);
        }
      );
    }
  };

  // application/scripts/reservation.js
  var reservation = class _reservation {
    email;
    phone_number;
    product_barcode;
    constructor(target = null) {
      this.email = null;
      this.phone_number = null;
      this.product_barcode = null;
      if (target === null) {
        return;
      }
      if ("email" in target) {
        this.email = target["email"];
      }
      if ("target_barcode" in target) {
        this.product_barcode = target["target_barcode"];
      }
      if ("phone_number" in target) {
        this.phone_number = target["phone_number"];
      }
    }
    get dump() {
      const dumped = {
        "target_barcode": this.product_barcode
      };
      if (this.email !== null) {
        dumped["email"] = this.email;
      }
      if (this.phone_number !== null) {
        dumped["phone_number"] = this.phone_number;
      }
      return dumped;
    }
    get ready() {
      if (this.product_barcode === null) return false;
      if (this.email === null && this.phone_number === null) return false;
      return true;
    }
    copy() {
      return new _reservation(this.dump);
    }
  };

  // application/scripts/product_rent_request.js
  var product_rent_request = class extends request {
    #reservation;
    constructor(reservation2) {
      super();
      this.#reservation = reservation2;
    }
    get data() {
      return Object.assign(this.#reservation.dump, {
        "apikey": this._apikey
      });
    }
    get _response() {
      return bool_response;
    }
    get method() {
      return "POST";
    }
    get url() {
      return "/rent/product/barcode/" + this.#reservation.product_barcode;
    }
  };

  // application/scripts/reservation_factory.js
  var reservation_factory = class {
    #target;
    constructor() {
      this.#target = new reservation();
    }
    phone_number(target) {
      target = target.trim().replaceAll("-", "");
      if (target.length === 0) {
        target = null;
      }
      this.#target.phone_number = target;
      return this;
    }
    email(target) {
      target = target.trim();
      if (target.length === 0) {
        target = null;
      }
      this.#target.email = target;
      return this;
    }
    product(target) {
      this.#target.product_barcode = target.barcode;
      return this;
    }
    result() {
      if (this.#target.ready) {
        return this.#target;
      }
      throw new Error("Target reservation is not ready yet.");
    }
  };

  // application/scripts/product_rent.js
  var product_rent = class extends rents_screen {
    get _name() {
      return _("product-rent");
    }
    async _process() {
      try {
        this._info = _("processing");
        const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();
        const request2 = new product_rent_request(target);
        const response = await request2.connect();
        if (!response.result) {
          throw new Error(response.cause);
        }
        this._success = _("new-rent-added");
        searcher.reload();
        setTimeout(() => {
          this.hide();
        }, 500);
      } catch (error) {
        this._error = String(error);
      }
    }
  };

  // application/scripts/product_give_back_request.js
  var product_give_back_request = class extends request {
    #reservation;
    constructor(reservation2) {
      super();
      this.#reservation = reservation2;
    }
    get data() {
      return Object.assign(this.#reservation.dump, {
        "apikey": this._apikey
      });
    }
    get _response() {
      return bool_response;
    }
    get method() {
      return "POST";
    }
    get url() {
      return "/give_back/product/barcode/" + this.#reservation.product_barcode;
    }
  };

  // application/scripts/product_give_back.js
  var product_give_back = class extends rents_screen {
    get _name() {
      return _("product-give-back");
    }
    async _process() {
      try {
        this._info = _("processing");
        const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();
        const request2 = new product_give_back_request(target);
        const response = await request2.connect();
        if (!response.result) {
          throw new Error(response.cause);
        }
        this._success = _("give-back-successfull");
        searcher.reload();
        setTimeout(() => {
          this.hide();
        }, 500);
      } catch (error) {
        this._error = String(error);
      }
    }
  };

  // application/scripts/reservations_response.js
  var reservations_response = class extends bool_response {
    #collection;
    constructor(target) {
      super(target);
      if (!this.result) {
        return;
      }
      this.#collection = new Array();
      target["reservations"].forEach((count) => {
        this.#collection.push(new reservation(count));
      });
    }
    get collection() {
      if (!this.result) {
        throw new Error(this.cause);
      }
      return this.#collection;
    }
  };

  // application/scripts/product_reservations_request.js
  var product_reservations_request = class extends request {
    #target;
    constructor(target) {
      super();
      this.#target = target;
    }
    get _response() {
      return reservations_response;
    }
    get data() {
      return {
        "apikey": this._apikey
      };
    }
    get method() {
      return "POST";
    }
    get url() {
      return "/reservations/product/barcode/" + this.#target.barcode;
    }
  };

  // application/scripts/product_all_rents.js
  var product_all_rents = class extends formscreen {
    #target;
    constructor(target) {
      super();
      this.#target = target;
    }
    get _name() {
      return _("all-rents");
    }
    get _has_submit() {
      return false;
    }
    #create_single(target) {
      const container = document.createElement("div");
      container.classList.add("reservation-info");
      if (target.phone_number !== null) {
        const phone_icon = document.createElement("span");
        phone_icon.classList.add("material-icons");
        phone_icon.innerText = "phone";
        const phone_number = document.createElement("span");
        phone_number.classList.add("numbers");
        phone_number.innerText = target.phone_number;
        const phone_number_container = document.createElement("p");
        phone_number_container.appendChild(phone_icon);
        phone_number_container.appendChild(phone_number);
        container.appendChild(phone_number_container);
      }
      if (target.email !== null) {
        const email_icon = document.createElement("span");
        email_icon.classList.add("material-icons");
        email_icon.innerText = "mail";
        const email = document.createElement("span");
        email.innerText = target.email;
        const email_container = document.createElement("p");
        email_container.appendChild(email_icon);
        email_container.appendChild(email);
        container.appendChild(email_container);
      }
      return container;
    }
    #create_single_button(target) {
      const button = document.createElement("button");
      button.classList.add("material-icons");
      button.classList.add("give-back-button");
      button.innerText = "save_alt";
      button.addEventListener("click", async () => {
        try {
          this._info = _("processing");
          const request2 = new product_give_back_request(target);
          const response = await request2.connect();
          if (!response.result) {
            throw new Error(_(response.cause));
          }
          this._refresh();
          searcher.reload();
        } catch (error) {
          this._error = String(error);
        }
      });
      return button;
    }
    _process() {
      return;
    }
    async _build_form() {
      try {
        this._info = _("loading");
        const request2 = new product_reservations_request(this.#target);
        const response = await request2.connect();
        const list = document.createElement("div");
        list.classList.add("reservations-list");
        let empty = true;
        response.collection.forEach((count) => {
          const item = document.createElement("div");
          item.classList.add("reservation");
          const left = this.#create_single(count);
          const right = this.#create_single_button(count);
          empty = false;
          item.appendChild(left);
          item.appendChild(right);
          list.appendChild(item);
        });
        this._append_child(list);
        if (empty) {
          this._success = "not-found-any-reservations";
        } else {
          this._clear_results();
        }
      } catch (error) {
        this._error = String(error);
      }
    }
  };

  // application/scripts/product_not_avairable.js
  var product_not_avairable = class extends confirm_action {
    get _title() {
      return _("product-not-avairable");
    }
    get _description() {
      return _("this-product-is-not-avairable-yet");
    }
    get _info() {
      return true;
    }
  };

  // application/scripts/product_container.js
  var product_container = class {
    #target;
    #node;
    #login;
    constructor(target) {
      this.#target = new product(target.dump);
      this.#node = null;
      this.#login = new login_manager().logged_in;
    }
    get #header() {
      const header = document.createElement("div");
      header.classList.add("header");
      const title = document.createElement("h3");
      title.innerText = this.#target.name;
      header.appendChild(title);
      if (this.#login) {
        header.appendChild(this.#manage);
      }
      return header;
    }
    get #manage() {
      const manage = document.createElement("div");
      manage.classList.add("manage");
      const all_rents_button = document.createElement("button");
      all_rents_button.classList.add("material-icons");
      all_rents_button.classList.add("all-rents-button");
      all_rents_button.innerText = "list";
      manage.appendChild(all_rents_button);
      const rent_button = document.createElement("button");
      rent_button.classList.add("material-icons");
      rent_button.classList.add("rent-button");
      rent_button.innerText = "backpack";
      manage.appendChild(rent_button);
      const give_back_button = document.createElement("button");
      give_back_button.classList.add("material-icons");
      give_back_button.classList.add("give-back-button");
      give_back_button.innerText = "save_alt";
      manage.appendChild(give_back_button);
      const edit_button = document.createElement("button");
      edit_button.classList.add("material-icons");
      edit_button.classList.add("edit-button");
      edit_button.innerText = "edit";
      manage.appendChild(edit_button);
      const delete_button = document.createElement("button");
      delete_button.classList.add("material-icons");
      delete_button.classList.add("delete-button");
      delete_button.innerText = "remove_circle_outline";
      manage.appendChild(delete_button);
      all_rents_button.addEventListener("click", () => {
        new product_all_rents(this.#target).show();
      });
      rent_button.addEventListener("click", () => {
        if (this.#target.on_stock > 0) {
          new product_rent(this.#target).show();
        } else {
          new product_not_avairable().show();
        }
      });
      give_back_button.addEventListener("click", () => {
        new product_give_back(this.#target).show();
      });
      edit_button.addEventListener("click", () => {
        new product_editor(this.#target).show();
      });
      delete_button.addEventListener("click", () => {
        new delete_product_window(this.#target).show();
      });
      return manage;
    }
    get #description() {
      const container = document.createElement("div");
      container.classList.add("description");
      const description = document.createElement("p");
      description.innerText = this.#target.description;
      description.classList.add("content");
      const author_container = document.createElement("div");
      author_container.classList.add("author");
      const author = document.createElement("span");
      author.innerText = this.#target.author;
      const author_icon = document.createElement("span");
      author_icon.classList.add("material-icons");
      author_icon.innerText = "attribution";
      author_container.appendChild(author_icon);
      author_container.appendChild(author);
      const stock_count = document.createElement("p");
      stock_count.classList.add("stock-count");
      stock_count.classList.add("material-icons");
      if (this.#target.on_stock > 0) {
        stock_count.innerText = "check_circle";
        stock_count.classList.add("avairable");
      } else {
        stock_count.innerText = "cancel";
        stock_count.classList.add("unavairable");
      }
      const barcode_container = document.createElement("p");
      barcode_container.classList.add("barcode");
      const barcode = document.createElement("span");
      barcode.innerText = this.#target.barcode;
      barcode.classList.add("numbers");
      const barcode_icon = document.createElement("span");
      barcode_icon.classList.add("material-icons");
      barcode_icon.innerText = "qr_code_scanner";
      barcode_container.appendChild(barcode_icon);
      barcode_container.appendChild(barcode);
      container.appendChild(description);
      container.appendChild(author_container);
      container.appendChild(barcode_container);
      container.appendChild(stock_count);
      return container;
    }
    get #cache_bypass() {
      if (!this.#login) {
        return "?cache=1";
      }
      return "?cache=" + new String(Math.floor(Math.random() * 100));
    }
    get #image() {
      const image = document.createElement("img");
      image.classList.add("image");
      image.src = this.#target.thumbnail + this.#cache_bypass;
      image.alt = this.#target.name;
      image.loading = "lazy";
      image.addEventListener("click", () => {
        new product_fullscreen(this.#target).show();
      });
      return image;
    }
    get node() {
      if (this.#node !== null) {
        return this.#node;
      }
      const bottom_container = document.createElement("div");
      bottom_container.classList.add("bottom-container");
      bottom_container.appendChild(this.#description);
      bottom_container.appendChild(this.#image);
      const container = document.createElement("div");
      container.classList.add("product");
      container.appendChild(this.#header);
      container.appendChild(bottom_container);
      return this.#node = container;
    }
    add(target) {
      const node = this.node;
      node.style.opacity = "0";
      node.style.transition = "opacity 0.5s";
      target.appendChild(node);
      setTimeout(() => {
        node.style.opacity = "1";
      }, 50);
    }
    drop() {
      const container = this.#node;
      if (container === null) {
        throw new TypeError("It is not showed yet.");
      }
      container.style.opacity = "1";
      container.style.transition = "opacity 0.5s";
      setTimeout(() => {
        container.style.opacity = "0";
      }, 50);
      setTimeout(() => {
        this.#node = null;
        container.remove();
      }, 550);
    }
  };

  // application/scripts/login_prompt.js
  var login_prompt = class extends formscreen {
    #nick;
    #password;
    constructor(target) {
      super();
      target.addEventListener("click", () => {
        this.show();
      });
    }
    get _name() {
      return _("login-window");
    }
    async _process() {
      try {
        this._info = _("processing");
        await this.#login();
        this._success = _("logged-in");
        setTimeout(() => {
          location.reload();
        }, 250);
      } catch (error) {
        this._error = new String(error);
      }
    }
    async #login() {
      const manager = new login_manager();
      const result = await manager.login(
        this.#nick(),
        this.#password()
      );
      if (result) {
        return;
      }
      throw new Error(_("can-not-login-check-nick-and-password"));
    }
    _build_form() {
      this.#nick = this._create_input(
        "nick",
        _("nick-prompt"),
        _("nick-sample")
      );
      this.#password = this._create_input(
        "password",
        _("password-prompt"),
        _("password-sample"),
        (input) => {
          input.type = "password";
        }
      );
    }
  };

  // application/scripts/create_request.js
  var create_request = class extends request {
    #image;
    #product;
    constructor(product2, image) {
      super();
      this.#image = image;
      this.#product = product2;
    }
    get _response() {
      return bool_response;
    }
    get data() {
      return Object.assign(this.#product.dump, {
        "image": this.#image,
        "apikey": this._apikey
      });
    }
    get method() {
      return "POST";
    }
    get url() {
      return "/product/create";
    }
  };

  // application/scripts/autocomplete_response.js
  var autocomplete_response = class extends bool_response {
    #found;
    constructor(target) {
      super(target);
      this.#found = null;
      if (this.result) {
        this.#found = target["found"];
      }
    }
    get found() {
      if (this.#found === null) {
        throw new Error("Server response is not complete.");
      }
      return this.#found;
    }
  };

  // application/scripts/autocomplete_request.js
  var autocomplete_request = class extends request {
    #barcode;
    constructor(barcode) {
      super();
      this.#barcode = barcode;
    }
    get _response() {
      return autocomplete_response;
    }
    get data() {
      return {
        "apikey": this._apikey
      };
    }
    get method() {
      return "POST";
    }
    get url() {
      return "/complete/barcode/" + this.#barcode;
    }
  };

  // application/scripts/product_adder.js
  var product_adder = class extends formscreen {
    #name;
    #description;
    #author;
    #barcode;
    #stock_count;
    #image;
    #loaded_image_type;
    #loaded_image;
    #image_preview;
    get _name() {
      return _("add-product");
    }
    async #autocomplete() {
      const barcode = this.#barcode();
      if (barcode.length === 0) {
        this._info = _("fill-barcode-first");
        return;
      }
      this._info = _("searching-in-the-web");
      try {
        const request2 = new autocomplete_request(barcode);
        const response = await request2.connect();
        if (!response.result) {
          throw new Error(response.cause);
        }
        const product2 = response.found;
        this.#name(product2.title);
        this.#description(product2.description);
        this.#author(product2.author);
        this.#barcode(product2.barcode);
        this.#loaded_image = product2.image;
        this.#loaded_image_type = product2.image_type;
        this.#update_image_preview();
        this._info = _("autocomplete-ready-check-results");
      } catch (error) {
        this._error = new String(error);
      }
    }
    #update_image_preview() {
      this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;
      this.#image_preview.style.opacity = "1";
    }
    get #autocomplete_button() {
      const button = document.createElement("div");
      button.classList.add("autocomplete-button");
      button.classList.add("button");
      const icon = document.createElement("span");
      icon.classList.add("material-icons");
      icon.innerText = "auto_fix_normal";
      button.appendChild(icon);
      const text = document.createElement("span");
      text.classList.add("text");
      text.innerText = _("autocomplete");
      button.appendChild(text);
      return button;
    }
    _build_form() {
      this.#loaded_image = null;
      this.#loaded_image_type = null;
      this.#name = this._create_input(
        "name",
        _("name-prompt"),
        _("name-sample")
      );
      this.#description = this._create_input(
        "description",
        _("description-prompt"),
        _("description-sample")
      );
      this.#author = this._create_input(
        "author",
        _("author-prompt"),
        _("author-sample")
      );
      this.#barcode = this._create_input(
        "barcode",
        _("barcode-prompt"),
        _("barcode-sample"),
        (input) => {
          input.type = "number";
        }
      );
      this.#stock_count = this._create_input(
        "stock_count",
        _("stock-count-prompt"),
        _("stock-count-sample"),
        (input) => {
          input.type = "number";
        }
      );
      this._create_input(
        "image",
        _("image-prompt"),
        "",
        (input) => {
          this.#image = input;
          input.type = "file";
          input.accept = "image/*";
          input.addEventListener("change", () => {
            this.#load_image_from_file();
          });
        }
      );
      this.#image_preview = document.createElement("img");
      this.#image_preview.style.opacity = "0";
      this._append_child(this.#image_preview);
      const autocomplete = this.#autocomplete_button;
      this._append_child(autocomplete);
      autocomplete.addEventListener("click", () => {
        this.#autocomplete();
      });
    }
    #reset_image() {
      this.#loaded_image = null;
      this.#loaded_image_type = null;
      this.#image_preview.style.opacity = "0";
      this.#image_preview.src = "";
    }
    async #load_image_from_file() {
      if (this.#image.files.length === 0) {
        this.#reset_image();
      }
      const file = this.#image.files.item(0);
      const buffer = await file.arrayBuffer();
      let as_string = new String();
      new Uint8Array(buffer).forEach((letter) => {
        as_string += String.fromCharCode(letter);
      });
      this.#loaded_image = btoa(as_string);
      this.#loaded_image_type = file.type;
      this.#update_image_preview();
    }
    get #ready_image() {
      if (this.#loaded_image === null) {
        throw new Error(_("load-any-image-first"));
      }
      return this.#loaded_image;
    }
    async #submit() {
      const product2 = new product_base();
      product2.name = this.#name();
      product2.description = this.#description();
      product2.author = this.#author();
      product2.stock_count = this.#stock_count();
      product2.barcode = this.#barcode();
      const request2 = new create_request(product2, this.#ready_image);
      const response = await request2.connect();
      if (!response.result) {
        throw new Error(response.cause);
      }
    }
    async _process() {
      try {
        this._info = _("creating-new-product");
        await this.#submit();
        this._success = _("created-new-product-success");
        searcher.reload();
        setTimeout(() => {
          this.hide();
        }, 500);
      } catch (error) {
        this._error = new String(error);
      }
    }
  };

  // application/scripts/import_process_fail.js
  var import_process_fail = class {
    #product;
    #error;
    constructor(product2, error) {
      this.#product = product2;
      this.#error = error;
    }
    get error() {
      return this.#error;
    }
    get product() {
      return this.#product;
    }
  };

  // application/scripts/database.js
  var database = class {
    #content;
    #processed;
    #on_skip;
    constructor(content) {
      this.#content = content;
      this.#processed = /* @__PURE__ */ new Map();
      this.#on_skip = null;
    }
    #append(target) {
      if (this.#processed.has(target.barcode)) {
        this.#processed.get(target.barcode).stock_count += 1;
        return;
      }
      this.#processed.set(target.barcode, target);
    }
    #validate(target) {
      if (!("id" in target)) {
        throw new Error("One of item has no ID.");
      }
      if (!("title" in target)) {
        throw new Error("Product " + target.barcode + " has no title.");
      }
      if (!("author" in target)) {
        throw new Error("Product " + target.barcode + " has no author.");
      }
    }
    #convert(target) {
      this.#validate(target);
      const product2 = new product_base();
      product2.name = target.title;
      product2.description = "";
      product2.author = target.author;
      product2.stock_count = 1;
      product2.barcode = target.id;
      return product2;
    }
    on_skip(target) {
      this.#on_skip = target;
      return this;
    }
    process() {
      this.#processed.clear();
      if (!(this.#content instanceof Array)) {
        throw new Error("Database woud be array of objects.");
      }
      this.#content.forEach((count) => {
        try {
          const product2 = this.#convert(count);
          this.#append(product2);
        } catch (error) {
          if (this.#on_skip === null) {
            return;
          }
          try {
            this.#on_skip(new import_process_fail(count, error));
          } catch (fail) {
            console.log(fail);
          }
        }
      });
      return this;
    }
    results() {
      return Array.from(this.#processed.values());
    }
  };

  // application/scripts/product_response.js
  var product_response = class extends bool_response {
    #product;
    constructor(target) {
      super(target);
      this.#product = null;
      if (this.result) {
        if (!("product" in target)) {
          throw new Error(_("incomplete-request-with-good-status"));
        }
        this.#product = new product(target.product);
      }
    }
    get product() {
      return this.#product;
    }
  };

  // application/scripts/product_get_request.js
  var product_get_request = class extends request {
    #barcode;
    constructor(barcode) {
      super();
      this.#barcode = barcode;
    }
    get _response() {
      return product_response;
    }
    get data() {
      return null;
    }
    get method() {
      return "GET";
    }
    get url() {
      return "/product/get/barcode/" + new String(this.#barcode);
    }
  };

  // application/scripts/import_loop.js
  var import_loop = class {
    #content;
    #on_autocomplete;
    #on_create;
    #on_single_fail;
    #on_skip;
    #on_single_success;
    #finally;
    on_autocomplete(target) {
      this.#on_autocomplete = target;
      return this;
    }
    on_create(target) {
      this.#on_create = target;
      return this;
    }
    on_single_fail(target) {
      this.#on_single_fail = target;
      return this;
    }
    on_skip(target) {
      this.#on_skip = target;
      return this;
    }
    on_single_success(target) {
      this.#on_single_success = target;
      return this;
    }
    finally(target) {
      this.#finally = target;
      return this;
    }
    constructor(dataset) {
      this.#content = dataset;
      this.#on_autocomplete = null;
      this.#on_create = null;
      this.#on_single_fail = null;
      this.#on_skip = null;
      this.#on_single_success = null;
      this.#finally = null;
    }
    async #autocomplete(target) {
      if (this.#on_autocomplete !== null) {
        try {
          this.#on_autocomplete(target);
        } catch (error) {
          console.log(error);
        }
      }
      const request2 = new autocomplete_request(target.barcode);
      const response = await request2.connect();
      if (!response.result) {
        throw new Error(response.cause);
      }
      const found = response.found;
      target.description = found.description;
      if (found.image.length === 0) {
        throw new Error("Image for " + target.barcode + " not found.");
      }
      return new create_request(target, found.image);
    }
    async process() {
      for (const count of this.#content) {
        try {
          await this.#create(count);
        } catch (error) {
          if (this.#on_single_fail !== null) {
            try {
              const fail = new import_process_fail(count, error);
              this.#on_single_fail(fail);
            } catch (error2) {
              console.log(error2);
            }
          }
        }
      }
      if (this.#finally !== null) {
        try {
          this.#finally();
        } catch (error) {
          console.log(error);
        }
      }
      return this;
    }
    async #exists(target) {
      const request2 = new product_get_request(target.barcode);
      const response = await request2.connect();
      return response.product !== null;
    }
    async #create(target) {
      if (await this.#exists(target)) {
        try {
          const result = new import_process_fail(target, null);
          this.#on_skip(result);
        } catch (error) {
          console.log(error);
        }
        return;
      }
      const request2 = await this.#autocomplete(target);
      if (this.on_create !== null) {
        try {
          this.#on_create(target);
        } catch (error) {
          console.log(error);
        }
      }
      const response = await request2.connect();
      if (!response.result) {
        throw new Error(response.cause);
      }
      if (this.#on_single_success !== null) {
        try {
          this.#on_single_success(target);
        } catch (error) {
          console.log(error);
        }
      }
    }
  };

  // application/scripts/import_log.js
  var import_log = class {
    #log;
    constructor() {
      this.#log = new Array();
    }
    #append(target) {
      this.#log.push(target);
    }
    #error_dump(error) {
      return "Error: " + new String(error) + ".";
    }
    #product_dump(product2) {
      return 'Product: barcode: "' + product2.barcode + '", title: "' + product2.title + '".';
    }
    fail(target) {
      this.#append(
        "Fail when processing item. " + this.#product_dump(target.product) + " " + this.#error_dump(target.error)
      );
    }
    skip(target) {
      this.#append(
        "Skipping not ready item. " + this.#product_dump(target.product) + " " + this.#error_dump(target.error)
      );
    }
    get length() {
      return this.#log.length;
    }
    content() {
      return this.#log.join("\n");
    }
  };

  // application/scripts/downloader.js
  var downloader = class {
    #name;
    #content;
    #type;
    #encode;
    constructor() {
      this.#name = "download.json";
      this.#content = "";
      this.#type = "text/plain";
      this.#encode = "utf-8";
    }
    name(target) {
      this.#name = target;
      return this;
    }
    content(target) {
      this.#content = target;
      return this;
    }
    type(target) {
      this.#type = target;
      return this;
    }
    encode(target) {
      this.#encode = target;
      return this;
    }
    get #href() {
      return "data:" + this.#type + ";charset=" + this.#encode + "," + encodeURIComponent(this.#content);
    }
    get #link() {
      const link = document.createElement("a");
      link.style.display = "none";
      link.href = this.#href;
      link.download = this.#name;
      return link;
    }
    process() {
      const link = this.#link;
      const body = document.querySelector("body");
      body.appendChild(link);
      link.click();
      body.removeChild(link);
      return this;
    }
  };

  // application/scripts/import_products.js
  var import_products = class extends formscreen {
    #file;
    #content;
    get _name() {
      return _("import-products-json");
    }
    _build_form() {
      this._create_input("file", "Database:", "", (input) => {
        this.#file = input;
        input.type = "file";
        input.accept = "application/json";
      });
    }
    async #load_file() {
      if (this.#file.files.length === 0) {
        throw new Error("select-products-json-database-first");
      }
      const file = this.#file.files.item(0);
      const text = await file.text();
      return JSON.parse(text);
    }
    async _process() {
      try {
        this._info = _("loading-file");
        this.#content = await this.#load_file();
        this._info = _("parsing-file-to-dataset");
        const result = new import_log();
        const dataset = new database(this.#content).on_skip((fail) => {
          this._info = _("skipping-import-product-__barcode__").format({
            barcode: fail.product.barcode
          });
          result.skip(fail);
        }).process().results();
        const loop = new import_loop(dataset).on_autocomplete((target) => {
          this._info = _("searching-for-product-__barcode__").format({
            barcode: target.barcode
          });
        }).on_create((target) => {
          this._info = _("creating-product-__barcode__").format({
            barcode: target.barcode
          });
        }).on_single_fail((target) => {
          this._info = _("can-not-add-product-__barcode__").format({
            barcode: target.product.barcode
          });
          result.fail(target);
        }).on_skip((target) => {
          this._info = _("skipping-product-__barcode").format({
            barcode: target.product.barcode
          });
          result.skip(target);
        }).on_single_success((target) => {
          this._info = _("created-product-__barcode__").format({
            barcode: target.barcode
          });
        }).finally(() => {
          searcher.reload();
          const log = new downloader().content(result.content()).type("text/plain").encode("utf-8").name("import-json.log").process();
          if (result.length === 0) {
            this._success = _("all-items-imported");
            setTimeout(() => {
              this.hide();
            });
          } else {
            this._success = _("not-all-items-imported");
          }
        }).process();
      } catch (error) {
        this._error = new String(error);
      }
    }
  };

  // application/scripts/login_bar.js
  var login_bar = class {
    #manager;
    constructor(target) {
      this.#manager = new login_manager();
      if (!this.#manager.logged_in) {
        this.#not_logged(target);
        return;
      }
      this.#logged(target);
    }
    #not_login_propertly() {
      this.#manager.logout();
      location.reload();
    }
    async #logged(target) {
      const user2 = await this.#manager.get_user();
      if (user2 === null) {
        this.#not_login_propertly();
      }
      const info_icon = document.createElement("span");
      info_icon.classList.add("icon");
      info_icon.classList.add("material-icons");
      info_icon.innerText = "account_circle";
      const info_content = document.createElement("span");
      info_content.innerText = user2.nick;
      const info = document.createElement("p");
      info.classList.add("login-info");
      info.appendChild(info_icon);
      info.appendChild(info_content);
      target.appendChild(info);
      const logout_button = document.createElement("button");
      logout_button.innerText = "logout";
      logout_button.classList.add("logout-button");
      logout_button.classList.add("material-icons");
      target.appendChild(logout_button);
      const add_product_button = document.createElement("button");
      add_product_button.innerText = "add";
      add_product_button.classList.add("add-product-button");
      add_product_button.classList.add("material-icons");
      target.appendChild(add_product_button);
      const import_products_button = document.createElement("button");
      import_products_button.innerText = "dataset_linked";
      import_products_button.classList.add("material-icons");
      import_products_button.classList.add("import-products-button");
      target.appendChild(import_products_button);
      add_product_button.addEventListener("click", () => {
        new product_adder().show();
      });
      import_products_button.addEventListener("click", () => {
        new import_products().show();
      });
      logout_button.addEventListener("click", () => {
        this.#manager.logout();
        location.reload();
      });
    }
    #not_logged(target) {
      const login_button = document.createElement("button");
      login_button.innerText = "account_circle";
      login_button.classList.add("login-button");
      login_button.classList.add("material-icons");
      target.appendChild(login_button);
      new login_prompt(login_button);
    }
  };

  // application/scripts/scroll_up.js
  var scroll_up = class {
    #button;
    constructor(button) {
      this.#button = button;
      this.#update();
      document.addEventListener("scroll", () => {
        this.#update();
      });
      this.#button.addEventListener("click", () => {
        this.scroll();
      });
    }
    scroll() {
      this.#position = 0;
    }
    get #position() {
      return document.scrollingElement.scrollTop;
    }
    set #position(target) {
      document.scrollingElement.scrollTop = target;
    }
    get #visible() {
      return Number(this.#button.style.opacity) === 1;
    }
    set #visible(target) {
      this.#button.style.opacity = target ? "1" : "0";
    }
    get #margin() {
      return 20;
    }
    #update() {
      this.#visible = this.#position > this.#margin;
    }
  };

  // application/scripts/color_theme.js
  var color_theme = class {
    #button;
    #themes;
    get themes() {
      return Object.keys(this.#themes);
    }
    theme_name(target) {
      return this.#themes[target];
    }
    constructor(button, themes = null) {
      this.#button = button;
      this.#themes = themes;
      if (this.#themes === null) {
        this.#themes = {
          "dark-theme": "Dark",
          "white-theme": "White"
        };
      }
      this.#load();
      this.#button.addEventListener("click", () => {
        this.change();
      });
    }
    get current() {
      if (localStorage.hasOwnProperty("theme")) {
        return localStorage.getItem("theme");
      }
      return this.themes[this.themes.length - 1];
    }
    #load() {
      this.#show(this.current);
    }
    #save(target) {
      localStorage.setItem("theme", target);
    }
    #show(target) {
      const themes = this.themes;
      const body = document.querySelector("body");
      body.classList.forEach((count) => {
        if (themes.indexOf(count) !== -1) {
          body.classList.remove(count);
        }
      });
      body.classList.add(target);
    }
    change() {
      const themes = this.themes;
      const current = this.current;
      let position = themes.indexOf(current) + 1;
      if (position === themes.length) {
        position = 0;
      }
      const updated = themes[position];
      this.#save(updated);
      this.#show(updated);
    }
  };

  // application/scripts/core.js
  document.addEventListener("DOMContentLoaded", async () => {
    const languages = new cx_libtranslate.languages("app/assets/languages");
    await languages.load("index.json?ver=02112025");
    const preferences = new cx_libtranslate.preferences(languages);
    preferences.selector.insert().add_listener(() => {
      location.reload();
    });
    const phrasebook = await preferences.load_choosen_phrasebook();
    phrasebook.set_as_default();
    const autotranslate = await preferences.get_autotranslate();
    autotranslate.connect();
    const top_bar_spacing = new height_equaler(
      document.querySelector(".top-bar"),
      document.querySelector(".top-bar-spacing")
    );
    const container = document.querySelector(".products");
    const search_bar = document.querySelector("form.search");
    const search_title = document.querySelector(".search-title");
    const login_space = document.querySelector(".top-bar .right");
    const scroll_up_button = document.querySelector(".scroll-up-button");
    const reverse_colors = document.querySelector(".reverse-colors");
    const counter = document.querySelector(".products-counter");
    const manager = new product_containers(container);
    new login_bar(login_space);
    new scroll_up(scroll_up_button);
    new color_theme(reverse_colors);
    new searcher(search_bar, manager, search_title, counter).show_all();
  });
})();
