<commit_before>import * as React from "react";
import {
  ApolloClient,
  InMemoryCache,
  useQuery as useApolloQuery,
  ApolloProvider as BaseApolloProvider,
} from "@apollo/client";
import { useAuthToken } from "./Auth";

function ApolloProvider({ children, authToken }) {
  const authorization = authToken ? `Bearer ${authToken}` : null;
  const apolloClient = React.useMemo(
    () =>
      new ApolloClient({
        uri: `/graphql`,
        cache: new InMemoryCache(),
        headers: {
          authorization,
        },
      }),
    [authorization]
  );
  return (
    <BaseApolloProvider client={apolloClient}>{children}</BaseApolloProvider>
  );
}

export function ApolloInitializer({ children }) {
  const authToken = useAuthToken();
  return <ApolloProvider authToken={authToken}>{children}</ApolloProvider>;
}

export function useQuery(query, options) {
  const { loading, error, data, ...others } = useApolloQuery(query, options);
  if (error) {
    throw error;
  }
  return { loading, data, ...others };
}

export function Query({ fallback = null, children, query, ...props }) {
  const { data } = useQuery(query, props);

  if (!data) {
    return fallback;
  }

  return children(data);
}
<commit_msg>fix: set apollo possible types<commit_after>import * as React from "react";
import {
  ApolloClient,
  InMemoryCache,
  useQuery as useApolloQuery,
  ApolloProvider as BaseApolloProvider,
} from "@apollo/client";
import { useAuthToken } from "./Auth";

function ApolloProvider({ children, authToken }) {
  const authorization = authToken ? `Bearer ${authToken}` : null;
  const apolloClient = React.useMemo(
    () =>
      new ApolloClient({
        uri: `/graphql`,
        cache: new InMemoryCache({
          possibleTypes: {
            Owner: ["User", "Organization"],
          },
        }),
        headers: {
          authorization,
        },
      }),
    [authorization]
  );
  return (
    <BaseApolloProvider client={apolloClient}>{children}</BaseApolloProvider>
  );
}

export function ApolloInitializer({ children }) {
  const authToken = useAuthToken();
  return <ApolloProvider authToken={authToken}>{children}</ApolloProvider>;
}

export function useQuery(query, options) {
  const { loading, error, data, ...others } = useApolloQuery(query, options);
  if (error) {
    throw error;
  }
  return { loading, data, ...others };
}

export function Query({ fallback = null, children, query, ...props }) {
  const { data } = useQuery(query, props);

  if (!data) {
    return fallback;
  }

  return children(data);
}
<|endoftext|>


<commit_before>'use strict';

/* global $ document window fetch QrCodeWithLogo QRious yasgui */

let globalLookup = {};

function makeAdressInfo(locatieserverLookup) {
  console.log(locatieserverLookup);
  globalLookup = locatieserverLookup;
  $('#AdressInfo').html(`
Nummeraanduiding: https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}

Weergavenaam: ${locatieserverLookup.weergavenaam}

Woonplaats: ${locatieserverLookup.woonplaatsnaam}

Buurtnaam: ${locatieserverLookup.buurtnaam}

Wijknaam: ${locatieserverLookup.wijknaam}

Gemeentenaam: ${locatieserverLookup.gemeentenaam}

Provincienaam: ${locatieserverLookup.provincienaam}

Waterschapsnaam: ${locatieserverLookup.waterschapsnaam}

`);

  const logoSrc = `https://data.labs.pdok.nl/api/v1/text2image?text=${locatieserverLookup.huis_nlt}`;

  fetch(logoSrc)
    .then((res) => {
      if (res.status === 200) {
        return QrCodeWithLogo.toCanvas({
          canvas: document.getElementById('qrcodeCanvas'),
          content: `https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}`,
          width: 200,
          logo: {
            src: logoSrc,
            logoSize: 0.2,
          },
        });
      }

      return new QRious({
        element: document.getElementById('qrcodeCanvas'),
        size: 220,
        padding: 16,
        value: `https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}`,
      });
    })
    .catch((err) => {
      console.error(err);

      return new QRious({
        element: document.getElementById('qrcodeCanvas'),
        size: 220,
        padding: 16,
        value: `https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}`,
      });
    });
}

$(document).ready(() => {
  $('#huischeck_now').click(() => {
    const address = $('#adres');
    console.log(address.val());

    fetch(`https://geodata.nationaalgeoregister.nl/locatieserver/v3/suggest?q=${address.val()}`)
      .then(response => response.json())
      .then(json => json.response.docs[0].id)
      .then(id => fetch(`https://geodata.nationaalgeoregister.nl/locatieserver/v3/lookup?id=${id}`))
      .then(response => response.json())
      .then(json => json.response.docs[0])
      .then(makeAdressInfo)
      .catch(err => console.error(err));
  });

  $('#printQRcode').click(() => {
    if (!globalLookup) return;
    const qrPrintWindow = window.open('', 'PRINT', 'height=1920,width=1080');

    qrPrintWindow.document.write(`
<!doctype html>

<title>${document.title}</title>

<canvas id="qrcodeCanvas"/>

`);
    qrPrintWindow.focus(); // necessary for IE >= 10
  });
});

function createPrintTable() {
  const printTableWindowText = `
<!doctype html>

<title>${document.title}</title>

Informatie over uw huis
URL:${$('#nummeraanduiding')[0].innerText}

Adres:	${$('#straatnaam')[0].innerText} ${$('#huisnummer')[0].innerText}

Postcode:	${$('#postcode')[0].innerText}

Woonplaats:	${$('#woonplaats')[0].innerText}

Bouwjaar:	${$('#bouwjaar')[0].nextSibling.data}

Oppervlak:	${$('#oppervlak')[0].nextSibling.data}

Informatie over uw buurt

Buurtnaam:	${$('#buurtnaam')[0].innerText}

Aantal inwoners:	${$('#aantalinwoners')[0].nextSibling.data}

Aantal mannen:	${$('#aantalmannen')[0].nextSibling.data}

Aantal vrouwen:	${$('#aantalvrouwen')[0].nextSibling.data}

Gemiddelde woningwaarde:	${$('#woningwaarde')[0].nextSibling.data}

Percentage koopwoningen:	${$('#koopwoningen')[0].nextSibling.data}

Percentage huurwoningen:	${$('#huurwoningen')[0].nextSibling.data}

Percentage woningen voor 2000:	${$('#woningenvoor2000')[0].innerText}

Percentage woningen na 2000:	${$('#woningenna2000')[0].innerText}

Gem. elektriciteitsverbruik:	${$('#elektriciteitsverbruik')[0].nextSibling.data}

Gem. afstand tot supermarkt:	${$('#supermarkt')[0].nextSibling.data}

Gem. afstand tot huisarts:	${$('#huisarts')[0].nextSibling.data}

Gem. afst. tot kinderdagverblijf:	${$('#kinderdagverblijf')[0].nextSibling.data}

Gem. afstand tot school:	${$('#school')[0].nextSibling.data}

Deze informatie is verkregen via de Huischeck van PDOK.

  https://data.labs.pdok.nl/apps/huischeck/huischeck.html

`;

  const printTableWindow = window.open('', 'print table', 'height=1920,width=1080');
  console.log(printTableWindowText.replace('\n', ''));
  printTableWindow.document.write(printTableWindowText.replace('\n', ''));
}
<commit_msg>cleanup<commit_after>'use strict';

/* global $ document window fetch QrCodeWithLogo QRious yasgui */

let globalLookup = {};

function makeAdressInfo(locatieserverLookup) {
  console.log(locatieserverLookup);
  globalLookup = locatieserverLookup;
  $('#AdressInfo').html(`
Nummeraanduiding: https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}

Weergavenaam: ${locatieserverLookup.weergavenaam}

Woonplaats: ${locatieserverLookup.woonplaatsnaam}

Buurtnaam: ${locatieserverLookup.buurtnaam}

Wijknaam: ${locatieserverLookup.wijknaam}

Gemeentenaam: ${locatieserverLookup.gemeentenaam}

Provincienaam: ${locatieserverLookup.provincienaam}

Waterschapsnaam: ${locatieserverLookup.waterschapsnaam}

`);

  const logoSrc = `https://data.labs.pdok.nl/api/v1/text2image?text=${locatieserverLookup.huis_nlt}`;

  fetch(logoSrc)
    .then((res) => {
      if (res.status === 200) {
        return QrCodeWithLogo.toCanvas({
          canvas: document.getElementById('qrcodeCanvas'),
          content: `https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}`,
          width: 200,
          logo: {
            src: logoSrc,
            logoSize: 0.2,
          },
        });
      }

      return new QRious({
        element: document.getElementById('qrcodeCanvas'),
        size: 220,
        padding: 16,
        value: `https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}`,
      });
    })
    .catch((err) => {
      console.error(err);

      return new QRious({
        element: document.getElementById('qrcodeCanvas'),
        size: 220,
        padding: 16,
        value: `https://bag.basisregistraties.overheid.nl/bag/doc/nummeraanduiding/${locatieserverLookup.nummeraanduiding_id}`,
      });
    });
}

$(document).ready(() => {
  $('#huischeck_now').click(() => {
    const address = $('#adres');
    console.log(address.val());

    fetch(`https://geodata.nationaalgeoregister.nl/locatieserver/v3/suggest?q=${address.val()}`)
      .then(response => response.json())
      .then(json => json.response.docs[0].id)
      .then(id => fetch(`https://geodata.nationaalgeoregister.nl/locatieserver/v3/lookup?id=${id}`))
      .then(response => response.json())
      .then(json => json.response.docs[0])
      .then(makeAdressInfo)
      .catch(err => console.error(err));
  });

  $('#printQRcode').click(() => {
    if (!globalLookup) return;
    const qrPrintWindow = window.open('', 'PRINT', 'height=1920,width=1080');

    qrPrintWindow.document.write(`
<!doctype html>

<title>${document.title}</title>

<canvas id="qrcodeCanvas"/>

`);
    qrPrintWindow.focus(); // necessary for IE >= 10
  });
});

function createPrintTable() {
  const printTableWindowText = `
<!doctype html>

<title>${document.title}</title>

Informatie over uw huis
URL:${$('#nummeraanduiding')[0].innerText}

Adres:	${$('#straatnaam')[0].innerText} ${$('#huisnummer')[0].innerText}

Postcode:	${$('#postcode')[0].innerText}

Woonplaats:	${$('#woonplaats')[0].innerText}

Bouwjaar:	${$('#bouwjaar')[0].nextSibling.data}

Oppervlak:	${$('#oppervlak')[0].nextSibling.data}

Informatie over uw buurt

Buurtnaam:	${$('#buurtnaam')[0].innerText}

Aantal inwoners:	${$('#aantalinwoners')[0].nextSibling.data}

Aantal mannen:	${$('#aantalmannen')[0].nextSibling.data}

Aantal vrouwen:	${$('#aantalvrouwen')[0].nextSibling.data}

Gemiddelde woningwaarde:	${$('#woningwaarde')[0].nextSibling.data}

Percentage koopwoningen:	${$('#koopwoningen')[0].nextSibling.data}

Percentage huurwoningen:	${$('#huurwoningen')[0].nextSibling.data}

Percentage woningen voor 2000:	${$('#woningenvoor2000')[0].innerText}

Percentage woningen na 2000:	${$('#woningenna2000')[0].innerText}

Gem. elektriciteitsverbruik:	${$('#elektriciteitsverbruik')[0].nextSibling.data}

Gem. afstand tot supermarkt:	${$('#supermarkt')[0].nextSibling.data}

Gem. afstand tot huisarts:	${$('#huisarts')[0].nextSibling.data}

Gem. afst. tot kinderdagverblijf:	${$('#kinderdagverblijf')[0].nextSibling.data}

Gem. afstand tot school:	${$('#school')[0].nextSibling.data}

Deze informatie is verkregen via de Huischeck van PDOK.

  https://data.labs.pdok.nl/apps/huischeck/huischeck.html

`;

  const printTableWindow = window.open('', 'print table', 'height=1920,width=1080');
  printTableWindow.document.write(printTableWindowText);
}
<|endoftext|>


<commit_before>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

const queryZcl = require('../db/query-zcl.js')
const dbEnum = require('../../src-shared/db-enum.js')
const templateUtil = require('./template-util.js')

/**
 * This module contains the API for templating. For more detailed instructions, read {@tutorial template-tutorial}
 *
 * @module Templating API: static zcl helpers
 */

/**
 * Block helper iterating over all bitmaps.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_bitmaps(options) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllBitmaps(this.global.db, packageId))
    .then((ens) => templateUtil.collectBlocks(ens, options, this))
}

/**
 * Iterates over enum items. Valid only inside zcl_enums.
 * @param {*} options
 */
function zcl_bitmap_items(options) {
  return queryZcl
    .selectAllBitmapFieldsById(this.global.db, this.id)
    .then((items) => templateUtil.collectBlocks(items, options, this))
}

/**
 * Block helper iterating over all enums.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_enums(options) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllEnums(this.global.db, packageId))
    .then((ens) => templateUtil.collectBlocks(ens, options, this))
}

/**
 * Iterates over enum items. Valid only inside zcl_enums.
 * @param {*} options
 */
function zcl_enum_items(options) {
  return queryZcl
    .selectAllEnumItemsById(this.global.db, this.id)
    .then((items) => templateUtil.collectBlocks(items, options, this))
}

/**
 * Block helper iterating over all structs.
 *function macroList(options)

 * @param {*} options
 * @returns Promise of content.
 */
function zcl_structs(options) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllStructs(this.global.db, packageId))
    .then((st) => templateUtil.collectBlocks(st, options, this))
}

/**
 * Block helper iterating over all struct items. Valid only inside zcl_structs.

 * @param {*} options
 * @returns Promise of content.
 */
function zcl_struct_items(options) {
  return queryZcl
    .selectAllStructItemsById(this.global.db, this.id)
    .then((st) => templateUtil.collectBlocks(st, options, this))
}

/**
 * Block helper iterating over all clusters.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_clusters(options) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllClusters(this.global.db, packageId))
    .then((cl) => templateUtil.collectBlocks(cl, options, this))
}

/**
 * Block helper iterating over all commands.
 * There are two modes of this helper:
 *   when used in a global context, it iterates over ALL commands in the database.
 *   when used inside a `zcl_cluster` block helper, it iterates only over the commands for that cluster.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_commands(options) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectCommandsByClusterId(
          this.global.db,
          this.id,
          packageId
        )
      } else {
        return queryZcl.selectAllCommands(this.global.db, packageId)
      }
    })
    .then((cmds) => templateUtil.collectBlocks(cmds, options, this))
}

/**
 * Helper to iterate over all global commands.
 *
 * @param {*} options
 * @returns Promise of global command iteration.
 */
function zcl_global_commands(options) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectAllGlobalCommands(this.global.db, packageId)
    )
    .then((cmds) => templateUtil.collectBlocks(cmds, options, this))
}

/**
 * Iterator over the attributes. If it is used at toplevel, if iterates over all the attributes
 * in the database. If used within zcl_cluster context, it iterates over all the attributes
 * that belong to that cluster.
 *
 * @param {*} options
 * @returns Promise of attribute iteration.
 */
function zcl_attributes(options) {
  // If used at the toplevel, 'this' is the toplevel context object.
  // when used at the cluster level, 'this' is a cluster
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectAttributesByClusterId(
          this.global.db,
          this.id,
          packageId
        )
      } else {
        return queryZcl.selectAllAttributes(this.global.db, packageId)
      }
    })
    .then((atts) => templateUtil.collectBlocks(atts, options, this))
}

/**
 * Iterator over the client attributes. If it is used at toplevel, if iterates over all the client attributes
 * in the database. If used within zcl_cluster context, it iterates over all the client attributes
 * that belong to that cluster.
 *
 * @param {*} options
 * @returns Promise of attribute iteration.
 */
function zcl_attributes_client(options) {
  // If used at the toplevel, 'this' is the toplevel context object.
  // when used at the cluster level, 'this' is a cluster
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        return queryZcl.selectAttributesByClusterIdAndSide(
          this.global.db,
          this.id,
          packageId,
          dbEnum.side.client
        )
      } else {
        return queryZcl.selectAllAttributesBySide(
          this.global.db,
          dbEnum.side.client,
          packageId
        )
      }
    })
    .then((atts) => templateUtil.collectBlocks(atts, options, this))
}

/**
 * Iterator over the server attributes. If it is used at toplevel, if iterates over all the server attributes
 * in the database. If used within zcl_cluster context, it iterates over all the server attributes
 * that belong to that cluster.
 *
 * @param {*} options
 * @returns Promise of attribute iteration.
 */
function zcl_attributes_server(options) {
  // If used at the toplevel, 'this' is the toplevel context object.
  // when used at the cluster level, 'this' is a cluster
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectAttributesByClusterIdAndSide(
          this.global.db,
          this.id,
          packageId,
          dbEnum.side.server
        )
      } else {
        return queryZcl.selectAllAttributesBySide(
          this.global.db,
          dbEnum.side.server,
          packageId
        )
      }
    })
    .then((atts) => templateUtil.collectBlocks(atts, options, this))
}

/**
 * Block helper iterating over all atomic types.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_atomics(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllAtomics(this.global.db, packageId))
    .then((ats) => templateUtil.collectBlocks(ats, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 *
 *
 * Given: N/A
 * @returns the length of largest cluster name in a list of clusters
 */
function zcl_cluster_largest_label_length() {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllClusters(this.global.db, packageId))
    .then((cl) => largestLabelLength(cl))
}

/**
 *
 *
 * @param {*} An Array
 * @returns the length of largest object name in an array. Helper for
 * zcl_cluster_largest_label_length
 */
function largestLabelLength(arrayOfClusters) {
  return Math.max(...arrayOfClusters.map((cl) => cl.label.length))
}

/**
 * Helper to extract the number of command arguments in a command
 *
 * @param {*} commandId
 * @returns Number of command arguments as an integer
 */
function zcl_command_arguments_count(commandId) {
  return templateUtil.ensureZclPackageId(this).then((packageId) => {
    var res = queryZcl.selectCommandArgumentsCountByCommandId(
      this.global.db,
      commandId,
      packageId
    )
    return res
  })
}

/**
 * Block helper iterating over command arguments within a command
 *
 * @param {*} options
 * @returns Promise of command argument iteration.
 */
function zcl_command_arguments(options) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectCommandArgumentsByCommandId(
          this.global.db,
          this.id,
          packageId
        )
      } else {
        return queryZcl.selectAllCommandArguments(this.global.db)
      }
    })
    .then((cmds) => templateUtil.collectBlocks(cmds, options, this))
}

/**
 * Helper that checks if an enum by this name exists
 *
 * @param {*} options
 * @returns Promise of content.
 */
function isEnum(enum_name) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectEnumByName(this.global.db, enum_name, packageId)
    )
    .then((enums) => (enums ? 1 : 0))
}

/**
 * Helper that checks if an enum by this name exists
 *
 * @param {*} options
 * @returns Promise of content.
 */
function isStruct(struct_name) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectStructByName(this.global.db, struct_name, packageId)
    )
    .then((st) => (st ? 1 : 0))
}

function isBitmap(bitmap_name) {
  return templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectBitmapByName(this.global.db, packageId, bitmap_name)
    )
    .then((st) => (st ? 1 : 0))
}

function isClient(side) {
  return 0 == side.localeCompare('client')
}

// WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
//
// Note: these exports are public API. Templates that might have been created in the past and are
// available in the wild might depend on these names.
// If you rename the functions, you need to still maintain old exports list.
exports.zcl_bitmaps = zcl_bitmaps
exports.zcl_bitmap_items = zcl_bitmap_items
exports.zcl_enums = zcl_enums
exports.zcl_enum_items = zcl_enum_items
exports.zcl_structs = zcl_structs
exports.zcl_struct_items = zcl_struct_items
exports.zcl_clusters = zcl_clusters
exports.zcl_commands = zcl_commands
exports.zcl_attributes = zcl_attributes
exports.zcl_attributes_client = zcl_attributes_client
exports.zcl_attributes_server = zcl_attributes_server
exports.zcl_atomics = zcl_atomics
exports.zcl_global_commands = zcl_global_commands
exports.zcl_cluster_largest_label_length = zcl_cluster_largest_label_length
exports.zcl_command_arguments_count = zcl_command_arguments_count
exports.zcl_command_arguments = zcl_command_arguments
exports.isEnum = isEnum
exports.isStruct = isStruct
exports.isBitmap = isBitmap
exports.isClient = isClient
<commit_msg>Propery deal with promises for entire ZCL helper package to enable sync handling of {{#after}}<commit_after>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

const queryZcl = require('../db/query-zcl.js')
const dbEnum = require('../../src-shared/db-enum.js')
const templateUtil = require('./template-util.js')
const { template } = require('handlebars')

/**
 * This module contains the API for templating. For more detailed instructions, read {@tutorial template-tutorial}
 *
 * @module Templating API: static zcl helpers
 */

/**
 * Block helper iterating over all bitmaps.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_bitmaps(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllBitmaps(this.global.db, packageId))
    .then((ens) => templateUtil.collectBlocks(ens, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Iterates over enum items. Valid only inside zcl_enums.
 * @param {*} options
 */
function zcl_bitmap_items(options) {
  var promise = queryZcl
    .selectAllBitmapFieldsById(this.global.db, this.id)
    .then((items) => templateUtil.collectBlocks(items, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Block helper iterating over all enums.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_enums(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllEnums(this.global.db, packageId))
    .then((ens) => templateUtil.collectBlocks(ens, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Iterates over enum items. Valid only inside zcl_enums.
 * @param {*} options
 */
function zcl_enum_items(options) {
  var promise = queryZcl
    .selectAllEnumItemsById(this.global.db, this.id)
    .then((items) => templateUtil.collectBlocks(items, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Block helper iterating over all structs.
 *function macroList(options)

 * @param {*} options
 * @returns Promise of content.
 */
function zcl_structs(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllStructs(this.global.db, packageId))
    .then((st) => templateUtil.collectBlocks(st, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Block helper iterating over all struct items. Valid only inside zcl_structs.

 * @param {*} options
 * @returns Promise of content.
 */
function zcl_struct_items(options) {
  var promise = queryZcl
    .selectAllStructItemsById(this.global.db, this.id)
    .then((st) => templateUtil.collectBlocks(st, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Block helper iterating over all clusters.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_clusters(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllClusters(this.global.db, packageId))
    .then((cl) => templateUtil.collectBlocks(cl, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Block helper iterating over all commands.
 * There are two modes of this helper:
 *   when used in a global context, it iterates over ALL commands in the database.
 *   when used inside a `zcl_cluster` block helper, it iterates only over the commands for that cluster.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_commands(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectCommandsByClusterId(
          this.global.db,
          this.id,
          packageId
        )
      } else {
        return queryZcl.selectAllCommands(this.global.db, packageId)
      }
    })
    .then((cmds) => templateUtil.collectBlocks(cmds, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Helper to iterate over all global commands.
 *
 * @param {*} options
 * @returns Promise of global command iteration.
 */
function zcl_global_commands(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectAllGlobalCommands(this.global.db, packageId)
    )
    .then((cmds) => templateUtil.collectBlocks(cmds, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Iterator over the attributes. If it is used at toplevel, if iterates over all the attributes
 * in the database. If used within zcl_cluster context, it iterates over all the attributes
 * that belong to that cluster.
 *
 * @param {*} options
 * @returns Promise of attribute iteration.
 */
function zcl_attributes(options) {
  // If used at the toplevel, 'this' is the toplevel context object.
  // when used at the cluster level, 'this' is a cluster
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectAttributesByClusterId(
          this.global.db,
          this.id,
          packageId
        )
      } else {
        return queryZcl.selectAllAttributes(this.global.db, packageId)
      }
    })
    .then((atts) => templateUtil.collectBlocks(atts, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Iterator over the client attributes. If it is used at toplevel, if iterates over all the client attributes
 * in the database. If used within zcl_cluster context, it iterates over all the client attributes
 * that belong to that cluster.
 *
 * @param {*} options
 * @returns Promise of attribute iteration.
 */
function zcl_attributes_client(options) {
  // If used at the toplevel, 'this' is the toplevel context object.
  // when used at the cluster level, 'this' is a cluster
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        return queryZcl.selectAttributesByClusterIdAndSide(
          this.global.db,
          this.id,
          packageId,
          dbEnum.side.client
        )
      } else {
        return queryZcl.selectAllAttributesBySide(
          this.global.db,
          dbEnum.side.client,
          packageId
        )
      }
    })
    .then((atts) => templateUtil.collectBlocks(atts, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Iterator over the server attributes. If it is used at toplevel, if iterates over all the server attributes
 * in the database. If used within zcl_cluster context, it iterates over all the server attributes
 * that belong to that cluster.
 *
 * @param {*} options
 * @returns Promise of attribute iteration.
 */
function zcl_attributes_server(options) {
  // If used at the toplevel, 'this' is the toplevel context object.
  // when used at the cluster level, 'this' is a cluster
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectAttributesByClusterIdAndSide(
          this.global.db,
          this.id,
          packageId,
          dbEnum.side.server
        )
      } else {
        return queryZcl.selectAllAttributesBySide(
          this.global.db,
          dbEnum.side.server,
          packageId
        )
      }
    })
    .then((atts) => templateUtil.collectBlocks(atts, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Block helper iterating over all atomic types.
 *
 * @param {*} options
 * @returns Promise of content.
 */
function zcl_atomics(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllAtomics(this.global.db, packageId))
    .then((ats) => templateUtil.collectBlocks(ats, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 *
 *
 * Given: N/A
 * @returns the length of largest cluster name in a list of clusters
 */
function zcl_cluster_largest_label_length() {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => queryZcl.selectAllClusters(this.global.db, packageId))
    .then((cl) => largestLabelLength(cl))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 *
 *
 * @param {*} An Array
 * @returns the length of largest object name in an array. Helper for
 * zcl_cluster_largest_label_length
 */
function largestLabelLength(arrayOfClusters) {
  return Math.max(...arrayOfClusters.map((cl) => cl.label.length))
}

/**
 * Helper to extract the number of command arguments in a command
 *
 * @param {*} commandId
 * @returns Number of command arguments as an integer
 */
function zcl_command_arguments_count(commandId) {
  var promise = templateUtil.ensureZclPackageId(this).then((packageId) => {
    var res = queryZcl.selectCommandArgumentsCountByCommandId(
      this.global.db,
      commandId,
      packageId
    )
    return res
  })
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Block helper iterating over command arguments within a command
 *
 * @param {*} options
 * @returns Promise of command argument iteration.
 */
function zcl_command_arguments(options) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) => {
      if ('id' in this) {
        // We're functioning inside a nested context with an id, so we will only query for this cluster.
        return queryZcl.selectCommandArgumentsByCommandId(
          this.global.db,
          this.id,
          packageId
        )
      } else {
        return queryZcl.selectAllCommandArguments(this.global.db)
      }
    })
    .then((cmds) => templateUtil.collectBlocks(cmds, options, this))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Helper that checks if an enum by this name exists
 *
 * @param {*} options
 * @returns Promise of content.
 */
function isEnum(enum_name) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectEnumByName(this.global.db, enum_name, packageId)
    )
    .then((enums) => (enums ? 1 : 0))
  return templateUtil.templatePromise(this.global, promise)
}

/**
 * Helper that checks if an enum by this name exists
 *
 * @param {*} options
 * @returns Promise of content.
 */
function isStruct(struct_name) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectStructByName(this.global.db, struct_name, packageId)
    )
    .then((st) => (st ? 1 : 0))
  return templateUtil.templatePromise(this.global, promise)
}

function isBitmap(bitmap_name) {
  var promise = templateUtil
    .ensureZclPackageId(this)
    .then((packageId) =>
      queryZcl.selectBitmapByName(this.global.db, packageId, bitmap_name)
    )
    .then((st) => (st ? 1 : 0))
  return templateUtil.templatePromise(this.global, promise)
}

function isClient(side) {
  return 0 == side.localeCompare('client')
}

// WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
//
// Note: these exports are public API. Templates that might have been created in the past and are
// available in the wild might depend on these names.
// If you rename the functions, you need to still maintain old exports list.
exports.zcl_bitmaps = zcl_bitmaps
exports.zcl_bitmap_items = zcl_bitmap_items
exports.zcl_enums = zcl_enums
exports.zcl_enum_items = zcl_enum_items
exports.zcl_structs = zcl_structs
exports.zcl_struct_items = zcl_struct_items
exports.zcl_clusters = zcl_clusters
exports.zcl_commands = zcl_commands
exports.zcl_attributes = zcl_attributes
exports.zcl_attributes_client = zcl_attributes_client
exports.zcl_attributes_server = zcl_attributes_server
exports.zcl_atomics = zcl_atomics
exports.zcl_global_commands = zcl_global_commands
exports.zcl_cluster_largest_label_length = zcl_cluster_largest_label_length
exports.zcl_command_arguments_count = zcl_command_arguments_count
exports.zcl_command_arguments = zcl_command_arguments
exports.isEnum = isEnum
exports.isStruct = isStruct
exports.isBitmap = isBitmap
exports.isClient = isClient
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
var URL = {};
(function() {
    URL.buildURL = function(url) {
        return new Url(url);
    };

    function Url(url) {
        this.url = url;
        this.urlBase = '';
        this.queryParams = [];
        init(this);
    }
    Url.prototype.compile = function() {
        return reconstructURL(this.urlBase, this.queryParams);
    };
    Url.prototype.toString = function() {
        return reconstructURL(this.urlBase, this.queryParams);
    }
    Url.prototype.queryParam = function() {
        if (arguments.length === 1) {
            return getQueryParam.apply(this, arguments);
        }
        if (arguments.length === 2) {
            addQueryParam.apply(this, arguments);
            return this;
        }
    };
    Url.prototype.removeQueryParam = function() {
        removeQuery.apply(this, arguments);
        return this;
    };

    function init(expression) {
        expression.urlBase = '';
        var components = expression.url.split('?');
        expression.urlBase = components[0];
        //If there are no other components
        if (components.length === 1) {
            return;
        }
        expression.queryParams = processQueryParams(components[1] || '');
    }

    function processQueryParams(queryParamsString) {
        var components = queryParamsString.split('&');
        var params = [];
        components.forEach(function(component) {
            if (component !== '') {
                params.push(new QueryParam(component));
            }
        });
        return params;
    }

    function reconstructURL(urlBase, queryParams) {
        var params = [];
        queryParams.forEach(function(queryParam) {
            params.push(queryParam.compile());
        });
        var queryParamComponent = params.join('&');
        queryParams = (queryParamComponent === '') ? [] : [queryParamComponent];
        return [urlBase].concat(queryParams).join('?');
    }

    function addQueryParam(key, value) {
        //Check if the query param exists
        var queryParam = this.queryParam(key);
        value = (typeof value === 'QueryParam') ? value : (new QueryParam(key, value));
        //New query parameter
        if (!queryParam) {
            this.queryParams.splice(0, 0, value);
            //this.queryParams.push(value);
            return;
        }
        var indexToReplace = getQueryParamIndex(key, this.queryParams);
        if (indexToReplace < 0) {
            throw 'Could not add the query parameter with key: ' + key;
        }
        this.queryParams.splice(indexToReplace, 1);
        this.queryParams = this.queryParams.slice(0, indexToReplace).concat([value]).concat(this.queryParams.slice(indexToReplace));
    }

    function getQueryParam(key) {
        var value = null;
        this.queryParams.forEach(function(queryParam) {
            if (queryParam.key === key) {
                value = queryParam;
            }
        });
        return value;
    }

    function getQueryParamIndex(key, queryParams) {
        var index = -1;
        queryParams.forEach(function(queryParam, indexOfQueryParam) {
            if (queryParam.key === key) {
                index = indexOfQueryParam;
            }
        });
        return index;
    }

    function removeQuery(key) {
        var indexToReplace = getQueryParamIndex(key, this.queryParams);
        if (indexToReplace < 0) {
            return;
        }
        this.queryParams.splice(indexToReplace, 1);
    }

    function QueryParam() {
        var value = arguments[0];
        if (arguments.length === 2) {
            value = arguments[0] + '=' + arguments[1];
        }
        this.queryParamString = value;
        this.key = '';
        this.value = '';
        //Break up the value into a map
        initQueryParam.apply(this);
    }
    QueryParam.prototype.set = function(key, newValue) {
        if (this.value instanceof ValueMap) {
            this.value.set(key, newValue);
            return this;
        }
        this.value = new ValueMap();
        this.value.set(key, newValue);
        return this;
    };
    QueryParam.prototype.get = function(key) {
        if (this.value instanceof ValueMap) {
            return this.value.get(key);
        }
        return this.value;
    };
    QueryParam.prototype.remove = function(key) {
        if (this.value instanceof ValueMap) {
            this.value.remove(key);
        }
        return this;
    };
    QueryParam.prototype.compile = function() {
        return this.toString();
    };
    QueryParam.prototype.toString = function() {
        return reconstructQueryParam.apply(this);
    };

    function initQueryParam() {
        var components = this.queryParamString.split('=');
        this.key = components[0];
        var valueComponents = (components[1] || '').split(',');
        if ((valueComponents.length === 1) && ((components[1] || '').indexOf(':') < 0)) {
            this.value = components[1];
        } else {
            this.value = new ValueMap(valueComponents);
        }
    }

    function reconstructQueryParam() {
        var value = this.value;
        if (this.value instanceof ValueMap) {
            value = value.compile();
        }
        if (value === '') {
            return '';
        }
        return [this.key].concat([value]).join('=');
    }

    function ValueMap(values) {
        values = values || [];
        this.map = {};
        that = this;
        values.forEach(function(kv) {
            var components = kv.split(':');
            that.map[components[0]] = components[1];
        });
    }
    ValueMap.prototype.get = function(key) {
        return this.map[key];
    };
    ValueMap.prototype.set = function(key, value) {
        this.map[key] = value;
        return this;
    };
    ValueMap.prototype.remove = function(key) {
        if (this.map.hasOwnProperty(key)) {
            delete this.map[key];
        }
        return this;
    };
    ValueMap.prototype.compile = function() {
        return this.toString();
    };
    ValueMap.prototype.toString = function() {
        var values = [];
        var that = this;
        Object.keys(this.map).forEach(function(key) {
            values.push(key + ':' + that.map[key]);
        })
        return values.join(',');
    };
}());<commit_msg>Improved the way in which query param values are retrieved<commit_after>/*
 *  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
var URL = {};
(function() {
    URL.buildURL = function(url) {
        return new Url(url);
    };

    function Url(url) {
        this.url = url;
        this.urlBase = '';
        this.queryParams = [];
        init(this);
    }
    Url.prototype.compile = function() {
        return reconstructURL(this.urlBase, this.queryParams);
    };
    Url.prototype.toString = function() {
        return reconstructURL(this.urlBase, this.queryParams);
    }
    Url.prototype.queryParam = function() {
        if (arguments.length === 1) {
            return getQueryParam.apply(this, arguments);
        }
        if (arguments.length === 2) {
            addQueryParam.apply(this, arguments);
            return this;
        }
    };
    Url.prototype.removeQueryParam = function() {
        removeQuery.apply(this, arguments);
        return this;
    };

    function init(expression) {
        expression.urlBase = '';
        var components = expression.url.split('?');
        expression.urlBase = components[0];
        //If there are no other components
        if (components.length === 1) {
            return;
        }
        expression.queryParams = processQueryParams(components[1] || '');
    }

    function processQueryParams(queryParamsString) {
        var components = queryParamsString.split('&');
        var params = [];
        components.forEach(function(component) {
            if (component !== '') {
                params.push(new QueryParam(component));
            }
        });
        return params;
    }

    function reconstructURL(urlBase, queryParams) {
        var params = [];
        queryParams.forEach(function(queryParam) {
            params.push(queryParam.compile());
        });
        var queryParamComponent = params.join('&');
        queryParams = (queryParamComponent === '') ? [] : [queryParamComponent];
        return [urlBase].concat(queryParams).join('?');
    }

    function addQueryParam(key, value) {
        //Check if the query param exists
        var queryParam = this.queryParam(key);
        value = (typeof value === 'QueryParam') ? value : (new QueryParam(key, value));
        //New query parameter
        if (!queryParam) {
            this.queryParams.splice(0, 0, value);
            //this.queryParams.push(value);
            return;
        }
        var indexToReplace = getQueryParamIndex(key, this.queryParams);
        if (indexToReplace < 0) {
            throw 'Could not add the query parameter with key: ' + key;
        }
        this.queryParams.splice(indexToReplace, 1);
        this.queryParams = this.queryParams.slice(0, indexToReplace).concat([value]).concat(this.queryParams.slice(indexToReplace));
    }

    function getQueryParam(key) {
        var value = null;
        this.queryParams.forEach(function(queryParam) {
            if (queryParam.key === key) {
                value = queryParam;
            }
        });
        return value;
    }

    function getQueryParamIndex(key, queryParams) {
        var index = -1;
        queryParams.forEach(function(queryParam, indexOfQueryParam) {
            if (queryParam.key === key) {
                index = indexOfQueryParam;
            }
        });
        return index;
    }

    function removeQuery(key) {
        var indexToReplace = getQueryParamIndex(key, this.queryParams);
        if (indexToReplace < 0) {
            return;
        }
        this.queryParams.splice(indexToReplace, 1);
    }

    function QueryParam() {
        var value = arguments[0];
        if (arguments.length === 2) {
            value = arguments[0] + '=' + arguments[1];
        }
        this.queryParamString = value;
        this.key = '';
        this.value = '';
        //Break up the value into a map
        initQueryParam.apply(this);
    }
    QueryParam.prototype.set = function(key, newValue) {
        if (this.value instanceof ValueMap) {
            this.value.set(key, newValue);
            return this;
        }
        this.value = new ValueMap();
        this.value.set(key, newValue);
        return this;
    };
    QueryParam.prototype.get = function(key) {
        //Retrieve the value of the query param
        if (!key) {
            return this.value;
        }
        if (this.value instanceof ValueMap) {
            return this.value.get(key);
        }
        return null;
    };
    QueryParam.prototype.remove = function(key) {
        if (this.value instanceof ValueMap) {
            this.value.remove(key);
        }
        return this;
    };
    QueryParam.prototype.compile = function() {
        return this.toString();
    };
    QueryParam.prototype.toString = function() {
        return reconstructQueryParam.apply(this);
    };

    function initQueryParam() {
        var components = this.queryParamString.split('=');
        this.key = components[0];
        var valueComponents = (components[1] || '').split(',');
        if ((valueComponents.length === 1) && ((components[1] || '').indexOf(':') < 0)) {
            this.value = components[1];
        } else {
            this.value = new ValueMap(valueComponents);
        }
    }

    function reconstructQueryParam() {
        var value = this.value;
        if (this.value instanceof ValueMap) {
            value = value.compile();
        }
        if (value === '') {
            return '';
        }
        return [this.key].concat([value]).join('=');
    }

    function ValueMap(values) {
        values = values || [];
        this.map = {};
        that = this;
        values.forEach(function(kv) {
            var components = kv.split(':');
            that.map[components[0]] = components[1];
        });
    }
    ValueMap.prototype.get = function(key) {
        return this.map[key];
    };
    ValueMap.prototype.set = function(key, value) {
        this.map[key] = value;
        return this;
    };
    ValueMap.prototype.remove = function(key) {
        if (this.map.hasOwnProperty(key)) {
            delete this.map[key];
        }
        return this;
    };
    ValueMap.prototype.compile = function() {
        return this.toString();
    };
    ValueMap.prototype.toString = function() {
        var values = [];
        var that = this;
        Object.keys(this.map).forEach(function(key) {
            values.push(key + ':' + that.map[key]);
        })
        return values.join(',');
    };
}());<|endoftext|>


<commit_before>// ==UserScript==
// @name            A Dark Room - Helper
// @namespace       http://github.com/taeram/user-scripts
// @description     Helper for A Dark Room
// @match           http://adarkroom.doublespeakgames.com/
// @grant           none
// @copyright       Jesse Patching
// @version         2.1.7
// @license         MIT https://github.com/taeram/user-scripts/blob/master/LICENSE
// @updateURL       https://raw.github.com/taeram/user-scripts/master/a-dark-room.user.js
// @downloadURL     https://raw.github.com/taeram/user-scripts/master/a-dark-room.user.js
// ==/UserScript==

(function() {
    'use strict';
    var ADR = {
        intervals: {},
        resources: {},
        elements: {},
        weapons: {},

        stokeFire: function () {
            $('#stokeButton').click();
        },

        gatherWood: function ()  {
            $('#gatherButton').click();
        },

        checkTraps: function ()  {
            $('#trapsButton').click();
        },

        countResources: function () {
            var stores = $('#stores .storeRow');
            for (var i = 0; i < stores.length; i++) {
                var store = stores[i];
                ADR.resources[$(store).find('> .row_key').text()] = parseInt($(store).find('> .row_val').text(), 10);
            }

            var weapons = $('#weapons .storeRow');
            for (i = 0; i < weapons.length; i++) {
                var weapon = weapons[i];
                ADR.weapons[$(weapon).find('> .row_key').text()] = parseInt($(weapon).find('> .row_val').text(), 10);
            }
        },

        hasEnoughResources: function(buttonEl) {
            ADR.countResources();

            // Figure out how many resources we need to purchase this thing
            var requiredResources = {};
            var resourceTooltips = $(buttonEl).find('.tooltip .row_key,.row_val');
            for (var j = 0; j < resourceTooltips.length; j += 2) {
                requiredResources[$(resourceTooltips[j]).text()] = parseInt($(resourceTooltips[j + 1]).text(), 10);
            }

            // Do we have enough resources to purchase this?
            for (var key in requiredResources) {
                if (ADR.resources[key] < requiredResources[key]) {
                    return false;
                }
            }

            return true;
        },

        balanceWorkers: function () {
            var resourceLimits = {
                bait: 1000,
                bullets: 1000,
                coal: 1000,
                "cured meat": 1000,
                iron: 1000,
                leather: 1000,
                fur: 1000,
                meat: 1000,
                steel: 1000,
                sulphur: 1000,
                wood: 1000,
            };

            var productionPerInterval = {
            };

            var workers = {};
            var rows = $('#workers .workerRow');
            for (var i = 0; i < rows.length; i++) {
                var name = $(rows[i]).attr('key');
                var count = $(rows[i]).find('.row_val > span:first-child').text();
                var resources = {};

                var resourceRows = $(rows[i]).find('.tooltip .storeRow');
                for (var j = 0; j < resourceRows.length; j++) {
                    var key = $(resourceRows[j]).find('.row_key').text();
                    var matches = $(resourceRows[j]).find('.row_val').text().match(/^(.+?) per (.+)s$/);
                    var value = parseInt(matches[1], 10);
                    var interval = parseInt(matches[2], 10);

                    resources[key] = {
                        value: value,
                        interval: interval
                    };

                    if (typeof productionPerInterval[key] === 'undefined') {
                        productionPerInterval[key] = value;
                    } else {
                        productionPerInterval[key] += value;
                    }
                }

                workers[name] = {
                    count: count,
                    resources: resources
                };
            }

            if (typeof ADR.elements.production_per_interval === 'undefined') {
                ADR.elements.production_per_interval = $('

').appendTo('#workers');
            }
            $(ADR.elements.production_per_interval).empty();
            for (var key in productionPerInterval) {
                $(ADR.elements.production_per_interval).append('
' + productionPerInterval[key] + '

' + key + '
');
            }

            for (var name in workers) {
                var resources = workers[name].resources;
                for (var resource in resources) {
                    if (resources[resource].value < 0) {
                        continue;
                    }

                    if (ADR.resources[resource] > resourceLimits[resource]) {
                        $('#workers_row_' + name + ' .dnManyBtn').click();
                    }
                }
            }
        },

        buildThings: function () {
            ADR.countResources();

            // Build all the things
            var things = $('#buildBtns .button');
            for (var i=0; i < things.length; i++) {
                if ($(things[i]).hasClass('disabled')) {
                    continue;
                }

                if (ADR.hasEnoughResources(things[i])) {
                    $(things[i]).click();
                }
            }

            // Craft most of the things
            var items = $('#craftBtns .button');
            for (i = 0; i < items.length; i++) {
                if ($(items[i]).hasClass('disabled')) {
                    continue;
                }

                var itemName = $(items[i]).attr('id').replace(/build_/, '');

                // Always have torches on hand
                if (itemName == 'torch' && ADR.resources.torch >= 10) {
                    continue;
                }

                // Only buy one of each weapon
                if (ADR.weapons[itemName] >= 1) {
                    continue;
                }

                if (ADR.hasEnoughResources(items[i])) {
                    $(items[i]).click();
                }
            }

            // Buy a few things
            var purchases = $('#buyBtns .button');
            for (i = 0; i < purchases.length; i++) {
                if ($(purchases[i]).hasClass('disabled')) {
                    continue;
                }

                var purchaseName = $(purchases[i]).attr('id').replace(/build_/, '');
                var purchaseItem = false;

                // Buy a compass
                if (purchaseName == 'compass') {
                    purchaseItem = true;
                }

                // Always have bolas
                if (purchaseName == 'bolas' && ADR.weapons.bolas <= 10) {
                    purchaseItem = true;
                }

                // Always have bullets
                if (purchaseName == 'bullets' && ADR.resources.bullets <= 50) {
                    purchaseItem = true;
                }

                if (purchaseItem && ADR.hasEnoughResources(purchases[i])) {
                    $(purchases[i]).click();
                }
            }
        },

        handleEvent: function () {
            if ($('#event').length > 0) {
                // Allow the old wanderer to stay the night
                if ($('#agree').length > 0 || $('#buyMap').length > 0) {
                    $('#agree').click();

                    // Learn scouting
                    $('#learn').click();

                    // Buy a shit load of maps
                    if ($('#buyMap').length > 0) {
                        while (!$('#buyMap').hasClass('disabled')) {
                            $('#buyMap').click();
                        }
                    }

                    $('#leave').click();
                    $('#deny').click();
                }

                // Spare the thief
                if ($('#spare').length > 0) {
                    $('#spare').click();
                    $('#leave').click();
                }

                // Mourn the dead
                if ($('#mourn').length > 0) {
                    $('#mourn').click();
                }

                // Track the prints into the forest
                if ($('#track').length > 0) {
                    $('#track').click();
                    $('#end').click();
                }

                // Investigate the scratching noises
                if ($('#investigate').length > 0) {
                    $('#investigate').click();
                    $('#leave').click();
                }

                // Give the beggar some furs
                if ($('#100furs').length > 0) {
                    $('#100furs').click();
                    $('#50furs').click();
                    $('#leave').click();
                    $('#deny').click();
                }

                // Give the beggar some furs
                if ($('#fur100').length > 0) {
                    $('#fur500').click();
                    $('#fur100').click();
                    $('#leave').click();
                    $('#deny').click();
                }

                // Give the wanderer some wood
                if ($('#wood500').length > 0) {
                    $('#wood500').click();
                    $('#wood100').click();
                    $('#leave').click();
                    $('#deny').click();
                }

                // Give the man some medicine
                if ($('#help').length > 0) {
                    $('#help').click();
                    $('#bye').click();
                }

                // Buy medicine to prevent the plague from spreading
                if ($('#buyMedicine').length > 0) {
                    $('#heal').click();
                    $('#buyMedicine').click();
                    $('#ignore').click();
                }

                // Buy a compass from the nomad
                if ($('#buyCompass').length > 0) {
                    $('#buyCompass').click();
                    $('#goodbye').click();
                }

                // Grab a trait
                if ($('#evasion').length > 0) {
                    $('#evasion').click();
                    $('#precision').click();
                    $('#force').click();
                    $('#nothing').click();
                }

                // Go home after the beasts attack
                if ($('#end').length > 0) {
                    $('#end').click();
                }

                // Go back inside
                if ($('#backinside').length > 0) {
                    $('#backinside').click();
                }
            }
        },

        handleFighting: function () {
            if ($('#event').length > 0) {
                $('.weaponButton').click();
            }
        }
    };

    // Keep that fire stoked
    ADR.intervals.stokeFire = setInterval(ADR.stokeFire, 300000);
    ADR.stokeFire();

    // Gather resources
    ADR.intervals.gatherWood = setInterval(ADR.gatherWood, 1000);
    ADR.intervals.checkTraps = setInterval(ADR.checkTraps, 1000);

    // Build all the things
    ADR.intervals.buildThings = setInterval(ADR.buildThings, 30000);
    ADR.buildThings();

    // Balance the workers
    ADR.intervals.balanceWorkers = setInterval(ADR.balanceWorkers, 1000);
    ADR.balanceWorkers();

    // Handle any incoming events
    ADR.intervals.handleEvent = setInterval(ADR.handleEvent, 1000);

    // Handle any fighting
    ADR.intervals.handleFighting = setInterval(ADR.handleFighting, 250);
})();
<commit_msg>Removed auto scaling workers<commit_after>// ==UserScript==
// @name            A Dark Room - Helper
// @namespace       http://github.com/taeram/user-scripts
// @description     Helper for A Dark Room
// @match           http://adarkroom.doublespeakgames.com/
// @grant           none
// @copyright       Jesse Patching
// @version         2.1.8
// @license         MIT https://github.com/taeram/user-scripts/blob/master/LICENSE
// @updateURL       https://raw.github.com/taeram/user-scripts/master/a-dark-room.user.js
// @downloadURL     https://raw.github.com/taeram/user-scripts/master/a-dark-room.user.js
// ==/UserScript==

(function() {
    'use strict';
    var ADR = {
        intervals: {},
        resources: {},
        elements: {},
        weapons: {},

        stokeFire: function () {
            $('#stokeButton').click();
        },

        gatherWood: function ()  {
            $('#gatherButton').click();
        },

        checkTraps: function ()  {
            $('#trapsButton').click();
        },

        countResources: function () {
            var stores = $('#stores .storeRow');
            for (var i = 0; i < stores.length; i++) {
                var store = stores[i];
                ADR.resources[$(store).find('> .row_key').text()] = parseInt($(store).find('> .row_val').text(), 10);
            }

            var weapons = $('#weapons .storeRow');
            for (i = 0; i < weapons.length; i++) {
                var weapon = weapons[i];
                ADR.weapons[$(weapon).find('> .row_key').text()] = parseInt($(weapon).find('> .row_val').text(), 10);
            }
        },

        hasEnoughResources: function(buttonEl) {
            ADR.countResources();

            // Figure out how many resources we need to purchase this thing
            var requiredResources = {};
            var resourceTooltips = $(buttonEl).find('.tooltip .row_key,.row_val');
            for (var j = 0; j < resourceTooltips.length; j += 2) {
                requiredResources[$(resourceTooltips[j]).text()] = parseInt($(resourceTooltips[j + 1]).text(), 10);
            }

            // Do we have enough resources to purchase this?
            for (var key in requiredResources) {
                if (ADR.resources[key] < requiredResources[key]) {
                    return false;
                }
            }

            return true;
        },

        balanceWorkers: function () {
            var resourceLimits = {
                bait: 1000,
                bullets: 1000,
                coal: 1000,
                "cured meat": 1000,
                iron: 1000,
                leather: 1000,
                fur: 1000,
                meat: 1000,
                steel: 1000,
                sulphur: 1000,
                wood: 1000,
            };

            var productionPerInterval = {
            };

            var workers = {};
            var rows = $('#workers .workerRow');
            for (var i = 0; i < rows.length; i++) {
                var name = $(rows[i]).attr('key');
                var count = $(rows[i]).find('.row_val > span:first-child').text();
                var resources = {};

                var resourceRows = $(rows[i]).find('.tooltip .storeRow');
                for (var j = 0; j < resourceRows.length; j++) {
                    var key = $(resourceRows[j]).find('.row_key').text();
                    var matches = $(resourceRows[j]).find('.row_val').text().match(/^(.+?) per (.+)s$/);
                    var value = parseInt(matches[1], 10);
                    var interval = parseInt(matches[2], 10);

                    resources[key] = {
                        value: value,
                        interval: interval
                    };

                    if (typeof productionPerInterval[key] === 'undefined') {
                        productionPerInterval[key] = value;
                    } else {
                        productionPerInterval[key] += value;
                    }
                }

                workers[name] = {
                    count: count,
                    resources: resources
                };
            }

            if (typeof ADR.elements.production_per_interval === 'undefined') {
                ADR.elements.production_per_interval = $('

').appendTo('#workers');
            }
            $(ADR.elements.production_per_interval).empty();
            for (var key in productionPerInterval) {
                $(ADR.elements.production_per_interval).append('
' + productionPerInterval[key] + '

' + key + '
');
            }
        },

        buildThings: function () {
            ADR.countResources();

            // Build all the things
            var things = $('#buildBtns .button');
            for (var i=0; i < things.length; i++) {
                if ($(things[i]).hasClass('disabled')) {
                    continue;
                }

                if (ADR.hasEnoughResources(things[i])) {
                    $(things[i]).click();
                }
            }

            // Craft most of the things
            var items = $('#craftBtns .button');
            for (i = 0; i < items.length; i++) {
                if ($(items[i]).hasClass('disabled')) {
                    continue;
                }

                var itemName = $(items[i]).attr('id').replace(/build_/, '');

                // Always have torches on hand
                if (itemName == 'torch' && ADR.resources.torch >= 10) {
                    continue;
                }

                // Only buy one of each weapon
                if (ADR.weapons[itemName] >= 1) {
                    continue;
                }

                if (ADR.hasEnoughResources(items[i])) {
                    $(items[i]).click();
                }
            }

            // Buy a few things
            var purchases = $('#buyBtns .button');
            for (i = 0; i < purchases.length; i++) {
                if ($(purchases[i]).hasClass('disabled')) {
                    continue;
                }

                var purchaseName = $(purchases[i]).attr('id').replace(/build_/, '');
                var purchaseItem = false;

                // Buy a compass
                if (purchaseName == 'compass') {
                    purchaseItem = true;
                }

                // Always have bolas
                if (purchaseName == 'bolas' && ADR.weapons.bolas <= 10) {
                    purchaseItem = true;
                }

                // Always have bullets
                if (purchaseName == 'bullets' && ADR.resources.bullets <= 50) {
                    purchaseItem = true;
                }

                if (purchaseItem && ADR.hasEnoughResources(purchases[i])) {
                    $(purchases[i]).click();
                }
            }
        },

        handleEvent: function () {
            if ($('#event').length > 0) {
                // Allow the old wanderer to stay the night
                if ($('#agree').length > 0 || $('#buyMap').length > 0) {
                    $('#agree').click();

                    // Learn scouting
                    $('#learn').click();

                    // Buy a shit load of maps
                    if ($('#buyMap').length > 0) {
                        while (!$('#buyMap').hasClass('disabled')) {
                            $('#buyMap').click();
                        }
                    }

                    $('#leave').click();
                    $('#deny').click();
                }

                // Spare the thief
                if ($('#spare').length > 0) {
                    $('#spare').click();
                    $('#leave').click();
                }

                // Mourn the dead
                if ($('#mourn').length > 0) {
                    $('#mourn').click();
                }

                // Track the prints into the forest
                if ($('#track').length > 0) {
                    $('#track').click();
                    $('#end').click();
                }

                // Investigate the scratching noises
                if ($('#investigate').length > 0) {
                    $('#investigate').click();
                    $('#leave').click();
                }

                // Give the beggar some furs
                if ($('#100furs').length > 0) {
                    $('#100furs').click();
                    $('#50furs').click();
                    $('#leave').click();
                    $('#deny').click();
                }

                // Give the beggar some furs
                if ($('#fur100').length > 0) {
                    $('#fur500').click();
                    $('#fur100').click();
                    $('#leave').click();
                    $('#deny').click();
                }

                // Give the wanderer some wood
                if ($('#wood500').length > 0) {
                    $('#wood500').click();
                    $('#wood100').click();
                    $('#leave').click();
                    $('#deny').click();
                }

                // Give the man some medicine
                if ($('#help').length > 0) {
                    $('#help').click();
                    $('#bye').click();
                }

                // Buy medicine to prevent the plague from spreading
                if ($('#buyMedicine').length > 0) {
                    $('#heal').click();
                    $('#buyMedicine').click();
                    $('#ignore').click();
                }

                // Buy a compass from the nomad
                if ($('#buyCompass').length > 0) {
                    $('#buyCompass').click();
                    $('#goodbye').click();
                }

                // Grab a trait
                if ($('#evasion').length > 0) {
                    $('#evasion').click();
                    $('#precision').click();
                    $('#force').click();
                    $('#nothing').click();
                }

                // Go home after the beasts attack
                if ($('#end').length > 0) {
                    $('#end').click();
                }

                // Go back inside
                if ($('#backinside').length > 0) {
                    $('#backinside').click();
                }
            }
        },

        handleFighting: function () {
            if ($('#event').length > 0) {
                $('.weaponButton').click();
            }
        }
    };

    // Keep that fire stoked
    ADR.intervals.stokeFire = setInterval(ADR.stokeFire, 300000);
    ADR.stokeFire();

    // Gather resources
    ADR.intervals.gatherWood = setInterval(ADR.gatherWood, 1000);
    ADR.intervals.checkTraps = setInterval(ADR.checkTraps, 1000);

    // Build all the things
    ADR.intervals.buildThings = setInterval(ADR.buildThings, 30000);
    ADR.buildThings();

    // Balance the workers
    ADR.intervals.balanceWorkers = setInterval(ADR.balanceWorkers, 1000);
    ADR.balanceWorkers();

    // Handle any incoming events
    ADR.intervals.handleEvent = setInterval(ADR.handleEvent, 1000);

    // Handle any fighting
    ADR.intervals.handleFighting = setInterval(ADR.handleFighting, 250);
})();
<|endoftext|>


<commit_before>/**
 * http://aeqdev.com/tools/js/abigimage/
 * v 1.1
 *
 * Copyright © 2014 Krylosov Maksim <Aequiternus@gmail.com>
 *
 * 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/.
 */

(function ($) {

    $.fn.abigimage = function(options) {

        var opts = $.extend(true, $.fn.abigimage.defaults, options);

        this.overlay    = $('<div>').attr(opts.overlayAttrs)    .css(opts.overlayCSS)   .appendTo('body'),
        this.layout     = $('<div>').attr(opts.layoutAttrs)     .css(opts.layoutCSS)    .appendTo('body'),
        this.wrapper    = $('<div>').attr(opts.wrapperAttrs)    .css(opts.wrapperCSS)   .appendTo(this.layout),
        this.box        = $('<div>').attr(opts.boxAttrs)        .css(opts.boxCSS)       .appendTo(this.wrapper),
        this.prevBtn    = $('<div>').attr(opts.prevBtnAttrs)    .css(opts.prevBtnCSS)   .appendTo(this.box)        .html(opts.prevBtnHtml),
        this.body       = $('<div>').attr(opts.bodyAttrs)       .css(opts.bodyCSS)      .appendTo(this.box),
        this.closeBtn   = $('<div>').attr(opts.closeBtnAttrs)   .css(opts.closeBtnCSS)  .appendTo(this.box)        .html(opts.nextBtnHtml),
        this.top        = $('<div>').attr(opts.topAttrs)        .css(opts.topCSS)       .appendTo(this.body),
        this.img        = $('<img>').attr(opts.imgAttrs)        .css(opts.imgCSS)       .appendTo(this.body),
        this.imgNext    = $('<img>').attr(opts.imgNextAttrs)    .css(opts.imgNextCSS)   .appendTo(this.body),
        this.imgPrev    = $('<img>').attr(opts.imgPrevAttrs)    .css(opts.imgPrevCSS)   .appendTo(this.body),
        this.bottom     = $('<div>').attr(opts.bottomAttrs)     .css(opts.bottomCSS)    .appendTo(this.body);

        var t = this,
            d = 0,
            i = null;

        function nextI() {
            var j = i + 1;
            if (j === t.length) {
                j = 0;
            }
            return j;
        }

        function prevI() {
            var j = i - 1;
            if (j === -1) {
                j = t.length - 1;
            }
            return j;
        }

        function next() {
            if (d === t.length - 1) {
                return close();
            } else {
                ++d;
                return open(nextI());
            }
        }

        function prev() {
            if (d === 1 - t.length) {
                return close();
            } else {
                --d;
                return open(prevI());
            }
        }

        function key(event) {
            if (opts.keyNext.indexOf(event.which) !== -1) {
                event.preventDefault();
                next();
            } else if (opts.keyPrev.indexOf(event.which) !== -1) {
                event.preventDefault();
                prev();
            } else if (opts.keyClose.indexOf(event.which) !== -1) {
                event.preventDefault();
                close();
            }
        }

        function close() {
            d = 0;
            t.overlay.fadeOut(opts.fadeOut);
            t.layout.fadeOut(opts.fadeOut);
            $(document).unbind('keydown', key);
            return false;
        }

        function open(openI) {
            if (openI < 0 || openI > t.length - 1) {
                return;
            }

            i = openI;

            t.img.attr('src', $(t[i]).attr('href'));
            t.imgNext.attr('src', $(t[nextI()]).attr('href'));
            t.imgPrev.attr('src', $(t[prevI()]).attr('href'));

            t.overlay.fadeIn(opts.fadeIn);
            t.layout.fadeIn(opts.fadeIn);
            t.layout.css({
                top: $(document).scrollTop() + 'px',
                height: $(window).height() + 'px'
            });

            $(document).unbind('keydown', key).bind('keydown', key);

            opts.onopen.call(t, t[i]);

            return false;
        }

        this.img.click(function() {
            return next();
        });

        this.prevBtn.click(function() {
            return prev();
        });

        this.closeBtn.click(function() {
            return close();
        });

        this.closeBtn.hover(function() {
            $(this).css(opts.closeBtnHoverCSS);
        }, function () {
            $(this).css(opts.closeBtnCSS);
        });

        this.prevBtn.hover(function() {
            $(this).css(opts.prevBtnHoverCSS);
        }, function() {
            $(this).css(opts.prevBtnCSS);
        });

        return this.each(function(i) {
            $(this).click(function() {
                return open(i);
            });
        });
    };

    var btnCSS = {color: '#808080', display: 'table-cell', verticalAlign: 'middle', textAlign: 'center', fontSize: '2em', fontWeight: 'bold', cursor: 'pointer', padding: '.75em'},
        btnHoverCSS = {color: '#c0c0c0'},
        imgPreCSS = {position: 'absolute', top: '-10000px', width: '100px'},
        textCSS = {color: '#c0c0c0'};

    $.fn.abigimage.defaults = {
        fadeIn:             'normal',
        fadeOut:            'fast',

        prevBtnHtml:        '◄',
        nextBtnHtml:        '✖',

        keyNext:            [13 /* enter */, 32 /* space */, 39 /* right */, 40 /* down */],
        keyPrev:            [8 /* backspace */, 37 /* left */, 38 /* up */],
        keyClose:           [27 /* escape */, 35 /* end */, 36 /* home */],

        onopen:             function() {},

        overlayCSS:         {backgroundColor: '#404040', opacity: 0.925, zIndex: 2, position: 'fixed', left: 0, top: 0, width: '100%', height: '100%', display: 'none'},
        layoutCSS:          {zIndex: 2, position: 'absolute', top: 0, left: 0, width: '100%', margin: '0 auto', display: 'none',
                                '-webkit-user-select': 'none', '-moz-user-select': 'none', 'user-select': 'none'},
        wrapperCSS:         {display: 'table', width: '100%', height: '100%'},
        boxCSS:             {display: 'table-row'},
        bodyCSS:            {display: 'table-cell', verticalAlign: 'middle', textAlign: 'center', width: '1%'},
        prevBtnCSS:         btnCSS,
        prevBtnHoverCSS:    btnHoverCSS,
        closeBtnCSS:        btnCSS,
        closeBtnHoverCSS:   btnHoverCSS,
        imgCSS:             {maxWidth: '800px', cursor: 'pointer', display: 'block', margin: '1ex 0'},
        imgNextCSS:         imgPreCSS,
        imgPrevCSS:         imgPreCSS,
        topCSS:             textCSS,
        bottomCSS:          textCSS,

        overlayAttrs:       {},
        layoutAttrs:        {},
        wrapperAttrs:       {},
        boxAttrs:           {},
        bodyAttrs:          {},
        prevBtnAttrs:       {},
        closeBtnAttrs:      {},
        imgAttrs:           {},
        imgNextAttrs:       {},
        imgPrevAttrs:       {},
        topAttrs:           {},
        bottomAttrs:        {}
    };

}(jQuery));
<commit_msg>fix option name: "nextBtnHtml" to "closeBtnHtml"<commit_after>/**
 * http://aeqdev.com/tools/js/abigimage/
 * v 1.1
 *
 * Copyright © 2014 Krylosov Maksim <Aequiternus@gmail.com>
 *
 * 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/.
 */

(function ($) {

    $.fn.abigimage = function(options) {

        var opts = $.extend(true, $.fn.abigimage.defaults, options);

        this.overlay    = $('<div>').attr(opts.overlayAttrs)    .css(opts.overlayCSS)   .appendTo('body'),
        this.layout     = $('<div>').attr(opts.layoutAttrs)     .css(opts.layoutCSS)    .appendTo('body'),
        this.wrapper    = $('<div>').attr(opts.wrapperAttrs)    .css(opts.wrapperCSS)   .appendTo(this.layout),
        this.box        = $('<div>').attr(opts.boxAttrs)        .css(opts.boxCSS)       .appendTo(this.wrapper),
        this.prevBtn    = $('<div>').attr(opts.prevBtnAttrs)    .css(opts.prevBtnCSS)   .appendTo(this.box)        .html(opts.prevBtnHtml),
        this.body       = $('<div>').attr(opts.bodyAttrs)       .css(opts.bodyCSS)      .appendTo(this.box),
        this.closeBtn   = $('<div>').attr(opts.closeBtnAttrs)   .css(opts.closeBtnCSS)  .appendTo(this.box)        .html(opts.closeBtnHtml),
        this.top        = $('<div>').attr(opts.topAttrs)        .css(opts.topCSS)       .appendTo(this.body),
        this.img        = $('<img>').attr(opts.imgAttrs)        .css(opts.imgCSS)       .appendTo(this.body),
        this.imgNext    = $('<img>').attr(opts.imgNextAttrs)    .css(opts.imgNextCSS)   .appendTo(this.body),
        this.imgPrev    = $('<img>').attr(opts.imgPrevAttrs)    .css(opts.imgPrevCSS)   .appendTo(this.body),
        this.bottom     = $('<div>').attr(opts.bottomAttrs)     .css(opts.bottomCSS)    .appendTo(this.body);

        var t = this,
            d = 0,
            i = null;

        function nextI() {
            var j = i + 1;
            if (j === t.length) {
                j = 0;
            }
            return j;
        }

        function prevI() {
            var j = i - 1;
            if (j === -1) {
                j = t.length - 1;
            }
            return j;
        }

        function next() {
            if (d === t.length - 1) {
                return close();
            } else {
                ++d;
                return open(nextI());
            }
        }

        function prev() {
            if (d === 1 - t.length) {
                return close();
            } else {
                --d;
                return open(prevI());
            }
        }

        function key(event) {
            if (opts.keyNext.indexOf(event.which) !== -1) {
                event.preventDefault();
                next();
            } else if (opts.keyPrev.indexOf(event.which) !== -1) {
                event.preventDefault();
                prev();
            } else if (opts.keyClose.indexOf(event.which) !== -1) {
                event.preventDefault();
                close();
            }
        }

        function close() {
            d = 0;
            t.overlay.fadeOut(opts.fadeOut);
            t.layout.fadeOut(opts.fadeOut);
            $(document).unbind('keydown', key);
            return false;
        }

        function open(openI) {
            if (openI < 0 || openI > t.length - 1) {
                return;
            }

            i = openI;

            t.img.attr('src', $(t[i]).attr('href'));
            t.imgNext.attr('src', $(t[nextI()]).attr('href'));
            t.imgPrev.attr('src', $(t[prevI()]).attr('href'));

            t.overlay.fadeIn(opts.fadeIn);
            t.layout.fadeIn(opts.fadeIn);
            t.layout.css({
                top: $(document).scrollTop() + 'px',
                height: $(window).height() + 'px'
            });

            $(document).unbind('keydown', key).bind('keydown', key);

            opts.onopen.call(t, t[i]);

            return false;
        }

        this.img.click(function() {
            return next();
        });

        this.prevBtn.click(function() {
            return prev();
        });

        this.closeBtn.click(function() {
            return close();
        });

        this.closeBtn.hover(function() {
            $(this).css(opts.closeBtnHoverCSS);
        }, function () {
            $(this).css(opts.closeBtnCSS);
        });

        this.prevBtn.hover(function() {
            $(this).css(opts.prevBtnHoverCSS);
        }, function() {
            $(this).css(opts.prevBtnCSS);
        });

        return this.each(function(i) {
            $(this).click(function() {
                return open(i);
            });
        });
    };

    var btnCSS = {color: '#808080', display: 'table-cell', verticalAlign: 'middle', textAlign: 'center', fontSize: '2em', fontWeight: 'bold', cursor: 'pointer', padding: '.75em'},
        btnHoverCSS = {color: '#c0c0c0'},
        imgPreCSS = {position: 'absolute', top: '-10000px', width: '100px'},
        textCSS = {color: '#c0c0c0'};

    $.fn.abigimage.defaults = {
        fadeIn:             'normal',
        fadeOut:            'fast',

        prevBtnHtml:        '◄',
        closeBtnHtml:       '✖',

        keyNext:            [13 /* enter */, 32 /* space */, 39 /* right */, 40 /* down */],
        keyPrev:            [8 /* backspace */, 37 /* left */, 38 /* up */],
        keyClose:           [27 /* escape */, 35 /* end */, 36 /* home */],

        onopen:             function() {},

        overlayCSS:         {backgroundColor: '#404040', opacity: 0.925, zIndex: 2, position: 'fixed', left: 0, top: 0, width: '100%', height: '100%', display: 'none'},
        layoutCSS:          {zIndex: 2, position: 'absolute', top: 0, left: 0, width: '100%', margin: '0 auto', display: 'none',
                                '-webkit-user-select': 'none', '-moz-user-select': 'none', 'user-select': 'none'},
        wrapperCSS:         {display: 'table', width: '100%', height: '100%'},
        boxCSS:             {display: 'table-row'},
        bodyCSS:            {display: 'table-cell', verticalAlign: 'middle', textAlign: 'center', width: '1%'},
        prevBtnCSS:         btnCSS,
        prevBtnHoverCSS:    btnHoverCSS,
        closeBtnCSS:        btnCSS,
        closeBtnHoverCSS:   btnHoverCSS,
        imgCSS:             {maxWidth: '800px', cursor: 'pointer', display: 'block', margin: '1ex 0'},
        imgNextCSS:         imgPreCSS,
        imgPrevCSS:         imgPreCSS,
        topCSS:             textCSS,
        bottomCSS:          textCSS,

        overlayAttrs:       {},
        layoutAttrs:        {},
        wrapperAttrs:       {},
        boxAttrs:           {},
        bodyAttrs:          {},
        prevBtnAttrs:       {},
        closeBtnAttrs:      {},
        imgAttrs:           {},
        imgNextAttrs:       {},
        imgPrevAttrs:       {},
        topAttrs:           {},
        bottomAttrs:        {}
    };

}(jQuery));
<|endoftext|>