From 0f1c293a93c60a829d18d501a165d78c2b9754d7 Mon Sep 17 00:00:00 2001 From: yuriy0803 <68668177+yuriy0803@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:30:06 +0200 Subject: [PATCH] jdenticon identicon --- www/ember-cli-build.js | 7 +- www/vendor/README.md | 61 ++ www/vendor/jdenticon-module.js | 1397 +++++++++++++++++++++++++ www/vendor/jdenticon-module.js.map | 1 + www/vendor/jdenticon-module.mjs | 1391 +++++++++++++++++++++++++ www/vendor/jdenticon-module.mjs.map | 1 + www/vendor/jdenticon-node.js | 1266 +++++++++++++++++++++++ www/vendor/jdenticon-node.js.map | 1 + www/vendor/jdenticon-node.mjs | 1230 ++++++++++++++++++++++ www/vendor/jdenticon-node.mjs.map | 1 + www/vendor/jdenticon.js | 1462 +++++++++++++++++++++++++++ www/vendor/jdenticon.min.js | 3 + www/vendor/jdenticon.min.js.map | 1 + 13 files changed, 6821 insertions(+), 1 deletion(-) create mode 100644 www/vendor/README.md create mode 100644 www/vendor/jdenticon-module.js create mode 100644 www/vendor/jdenticon-module.js.map create mode 100644 www/vendor/jdenticon-module.mjs create mode 100644 www/vendor/jdenticon-module.mjs.map create mode 100644 www/vendor/jdenticon-node.js create mode 100644 www/vendor/jdenticon-node.js.map create mode 100644 www/vendor/jdenticon-node.mjs create mode 100644 www/vendor/jdenticon-node.mjs.map create mode 100644 www/vendor/jdenticon.js create mode 100644 www/vendor/jdenticon.min.js create mode 100644 www/vendor/jdenticon.min.js.map diff --git a/www/ember-cli-build.js b/www/ember-cli-build.js index 8ee0c6c..68dfce7 100644 --- a/www/ember-cli-build.js +++ b/www/ember-cli-build.js @@ -2,7 +2,7 @@ var EmberApp = require('ember-cli/lib/broccoli/ember-app'); var Funnel = require('broccoli-funnel'); -module.exports = function(defaults) { +module.exports = function (defaults) { var app = new EmberApp(defaults, { // Add options here SRI: { @@ -25,6 +25,11 @@ module.exports = function(defaults) { app.import('bower_components/bootstrap/dist/css/bootstrap.min.css') app.import('bower_components/bootstrap/dist/js/bootstrap.min.js'); app.import('bower_components/font-awesome/css/font-awesome.min.css') + app.import('vendor/jdenticon.js', { + using: [ + { transformation: 'amd', as: 'jdenticon' } + ] + }); var extraAssets = new Funnel('bower_components/font-awesome/fonts', { srcDir: '/', diff --git a/www/vendor/README.md b/www/vendor/README.md new file mode 100644 index 0000000..a8bd7ec --- /dev/null +++ b/www/vendor/README.md @@ -0,0 +1,61 @@ +# What file should I use? + +## Overview + +| Platform | Bundle | File name | +|----------|------------------|----------------------| +| Browser | Standalone (UMD) | jdenticon.js | +| | | jdenticon.min.js | +| | ES module | jdenticon-module.mjs | +| | CommonJS module | jdenticon-module.js | +| Node.js | ES module | jdenticon-node.mjs | +| | CommonJS module | jdenticon-node.js | + +## Node vs browser +There are separate bundles for Node.js and browsers. The Node.js bundles contain support for generating PNG icons, while the browser bundles have support for updating DOM elements. It is important that the right bundle is used, since a web application bundle will be significally larger if the Node bundle is imported instead of the browser bundle. + +## Don't address `dist/*` directly +In first hand, don't import a specific file from the `dist` folder. Instead import the Jdenticon package and let the package decide what file to be imported. + +Jdenticon has multiple public entry points: + +### ES module + +For browsers `jdenticon-module.mjs` is imported and in Node.js environments `jdenticon-node.mjs` is imported. This is the preferred way of using Jdenticon since your bundler will most likely be able to eliminiate code from Jdenticon not used in your application (a.k.a. tree-shaking). + +**Example** + +```js +import { toSvg } from "jdenticon"; + +console.log(toSvg("my value", 100)); +``` + +### CommonJS module + +If Jdenticon is imported on platforms not supporting ES modules, `jdenticon-module.js` is imported for browser environments and `jdenticon-node.js` in Node.js environments. + +**Example** + +```js +const { toSvg } = require("jdenticon"); +console.log(toSvg("my value", 100)); +// or +const jdenticon = require("jdenticon"); +console.log(jdenticon.toSvg("my value", 100)); +``` + +### Standalone browser package + +This package will render icons automatically at startup and also provides a legacy jQuery plugin, if jQuery is loaded before Jdenticon. + +**Example** + +```js +import "jdenticon/standalone"; + +// or + +import { toSvg } from "jdenticon/standalone"; +console.log(toSvg("my value", 100)); +``` \ No newline at end of file diff --git a/www/vendor/jdenticon-module.js b/www/vendor/jdenticon-module.js new file mode 100644 index 0000000..93f8f68 --- /dev/null +++ b/www/vendor/jdenticon-module.js @@ -0,0 +1,1397 @@ +/** + * Jdenticon 3.1.0 + * http://jdenticon.com + * + * Built: 2020-12-12T13:51:48.709Z + * + * MIT License + * + * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +'use strict'; + +/** + * Parses a substring of the hash as a number. + * @param {number} startPosition + * @param {number=} octets + */ +function parseHex(hash, startPosition, octets) { + return parseInt(hash.substr(startPosition, octets), 16); +} + +function decToHex(v) { + v |= 0; // Ensure integer value + return v < 0 ? "00" : + v < 16 ? "0" + v.toString(16) : + v < 256 ? v.toString(16) : + "ff"; +} + +function hueToRgb(m1, m2, h) { + h = h < 0 ? h + 6 : h > 6 ? h - 6 : h; + return decToHex(255 * ( + h < 1 ? m1 + (m2 - m1) * h : + h < 3 ? m2 : + h < 4 ? m1 + (m2 - m1) * (4 - h) : + m1)); +} + +/** + * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported. + * @returns {string} + */ +function parseColor(color) { + if (/^#[0-9a-f]{3,8}$/i.test(color)) { + var result; + var colorLength = color.length; + + if (colorLength < 6) { + var r = color[1], + g = color[2], + b = color[3], + a = color[4] || ""; + result = "#" + r + r + g + g + b + b + a + a; + } + if (colorLength == 7 || colorLength > 8) { + result = color; + } + + return result; + } +} + +/** + * Converts a hexadecimal color to a CSS3 compatible color. + * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA" + * @returns {string} + */ +function toCss3Color(hexColor) { + var a = parseHex(hexColor, 7, 2); + var result; + + if (isNaN(a)) { + result = hexColor; + } else { + var r = parseHex(hexColor, 1, 2), + g = parseHex(hexColor, 3, 2), + b = parseHex(hexColor, 5, 2); + result = "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")"; + } + + return result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function hsl(hue, saturation, lightness) { + // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color + var result; + + if (saturation == 0) { + var partialHex = decToHex(lightness * 255); + result = partialHex + partialHex + partialHex; + } + else { + var m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation, + m1 = lightness * 2 - m2; + result = + hueToRgb(m1, m2, hue * 6 + 2) + + hueToRgb(m1, m2, hue * 6) + + hueToRgb(m1, m2, hue * 6 - 2); + } + + return "#" + result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the "dark" hues + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function correctedHsl(hue, saturation, lightness) { + // The corrector specifies the perceived middle lightness for each hue + var correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ], + corrector = correctors[(hue * 6 + 0.5) | 0]; + + // Adjust the input lightness relative to the corrector + lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2; + + return hsl(hue, saturation, lightness); +} + +// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for +// backward compatibility. + +var GLOBAL = + typeof window !== "undefined" ? window : + typeof self !== "undefined" ? self : + typeof global !== "undefined" ? global : + {}; + +/** + * @typedef {Object} ParsedConfiguration + * @property {number} colorSaturation + * @property {number} grayscaleSaturation + * @property {string} backColor + * @property {number} iconPadding + * @property {function(number):number} hue + * @property {function(number):number} colorLightness + * @property {function(number):number} grayscaleLightness + */ + +var CONFIG_PROPERTIES = { + W/*GLOBAL*/: "jdenticon_config", + n/*MODULE*/: "config", +}; + +var rootConfigurationHolder = {}; + +/** + * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console + * when it is being used. + * @param {!Object} rootObject + */ +function defineConfigProperty(rootObject) { + rootConfigurationHolder = rootObject; +} + +/** + * Sets a new icon style configuration. The new configuration is not merged with the previous one. * + * @param {Object} newConfiguration - New configuration object. + */ +function configure(newConfiguration) { + if (arguments.length) { + rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] = newConfiguration; + } + return rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/]; +} + +/** + * Gets the normalized current Jdenticon color configuration. Missing fields have default values. + * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A + * local configuration overrides the global configuration in it entirety. This parameter can for backward + * compatibility also contain a padding value. A padding value only overrides the global padding, not the + * entire global configuration. + * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor + * explicitly to the API method. + * @returns {ParsedConfiguration} + */ +function getConfiguration(paddingOrLocalConfig, defaultPadding) { + var configObject = + typeof paddingOrLocalConfig == "object" && paddingOrLocalConfig || + rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] || + GLOBAL[CONFIG_PROPERTIES.W/*GLOBAL*/] || + { }, + + lightnessConfig = configObject["lightness"] || { }, + + // In versions < 2.1.0 there was no grayscale saturation - + // saturation was the color saturation. + saturation = configObject["saturation"] || { }, + colorSaturation = "color" in saturation ? saturation["color"] : saturation, + grayscaleSaturation = saturation["grayscale"], + + backColor = configObject["backColor"], + padding = configObject["padding"]; + + /** + * Creates a lightness range. + */ + function lightness(configName, defaultRange) { + var range = lightnessConfig[configName]; + + // Check if the lightness range is an array-like object. This way we ensure the + // array contain two values at the same time. + if (!(range && range.length > 1)) { + range = defaultRange; + } + + /** + * Gets a lightness relative the specified value in the specified lightness range. + */ + return function (value) { + value = range[0] + value * (range[1] - range[0]); + return value < 0 ? 0 : value > 1 ? 1 : value; + }; + } + + /** + * Gets a hue allowed by the configured hue restriction, + * provided the originally computed hue. + */ + function hueFunction(originalHue) { + var hueConfig = configObject["hues"]; + var hue; + + // Check if 'hues' is an array-like object. This way we also ensure that + // the array is not empty, which would mean no hue restriction. + if (hueConfig && hueConfig.length > 0) { + // originalHue is in the range [0, 1] + // Multiply with 0.999 to change the range to [0, 1) and then truncate the index. + hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)]; + } + + return typeof hue == "number" ? + + // A hue was specified. We need to convert the hue from + // degrees on any turn - e.g. 746° is a perfectly valid hue - + // to turns in the range [0, 1). + ((((hue / 360) % 1) + 1) % 1) : + + // No hue configured => use original hue + originalHue; + } + + return { + X/*hue*/: hueFunction, + o/*colorSaturation*/: typeof colorSaturation == "number" ? colorSaturation : 0.5, + F/*grayscaleSaturation*/: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0, + p/*colorLightness*/: lightness("color", [0.4, 0.8]), + G/*grayscaleLightness*/: lightness("grayscale", [0.3, 0.9]), + H/*backColor*/: parseColor(backColor), + Y/*iconPadding*/: + typeof paddingOrLocalConfig == "number" ? paddingOrLocalConfig : + typeof padding == "number" ? padding : + defaultPadding + } +} + +/** + * Represents a point. + */ +function Point(x, y) { + this.x = x; + this.y = y; +} + +/** + * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, + * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly. + */ +function Transform(x, y, size, rotation) { + this.q/*_x*/ = x; + this.t/*_y*/ = y; + this.I/*_size*/ = size; + this.Z/*_rotation*/ = rotation; +} + +/** + * Transforms the specified point based on the translation and rotation specification for this Transform. + * @param {number} x x-coordinate + * @param {number} y y-coordinate + * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + */ +Transform.prototype.J/*transformIconPoint*/ = function transformIconPoint (x, y, w, h) { + var right = this.q/*_x*/ + this.I/*_size*/, + bottom = this.t/*_y*/ + this.I/*_size*/, + rotation = this.Z/*_rotation*/; + return rotation === 1 ? new Point(right - y - (h || 0), this.t/*_y*/ + x) : + rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) : + rotation === 3 ? new Point(this.q/*_x*/ + y, bottom - x - (w || 0)) : + new Point(this.q/*_x*/ + x, this.t/*_y*/ + y); +}; + +var NO_TRANSFORM = new Transform(0, 0, 0, 0); + + + +/** + * Provides helper functions for rendering common basic shapes. + */ +function Graphics(renderer) { + /** + * @type {Renderer} + * @private + */ + this.K/*_renderer*/ = renderer; + + /** + * @type {Transform} + */ + this.u/*currentTransform*/ = NO_TRANSFORM; +} +var Graphics__prototype = Graphics.prototype; + +/** + * Adds a polygon to the underlying renderer. + * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ] + * @param {boolean=} invert Specifies if the polygon will be inverted. + */ +Graphics__prototype.g/*addPolygon*/ = function addPolygon (points, invert) { + var this$1 = this; + + var di = invert ? -2 : 2, + transformedPoints = []; + + for (var i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) { + transformedPoints.push(this$1.u/*currentTransform*/.J/*transformIconPoint*/(points[i], points[i + 1])); + } + + this.K/*_renderer*/.g/*addPolygon*/(transformedPoints); +}; + +/** + * Adds a polygon to the underlying renderer. + * Source: http://stackoverflow.com/a/2173084 + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} size The size of the ellipse. + * @param {boolean=} invert Specifies if the ellipse will be inverted. + */ +Graphics__prototype.h/*addCircle*/ = function addCircle (x, y, size, invert) { + var p = this.u/*currentTransform*/.J/*transformIconPoint*/(x, y, size, size); + this.K/*_renderer*/.h/*addCircle*/(p, size, invert); +}; + +/** + * Adds a rectangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle. + * @param {number} w The width of the rectangle. + * @param {number} h The height of the rectangle. + * @param {boolean=} invert Specifies if the rectangle will be inverted. + */ +Graphics__prototype.i/*addRectangle*/ = function addRectangle (x, y, w, h, invert) { + this.g/*addPolygon*/([ + x, y, + x + w, y, + x + w, y + h, + x, y + h + ], invert); +}; + +/** + * Adds a right triangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} w The width of the triangle. + * @param {number} h The height of the triangle. + * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle. + * @param {boolean=} invert Specifies if the triangle will be inverted. + */ +Graphics__prototype.j/*addTriangle*/ = function addTriangle (x, y, w, h, r, invert) { + var points = [ + x + w, y, + x + w, y + h, + x, y + h, + x, y + ]; + points.splice(((r || 0) % 4) * 2, 2); + this.g/*addPolygon*/(points, invert); +}; + +/** + * Adds a rhombus to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} w The width of the rhombus. + * @param {number} h The height of the rhombus. + * @param {boolean=} invert Specifies if the rhombus will be inverted. + */ +Graphics__prototype.L/*addRhombus*/ = function addRhombus (x, y, w, h, invert) { + this.g/*addPolygon*/([ + x + w / 2, y, + x + w, y + h / 2, + x + w / 2, y + h, + x, y + h / 2 + ], invert); +}; + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + * @param {number} positionIndex + */ +function centerShape(index, g, cell, positionIndex) { + index = index % 14; + + var k, m, w, h, inner, outer; + + !index ? ( + k = cell * 0.42, + g.g/*addPolygon*/([ + 0, 0, + cell, 0, + cell, cell - k * 2, + cell - k, cell, + 0, cell + ])) : + + index == 1 ? ( + w = 0 | (cell * 0.5), + h = 0 | (cell * 0.8), + + g.j/*addTriangle*/(cell - w, 0, w, h, 2)) : + + index == 2 ? ( + w = 0 | (cell / 3), + g.i/*addRectangle*/(w, w, cell - w, cell - w)) : + + index == 3 ? ( + inner = cell * 0.1, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 6 ? 1 : + cell < 8 ? 2 : + (0 | (cell * 0.25)), + + inner = + inner > 1 ? (0 | inner) : // large icon => truncate decimals + inner > 0.5 ? 1 : // medium size icon => fixed width + inner, // small icon => anti-aliased border + + g.i/*addRectangle*/(outer, outer, cell - inner - outer, cell - inner - outer)) : + + index == 4 ? ( + m = 0 | (cell * 0.15), + w = 0 | (cell * 0.5), + g.h/*addCircle*/(cell - w - m, cell - w - m, w)) : + + index == 5 ? ( + inner = cell * 0.1, + outer = inner * 4, + + // Align edge to nearest pixel in large icons + outer > 3 && (outer = 0 | outer), + + g.i/*addRectangle*/(0, 0, cell, cell), + g.g/*addPolygon*/([ + outer, outer, + cell - inner, outer, + outer + (cell - outer - inner) / 2, cell - inner + ], true)) : + + index == 6 ? + g.g/*addPolygon*/([ + 0, 0, + cell, 0, + cell, cell * 0.7, + cell * 0.4, cell * 0.4, + cell * 0.7, cell, + 0, cell + ]) : + + index == 7 ? + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 8 ? ( + g.i/*addRectangle*/(0, 0, cell, cell / 2), + g.i/*addRectangle*/(0, cell / 2, cell / 2, cell / 2), + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 1)) : + + index == 9 ? ( + inner = cell * 0.14, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 4 ? 1 : + cell < 6 ? 2 : + (0 | (cell * 0.35)), + + inner = + cell < 8 ? inner : // small icon => anti-aliased border + (0 | inner), // large icon => truncate decimals + + g.i/*addRectangle*/(0, 0, cell, cell), + g.i/*addRectangle*/(outer, outer, cell - outer - inner, cell - outer - inner, true)) : + + index == 10 ? ( + inner = cell * 0.12, + outer = inner * 3, + + g.i/*addRectangle*/(0, 0, cell, cell), + g.h/*addCircle*/(outer, outer, cell - inner - outer, true)) : + + index == 11 ? + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 12 ? ( + m = cell * 0.25, + g.i/*addRectangle*/(0, 0, cell, cell), + g.L/*addRhombus*/(m, m, cell - m, cell - m, true)) : + + // 13 + ( + !positionIndex && ( + m = cell * 0.4, w = cell * 1.2, + g.h/*addCircle*/(m, m, w) + ) + ); +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + */ +function outerShape(index, g, cell) { + index = index % 4; + + var m; + + !index ? + g.j/*addTriangle*/(0, 0, cell, cell, 0) : + + index == 1 ? + g.j/*addTriangle*/(0, cell / 2, cell, cell / 2, 0) : + + index == 2 ? + g.L/*addRhombus*/(0, 0, cell, cell) : + + // 3 + ( + m = cell / 6, + g.h/*addCircle*/(m, m, cell - 2 * m) + ); +} + +/** + * Gets a set of identicon color candidates for a specified hue and config. + * @param {number} hue + * @param {ParsedConfiguration} config + */ +function colorTheme(hue, config) { + hue = config.X/*hue*/(hue); + return [ + // Dark gray + correctedHsl(hue, config.F/*grayscaleSaturation*/, config.G/*grayscaleLightness*/(0)), + // Mid color + correctedHsl(hue, config.o/*colorSaturation*/, config.p/*colorLightness*/(0.5)), + // Light gray + correctedHsl(hue, config.F/*grayscaleSaturation*/, config.G/*grayscaleLightness*/(1)), + // Light color + correctedHsl(hue, config.o/*colorSaturation*/, config.p/*colorLightness*/(1)), + // Dark color + correctedHsl(hue, config.o/*colorSaturation*/, config.p/*colorLightness*/(0)) + ]; +} + +/** + * Draws an identicon to a specified renderer. + * @param {Renderer} renderer + * @param {string} hash + * @param {Object|number=} config + */ +function iconGenerator(renderer, hash, config) { + var parsedConfig = getConfiguration(config, 0.08); + + // Set background color + if (parsedConfig.H/*backColor*/) { + renderer.m/*setBackground*/(parsedConfig.H/*backColor*/); + } + + // Calculate padding and round to nearest integer + var size = renderer.k/*iconSize*/; + var padding = (0.5 + size * parsedConfig.Y/*iconPadding*/) | 0; + size -= padding * 2; + + var graphics = new Graphics(renderer); + + // Calculate cell size and ensure it is an integer + var cell = 0 | (size / 4); + + // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon + var x = 0 | (padding + size / 2 - cell * 2); + var y = 0 | (padding + size / 2 - cell * 2); + + function renderShape(colorIndex, shapes, index, rotationIndex, positions) { + var shapeIndex = parseHex(hash, index, 1); + var r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0; + + renderer.M/*beginShape*/(availableColors[selectedColorIndexes[colorIndex]]); + + for (var i = 0; i < positions.length; i++) { + graphics.u/*currentTransform*/ = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4); + shapes(shapeIndex, graphics, cell, i); + } + + renderer.N/*endShape*/(); + } + + // AVAILABLE COLORS + var hue = parseHex(hash, -7) / 0xfffffff, + + // Available colors for this icon + availableColors = colorTheme(hue, parsedConfig), + + // The index of the selected colors + selectedColorIndexes = []; + + var index; + + function isDuplicate(values) { + if (values.indexOf(index) >= 0) { + for (var i = 0; i < values.length; i++) { + if (selectedColorIndexes.indexOf(values[i]) >= 0) { + return true; + } + } + } + } + + for (var i = 0; i < 3; i++) { + index = parseHex(hash, 8 + i, 1) % availableColors.length; + if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo + isDuplicate([2, 3])) { // Disallow light gray and light color combo + index = 1; + } + selectedColorIndexes.push(index); + } + + // ACTUAL RENDERING + // Sides + renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]); + // Corners + renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]); + // Center + renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]); + + renderer.finish(); +} + +/** + * Computes a SHA1 hash for any value and returns it as a hexadecimal string. + * + * This function is optimized for minimal code size and rather short messages. + * + * @param {string} message + */ +function sha1(message) { + var HASH_SIZE_HALF_BYTES = 40; + var BLOCK_SIZE_WORDS = 16; + + // Variables + // `var` is used to be able to minimize the number of `var` keywords. + var i = 0, + f = 0, + + // Use `encodeURI` to UTF8 encode the message without any additional libraries + // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky + // since `unescape` is deprecated. + urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding + + // This can be changed to a preallocated Uint32Array array for greater performance and larger code size + data = [], + dataSize, + + hashBuffer = [], + + a = 0x67452301, + b = 0xefcdab89, + c = ~a, + d = ~b, + e = 0xc3d2e1f0, + hash = [a, b, c, d, e], + + blockStartIndex = 0, + hexHash = ""; + + /** + * Rotates the value a specified number of bits to the left. + * @param {number} value Value to rotate + * @param {number} shift Bit count to shift. + */ + function rotl(value, shift) { + return (value << shift) | (value >>> (32 - shift)); + } + + // Message data + for ( ; i < urlEncodedMessage.length; f++) { + data[f >> 2] = data[f >> 2] | + ( + ( + urlEncodedMessage[i] == "%" + // Percent encoded byte + ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16) + // Unencoded byte + : urlEncodedMessage.charCodeAt(i++) + ) + + // Read bytes in reverse order (big endian words) + << ((3 - (f & 3)) * 8) + ); + } + + // f is now the length of the utf8 encoded message + // 7 = 8 bytes (64 bit) for message size, -1 to round down + // >> 6 = integer division with block size + dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS; + + // Message size in bits. + // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least + // significant 32 bits are set. -8 is for the '1' bit padding byte. + data[dataSize - 1] = f * 8 - 8; + + // Compute hash + for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) { + for (i = 0; i < 80; i++) { + f = rotl(a, 5) + e + ( + // Ch + i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 : + + // Parity + i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 : + + // Maj + i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc : + + // Parity + (b ^ c ^ d) + 0xca62c1d6 + ) + ( + hashBuffer[i] = i < BLOCK_SIZE_WORDS + // Bitwise OR is used to coerse `undefined` to 0 + ? (data[blockStartIndex + i] | 0) + : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1) + ); + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = f; + } + + hash[0] = a = ((hash[0] + a) | 0); + hash[1] = b = ((hash[1] + b) | 0); + hash[2] = c = ((hash[2] + c) | 0); + hash[3] = d = ((hash[3] + d) | 0); + hash[4] = e = ((hash[4] + e) | 0); + } + + // Format hex hash + for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) { + hexHash += ( + ( + // Get word (2^3 half-bytes per word) + hash[i >> 3] >>> + + // Append half-bytes in reverse order + ((7 - (i & 7)) * 4) + ) + // Clamp to half-byte + & 0xf + ).toString(16); + } + + return hexHash; +} + +/** + * Inputs a value that might be a valid hash string for Jdenticon and returns it + * if it is determined valid, otherwise a falsy value is returned. + */ +function isValidHash(hashCandidate) { + return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate; +} + +/** + * Computes a hash for the specified value. Currently SHA1 is used. This function + * always returns a valid hash. + */ +function computeHash(value) { + return sha1(value == null ? "" : "" + value); +} + + + +/** + * Renderer redirecting drawing commands to a canvas context. + * @implements {Renderer} + */ +function CanvasRenderer(ctx, iconSize) { + var canvas = ctx.canvas; + var width = canvas.width; + var height = canvas.height; + + ctx.save(); + + if (!iconSize) { + iconSize = Math.min(width, height); + + ctx.translate( + ((width - iconSize) / 2) | 0, + ((height - iconSize) / 2) | 0); + } + + /** + * @private + */ + this.l/*_ctx*/ = ctx; + this.k/*iconSize*/ = iconSize; + + ctx.clearRect(0, 0, iconSize, iconSize); +} +var CanvasRenderer__prototype = CanvasRenderer.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ +CanvasRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) { + var ctx = this.l/*_ctx*/; + var iconSize = this.k/*iconSize*/; + + ctx.fillStyle = toCss3Color(fillColor); + ctx.fillRect(0, 0, iconSize, iconSize); +}; + +/** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} fillColor Fill color on format #rrggbb[aa]. + */ +CanvasRenderer__prototype.M/*beginShape*/ = function beginShape (fillColor) { + var ctx = this.l/*_ctx*/; + ctx.fillStyle = toCss3Color(fillColor); + ctx.beginPath(); +}; + +/** + * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas. + */ +CanvasRenderer__prototype.N/*endShape*/ = function endShape () { + this.l/*_ctx*/.fill(); +}; + +/** + * Adds a polygon to the rendering queue. + * @param points An array of Point objects. + */ +CanvasRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) { + var ctx = this.l/*_ctx*/; + ctx.moveTo(points[0].x, points[0].y); + for (var i = 1; i < points.length; i++) { + ctx.lineTo(points[i].x, points[i].y); + } + ctx.closePath(); +}; + +/** + * Adds a circle to the rendering queue. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ +CanvasRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) { + var ctx = this.l/*_ctx*/, + radius = diameter / 2; + ctx.moveTo(point.x + radius, point.y + radius); + ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise); + ctx.closePath(); +}; + +/** + * Called when the icon has been completely drawn. + */ +CanvasRenderer__prototype.finish = function finish () { + this.l/*_ctx*/.restore(); +}; + +/** + * Draws an identicon to a context. + * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0). + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function drawIcon(ctx, hashOrValue, size, config) { + if (!ctx) { + throw new Error("No canvas specified."); + } + + iconGenerator(new CanvasRenderer(ctx, size), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); +} + +/** + * Prepares a measure to be used as a measure in an SVG path, by + * rounding the measure to a single decimal. This reduces the file + * size of the generated SVG with more than 50% in some cases. + */ +function svgValue(value) { + return ((value * 10 + 0.5) | 0) / 10; +} + +/** + * Represents an SVG path element. + */ +function SvgPath() { + /** + * This property holds the data string (path.d) of the SVG path. + * @type {string} + */ + this.v/*dataString*/ = ""; +} +var SvgPath__prototype = SvgPath.prototype; + +/** + * Adds a polygon with the current fill color to the SVG path. + * @param points An array of Point objects. + */ +SvgPath__prototype.g/*addPolygon*/ = function addPolygon (points) { + var dataString = ""; + for (var i = 0; i < points.length; i++) { + dataString += (i ? "L" : "M") + svgValue(points[i].x) + " " + svgValue(points[i].y); + } + this.v/*dataString*/ += dataString + "Z"; +}; + +/** + * Adds a circle with the current fill color to the SVG path. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ +SvgPath__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) { + var sweepFlag = counterClockwise ? 0 : 1, + svgRadius = svgValue(diameter / 2), + svgDiameter = svgValue(diameter), + svgArc = "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " "; + + this.v/*dataString*/ += + "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) + + svgArc + svgDiameter + ",0" + + svgArc + (-svgDiameter) + ",0"; +}; + + + +/** + * Renderer producing SVG output. + * @implements {Renderer} + */ +function SvgRenderer(target) { + /** + * @type {SvgPath} + * @private + */ + this.A/*_path*/; + + /** + * @type {Object.} + * @private + */ + this.B/*_pathsByColor*/ = { }; + + /** + * @type {SvgElement|SvgWriter} + * @private + */ + this.O/*_target*/ = target; + + /** + * @type {number} + */ + this.k/*iconSize*/ = target.k/*iconSize*/; +} +var SvgRenderer__prototype = SvgRenderer.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ +SvgRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) { + var match = /^(#......)(..)?/.exec(fillColor), + opacity = match[2] ? parseHex(match[2], 0) / 255 : 1; + this.O/*_target*/.m/*setBackground*/(match[1], opacity); +}; + +/** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} color Fill color on format #xxxxxx. + */ +SvgRenderer__prototype.M/*beginShape*/ = function beginShape (color) { + this.A/*_path*/ = this.B/*_pathsByColor*/[color] || (this.B/*_pathsByColor*/[color] = new SvgPath()); +}; + +/** + * Marks the end of the currently drawn shape. + */ +SvgRenderer__prototype.N/*endShape*/ = function endShape () { }; + +/** + * Adds a polygon with the current fill color to the SVG. + * @param points An array of Point objects. + */ +SvgRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) { + this.A/*_path*/.g/*addPolygon*/(points); +}; + +/** + * Adds a circle with the current fill color to the SVG. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ +SvgRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) { + this.A/*_path*/.h/*addCircle*/(point, diameter, counterClockwise); +}; + +/** + * Called when the icon has been completely drawn. + */ +SvgRenderer__prototype.finish = function finish () { + var this$1 = this; + + var pathsByColor = this.B/*_pathsByColor*/; + for (var color in pathsByColor) { + // hasOwnProperty cannot be shadowed in pathsByColor + // eslint-disable-next-line no-prototype-builtins + if (pathsByColor.hasOwnProperty(color)) { + this$1.O/*_target*/.P/*appendPath*/(color, pathsByColor[color].v/*dataString*/); + } + } +}; + +var SVG_CONSTANTS = { + R/*XMLNS*/: "http://www.w3.org/2000/svg", + S/*WIDTH*/: "width", + T/*HEIGHT*/: "height", +}; + +/** + * Renderer producing SVG output. + */ +function SvgWriter(iconSize) { + /** + * @type {number} + */ + this.k/*iconSize*/ = iconSize; + + /** + * @type {string} + * @private + */ + this.C/*_s*/ = + ''; +} +var SvgWriter__prototype = SvgWriter.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ +SvgWriter__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) { + if (opacity) { + this.C/*_s*/ += ''; + } +}; + +/** + * Writes a path to the SVG string. + * @param {string} color Fill color on format #rrggbb. + * @param {string} dataString The SVG path data string. + */ +SvgWriter__prototype.P/*appendPath*/ = function appendPath (color, dataString) { + this.C/*_s*/ += ''; +}; + +/** + * Gets the rendered image as an SVG string. + */ +SvgWriter__prototype.toString = function toString () { + return this.C/*_s*/ + ""; +}; + +/** + * Draws an identicon as an SVG string. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + * @returns {string} SVG string + */ +function toSvg(hashOrValue, size, config) { + var writer = new SvgWriter(size); + iconGenerator(new SvgRenderer(writer), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); + return writer.toString(); +} + +var ICON_TYPE_SVG = 1; + +var ICON_TYPE_CANVAS = 2; + +var ATTRIBUTES = { + U/*HASH*/: "data-jdenticon-hash", + D/*VALUE*/: "data-jdenticon-value" +}; + +var ICON_SELECTOR = "[" + ATTRIBUTES.U/*HASH*/ +"],[" + ATTRIBUTES.D/*VALUE*/ +"]"; + +var documentQuerySelectorAll = /** @type {!Function} */ ( + typeof document !== "undefined" && document.querySelectorAll.bind(document)); + +function getIdenticonType(el) { + if (el) { + var tagName = el["tagName"]; + + if (/^svg$/i.test(tagName)) { + return ICON_TYPE_SVG; + } + + if (/^canvas$/i.test(tagName) && "getContext" in el) { + return ICON_TYPE_CANVAS; + } + } +} + +/** + * Creates a new element and adds it to the specified parent. + * @param {Element} parentNode + * @param {string} name + * @param {...(string|number)} keyValuePairs + */ +function SvgElement_append(parentNode, name) { + var keyValuePairs = [], len = arguments.length - 2; + while ( len-- > 0 ) keyValuePairs[ len ] = arguments[ len + 2 ]; + + var el = document.createElementNS(SVG_CONSTANTS.R/*XMLNS*/, name); + + for (var i = 0; i + 1 < keyValuePairs.length; i += 2) { + el.setAttribute( + /** @type {string} */(keyValuePairs[i]), + /** @type {string} */(keyValuePairs[i + 1]) + ); + } + + parentNode.appendChild(el); +} + + +/** + * Renderer producing SVG output. + */ +function SvgElement(element) { + // Don't use the clientWidth and clientHeight properties on SVG elements + // since Firefox won't serve a proper value of these properties on SVG + // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811) + // Instead use 100px as a hardcoded size (the svg viewBox will rescale + // the icon to the correct dimensions) + var iconSize = this.k/*iconSize*/ = Math.min( + (Number(element.getAttribute(SVG_CONSTANTS.S/*WIDTH*/)) || 100), + (Number(element.getAttribute(SVG_CONSTANTS.T/*HEIGHT*/)) || 100) + ); + + /** + * @type {Element} + * @private + */ + this.V/*_el*/ = element; + + // Clear current SVG child elements + while (element.firstChild) { + element.removeChild(element.firstChild); + } + + // Set viewBox attribute to ensure the svg scales nicely. + element.setAttribute("viewBox", "0 0 " + iconSize + " " + iconSize); + element.setAttribute("preserveAspectRatio", "xMidYMid meet"); +} +var SvgElement__prototype = SvgElement.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ +SvgElement__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) { + if (opacity) { + SvgElement_append(this.V/*_el*/, "rect", + SVG_CONSTANTS.S/*WIDTH*/, "100%", + SVG_CONSTANTS.T/*HEIGHT*/, "100%", + "fill", fillColor, + "opacity", opacity); + } +}; + +/** + * Appends a path to the SVG element. + * @param {string} color Fill color on format #xxxxxx. + * @param {string} dataString The SVG path data string. + */ +SvgElement__prototype.P/*appendPath*/ = function appendPath (color, dataString) { + SvgElement_append(this.V/*_el*/, "path", + "fill", color, + "d", dataString); +}; + +/** + * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute. + */ +function updateAll() { + if (documentQuerySelectorAll) { + update(ICON_SELECTOR); + } +} + +/** + * Updates the identicon in the specified `` or `` elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * `` or ``, or a CSS selector to such an element. + * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function update(el, hashOrValue, config) { + renderDomElement(el, hashOrValue, config, function (el, iconType) { + if (iconType) { + return iconType == ICON_TYPE_SVG ? + new SvgRenderer(new SvgElement(el)) : + new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext("2d")); + } + }); +} + +/** + * Updates the identicon in the specified `` elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * ``, or a CSS selector to such an element. + * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function updateCanvas(el, hashOrValue, config) { + renderDomElement(el, hashOrValue, config, function (el, iconType) { + if (iconType == ICON_TYPE_CANVAS) { + return new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext("2d")); + } + }); +} + +/** + * Updates the identicon in the specified `` elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * ``, or a CSS selector to such an element. + * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function updateSvg(el, hashOrValue, config) { + renderDomElement(el, hashOrValue, config, function (el, iconType) { + if (iconType == ICON_TYPE_SVG) { + return new SvgRenderer(new SvgElement(el)); + } + }); +} + +/** + * Updates the identicon in the specified canvas or svg elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * `` or ``, or a CSS selector to such an element. + * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number|undefined} config + * @param {function(Element,number):Renderer} rendererFactory - Factory function for creating an icon renderer. + */ +function renderDomElement(el, hashOrValue, config, rendererFactory) { + if (typeof el === "string") { + if (documentQuerySelectorAll) { + var elements = documentQuerySelectorAll(el); + for (var i = 0; i < elements.length; i++) { + renderDomElement(elements[i], hashOrValue, config, rendererFactory); + } + } + return; + } + + // Hash selection. The result from getValidHash or computeHash is + // accepted as a valid hash. + var hash = + // 1. Explicit valid hash + isValidHash(hashOrValue) || + + // 2. Explicit value (`!= null` catches both null and undefined) + hashOrValue != null && computeHash(hashOrValue) || + + // 3. `data-jdenticon-hash` attribute + isValidHash(el.getAttribute(ATTRIBUTES.U/*HASH*/)) || + + // 4. `data-jdenticon-value` attribute. + // We want to treat an empty attribute as an empty value. + // Some browsers return empty string even if the attribute + // is not specified, so use hasAttribute to determine if + // the attribute is specified. + el.hasAttribute(ATTRIBUTES.D/*VALUE*/) && computeHash(el.getAttribute(ATTRIBUTES.D/*VALUE*/)); + + if (!hash) { + // No hash specified. Don't render an icon. + return; + } + + var renderer = rendererFactory(el, getIdenticonType(el)); + if (renderer) { + // Draw icon + iconGenerator(renderer, hash, config); + } +} + +// This file is compiled to dist/jdenticon-module.js + +var jdenticon = updateAll; + +defineConfigProperty(jdenticon); + +// Export public API +jdenticon["configure"] = configure; +jdenticon["drawIcon"] = drawIcon; +jdenticon["toSvg"] = toSvg; +jdenticon["update"] = update; +jdenticon["updateCanvas"] = updateCanvas; +jdenticon["updateSvg"] = updateSvg; + +/** + * Specifies the version of the Jdenticon package in use. + * @type {string} + */ +jdenticon["version"] = "3.1.0"; + +/** + * Specifies which bundle of Jdenticon that is used. + * @type {string} + */ +jdenticon["bundle"] = "browser-cjs"; + +module.exports = jdenticon; +//# sourceMappingURL=jdenticon-module.js.map diff --git a/www/vendor/jdenticon-module.js.map b/www/vendor/jdenticon-module.js.map new file mode 100644 index 0000000..5b2caa9 --- /dev/null +++ b/www/vendor/jdenticon-module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["replacement/7","src/common/parseHex.js","src/renderer/color.js","src/common/global.js","src/common/configuration.js","src/renderer/point.js","src/renderer/transform.js","src/renderer/graphics.js","replacement/1","src/renderer/shapes.js","src/renderer/colorTheme.js","src/renderer/iconGenerator.js","src/common/sha1.js","src/common/hashUtils.js","src/renderer/canvas/canvasRenderer.js","replacement/2","src/apis/drawIcon.js","src/renderer/svg/svgPath.js","replacement/3","src/renderer/svg/svgRenderer.js","replacement/4","src/renderer/svg/constants.js","src/renderer/svg/svgWriter.js","replacement/5","src/apis/toSvg.js","src/common/dom.js","src/renderer/svg/svgElement.js","replacement/6","src/apis/update.js","src/browser-cjs.js","replacement/8"],"names":["let","const","GLOBAL","MODULE","hue","colorSaturation","grayscaleSaturation","colorLightness","grayscaleLightness","backColor","iconPadding","_x","_y","_size","_rotation","transformIconPoint","_renderer","currentTransform","addPolygon","this","addCircle","addRectangle","addTriangle","addRhombus","setBackground","iconSize","beginShape","endShape","_ctx","dataString","_path","_pathsByColor","_target","appendPath","XMLNS","WIDTH","HEIGHT","_s","HASH","VALUE","_el"],"mappings":"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","file":"jdenticon-module.js","sourcesContent":["/**\r\n * Jdenticon 3.1.0\r\n * http://jdenticon.com\r\n *\r\n * Built: 2020-12-12T13:51:48.709Z\r\n * \r\n * MIT License\r\n * \r\n * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi\r\n * \r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n * \r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n * \r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Parses a substring of the hash as a number.\r\n * @param {number} startPosition \r\n * @param {number=} octets\r\n */\r\nexport function parseHex(hash, startPosition, octets) {\r\n return parseInt(hash.substr(startPosition, octets), 16);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseHex } from \"../common/parseHex\";\r\n\r\nfunction decToHex(v) {\r\n v |= 0; // Ensure integer value\r\n return v < 0 ? \"00\" :\r\n v < 16 ? \"0\" + v.toString(16) :\r\n v < 256 ? v.toString(16) :\r\n \"ff\";\r\n}\r\n\r\nfunction hueToRgb(m1, m2, h) {\r\n h = h < 0 ? h + 6 : h > 6 ? h - 6 : h;\r\n return decToHex(255 * (\r\n h < 1 ? m1 + (m2 - m1) * h :\r\n h < 3 ? m2 :\r\n h < 4 ? m1 + (m2 - m1) * (4 - h) :\r\n m1));\r\n}\r\n\r\n/**\r\n * @param {number} r Red channel [0, 255]\r\n * @param {number} g Green channel [0, 255]\r\n * @param {number} b Blue channel [0, 255]\r\n */\r\nexport function rgb(r, g, b) {\r\n return \"#\" + decToHex(r) + decToHex(g) + decToHex(b);\r\n}\r\n\r\n/**\r\n * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.\r\n * @returns {string}\r\n */\r\nexport function parseColor(color) {\r\n if (/^#[0-9a-f]{3,8}$/i.test(color)) {\r\n let result;\r\n const colorLength = color.length;\r\n\r\n if (colorLength < 6) {\r\n const r = color[1],\r\n g = color[2],\r\n b = color[3],\r\n a = color[4] || \"\";\r\n result = \"#\" + r + r + g + g + b + b + a + a;\r\n }\r\n if (colorLength == 7 || colorLength > 8) {\r\n result = color;\r\n }\r\n \r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * Converts a hexadecimal color to a CSS3 compatible color.\r\n * @param {string} hexColor Color on the format \"#RRGGBB\" or \"#RRGGBBAA\"\r\n * @returns {string}\r\n */\r\nexport function toCss3Color(hexColor) {\r\n const a = parseHex(hexColor, 7, 2);\r\n let result;\r\n\r\n if (isNaN(a)) {\r\n result = hexColor;\r\n } else {\r\n const r = parseHex(hexColor, 1, 2),\r\n g = parseHex(hexColor, 3, 2),\r\n b = parseHex(hexColor, 5, 2);\r\n result = \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (a / 255).toFixed(2) + \")\";\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color.\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function hsl(hue, saturation, lightness) {\r\n // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color\r\n let result;\r\n\r\n if (saturation == 0) {\r\n const partialHex = decToHex(lightness * 255);\r\n result = partialHex + partialHex + partialHex;\r\n }\r\n else {\r\n const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation,\r\n m1 = lightness * 2 - m2;\r\n result =\r\n hueToRgb(m1, m2, hue * 6 + 2) +\r\n hueToRgb(m1, m2, hue * 6) +\r\n hueToRgb(m1, m2, hue * 6 - 2);\r\n }\r\n\r\n return \"#\" + result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the \"dark\" hues\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function correctedHsl(hue, saturation, lightness) {\r\n // The corrector specifies the perceived middle lightness for each hue\r\n const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],\r\n corrector = correctors[(hue * 6 + 0.5) | 0];\r\n \r\n // Adjust the input lightness relative to the corrector\r\n lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2;\r\n \r\n return hsl(hue, saturation, lightness);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for\r\n// backward compatibility.\r\n\r\nexport const GLOBAL = \r\n typeof window !== \"undefined\" ? window :\r\n typeof self !== \"undefined\" ? self :\r\n typeof global !== \"undefined\" ? global :\r\n {};\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseColor } from \"../renderer/color\";\r\nimport { GLOBAL } from \"./global\";\r\n\r\n/**\r\n * @typedef {Object} ParsedConfiguration\r\n * @property {number} colorSaturation\r\n * @property {number} grayscaleSaturation\r\n * @property {string} backColor\r\n * @property {number} iconPadding\r\n * @property {function(number):number} hue\r\n * @property {function(number):number} colorLightness\r\n * @property {function(number):number} grayscaleLightness\r\n */\r\n\r\nexport const CONFIG_PROPERTIES = {\r\n GLOBAL: \"jdenticon_config\",\r\n MODULE: \"config\",\r\n};\r\n\r\nvar rootConfigurationHolder = {};\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object. When the property is set a warning is \r\n * printed in the console. To minimize bundle size, this is only used in Node bundles.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigPropertyWithWarn(rootObject) {\r\n Object.defineProperty(rootObject, CONFIG_PROPERTIES.MODULE, {\r\n configurable: true,\r\n get: () => rootConfigurationHolder[CONFIG_PROPERTIES.MODULE],\r\n set: newConfiguration => {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n console.warn(\"jdenticon.config is deprecated. Use jdenticon.configure() instead.\");\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console\r\n * when it is being used.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigProperty(rootObject) {\r\n rootConfigurationHolder = rootObject;\r\n}\r\n\r\n/**\r\n * Sets a new icon style configuration. The new configuration is not merged with the previous one. * \r\n * @param {Object} newConfiguration - New configuration object.\r\n */\r\nexport function configure(newConfiguration) {\r\n if (arguments.length) {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n }\r\n return rootConfigurationHolder[CONFIG_PROPERTIES.MODULE];\r\n}\r\n\r\n/**\r\n * Gets the normalized current Jdenticon color configuration. Missing fields have default values.\r\n * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A\r\n * local configuration overrides the global configuration in it entirety. This parameter can for backward\r\n * compatibility also contain a padding value. A padding value only overrides the global padding, not the\r\n * entire global configuration.\r\n * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor\r\n * explicitly to the API method.\r\n * @returns {ParsedConfiguration}\r\n */\r\nexport function getConfiguration(paddingOrLocalConfig, defaultPadding) {\r\n const configObject = \r\n typeof paddingOrLocalConfig == \"object\" && paddingOrLocalConfig ||\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] ||\r\n GLOBAL[CONFIG_PROPERTIES.GLOBAL] ||\r\n { },\r\n\r\n lightnessConfig = configObject[\"lightness\"] || { },\r\n \r\n // In versions < 2.1.0 there was no grayscale saturation -\r\n // saturation was the color saturation.\r\n saturation = configObject[\"saturation\"] || { },\r\n colorSaturation = \"color\" in saturation ? saturation[\"color\"] : saturation,\r\n grayscaleSaturation = saturation[\"grayscale\"],\r\n\r\n backColor = configObject[\"backColor\"],\r\n padding = configObject[\"padding\"];\r\n \r\n /**\r\n * Creates a lightness range.\r\n */\r\n function lightness(configName, defaultRange) {\r\n let range = lightnessConfig[configName];\r\n \r\n // Check if the lightness range is an array-like object. This way we ensure the\r\n // array contain two values at the same time.\r\n if (!(range && range.length > 1)) {\r\n range = defaultRange;\r\n }\r\n\r\n /**\r\n * Gets a lightness relative the specified value in the specified lightness range.\r\n */\r\n return function (value) {\r\n value = range[0] + value * (range[1] - range[0]);\r\n return value < 0 ? 0 : value > 1 ? 1 : value;\r\n };\r\n }\r\n\r\n /**\r\n * Gets a hue allowed by the configured hue restriction,\r\n * provided the originally computed hue.\r\n */\r\n function hueFunction(originalHue) {\r\n const hueConfig = configObject[\"hues\"];\r\n let hue;\r\n \r\n // Check if 'hues' is an array-like object. This way we also ensure that\r\n // the array is not empty, which would mean no hue restriction.\r\n if (hueConfig && hueConfig.length > 0) {\r\n // originalHue is in the range [0, 1]\r\n // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.\r\n hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];\r\n }\r\n\r\n return typeof hue == \"number\" ?\r\n \r\n // A hue was specified. We need to convert the hue from\r\n // degrees on any turn - e.g. 746° is a perfectly valid hue -\r\n // to turns in the range [0, 1).\r\n ((((hue / 360) % 1) + 1) % 1) :\r\n\r\n // No hue configured => use original hue\r\n originalHue;\r\n }\r\n \r\n return {\r\n hue: hueFunction,\r\n colorSaturation: typeof colorSaturation == \"number\" ? colorSaturation : 0.5,\r\n grayscaleSaturation: typeof grayscaleSaturation == \"number\" ? grayscaleSaturation : 0,\r\n colorLightness: lightness(\"color\", [0.4, 0.8]),\r\n grayscaleLightness: lightness(\"grayscale\", [0.3, 0.9]),\r\n backColor: parseColor(backColor),\r\n iconPadding: \r\n typeof paddingOrLocalConfig == \"number\" ? paddingOrLocalConfig : \r\n typeof padding == \"number\" ? padding : \r\n defaultPadding\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Represents a point.\r\n */\r\nexport class Point {\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n */\r\n constructor(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Point } from \"./point\";\r\n\r\n/**\r\n * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, \r\n * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.\r\n */\r\nexport class Transform {\r\n /**\r\n * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} size The size of the transformed rectangle.\r\n * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad\r\n */\r\n constructor(x, y, size, rotation) {\r\n this._x = x;\r\n this._y = y;\r\n this._size = size;\r\n this._rotation = rotation;\r\n }\r\n\r\n /**\r\n * Transforms the specified point based on the translation and rotation specification for this Transform.\r\n * @param {number} x x-coordinate\r\n * @param {number} y y-coordinate\r\n * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n */\r\n transformIconPoint(x, y, w, h) {\r\n const right = this._x + this._size,\r\n bottom = this._y + this._size,\r\n rotation = this._rotation;\r\n return rotation === 1 ? new Point(right - y - (h || 0), this._y + x) :\r\n rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :\r\n rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) :\r\n new Point(this._x + x, this._y + y);\r\n }\r\n}\r\n\r\nexport const NO_TRANSFORM = new Transform(0, 0, 0, 0);\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { NO_TRANSFORM } from \"./transform\";\r\n\r\n/**\r\n * @typedef {import(\"./renderer\").Renderer} Renderer\r\n * @typedef {import(\"./transform\").Transform} Transform\r\n */\r\n\r\n/**\r\n * Provides helper functions for rendering common basic shapes.\r\n */\r\nexport class Graphics {\r\n /**\r\n * @param {Renderer} renderer \r\n */\r\n constructor(renderer) {\r\n /**\r\n * @type {Renderer}\r\n * @private\r\n */\r\n this._renderer = renderer;\r\n\r\n /**\r\n * @type {Transform}\r\n */\r\n this.currentTransform = NO_TRANSFORM;\r\n }\r\n\r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]\r\n * @param {boolean=} invert Specifies if the polygon will be inverted.\r\n */\r\n addPolygon(points, invert) {\r\n const di = invert ? -2 : 2,\r\n transformedPoints = [];\r\n \r\n for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {\r\n transformedPoints.push(this.currentTransform.transformIconPoint(points[i], points[i + 1]));\r\n }\r\n \r\n this._renderer.addPolygon(transformedPoints);\r\n }\r\n \r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * Source: http://stackoverflow.com/a/2173084\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} size The size of the ellipse.\r\n * @param {boolean=} invert Specifies if the ellipse will be inverted.\r\n */\r\n addCircle(x, y, size, invert) {\r\n const p = this.currentTransform.transformIconPoint(x, y, size, size);\r\n this._renderer.addCircle(p, size, invert);\r\n }\r\n\r\n /**\r\n * Adds a rectangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle.\r\n * @param {number} w The width of the rectangle.\r\n * @param {number} h The height of the rectangle.\r\n * @param {boolean=} invert Specifies if the rectangle will be inverted.\r\n */\r\n addRectangle(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x, y, \r\n x + w, y,\r\n x + w, y + h,\r\n x, y + h\r\n ], invert);\r\n }\r\n\r\n /**\r\n * Adds a right triangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} w The width of the triangle.\r\n * @param {number} h The height of the triangle.\r\n * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.\r\n * @param {boolean=} invert Specifies if the triangle will be inverted.\r\n */\r\n addTriangle(x, y, w, h, r, invert) {\r\n const points = [\r\n x + w, y, \r\n x + w, y + h, \r\n x, y + h,\r\n x, y\r\n ];\r\n points.splice(((r || 0) % 4) * 2, 2);\r\n this.addPolygon(points, invert);\r\n }\r\n\r\n /**\r\n * Adds a rhombus to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} w The width of the rhombus.\r\n * @param {number} h The height of the rhombus.\r\n * @param {boolean=} invert Specifies if the rhombus will be inverted.\r\n */\r\n addRhombus(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x + w / 2, y,\r\n x + w, y + h / 2,\r\n x + w / 2, y + h,\r\n x, y + h / 2\r\n ], invert);\r\n }\r\n}","\r\nvar Graphics__prototype = Graphics.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n * @param {number} positionIndex\r\n * @typedef {import('./graphics').Graphics} Graphics\r\n */\r\nexport function centerShape(index, g, cell, positionIndex) {\r\n index = index % 14;\r\n\r\n let k, m, w, h, inner, outer;\r\n\r\n !index ? (\r\n k = cell * 0.42,\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell - k * 2,\r\n cell - k, cell,\r\n 0, cell\r\n ])) :\r\n\r\n index == 1 ? (\r\n w = 0 | (cell * 0.5), \r\n h = 0 | (cell * 0.8),\r\n\r\n g.addTriangle(cell - w, 0, w, h, 2)) :\r\n\r\n index == 2 ? (\r\n w = 0 | (cell / 3),\r\n g.addRectangle(w, w, cell - w, cell - w)) :\r\n\r\n index == 3 ? (\r\n inner = cell * 0.1,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 6 ? 1 :\r\n cell < 8 ? 2 :\r\n (0 | (cell * 0.25)),\r\n \r\n inner = \r\n inner > 1 ? (0 | inner) : // large icon => truncate decimals\r\n inner > 0.5 ? 1 : // medium size icon => fixed width\r\n inner, // small icon => anti-aliased border\r\n\r\n g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer)) :\r\n\r\n index == 4 ? (\r\n m = 0 | (cell * 0.15),\r\n w = 0 | (cell * 0.5),\r\n g.addCircle(cell - w - m, cell - w - m, w)) :\r\n\r\n index == 5 ? (\r\n inner = cell * 0.1,\r\n outer = inner * 4,\r\n\r\n // Align edge to nearest pixel in large icons\r\n outer > 3 && (outer = 0 | outer),\r\n \r\n g.addRectangle(0, 0, cell, cell),\r\n g.addPolygon([\r\n outer, outer,\r\n cell - inner, outer,\r\n outer + (cell - outer - inner) / 2, cell - inner\r\n ], true)) :\r\n\r\n index == 6 ? \r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell * 0.7,\r\n cell * 0.4, cell * 0.4,\r\n cell * 0.7, cell,\r\n 0, cell\r\n ]) :\r\n\r\n index == 7 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 8 ? (\r\n g.addRectangle(0, 0, cell, cell / 2),\r\n g.addRectangle(0, cell / 2, cell / 2, cell / 2),\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1)) :\r\n\r\n index == 9 ? (\r\n inner = cell * 0.14,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 4 ? 1 :\r\n cell < 6 ? 2 :\r\n (0 | (cell * 0.35)),\r\n\r\n inner = \r\n cell < 8 ? inner : // small icon => anti-aliased border\r\n (0 | inner), // large icon => truncate decimals\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true)) :\r\n\r\n index == 10 ? (\r\n inner = cell * 0.12,\r\n outer = inner * 3,\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addCircle(outer, outer, cell - inner - outer, true)) :\r\n\r\n index == 11 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 12 ? (\r\n m = cell * 0.25,\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRhombus(m, m, cell - m, cell - m, true)) :\r\n\r\n // 13\r\n (\r\n !positionIndex && (\r\n m = cell * 0.4, w = cell * 1.2,\r\n g.addCircle(m, m, w)\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n */\r\nexport function outerShape(index, g, cell) {\r\n index = index % 4;\r\n\r\n let m;\r\n\r\n !index ?\r\n g.addTriangle(0, 0, cell, cell, 0) :\r\n \r\n index == 1 ?\r\n g.addTriangle(0, cell / 2, cell, cell / 2, 0) :\r\n\r\n index == 2 ?\r\n g.addRhombus(0, 0, cell, cell) :\r\n\r\n // 3\r\n (\r\n m = cell / 6,\r\n g.addCircle(m, m, cell - 2 * m)\r\n );\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { correctedHsl } from \"./color\";\r\n\r\n/**\r\n * Gets a set of identicon color candidates for a specified hue and config.\r\n * @param {number} hue\r\n * @param {import(\"../common/configuration\").ParsedConfiguration} config\r\n */\r\nexport function colorTheme(hue, config) {\r\n hue = config.hue(hue);\r\n return [\r\n // Dark gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)),\r\n // Mid color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)),\r\n // Light gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)),\r\n // Light color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(1)),\r\n // Dark color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0))\r\n ];\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Transform } from \"./transform\";\r\nimport { Graphics } from \"./graphics\";\r\nimport { centerShape, outerShape } from \"./shapes\";\r\nimport { colorTheme } from \"./colorTheme\";\r\nimport { parseHex } from \"../common/parseHex\";\r\nimport { getConfiguration } from \"../common/configuration\";\r\n \r\n/**\r\n * Draws an identicon to a specified renderer.\r\n * @param {import('./renderer').Renderer} renderer\r\n * @param {string} hash\r\n * @param {Object|number=} config\r\n */\r\nexport function iconGenerator(renderer, hash, config) {\r\n const parsedConfig = getConfiguration(config, 0.08);\r\n\r\n // Set background color\r\n if (parsedConfig.backColor) {\r\n renderer.setBackground(parsedConfig.backColor);\r\n }\r\n \r\n // Calculate padding and round to nearest integer\r\n let size = renderer.iconSize;\r\n const padding = (0.5 + size * parsedConfig.iconPadding) | 0;\r\n size -= padding * 2;\r\n \r\n const graphics = new Graphics(renderer);\r\n \r\n // Calculate cell size and ensure it is an integer\r\n const cell = 0 | (size / 4);\r\n \r\n // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon\r\n const x = 0 | (padding + size / 2 - cell * 2);\r\n const y = 0 | (padding + size / 2 - cell * 2);\r\n\r\n function renderShape(colorIndex, shapes, index, rotationIndex, positions) {\r\n const shapeIndex = parseHex(hash, index, 1);\r\n let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0;\r\n \r\n renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]);\r\n \r\n for (let i = 0; i < positions.length; i++) {\r\n graphics.currentTransform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);\r\n shapes(shapeIndex, graphics, cell, i);\r\n }\r\n \r\n renderer.endShape();\r\n }\r\n\r\n // AVAILABLE COLORS\r\n const hue = parseHex(hash, -7) / 0xfffffff,\r\n \r\n // Available colors for this icon\r\n availableColors = colorTheme(hue, parsedConfig),\r\n\r\n // The index of the selected colors\r\n selectedColorIndexes = [];\r\n\r\n let index;\r\n\r\n function isDuplicate(values) {\r\n if (values.indexOf(index) >= 0) {\r\n for (let i = 0; i < values.length; i++) {\r\n if (selectedColorIndexes.indexOf(values[i]) >= 0) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < 3; i++) {\r\n index = parseHex(hash, 8 + i, 1) % availableColors.length;\r\n if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo\r\n isDuplicate([2, 3])) { // Disallow light gray and light color combo\r\n index = 1;\r\n }\r\n selectedColorIndexes.push(index);\r\n }\r\n\r\n // ACTUAL RENDERING\r\n // Sides\r\n renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);\r\n // Corners\r\n renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);\r\n // Center\r\n renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);\r\n \r\n renderer.finish();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Computes a SHA1 hash for any value and returns it as a hexadecimal string.\r\n * \r\n * This function is optimized for minimal code size and rather short messages.\r\n * \r\n * @param {string} message \r\n */\r\nexport function sha1(message) {\r\n const HASH_SIZE_HALF_BYTES = 40;\r\n const BLOCK_SIZE_WORDS = 16;\r\n\r\n // Variables\r\n // `var` is used to be able to minimize the number of `var` keywords.\r\n var i = 0,\r\n f = 0,\r\n \r\n // Use `encodeURI` to UTF8 encode the message without any additional libraries\r\n // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky\r\n // since `unescape` is deprecated.\r\n urlEncodedMessage = encodeURI(message) + \"%80\", // trailing '1' bit padding\r\n \r\n // This can be changed to a preallocated Uint32Array array for greater performance and larger code size\r\n data = [],\r\n dataSize,\r\n \r\n hashBuffer = [],\r\n\r\n a = 0x67452301,\r\n b = 0xefcdab89,\r\n c = ~a,\r\n d = ~b,\r\n e = 0xc3d2e1f0,\r\n hash = [a, b, c, d, e],\r\n\r\n blockStartIndex = 0,\r\n hexHash = \"\";\r\n\r\n /**\r\n * Rotates the value a specified number of bits to the left.\r\n * @param {number} value Value to rotate\r\n * @param {number} shift Bit count to shift.\r\n */\r\n function rotl(value, shift) {\r\n return (value << shift) | (value >>> (32 - shift));\r\n }\r\n\r\n // Message data\r\n for ( ; i < urlEncodedMessage.length; f++) {\r\n data[f >> 2] = data[f >> 2] |\r\n (\r\n (\r\n urlEncodedMessage[i] == \"%\"\r\n // Percent encoded byte\r\n ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)\r\n // Unencoded byte\r\n : urlEncodedMessage.charCodeAt(i++)\r\n )\r\n\r\n // Read bytes in reverse order (big endian words)\r\n << ((3 - (f & 3)) * 8)\r\n );\r\n }\r\n\r\n // f is now the length of the utf8 encoded message\r\n // 7 = 8 bytes (64 bit) for message size, -1 to round down\r\n // >> 6 = integer division with block size\r\n dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;\r\n\r\n // Message size in bits.\r\n // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least\r\n // significant 32 bits are set. -8 is for the '1' bit padding byte.\r\n data[dataSize - 1] = f * 8 - 8;\r\n \r\n // Compute hash\r\n for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {\r\n for (i = 0; i < 80; i++) {\r\n f = rotl(a, 5) + e + (\r\n // Ch\r\n i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :\r\n \r\n // Parity\r\n i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :\r\n \r\n // Maj\r\n i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :\r\n \r\n // Parity\r\n (b ^ c ^ d) + 0xca62c1d6\r\n ) + ( \r\n hashBuffer[i] = i < BLOCK_SIZE_WORDS\r\n // Bitwise OR is used to coerse `undefined` to 0\r\n ? (data[blockStartIndex + i] | 0)\r\n : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)\r\n );\r\n\r\n e = d;\r\n d = c;\r\n c = rotl(b, 30);\r\n b = a;\r\n a = f;\r\n }\r\n\r\n hash[0] = a = ((hash[0] + a) | 0);\r\n hash[1] = b = ((hash[1] + b) | 0);\r\n hash[2] = c = ((hash[2] + c) | 0);\r\n hash[3] = d = ((hash[3] + d) | 0);\r\n hash[4] = e = ((hash[4] + e) | 0);\r\n }\r\n\r\n // Format hex hash\r\n for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {\r\n hexHash += (\r\n (\r\n // Get word (2^3 half-bytes per word)\r\n hash[i >> 3] >>>\r\n\r\n // Append half-bytes in reverse order\r\n ((7 - (i & 7)) * 4)\r\n ) \r\n // Clamp to half-byte\r\n & 0xf\r\n ).toString(16);\r\n }\r\n\r\n return hexHash;\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { sha1 } from \"./sha1\";\r\n\r\n/**\r\n * Inputs a value that might be a valid hash string for Jdenticon and returns it \r\n * if it is determined valid, otherwise a falsy value is returned.\r\n */\r\nexport function isValidHash(hashCandidate) {\r\n return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;\r\n}\r\n\r\n/**\r\n * Computes a hash for the specified value. Currently SHA1 is used. This function\r\n * always returns a valid hash.\r\n */\r\nexport function computeHash(value) {\r\n return sha1(value == null ? \"\" : \"\" + value);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { toCss3Color } from \"../color\";\r\n\r\n/**\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import('../point').Point} Point\r\n */\r\n\r\n/**\r\n * Renderer redirecting drawing commands to a canvas context.\r\n * @implements {Renderer}\r\n */\r\nexport class CanvasRenderer {\r\n /**\r\n * @param {number=} iconSize\r\n */\r\n constructor(ctx, iconSize) {\r\n const canvas = ctx.canvas; \r\n const width = canvas.width;\r\n const height = canvas.height;\r\n \r\n ctx.save();\r\n \r\n if (!iconSize) {\r\n iconSize = Math.min(width, height);\r\n \r\n ctx.translate(\r\n ((width - iconSize) / 2) | 0,\r\n ((height - iconSize) / 2) | 0);\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n this._ctx = ctx;\r\n this.iconSize = iconSize;\r\n \r\n ctx.clearRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const ctx = this._ctx;\r\n const iconSize = this.iconSize;\r\n\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.fillRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} fillColor Fill color on format #rrggbb[aa].\r\n */\r\n beginShape(fillColor) {\r\n const ctx = this._ctx;\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.beginPath();\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.\r\n */\r\n endShape() {\r\n this._ctx.fill();\r\n }\r\n\r\n /**\r\n * Adds a polygon to the rendering queue.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n const ctx = this._ctx;\r\n ctx.moveTo(points[0].x, points[0].y);\r\n for (let i = 1; i < points.length; i++) {\r\n ctx.lineTo(points[i].x, points[i].y);\r\n }\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Adds a circle to the rendering queue.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const ctx = this._ctx,\r\n radius = diameter / 2;\r\n ctx.moveTo(point.x + radius, point.y + radius);\r\n ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() {\r\n this._ctx.restore();\r\n }\r\n}\r\n","\r\nvar CanvasRenderer__prototype = CanvasRenderer.prototype;","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\n\r\n/**\r\n * Draws an identicon to a context.\r\n * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function drawIcon(ctx, hashOrValue, size, config) {\r\n if (!ctx) {\r\n throw new Error(\"No canvas specified.\");\r\n }\r\n \r\n iconGenerator(new CanvasRenderer(ctx, size), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue), \r\n config);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Prepares a measure to be used as a measure in an SVG path, by\r\n * rounding the measure to a single decimal. This reduces the file\r\n * size of the generated SVG with more than 50% in some cases.\r\n */\r\nfunction svgValue(value) {\r\n return ((value * 10 + 0.5) | 0) / 10;\r\n}\r\n\r\n/**\r\n * Represents an SVG path element.\r\n */\r\nexport class SvgPath {\r\n constructor() {\r\n /**\r\n * This property holds the data string (path.d) of the SVG path.\r\n * @type {string}\r\n */\r\n this.dataString = \"\";\r\n }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG path.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n let dataString = \"\";\r\n for (let i = 0; i < points.length; i++) {\r\n dataString += (i ? \"L\" : \"M\") + svgValue(points[i].x) + \" \" + svgValue(points[i].y);\r\n }\r\n this.dataString += dataString + \"Z\";\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG path.\r\n * @param {import('../point').Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const sweepFlag = counterClockwise ? 0 : 1,\r\n svgRadius = svgValue(diameter / 2),\r\n svgDiameter = svgValue(diameter),\r\n svgArc = \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \";\r\n \r\n this.dataString += \r\n \"M\" + svgValue(point.x) + \" \" + svgValue(point.y + diameter / 2) +\r\n svgArc + svgDiameter + \",0\" + \r\n svgArc + (-svgDiameter) + \",0\";\r\n }\r\n}\r\n\r\n","\r\nvar SvgPath__prototype = SvgPath.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SvgPath } from \"./svgPath\";\r\nimport { parseHex } from \"../../common/parseHex\";\r\n\r\n/**\r\n * @typedef {import(\"../point\").Point} Point\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import(\"./svgElement\").SvgElement} SvgElement\r\n * @typedef {import(\"./svgWriter\").SvgWriter} SvgWriter\r\n */\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @implements {Renderer}\r\n */\r\nexport class SvgRenderer {\r\n /**\r\n * @param {SvgElement|SvgWriter} target \r\n */\r\n constructor(target) {\r\n /**\r\n * @type {SvgPath}\r\n * @private\r\n */\r\n this._path;\r\n\r\n /**\r\n * @type {Object.}\r\n * @private\r\n */\r\n this._pathsByColor = { };\r\n\r\n /**\r\n * @type {SvgElement|SvgWriter}\r\n * @private\r\n */\r\n this._target = target;\r\n\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = target.iconSize;\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const match = /^(#......)(..)?/.exec(fillColor),\r\n opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;\r\n this._target.setBackground(match[1], opacity);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n */\r\n beginShape(color) {\r\n this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath());\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape.\r\n */\r\n endShape() { }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n this._path.addPolygon(points);\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n this._path.addCircle(point, diameter, counterClockwise);\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() { \r\n const pathsByColor = this._pathsByColor;\r\n for (let color in pathsByColor) {\r\n // hasOwnProperty cannot be shadowed in pathsByColor\r\n // eslint-disable-next-line no-prototype-builtins\r\n if (pathsByColor.hasOwnProperty(color)) {\r\n this._target.appendPath(color, pathsByColor[color].dataString);\r\n }\r\n }\r\n }\r\n}\r\n","\r\nvar SvgRenderer__prototype = SvgRenderer.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const SVG_CONSTANTS = {\r\n XMLNS: \"http://www.w3.org/2000/svg\",\r\n WIDTH: \"width\",\r\n HEIGHT: \"height\",\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgWriter {\r\n /**\r\n * @param {number} iconSize - Icon width and height in pixels.\r\n */\r\n constructor(iconSize) {\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = iconSize;\r\n\r\n /**\r\n * @type {string}\r\n * @private\r\n */\r\n this._s =\r\n '';\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n this._s += '';\r\n }\r\n }\r\n\r\n /**\r\n * Writes a path to the SVG string.\r\n * @param {string} color Fill color on format #rrggbb.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n this._s += '';\r\n }\r\n\r\n /**\r\n * Gets the rendered image as an SVG string.\r\n */\r\n toString() {\r\n return this._s + \"\";\r\n }\r\n}\r\n","\r\nvar SvgWriter__prototype = SvgWriter.prototype;","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgWriter } from \"../renderer/svg/svgWriter\";\r\n\r\n/**\r\n * Draws an identicon as an SVG string.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n * @returns {string} SVG string\r\n */\r\nexport function toSvg(hashOrValue, size, config) {\r\n const writer = new SvgWriter(size);\r\n iconGenerator(new SvgRenderer(writer), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue),\r\n config);\r\n return writer.toString();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const ICON_TYPE_SVG = 1;\r\n\r\nexport const ICON_TYPE_CANVAS = 2;\r\n\r\nexport const ATTRIBUTES = {\r\n HASH: \"data-jdenticon-hash\",\r\n VALUE: \"data-jdenticon-value\"\r\n};\r\n\r\nexport const ICON_SELECTOR = \"[\" + ATTRIBUTES.HASH +\"],[\" + ATTRIBUTES.VALUE +\"]\";\r\n\r\nexport const documentQuerySelectorAll = /** @type {!Function} */ (\r\n typeof document !== \"undefined\" && document.querySelectorAll.bind(document));\r\n\r\nexport function getIdenticonType(el) {\r\n if (el) {\r\n const tagName = el[\"tagName\"];\r\n\r\n if (/^svg$/i.test(tagName)) {\r\n return ICON_TYPE_SVG;\r\n }\r\n\r\n if (/^canvas$/i.test(tagName) && \"getContext\" in el) {\r\n return ICON_TYPE_CANVAS;\r\n }\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Creates a new element and adds it to the specified parent.\r\n * @param {Element} parentNode\r\n * @param {string} name\r\n * @param {...(string|number)} keyValuePairs\r\n */\r\nfunction SvgElement_append(parentNode, name, ...keyValuePairs) {\r\n const el = document.createElementNS(SVG_CONSTANTS.XMLNS, name);\r\n \r\n for (let i = 0; i + 1 < keyValuePairs.length; i += 2) {\r\n el.setAttribute(\r\n /** @type {string} */(keyValuePairs[i]),\r\n /** @type {string} */(keyValuePairs[i + 1]),\r\n );\r\n }\r\n\r\n parentNode.appendChild(el);\r\n}\r\n\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgElement {\r\n /**\r\n * @param {Element} element - Target element\r\n */\r\n constructor(element) {\r\n // Don't use the clientWidth and clientHeight properties on SVG elements\r\n // since Firefox won't serve a proper value of these properties on SVG\r\n // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811)\r\n // Instead use 100px as a hardcoded size (the svg viewBox will rescale \r\n // the icon to the correct dimensions)\r\n const iconSize = this.iconSize = Math.min(\r\n (Number(element.getAttribute(SVG_CONSTANTS.WIDTH)) || 100),\r\n (Number(element.getAttribute(SVG_CONSTANTS.HEIGHT)) || 100)\r\n );\r\n \r\n /**\r\n * @type {Element}\r\n * @private\r\n */\r\n this._el = element;\r\n \r\n // Clear current SVG child elements\r\n while (element.firstChild) {\r\n element.removeChild(element.firstChild);\r\n }\r\n \r\n // Set viewBox attribute to ensure the svg scales nicely.\r\n element.setAttribute(\"viewBox\", \"0 0 \" + iconSize + \" \" + iconSize);\r\n element.setAttribute(\"preserveAspectRatio\", \"xMidYMid meet\");\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n SvgElement_append(this._el, \"rect\",\r\n SVG_CONSTANTS.WIDTH, \"100%\",\r\n SVG_CONSTANTS.HEIGHT, \"100%\",\r\n \"fill\", fillColor,\r\n \"opacity\", opacity);\r\n }\r\n }\r\n\r\n /**\r\n * Appends a path to the SVG element.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n SvgElement_append(this._el, \"path\",\r\n \"fill\", color,\r\n \"d\", dataString);\r\n }\r\n}\r\n","\r\nvar SvgElement__prototype = SvgElement.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { ATTRIBUTES, ICON_SELECTOR, documentQuerySelectorAll } from \"../common/dom\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgElement } from \"../renderer/svg/svgElement\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\nimport { ICON_TYPE_CANVAS, ICON_TYPE_SVG, getIdenticonType } from \"../common/dom\";\r\n\r\n\r\n/**\r\n * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute.\r\n */\r\nexport function updateAll() {\r\n if (documentQuerySelectorAll) {\r\n update(ICON_SELECTOR);\r\n }\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` or `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * `` or ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function update(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType) {\r\n return iconType == ICON_TYPE_SVG ? \r\n new SvgRenderer(new SvgElement(el)) : \r\n new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext(\"2d\"));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function updateCanvas(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType == ICON_TYPE_CANVAS) {\r\n return new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext(\"2d\"));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function updateSvg(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType == ICON_TYPE_SVG) {\r\n return new SvgRenderer(new SvgElement(el));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified canvas or svg elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * `` or ``, or a CSS selector to such an element.\r\n * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number|undefined} config\r\n * @param {function(Element,number):import(\"../renderer/renderer\").Renderer} rendererFactory - Factory function for creating an icon renderer.\r\n */\r\nfunction renderDomElement(el, hashOrValue, config, rendererFactory) {\r\n if (typeof el === \"string\") {\r\n if (documentQuerySelectorAll) {\r\n const elements = documentQuerySelectorAll(el);\r\n for (let i = 0; i < elements.length; i++) {\r\n renderDomElement(elements[i], hashOrValue, config, rendererFactory);\r\n }\r\n }\r\n return;\r\n }\r\n \r\n // Hash selection. The result from getValidHash or computeHash is \r\n // accepted as a valid hash.\r\n const hash = \r\n // 1. Explicit valid hash\r\n isValidHash(hashOrValue) ||\r\n \r\n // 2. Explicit value (`!= null` catches both null and undefined)\r\n hashOrValue != null && computeHash(hashOrValue) ||\r\n \r\n // 3. `data-jdenticon-hash` attribute\r\n isValidHash(el.getAttribute(ATTRIBUTES.HASH)) ||\r\n \r\n // 4. `data-jdenticon-value` attribute. \r\n // We want to treat an empty attribute as an empty value. \r\n // Some browsers return empty string even if the attribute \r\n // is not specified, so use hasAttribute to determine if \r\n // the attribute is specified.\r\n el.hasAttribute(ATTRIBUTES.VALUE) && computeHash(el.getAttribute(ATTRIBUTES.VALUE));\r\n \r\n if (!hash) {\r\n // No hash specified. Don't render an icon.\r\n return;\r\n }\r\n \r\n const renderer = rendererFactory(el, getIdenticonType(el));\r\n if (renderer) {\r\n // Draw icon\r\n iconGenerator(renderer, hash, config);\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// This file is compiled to dist/jdenticon-module.js\r\n\r\nimport { defineConfigProperty } from \"./common/configuration\";\r\nimport { configure } from \"./apis/configure\";\r\nimport { drawIcon } from \"./apis/drawIcon\";\r\nimport { toSvg } from \"./apis/toSvg\";\r\nimport { update, updateAll, updateCanvas, updateSvg } from \"./apis/update\";\r\n\r\nconst jdenticon = updateAll;\r\n\r\ndefineConfigProperty(jdenticon);\r\n\r\n// Export public API\r\njdenticon[\"configure\"] = configure;\r\njdenticon[\"drawIcon\"] = drawIcon;\r\njdenticon[\"toSvg\"] = toSvg;\r\njdenticon[\"update\"] = update;\r\njdenticon[\"updateCanvas\"] = updateCanvas;\r\njdenticon[\"updateSvg\"] = updateSvg;\r\n\r\n/**\r\n * Specifies the version of the Jdenticon package in use.\r\n * @type {string}\r\n */\r\njdenticon[\"version\"] = \"#version#\";\r\n\r\n/**\r\n * Specifies which bundle of Jdenticon that is used.\r\n * @type {string}\r\n */\r\njdenticon[\"bundle\"] = \"browser-cjs\";\r\n\r\nmodule.exports = jdenticon;","\n//# sourceMappingURL=jdenticon-module.js.map\n"]} \ No newline at end of file diff --git a/www/vendor/jdenticon-module.mjs b/www/vendor/jdenticon-module.mjs new file mode 100644 index 0000000..9a2312d --- /dev/null +++ b/www/vendor/jdenticon-module.mjs @@ -0,0 +1,1391 @@ +/** + * Jdenticon 3.1.0 + * http://jdenticon.com + * + * Built: 2020-12-12T13:51:48.709Z + * + * MIT License + * + * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Parses a substring of the hash as a number. + * @param {number} startPosition + * @param {number=} octets + */ +function parseHex(hash, startPosition, octets) { + return parseInt(hash.substr(startPosition, octets), 16); +} + +function decToHex(v) { + v |= 0; // Ensure integer value + return v < 0 ? "00" : + v < 16 ? "0" + v.toString(16) : + v < 256 ? v.toString(16) : + "ff"; +} + +function hueToRgb(m1, m2, h) { + h = h < 0 ? h + 6 : h > 6 ? h - 6 : h; + return decToHex(255 * ( + h < 1 ? m1 + (m2 - m1) * h : + h < 3 ? m2 : + h < 4 ? m1 + (m2 - m1) * (4 - h) : + m1)); +} + +/** + * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported. + * @returns {string} + */ +function parseColor(color) { + if (/^#[0-9a-f]{3,8}$/i.test(color)) { + let result; + const colorLength = color.length; + + if (colorLength < 6) { + const r = color[1], + g = color[2], + b = color[3], + a = color[4] || ""; + result = "#" + r + r + g + g + b + b + a + a; + } + if (colorLength == 7 || colorLength > 8) { + result = color; + } + + return result; + } +} + +/** + * Converts a hexadecimal color to a CSS3 compatible color. + * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA" + * @returns {string} + */ +function toCss3Color(hexColor) { + const a = parseHex(hexColor, 7, 2); + let result; + + if (isNaN(a)) { + result = hexColor; + } else { + const r = parseHex(hexColor, 1, 2), + g = parseHex(hexColor, 3, 2), + b = parseHex(hexColor, 5, 2); + result = "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")"; + } + + return result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function hsl(hue, saturation, lightness) { + // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color + let result; + + if (saturation == 0) { + const partialHex = decToHex(lightness * 255); + result = partialHex + partialHex + partialHex; + } + else { + const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation, + m1 = lightness * 2 - m2; + result = + hueToRgb(m1, m2, hue * 6 + 2) + + hueToRgb(m1, m2, hue * 6) + + hueToRgb(m1, m2, hue * 6 - 2); + } + + return "#" + result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the "dark" hues + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function correctedHsl(hue, saturation, lightness) { + // The corrector specifies the perceived middle lightness for each hue + const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ], + corrector = correctors[(hue * 6 + 0.5) | 0]; + + // Adjust the input lightness relative to the corrector + lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2; + + return hsl(hue, saturation, lightness); +} + +// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for +// backward compatibility. + +const GLOBAL = + typeof window !== "undefined" ? window : + typeof self !== "undefined" ? self : + typeof global !== "undefined" ? global : + {}; + +/** + * @typedef {Object} ParsedConfiguration + * @property {number} colorSaturation + * @property {number} grayscaleSaturation + * @property {string} backColor + * @property {number} iconPadding + * @property {function(number):number} hue + * @property {function(number):number} colorLightness + * @property {function(number):number} grayscaleLightness + */ + +const CONFIG_PROPERTIES = { + V/*GLOBAL*/: "jdenticon_config", + n/*MODULE*/: "config", +}; + +var rootConfigurationHolder = {}; + +/** + * Sets a new icon style configuration. The new configuration is not merged with the previous one. * + * @param {Object} newConfiguration - New configuration object. + */ +function configure(newConfiguration) { + if (arguments.length) { + rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] = newConfiguration; + } + return rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/]; +} + +/** + * Gets the normalized current Jdenticon color configuration. Missing fields have default values. + * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A + * local configuration overrides the global configuration in it entirety. This parameter can for backward + * compatibility also contain a padding value. A padding value only overrides the global padding, not the + * entire global configuration. + * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor + * explicitly to the API method. + * @returns {ParsedConfiguration} + */ +function getConfiguration(paddingOrLocalConfig, defaultPadding) { + const configObject = + typeof paddingOrLocalConfig == "object" && paddingOrLocalConfig || + rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] || + GLOBAL[CONFIG_PROPERTIES.V/*GLOBAL*/] || + { }, + + lightnessConfig = configObject["lightness"] || { }, + + // In versions < 2.1.0 there was no grayscale saturation - + // saturation was the color saturation. + saturation = configObject["saturation"] || { }, + colorSaturation = "color" in saturation ? saturation["color"] : saturation, + grayscaleSaturation = saturation["grayscale"], + + backColor = configObject["backColor"], + padding = configObject["padding"]; + + /** + * Creates a lightness range. + */ + function lightness(configName, defaultRange) { + let range = lightnessConfig[configName]; + + // Check if the lightness range is an array-like object. This way we ensure the + // array contain two values at the same time. + if (!(range && range.length > 1)) { + range = defaultRange; + } + + /** + * Gets a lightness relative the specified value in the specified lightness range. + */ + return function (value) { + value = range[0] + value * (range[1] - range[0]); + return value < 0 ? 0 : value > 1 ? 1 : value; + }; + } + + /** + * Gets a hue allowed by the configured hue restriction, + * provided the originally computed hue. + */ + function hueFunction(originalHue) { + const hueConfig = configObject["hues"]; + let hue; + + // Check if 'hues' is an array-like object. This way we also ensure that + // the array is not empty, which would mean no hue restriction. + if (hueConfig && hueConfig.length > 0) { + // originalHue is in the range [0, 1] + // Multiply with 0.999 to change the range to [0, 1) and then truncate the index. + hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)]; + } + + return typeof hue == "number" ? + + // A hue was specified. We need to convert the hue from + // degrees on any turn - e.g. 746° is a perfectly valid hue - + // to turns in the range [0, 1). + ((((hue / 360) % 1) + 1) % 1) : + + // No hue configured => use original hue + originalHue; + } + + return { + W/*hue*/: hueFunction, + o/*colorSaturation*/: typeof colorSaturation == "number" ? colorSaturation : 0.5, + D/*grayscaleSaturation*/: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0, + p/*colorLightness*/: lightness("color", [0.4, 0.8]), + F/*grayscaleLightness*/: lightness("grayscale", [0.3, 0.9]), + G/*backColor*/: parseColor(backColor), + X/*iconPadding*/: + typeof paddingOrLocalConfig == "number" ? paddingOrLocalConfig : + typeof padding == "number" ? padding : + defaultPadding + } +} + +/** + * Represents a point. + */ +class Point { + /** + * @param {number} x + * @param {number} y + */ + constructor(x, y) { + this.x = x; + this.y = y; + } +} + +/** + * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, + * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly. + */ +class Transform { + /** + * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle. + * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle. + * @param {number} size The size of the transformed rectangle. + * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad + */ + constructor(x, y, size, rotation) { + this.q/*_x*/ = x; + this.t/*_y*/ = y; + this.H/*_size*/ = size; + this.Y/*_rotation*/ = rotation; + } + + /** + * Transforms the specified point based on the translation and rotation specification for this Transform. + * @param {number} x x-coordinate + * @param {number} y y-coordinate + * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + */ + I/*transformIconPoint*/(x, y, w, h) { + const right = this.q/*_x*/ + this.H/*_size*/, + bottom = this.t/*_y*/ + this.H/*_size*/, + rotation = this.Y/*_rotation*/; + return rotation === 1 ? new Point(right - y - (h || 0), this.t/*_y*/ + x) : + rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) : + rotation === 3 ? new Point(this.q/*_x*/ + y, bottom - x - (w || 0)) : + new Point(this.q/*_x*/ + x, this.t/*_y*/ + y); + } +} + +const NO_TRANSFORM = new Transform(0, 0, 0, 0); + + + +/** + * Provides helper functions for rendering common basic shapes. + */ +class Graphics { + /** + * @param {Renderer} renderer + */ + constructor(renderer) { + /** + * @type {Renderer} + * @private + */ + this.J/*_renderer*/ = renderer; + + /** + * @type {Transform} + */ + this.u/*currentTransform*/ = NO_TRANSFORM; + } + + /** + * Adds a polygon to the underlying renderer. + * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ] + * @param {boolean=} invert Specifies if the polygon will be inverted. + */ + g/*addPolygon*/(points, invert) { + const di = invert ? -2 : 2, + transformedPoints = []; + + for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) { + transformedPoints.push(this.u/*currentTransform*/.I/*transformIconPoint*/(points[i], points[i + 1])); + } + + this.J/*_renderer*/.g/*addPolygon*/(transformedPoints); + } + + /** + * Adds a polygon to the underlying renderer. + * Source: http://stackoverflow.com/a/2173084 + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} size The size of the ellipse. + * @param {boolean=} invert Specifies if the ellipse will be inverted. + */ + h/*addCircle*/(x, y, size, invert) { + const p = this.u/*currentTransform*/.I/*transformIconPoint*/(x, y, size, size); + this.J/*_renderer*/.h/*addCircle*/(p, size, invert); + } + + /** + * Adds a rectangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle. + * @param {number} w The width of the rectangle. + * @param {number} h The height of the rectangle. + * @param {boolean=} invert Specifies if the rectangle will be inverted. + */ + i/*addRectangle*/(x, y, w, h, invert) { + this.g/*addPolygon*/([ + x, y, + x + w, y, + x + w, y + h, + x, y + h + ], invert); + } + + /** + * Adds a right triangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} w The width of the triangle. + * @param {number} h The height of the triangle. + * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle. + * @param {boolean=} invert Specifies if the triangle will be inverted. + */ + j/*addTriangle*/(x, y, w, h, r, invert) { + const points = [ + x + w, y, + x + w, y + h, + x, y + h, + x, y + ]; + points.splice(((r || 0) % 4) * 2, 2); + this.g/*addPolygon*/(points, invert); + } + + /** + * Adds a rhombus to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} w The width of the rhombus. + * @param {number} h The height of the rhombus. + * @param {boolean=} invert Specifies if the rhombus will be inverted. + */ + K/*addRhombus*/(x, y, w, h, invert) { + this.g/*addPolygon*/([ + x + w / 2, y, + x + w, y + h / 2, + x + w / 2, y + h, + x, y + h / 2 + ], invert); + } +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + * @param {number} positionIndex + */ +function centerShape(index, g, cell, positionIndex) { + index = index % 14; + + let k, m, w, h, inner, outer; + + !index ? ( + k = cell * 0.42, + g.g/*addPolygon*/([ + 0, 0, + cell, 0, + cell, cell - k * 2, + cell - k, cell, + 0, cell + ])) : + + index == 1 ? ( + w = 0 | (cell * 0.5), + h = 0 | (cell * 0.8), + + g.j/*addTriangle*/(cell - w, 0, w, h, 2)) : + + index == 2 ? ( + w = 0 | (cell / 3), + g.i/*addRectangle*/(w, w, cell - w, cell - w)) : + + index == 3 ? ( + inner = cell * 0.1, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 6 ? 1 : + cell < 8 ? 2 : + (0 | (cell * 0.25)), + + inner = + inner > 1 ? (0 | inner) : // large icon => truncate decimals + inner > 0.5 ? 1 : // medium size icon => fixed width + inner, // small icon => anti-aliased border + + g.i/*addRectangle*/(outer, outer, cell - inner - outer, cell - inner - outer)) : + + index == 4 ? ( + m = 0 | (cell * 0.15), + w = 0 | (cell * 0.5), + g.h/*addCircle*/(cell - w - m, cell - w - m, w)) : + + index == 5 ? ( + inner = cell * 0.1, + outer = inner * 4, + + // Align edge to nearest pixel in large icons + outer > 3 && (outer = 0 | outer), + + g.i/*addRectangle*/(0, 0, cell, cell), + g.g/*addPolygon*/([ + outer, outer, + cell - inner, outer, + outer + (cell - outer - inner) / 2, cell - inner + ], true)) : + + index == 6 ? + g.g/*addPolygon*/([ + 0, 0, + cell, 0, + cell, cell * 0.7, + cell * 0.4, cell * 0.4, + cell * 0.7, cell, + 0, cell + ]) : + + index == 7 ? + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 8 ? ( + g.i/*addRectangle*/(0, 0, cell, cell / 2), + g.i/*addRectangle*/(0, cell / 2, cell / 2, cell / 2), + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 1)) : + + index == 9 ? ( + inner = cell * 0.14, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 4 ? 1 : + cell < 6 ? 2 : + (0 | (cell * 0.35)), + + inner = + cell < 8 ? inner : // small icon => anti-aliased border + (0 | inner), // large icon => truncate decimals + + g.i/*addRectangle*/(0, 0, cell, cell), + g.i/*addRectangle*/(outer, outer, cell - outer - inner, cell - outer - inner, true)) : + + index == 10 ? ( + inner = cell * 0.12, + outer = inner * 3, + + g.i/*addRectangle*/(0, 0, cell, cell), + g.h/*addCircle*/(outer, outer, cell - inner - outer, true)) : + + index == 11 ? + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 12 ? ( + m = cell * 0.25, + g.i/*addRectangle*/(0, 0, cell, cell), + g.K/*addRhombus*/(m, m, cell - m, cell - m, true)) : + + // 13 + ( + !positionIndex && ( + m = cell * 0.4, w = cell * 1.2, + g.h/*addCircle*/(m, m, w) + ) + ); +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + */ +function outerShape(index, g, cell) { + index = index % 4; + + let m; + + !index ? + g.j/*addTriangle*/(0, 0, cell, cell, 0) : + + index == 1 ? + g.j/*addTriangle*/(0, cell / 2, cell, cell / 2, 0) : + + index == 2 ? + g.K/*addRhombus*/(0, 0, cell, cell) : + + // 3 + ( + m = cell / 6, + g.h/*addCircle*/(m, m, cell - 2 * m) + ); +} + +/** + * Gets a set of identicon color candidates for a specified hue and config. + * @param {number} hue + * @param {ParsedConfiguration} config + */ +function colorTheme(hue, config) { + hue = config.W/*hue*/(hue); + return [ + // Dark gray + correctedHsl(hue, config.D/*grayscaleSaturation*/, config.F/*grayscaleLightness*/(0)), + // Mid color + correctedHsl(hue, config.o/*colorSaturation*/, config.p/*colorLightness*/(0.5)), + // Light gray + correctedHsl(hue, config.D/*grayscaleSaturation*/, config.F/*grayscaleLightness*/(1)), + // Light color + correctedHsl(hue, config.o/*colorSaturation*/, config.p/*colorLightness*/(1)), + // Dark color + correctedHsl(hue, config.o/*colorSaturation*/, config.p/*colorLightness*/(0)) + ]; +} + +/** + * Draws an identicon to a specified renderer. + * @param {Renderer} renderer + * @param {string} hash + * @param {Object|number=} config + */ +function iconGenerator(renderer, hash, config) { + const parsedConfig = getConfiguration(config, 0.08); + + // Set background color + if (parsedConfig.G/*backColor*/) { + renderer.m/*setBackground*/(parsedConfig.G/*backColor*/); + } + + // Calculate padding and round to nearest integer + let size = renderer.k/*iconSize*/; + const padding = (0.5 + size * parsedConfig.X/*iconPadding*/) | 0; + size -= padding * 2; + + const graphics = new Graphics(renderer); + + // Calculate cell size and ensure it is an integer + const cell = 0 | (size / 4); + + // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon + const x = 0 | (padding + size / 2 - cell * 2); + const y = 0 | (padding + size / 2 - cell * 2); + + function renderShape(colorIndex, shapes, index, rotationIndex, positions) { + const shapeIndex = parseHex(hash, index, 1); + let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0; + + renderer.L/*beginShape*/(availableColors[selectedColorIndexes[colorIndex]]); + + for (let i = 0; i < positions.length; i++) { + graphics.u/*currentTransform*/ = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4); + shapes(shapeIndex, graphics, cell, i); + } + + renderer.M/*endShape*/(); + } + + // AVAILABLE COLORS + const hue = parseHex(hash, -7) / 0xfffffff, + + // Available colors for this icon + availableColors = colorTheme(hue, parsedConfig), + + // The index of the selected colors + selectedColorIndexes = []; + + let index; + + function isDuplicate(values) { + if (values.indexOf(index) >= 0) { + for (let i = 0; i < values.length; i++) { + if (selectedColorIndexes.indexOf(values[i]) >= 0) { + return true; + } + } + } + } + + for (let i = 0; i < 3; i++) { + index = parseHex(hash, 8 + i, 1) % availableColors.length; + if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo + isDuplicate([2, 3])) { // Disallow light gray and light color combo + index = 1; + } + selectedColorIndexes.push(index); + } + + // ACTUAL RENDERING + // Sides + renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]); + // Corners + renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]); + // Center + renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]); + + renderer.finish(); +} + +/** + * Computes a SHA1 hash for any value and returns it as a hexadecimal string. + * + * This function is optimized for minimal code size and rather short messages. + * + * @param {string} message + */ +function sha1(message) { + const HASH_SIZE_HALF_BYTES = 40; + const BLOCK_SIZE_WORDS = 16; + + // Variables + // `var` is used to be able to minimize the number of `var` keywords. + var i = 0, + f = 0, + + // Use `encodeURI` to UTF8 encode the message without any additional libraries + // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky + // since `unescape` is deprecated. + urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding + + // This can be changed to a preallocated Uint32Array array for greater performance and larger code size + data = [], + dataSize, + + hashBuffer = [], + + a = 0x67452301, + b = 0xefcdab89, + c = ~a, + d = ~b, + e = 0xc3d2e1f0, + hash = [a, b, c, d, e], + + blockStartIndex = 0, + hexHash = ""; + + /** + * Rotates the value a specified number of bits to the left. + * @param {number} value Value to rotate + * @param {number} shift Bit count to shift. + */ + function rotl(value, shift) { + return (value << shift) | (value >>> (32 - shift)); + } + + // Message data + for ( ; i < urlEncodedMessage.length; f++) { + data[f >> 2] = data[f >> 2] | + ( + ( + urlEncodedMessage[i] == "%" + // Percent encoded byte + ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16) + // Unencoded byte + : urlEncodedMessage.charCodeAt(i++) + ) + + // Read bytes in reverse order (big endian words) + << ((3 - (f & 3)) * 8) + ); + } + + // f is now the length of the utf8 encoded message + // 7 = 8 bytes (64 bit) for message size, -1 to round down + // >> 6 = integer division with block size + dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS; + + // Message size in bits. + // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least + // significant 32 bits are set. -8 is for the '1' bit padding byte. + data[dataSize - 1] = f * 8 - 8; + + // Compute hash + for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) { + for (i = 0; i < 80; i++) { + f = rotl(a, 5) + e + ( + // Ch + i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 : + + // Parity + i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 : + + // Maj + i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc : + + // Parity + (b ^ c ^ d) + 0xca62c1d6 + ) + ( + hashBuffer[i] = i < BLOCK_SIZE_WORDS + // Bitwise OR is used to coerse `undefined` to 0 + ? (data[blockStartIndex + i] | 0) + : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1) + ); + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = f; + } + + hash[0] = a = ((hash[0] + a) | 0); + hash[1] = b = ((hash[1] + b) | 0); + hash[2] = c = ((hash[2] + c) | 0); + hash[3] = d = ((hash[3] + d) | 0); + hash[4] = e = ((hash[4] + e) | 0); + } + + // Format hex hash + for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) { + hexHash += ( + ( + // Get word (2^3 half-bytes per word) + hash[i >> 3] >>> + + // Append half-bytes in reverse order + ((7 - (i & 7)) * 4) + ) + // Clamp to half-byte + & 0xf + ).toString(16); + } + + return hexHash; +} + +/** + * Inputs a value that might be a valid hash string for Jdenticon and returns it + * if it is determined valid, otherwise a falsy value is returned. + */ +function isValidHash(hashCandidate) { + return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate; +} + +/** + * Computes a hash for the specified value. Currently SHA1 is used. This function + * always returns a valid hash. + */ +function computeHash(value) { + return sha1(value == null ? "" : "" + value); +} + + + +/** + * Renderer redirecting drawing commands to a canvas context. + * @implements {Renderer} + */ +class CanvasRenderer { + /** + * @param {number=} iconSize + */ + constructor(ctx, iconSize) { + const canvas = ctx.canvas; + const width = canvas.width; + const height = canvas.height; + + ctx.save(); + + if (!iconSize) { + iconSize = Math.min(width, height); + + ctx.translate( + ((width - iconSize) / 2) | 0, + ((height - iconSize) / 2) | 0); + } + + /** + * @private + */ + this.l/*_ctx*/ = ctx; + this.k/*iconSize*/ = iconSize; + + ctx.clearRect(0, 0, iconSize, iconSize); + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + m/*setBackground*/(fillColor) { + const ctx = this.l/*_ctx*/; + const iconSize = this.k/*iconSize*/; + + ctx.fillStyle = toCss3Color(fillColor); + ctx.fillRect(0, 0, iconSize, iconSize); + } + + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} fillColor Fill color on format #rrggbb[aa]. + */ + L/*beginShape*/(fillColor) { + const ctx = this.l/*_ctx*/; + ctx.fillStyle = toCss3Color(fillColor); + ctx.beginPath(); + } + + /** + * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas. + */ + M/*endShape*/() { + this.l/*_ctx*/.fill(); + } + + /** + * Adds a polygon to the rendering queue. + * @param points An array of Point objects. + */ + g/*addPolygon*/(points) { + const ctx = this.l/*_ctx*/; + ctx.moveTo(points[0].x, points[0].y); + for (let i = 1; i < points.length; i++) { + ctx.lineTo(points[i].x, points[i].y); + } + ctx.closePath(); + } + + /** + * Adds a circle to the rendering queue. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + h/*addCircle*/(point, diameter, counterClockwise) { + const ctx = this.l/*_ctx*/, + radius = diameter / 2; + ctx.moveTo(point.x + radius, point.y + radius); + ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise); + ctx.closePath(); + } + + /** + * Called when the icon has been completely drawn. + */ + finish() { + this.l/*_ctx*/.restore(); + } +} + +/** + * Draws an identicon to a context. + * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0). + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function drawIcon(ctx, hashOrValue, size, config) { + if (!ctx) { + throw new Error("No canvas specified."); + } + + iconGenerator(new CanvasRenderer(ctx, size), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); +} + +/** + * Prepares a measure to be used as a measure in an SVG path, by + * rounding the measure to a single decimal. This reduces the file + * size of the generated SVG with more than 50% in some cases. + */ +function svgValue(value) { + return ((value * 10 + 0.5) | 0) / 10; +} + +/** + * Represents an SVG path element. + */ +class SvgPath { + constructor() { + /** + * This property holds the data string (path.d) of the SVG path. + * @type {string} + */ + this.v/*dataString*/ = ""; + } + + /** + * Adds a polygon with the current fill color to the SVG path. + * @param points An array of Point objects. + */ + g/*addPolygon*/(points) { + let dataString = ""; + for (let i = 0; i < points.length; i++) { + dataString += (i ? "L" : "M") + svgValue(points[i].x) + " " + svgValue(points[i].y); + } + this.v/*dataString*/ += dataString + "Z"; + } + + /** + * Adds a circle with the current fill color to the SVG path. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + h/*addCircle*/(point, diameter, counterClockwise) { + const sweepFlag = counterClockwise ? 0 : 1, + svgRadius = svgValue(diameter / 2), + svgDiameter = svgValue(diameter), + svgArc = "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " "; + + this.v/*dataString*/ += + "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) + + svgArc + svgDiameter + ",0" + + svgArc + (-svgDiameter) + ",0"; + } +} + + + +/** + * Renderer producing SVG output. + * @implements {Renderer} + */ +class SvgRenderer { + /** + * @param {SvgElement|SvgWriter} target + */ + constructor(target) { + /** + * @type {SvgPath} + * @private + */ + this.A/*_path*/; + + /** + * @type {Object.} + * @private + */ + this.B/*_pathsByColor*/ = { }; + + /** + * @type {SvgElement|SvgWriter} + * @private + */ + this.N/*_target*/ = target; + + /** + * @type {number} + */ + this.k/*iconSize*/ = target.k/*iconSize*/; + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + m/*setBackground*/(fillColor) { + const match = /^(#......)(..)?/.exec(fillColor), + opacity = match[2] ? parseHex(match[2], 0) / 255 : 1; + this.N/*_target*/.m/*setBackground*/(match[1], opacity); + } + + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} color Fill color on format #xxxxxx. + */ + L/*beginShape*/(color) { + this.A/*_path*/ = this.B/*_pathsByColor*/[color] || (this.B/*_pathsByColor*/[color] = new SvgPath()); + } + + /** + * Marks the end of the currently drawn shape. + */ + M/*endShape*/() { } + + /** + * Adds a polygon with the current fill color to the SVG. + * @param points An array of Point objects. + */ + g/*addPolygon*/(points) { + this.A/*_path*/.g/*addPolygon*/(points); + } + + /** + * Adds a circle with the current fill color to the SVG. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + h/*addCircle*/(point, diameter, counterClockwise) { + this.A/*_path*/.h/*addCircle*/(point, diameter, counterClockwise); + } + + /** + * Called when the icon has been completely drawn. + */ + finish() { + const pathsByColor = this.B/*_pathsByColor*/; + for (let color in pathsByColor) { + // hasOwnProperty cannot be shadowed in pathsByColor + // eslint-disable-next-line no-prototype-builtins + if (pathsByColor.hasOwnProperty(color)) { + this.N/*_target*/.O/*appendPath*/(color, pathsByColor[color].v/*dataString*/); + } + } + } +} + +const SVG_CONSTANTS = { + P/*XMLNS*/: "http://www.w3.org/2000/svg", + R/*WIDTH*/: "width", + S/*HEIGHT*/: "height", +}; + +/** + * Renderer producing SVG output. + */ +class SvgWriter { + /** + * @param {number} iconSize - Icon width and height in pixels. + */ + constructor(iconSize) { + /** + * @type {number} + */ + this.k/*iconSize*/ = iconSize; + + /** + * @type {string} + * @private + */ + this.C/*_s*/ = + ''; + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ + m/*setBackground*/(fillColor, opacity) { + if (opacity) { + this.C/*_s*/ += ''; + } + } + + /** + * Writes a path to the SVG string. + * @param {string} color Fill color on format #rrggbb. + * @param {string} dataString The SVG path data string. + */ + O/*appendPath*/(color, dataString) { + this.C/*_s*/ += ''; + } + + /** + * Gets the rendered image as an SVG string. + */ + toString() { + return this.C/*_s*/ + ""; + } +} + +/** + * Draws an identicon as an SVG string. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + * @returns {string} SVG string + */ +function toSvg(hashOrValue, size, config) { + const writer = new SvgWriter(size); + iconGenerator(new SvgRenderer(writer), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); + return writer.toString(); +} + +const ICON_TYPE_SVG = 1; + +const ICON_TYPE_CANVAS = 2; + +const ATTRIBUTES = { + Z/*HASH*/: "data-jdenticon-hash", + T/*VALUE*/: "data-jdenticon-value" +}; + +const documentQuerySelectorAll = /** @type {!Function} */ ( + typeof document !== "undefined" && document.querySelectorAll.bind(document)); + +function getIdenticonType(el) { + if (el) { + const tagName = el["tagName"]; + + if (/^svg$/i.test(tagName)) { + return ICON_TYPE_SVG; + } + + if (/^canvas$/i.test(tagName) && "getContext" in el) { + return ICON_TYPE_CANVAS; + } + } +} + +/** + * Creates a new element and adds it to the specified parent. + * @param {Element} parentNode + * @param {string} name + * @param {...(string|number)} keyValuePairs + */ +function SvgElement_append(parentNode, name, ...keyValuePairs) { + const el = document.createElementNS(SVG_CONSTANTS.P/*XMLNS*/, name); + + for (let i = 0; i + 1 < keyValuePairs.length; i += 2) { + el.setAttribute( + /** @type {string} */(keyValuePairs[i]), + /** @type {string} */(keyValuePairs[i + 1]), + ); + } + + parentNode.appendChild(el); +} + + +/** + * Renderer producing SVG output. + */ +class SvgElement { + /** + * @param {Element} element - Target element + */ + constructor(element) { + // Don't use the clientWidth and clientHeight properties on SVG elements + // since Firefox won't serve a proper value of these properties on SVG + // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811) + // Instead use 100px as a hardcoded size (the svg viewBox will rescale + // the icon to the correct dimensions) + const iconSize = this.k/*iconSize*/ = Math.min( + (Number(element.getAttribute(SVG_CONSTANTS.R/*WIDTH*/)) || 100), + (Number(element.getAttribute(SVG_CONSTANTS.S/*HEIGHT*/)) || 100) + ); + + /** + * @type {Element} + * @private + */ + this.U/*_el*/ = element; + + // Clear current SVG child elements + while (element.firstChild) { + element.removeChild(element.firstChild); + } + + // Set viewBox attribute to ensure the svg scales nicely. + element.setAttribute("viewBox", "0 0 " + iconSize + " " + iconSize); + element.setAttribute("preserveAspectRatio", "xMidYMid meet"); + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ + m/*setBackground*/(fillColor, opacity) { + if (opacity) { + SvgElement_append(this.U/*_el*/, "rect", + SVG_CONSTANTS.R/*WIDTH*/, "100%", + SVG_CONSTANTS.S/*HEIGHT*/, "100%", + "fill", fillColor, + "opacity", opacity); + } + } + + /** + * Appends a path to the SVG element. + * @param {string} color Fill color on format #xxxxxx. + * @param {string} dataString The SVG path data string. + */ + O/*appendPath*/(color, dataString) { + SvgElement_append(this.U/*_el*/, "path", + "fill", color, + "d", dataString); + } +} + +/** + * Updates the identicon in the specified `` or `` elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * `` or ``, or a CSS selector to such an element. + * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function update(el, hashOrValue, config) { + renderDomElement(el, hashOrValue, config, function (el, iconType) { + if (iconType) { + return iconType == ICON_TYPE_SVG ? + new SvgRenderer(new SvgElement(el)) : + new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext("2d")); + } + }); +} + +/** + * Updates the identicon in the specified `` elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * ``, or a CSS selector to such an element. + * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function updateCanvas(el, hashOrValue, config) { + renderDomElement(el, hashOrValue, config, function (el, iconType) { + if (iconType == ICON_TYPE_CANVAS) { + return new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext("2d")); + } + }); +} + +/** + * Updates the identicon in the specified `` elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * ``, or a CSS selector to such an element. + * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function updateSvg(el, hashOrValue, config) { + renderDomElement(el, hashOrValue, config, function (el, iconType) { + if (iconType == ICON_TYPE_SVG) { + return new SvgRenderer(new SvgElement(el)); + } + }); +} + +/** + * Updates the identicon in the specified canvas or svg elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * `` or ``, or a CSS selector to such an element. + * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number|undefined} config + * @param {function(Element,number):Renderer} rendererFactory - Factory function for creating an icon renderer. + */ +function renderDomElement(el, hashOrValue, config, rendererFactory) { + if (typeof el === "string") { + if (documentQuerySelectorAll) { + const elements = documentQuerySelectorAll(el); + for (let i = 0; i < elements.length; i++) { + renderDomElement(elements[i], hashOrValue, config, rendererFactory); + } + } + return; + } + + // Hash selection. The result from getValidHash or computeHash is + // accepted as a valid hash. + const hash = + // 1. Explicit valid hash + isValidHash(hashOrValue) || + + // 2. Explicit value (`!= null` catches both null and undefined) + hashOrValue != null && computeHash(hashOrValue) || + + // 3. `data-jdenticon-hash` attribute + isValidHash(el.getAttribute(ATTRIBUTES.Z/*HASH*/)) || + + // 4. `data-jdenticon-value` attribute. + // We want to treat an empty attribute as an empty value. + // Some browsers return empty string even if the attribute + // is not specified, so use hasAttribute to determine if + // the attribute is specified. + el.hasAttribute(ATTRIBUTES.T/*VALUE*/) && computeHash(el.getAttribute(ATTRIBUTES.T/*VALUE*/)); + + if (!hash) { + // No hash specified. Don't render an icon. + return; + } + + const renderer = rendererFactory(el, getIdenticonType(el)); + if (renderer) { + // Draw icon + iconGenerator(renderer, hash, config); + } +} + +// This file is compiled to dist/jdenticon-module.mjs + +/** + * Specifies the version of the Jdenticon package in use. + * @type {string} + */ +const version = "3.1.0"; + +/** + * Specifies which bundle of Jdenticon that is used. + * @type {string} + */ +const bundle = "browser-esm"; + +export { bundle, configure, drawIcon, toSvg, update, updateCanvas, updateSvg, version }; +//# sourceMappingURL=jdenticon-module.mjs.map diff --git a/www/vendor/jdenticon-module.mjs.map b/www/vendor/jdenticon-module.mjs.map new file mode 100644 index 0000000..4868188 --- /dev/null +++ b/www/vendor/jdenticon-module.mjs.map @@ -0,0 +1 @@ +{"version":3,"sources":["replacement/1","src/common/parseHex.js","src/renderer/color.js","src/common/global.js","src/common/configuration.js","src/renderer/point.js","src/renderer/transform.js","src/renderer/graphics.js","src/renderer/shapes.js","src/renderer/colorTheme.js","src/renderer/iconGenerator.js","src/common/sha1.js","src/common/hashUtils.js","src/renderer/canvas/canvasRenderer.js","src/apis/drawIcon.js","src/renderer/svg/svgPath.js","src/renderer/svg/svgRenderer.js","src/renderer/svg/constants.js","src/renderer/svg/svgWriter.js","src/apis/toSvg.js","src/common/dom.js","src/renderer/svg/svgElement.js","src/apis/update.js","src/browser-esm.js","replacement/2"],"names":["GLOBAL","MODULE","hue","colorSaturation","grayscaleSaturation","colorLightness","grayscaleLightness","backColor","iconPadding","_x","_y","_size","_rotation","transformIconPoint","_renderer","currentTransform","addPolygon","addCircle","addRectangle","addTriangle","addRhombus","setBackground","iconSize","beginShape","endShape","_ctx","dataString","_path","_pathsByColor","_target","appendPath","XMLNS","WIDTH","HEIGHT","_s","HASH","VALUE","_el"],"mappings":"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","file":"jdenticon-module.mjs","sourcesContent":["/**\r\n * Jdenticon 3.1.0\r\n * http://jdenticon.com\r\n *\r\n * Built: 2020-12-12T13:51:48.709Z\r\n * \r\n * MIT License\r\n * \r\n * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi\r\n * \r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n * \r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n * \r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Parses a substring of the hash as a number.\r\n * @param {number} startPosition \r\n * @param {number=} octets\r\n */\r\nexport function parseHex(hash, startPosition, octets) {\r\n return parseInt(hash.substr(startPosition, octets), 16);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseHex } from \"../common/parseHex\";\r\n\r\nfunction decToHex(v) {\r\n v |= 0; // Ensure integer value\r\n return v < 0 ? \"00\" :\r\n v < 16 ? \"0\" + v.toString(16) :\r\n v < 256 ? v.toString(16) :\r\n \"ff\";\r\n}\r\n\r\nfunction hueToRgb(m1, m2, h) {\r\n h = h < 0 ? h + 6 : h > 6 ? h - 6 : h;\r\n return decToHex(255 * (\r\n h < 1 ? m1 + (m2 - m1) * h :\r\n h < 3 ? m2 :\r\n h < 4 ? m1 + (m2 - m1) * (4 - h) :\r\n m1));\r\n}\r\n\r\n/**\r\n * @param {number} r Red channel [0, 255]\r\n * @param {number} g Green channel [0, 255]\r\n * @param {number} b Blue channel [0, 255]\r\n */\r\nexport function rgb(r, g, b) {\r\n return \"#\" + decToHex(r) + decToHex(g) + decToHex(b);\r\n}\r\n\r\n/**\r\n * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.\r\n * @returns {string}\r\n */\r\nexport function parseColor(color) {\r\n if (/^#[0-9a-f]{3,8}$/i.test(color)) {\r\n let result;\r\n const colorLength = color.length;\r\n\r\n if (colorLength < 6) {\r\n const r = color[1],\r\n g = color[2],\r\n b = color[3],\r\n a = color[4] || \"\";\r\n result = \"#\" + r + r + g + g + b + b + a + a;\r\n }\r\n if (colorLength == 7 || colorLength > 8) {\r\n result = color;\r\n }\r\n \r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * Converts a hexadecimal color to a CSS3 compatible color.\r\n * @param {string} hexColor Color on the format \"#RRGGBB\" or \"#RRGGBBAA\"\r\n * @returns {string}\r\n */\r\nexport function toCss3Color(hexColor) {\r\n const a = parseHex(hexColor, 7, 2);\r\n let result;\r\n\r\n if (isNaN(a)) {\r\n result = hexColor;\r\n } else {\r\n const r = parseHex(hexColor, 1, 2),\r\n g = parseHex(hexColor, 3, 2),\r\n b = parseHex(hexColor, 5, 2);\r\n result = \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (a / 255).toFixed(2) + \")\";\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color.\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function hsl(hue, saturation, lightness) {\r\n // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color\r\n let result;\r\n\r\n if (saturation == 0) {\r\n const partialHex = decToHex(lightness * 255);\r\n result = partialHex + partialHex + partialHex;\r\n }\r\n else {\r\n const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation,\r\n m1 = lightness * 2 - m2;\r\n result =\r\n hueToRgb(m1, m2, hue * 6 + 2) +\r\n hueToRgb(m1, m2, hue * 6) +\r\n hueToRgb(m1, m2, hue * 6 - 2);\r\n }\r\n\r\n return \"#\" + result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the \"dark\" hues\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function correctedHsl(hue, saturation, lightness) {\r\n // The corrector specifies the perceived middle lightness for each hue\r\n const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],\r\n corrector = correctors[(hue * 6 + 0.5) | 0];\r\n \r\n // Adjust the input lightness relative to the corrector\r\n lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2;\r\n \r\n return hsl(hue, saturation, lightness);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for\r\n// backward compatibility.\r\n\r\nexport const GLOBAL = \r\n typeof window !== \"undefined\" ? window :\r\n typeof self !== \"undefined\" ? self :\r\n typeof global !== \"undefined\" ? global :\r\n {};\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseColor } from \"../renderer/color\";\r\nimport { GLOBAL } from \"./global\";\r\n\r\n/**\r\n * @typedef {Object} ParsedConfiguration\r\n * @property {number} colorSaturation\r\n * @property {number} grayscaleSaturation\r\n * @property {string} backColor\r\n * @property {number} iconPadding\r\n * @property {function(number):number} hue\r\n * @property {function(number):number} colorLightness\r\n * @property {function(number):number} grayscaleLightness\r\n */\r\n\r\nexport const CONFIG_PROPERTIES = {\r\n GLOBAL: \"jdenticon_config\",\r\n MODULE: \"config\",\r\n};\r\n\r\nvar rootConfigurationHolder = {};\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object. When the property is set a warning is \r\n * printed in the console. To minimize bundle size, this is only used in Node bundles.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigPropertyWithWarn(rootObject) {\r\n Object.defineProperty(rootObject, CONFIG_PROPERTIES.MODULE, {\r\n configurable: true,\r\n get: () => rootConfigurationHolder[CONFIG_PROPERTIES.MODULE],\r\n set: newConfiguration => {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n console.warn(\"jdenticon.config is deprecated. Use jdenticon.configure() instead.\");\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console\r\n * when it is being used.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigProperty(rootObject) {\r\n rootConfigurationHolder = rootObject;\r\n}\r\n\r\n/**\r\n * Sets a new icon style configuration. The new configuration is not merged with the previous one. * \r\n * @param {Object} newConfiguration - New configuration object.\r\n */\r\nexport function configure(newConfiguration) {\r\n if (arguments.length) {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n }\r\n return rootConfigurationHolder[CONFIG_PROPERTIES.MODULE];\r\n}\r\n\r\n/**\r\n * Gets the normalized current Jdenticon color configuration. Missing fields have default values.\r\n * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A\r\n * local configuration overrides the global configuration in it entirety. This parameter can for backward\r\n * compatibility also contain a padding value. A padding value only overrides the global padding, not the\r\n * entire global configuration.\r\n * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor\r\n * explicitly to the API method.\r\n * @returns {ParsedConfiguration}\r\n */\r\nexport function getConfiguration(paddingOrLocalConfig, defaultPadding) {\r\n const configObject = \r\n typeof paddingOrLocalConfig == \"object\" && paddingOrLocalConfig ||\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] ||\r\n GLOBAL[CONFIG_PROPERTIES.GLOBAL] ||\r\n { },\r\n\r\n lightnessConfig = configObject[\"lightness\"] || { },\r\n \r\n // In versions < 2.1.0 there was no grayscale saturation -\r\n // saturation was the color saturation.\r\n saturation = configObject[\"saturation\"] || { },\r\n colorSaturation = \"color\" in saturation ? saturation[\"color\"] : saturation,\r\n grayscaleSaturation = saturation[\"grayscale\"],\r\n\r\n backColor = configObject[\"backColor\"],\r\n padding = configObject[\"padding\"];\r\n \r\n /**\r\n * Creates a lightness range.\r\n */\r\n function lightness(configName, defaultRange) {\r\n let range = lightnessConfig[configName];\r\n \r\n // Check if the lightness range is an array-like object. This way we ensure the\r\n // array contain two values at the same time.\r\n if (!(range && range.length > 1)) {\r\n range = defaultRange;\r\n }\r\n\r\n /**\r\n * Gets a lightness relative the specified value in the specified lightness range.\r\n */\r\n return function (value) {\r\n value = range[0] + value * (range[1] - range[0]);\r\n return value < 0 ? 0 : value > 1 ? 1 : value;\r\n };\r\n }\r\n\r\n /**\r\n * Gets a hue allowed by the configured hue restriction,\r\n * provided the originally computed hue.\r\n */\r\n function hueFunction(originalHue) {\r\n const hueConfig = configObject[\"hues\"];\r\n let hue;\r\n \r\n // Check if 'hues' is an array-like object. This way we also ensure that\r\n // the array is not empty, which would mean no hue restriction.\r\n if (hueConfig && hueConfig.length > 0) {\r\n // originalHue is in the range [0, 1]\r\n // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.\r\n hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];\r\n }\r\n\r\n return typeof hue == \"number\" ?\r\n \r\n // A hue was specified. We need to convert the hue from\r\n // degrees on any turn - e.g. 746° is a perfectly valid hue -\r\n // to turns in the range [0, 1).\r\n ((((hue / 360) % 1) + 1) % 1) :\r\n\r\n // No hue configured => use original hue\r\n originalHue;\r\n }\r\n \r\n return {\r\n hue: hueFunction,\r\n colorSaturation: typeof colorSaturation == \"number\" ? colorSaturation : 0.5,\r\n grayscaleSaturation: typeof grayscaleSaturation == \"number\" ? grayscaleSaturation : 0,\r\n colorLightness: lightness(\"color\", [0.4, 0.8]),\r\n grayscaleLightness: lightness(\"grayscale\", [0.3, 0.9]),\r\n backColor: parseColor(backColor),\r\n iconPadding: \r\n typeof paddingOrLocalConfig == \"number\" ? paddingOrLocalConfig : \r\n typeof padding == \"number\" ? padding : \r\n defaultPadding\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Represents a point.\r\n */\r\nexport class Point {\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n */\r\n constructor(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Point } from \"./point\";\r\n\r\n/**\r\n * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, \r\n * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.\r\n */\r\nexport class Transform {\r\n /**\r\n * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} size The size of the transformed rectangle.\r\n * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad\r\n */\r\n constructor(x, y, size, rotation) {\r\n this._x = x;\r\n this._y = y;\r\n this._size = size;\r\n this._rotation = rotation;\r\n }\r\n\r\n /**\r\n * Transforms the specified point based on the translation and rotation specification for this Transform.\r\n * @param {number} x x-coordinate\r\n * @param {number} y y-coordinate\r\n * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n */\r\n transformIconPoint(x, y, w, h) {\r\n const right = this._x + this._size,\r\n bottom = this._y + this._size,\r\n rotation = this._rotation;\r\n return rotation === 1 ? new Point(right - y - (h || 0), this._y + x) :\r\n rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :\r\n rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) :\r\n new Point(this._x + x, this._y + y);\r\n }\r\n}\r\n\r\nexport const NO_TRANSFORM = new Transform(0, 0, 0, 0);\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { NO_TRANSFORM } from \"./transform\";\r\n\r\n/**\r\n * @typedef {import(\"./renderer\").Renderer} Renderer\r\n * @typedef {import(\"./transform\").Transform} Transform\r\n */\r\n\r\n/**\r\n * Provides helper functions for rendering common basic shapes.\r\n */\r\nexport class Graphics {\r\n /**\r\n * @param {Renderer} renderer \r\n */\r\n constructor(renderer) {\r\n /**\r\n * @type {Renderer}\r\n * @private\r\n */\r\n this._renderer = renderer;\r\n\r\n /**\r\n * @type {Transform}\r\n */\r\n this.currentTransform = NO_TRANSFORM;\r\n }\r\n\r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]\r\n * @param {boolean=} invert Specifies if the polygon will be inverted.\r\n */\r\n addPolygon(points, invert) {\r\n const di = invert ? -2 : 2,\r\n transformedPoints = [];\r\n \r\n for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {\r\n transformedPoints.push(this.currentTransform.transformIconPoint(points[i], points[i + 1]));\r\n }\r\n \r\n this._renderer.addPolygon(transformedPoints);\r\n }\r\n \r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * Source: http://stackoverflow.com/a/2173084\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} size The size of the ellipse.\r\n * @param {boolean=} invert Specifies if the ellipse will be inverted.\r\n */\r\n addCircle(x, y, size, invert) {\r\n const p = this.currentTransform.transformIconPoint(x, y, size, size);\r\n this._renderer.addCircle(p, size, invert);\r\n }\r\n\r\n /**\r\n * Adds a rectangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle.\r\n * @param {number} w The width of the rectangle.\r\n * @param {number} h The height of the rectangle.\r\n * @param {boolean=} invert Specifies if the rectangle will be inverted.\r\n */\r\n addRectangle(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x, y, \r\n x + w, y,\r\n x + w, y + h,\r\n x, y + h\r\n ], invert);\r\n }\r\n\r\n /**\r\n * Adds a right triangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} w The width of the triangle.\r\n * @param {number} h The height of the triangle.\r\n * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.\r\n * @param {boolean=} invert Specifies if the triangle will be inverted.\r\n */\r\n addTriangle(x, y, w, h, r, invert) {\r\n const points = [\r\n x + w, y, \r\n x + w, y + h, \r\n x, y + h,\r\n x, y\r\n ];\r\n points.splice(((r || 0) % 4) * 2, 2);\r\n this.addPolygon(points, invert);\r\n }\r\n\r\n /**\r\n * Adds a rhombus to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} w The width of the rhombus.\r\n * @param {number} h The height of the rhombus.\r\n * @param {boolean=} invert Specifies if the rhombus will be inverted.\r\n */\r\n addRhombus(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x + w / 2, y,\r\n x + w, y + h / 2,\r\n x + w / 2, y + h,\r\n x, y + h / 2\r\n ], invert);\r\n }\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n * @param {number} positionIndex\r\n * @typedef {import('./graphics').Graphics} Graphics\r\n */\r\nexport function centerShape(index, g, cell, positionIndex) {\r\n index = index % 14;\r\n\r\n let k, m, w, h, inner, outer;\r\n\r\n !index ? (\r\n k = cell * 0.42,\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell - k * 2,\r\n cell - k, cell,\r\n 0, cell\r\n ])) :\r\n\r\n index == 1 ? (\r\n w = 0 | (cell * 0.5), \r\n h = 0 | (cell * 0.8),\r\n\r\n g.addTriangle(cell - w, 0, w, h, 2)) :\r\n\r\n index == 2 ? (\r\n w = 0 | (cell / 3),\r\n g.addRectangle(w, w, cell - w, cell - w)) :\r\n\r\n index == 3 ? (\r\n inner = cell * 0.1,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 6 ? 1 :\r\n cell < 8 ? 2 :\r\n (0 | (cell * 0.25)),\r\n \r\n inner = \r\n inner > 1 ? (0 | inner) : // large icon => truncate decimals\r\n inner > 0.5 ? 1 : // medium size icon => fixed width\r\n inner, // small icon => anti-aliased border\r\n\r\n g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer)) :\r\n\r\n index == 4 ? (\r\n m = 0 | (cell * 0.15),\r\n w = 0 | (cell * 0.5),\r\n g.addCircle(cell - w - m, cell - w - m, w)) :\r\n\r\n index == 5 ? (\r\n inner = cell * 0.1,\r\n outer = inner * 4,\r\n\r\n // Align edge to nearest pixel in large icons\r\n outer > 3 && (outer = 0 | outer),\r\n \r\n g.addRectangle(0, 0, cell, cell),\r\n g.addPolygon([\r\n outer, outer,\r\n cell - inner, outer,\r\n outer + (cell - outer - inner) / 2, cell - inner\r\n ], true)) :\r\n\r\n index == 6 ? \r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell * 0.7,\r\n cell * 0.4, cell * 0.4,\r\n cell * 0.7, cell,\r\n 0, cell\r\n ]) :\r\n\r\n index == 7 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 8 ? (\r\n g.addRectangle(0, 0, cell, cell / 2),\r\n g.addRectangle(0, cell / 2, cell / 2, cell / 2),\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1)) :\r\n\r\n index == 9 ? (\r\n inner = cell * 0.14,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 4 ? 1 :\r\n cell < 6 ? 2 :\r\n (0 | (cell * 0.35)),\r\n\r\n inner = \r\n cell < 8 ? inner : // small icon => anti-aliased border\r\n (0 | inner), // large icon => truncate decimals\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true)) :\r\n\r\n index == 10 ? (\r\n inner = cell * 0.12,\r\n outer = inner * 3,\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addCircle(outer, outer, cell - inner - outer, true)) :\r\n\r\n index == 11 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 12 ? (\r\n m = cell * 0.25,\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRhombus(m, m, cell - m, cell - m, true)) :\r\n\r\n // 13\r\n (\r\n !positionIndex && (\r\n m = cell * 0.4, w = cell * 1.2,\r\n g.addCircle(m, m, w)\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n */\r\nexport function outerShape(index, g, cell) {\r\n index = index % 4;\r\n\r\n let m;\r\n\r\n !index ?\r\n g.addTriangle(0, 0, cell, cell, 0) :\r\n \r\n index == 1 ?\r\n g.addTriangle(0, cell / 2, cell, cell / 2, 0) :\r\n\r\n index == 2 ?\r\n g.addRhombus(0, 0, cell, cell) :\r\n\r\n // 3\r\n (\r\n m = cell / 6,\r\n g.addCircle(m, m, cell - 2 * m)\r\n );\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { correctedHsl } from \"./color\";\r\n\r\n/**\r\n * Gets a set of identicon color candidates for a specified hue and config.\r\n * @param {number} hue\r\n * @param {import(\"../common/configuration\").ParsedConfiguration} config\r\n */\r\nexport function colorTheme(hue, config) {\r\n hue = config.hue(hue);\r\n return [\r\n // Dark gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)),\r\n // Mid color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)),\r\n // Light gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)),\r\n // Light color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(1)),\r\n // Dark color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0))\r\n ];\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Transform } from \"./transform\";\r\nimport { Graphics } from \"./graphics\";\r\nimport { centerShape, outerShape } from \"./shapes\";\r\nimport { colorTheme } from \"./colorTheme\";\r\nimport { parseHex } from \"../common/parseHex\";\r\nimport { getConfiguration } from \"../common/configuration\";\r\n \r\n/**\r\n * Draws an identicon to a specified renderer.\r\n * @param {import('./renderer').Renderer} renderer\r\n * @param {string} hash\r\n * @param {Object|number=} config\r\n */\r\nexport function iconGenerator(renderer, hash, config) {\r\n const parsedConfig = getConfiguration(config, 0.08);\r\n\r\n // Set background color\r\n if (parsedConfig.backColor) {\r\n renderer.setBackground(parsedConfig.backColor);\r\n }\r\n \r\n // Calculate padding and round to nearest integer\r\n let size = renderer.iconSize;\r\n const padding = (0.5 + size * parsedConfig.iconPadding) | 0;\r\n size -= padding * 2;\r\n \r\n const graphics = new Graphics(renderer);\r\n \r\n // Calculate cell size and ensure it is an integer\r\n const cell = 0 | (size / 4);\r\n \r\n // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon\r\n const x = 0 | (padding + size / 2 - cell * 2);\r\n const y = 0 | (padding + size / 2 - cell * 2);\r\n\r\n function renderShape(colorIndex, shapes, index, rotationIndex, positions) {\r\n const shapeIndex = parseHex(hash, index, 1);\r\n let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0;\r\n \r\n renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]);\r\n \r\n for (let i = 0; i < positions.length; i++) {\r\n graphics.currentTransform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);\r\n shapes(shapeIndex, graphics, cell, i);\r\n }\r\n \r\n renderer.endShape();\r\n }\r\n\r\n // AVAILABLE COLORS\r\n const hue = parseHex(hash, -7) / 0xfffffff,\r\n \r\n // Available colors for this icon\r\n availableColors = colorTheme(hue, parsedConfig),\r\n\r\n // The index of the selected colors\r\n selectedColorIndexes = [];\r\n\r\n let index;\r\n\r\n function isDuplicate(values) {\r\n if (values.indexOf(index) >= 0) {\r\n for (let i = 0; i < values.length; i++) {\r\n if (selectedColorIndexes.indexOf(values[i]) >= 0) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < 3; i++) {\r\n index = parseHex(hash, 8 + i, 1) % availableColors.length;\r\n if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo\r\n isDuplicate([2, 3])) { // Disallow light gray and light color combo\r\n index = 1;\r\n }\r\n selectedColorIndexes.push(index);\r\n }\r\n\r\n // ACTUAL RENDERING\r\n // Sides\r\n renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);\r\n // Corners\r\n renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);\r\n // Center\r\n renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);\r\n \r\n renderer.finish();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Computes a SHA1 hash for any value and returns it as a hexadecimal string.\r\n * \r\n * This function is optimized for minimal code size and rather short messages.\r\n * \r\n * @param {string} message \r\n */\r\nexport function sha1(message) {\r\n const HASH_SIZE_HALF_BYTES = 40;\r\n const BLOCK_SIZE_WORDS = 16;\r\n\r\n // Variables\r\n // `var` is used to be able to minimize the number of `var` keywords.\r\n var i = 0,\r\n f = 0,\r\n \r\n // Use `encodeURI` to UTF8 encode the message without any additional libraries\r\n // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky\r\n // since `unescape` is deprecated.\r\n urlEncodedMessage = encodeURI(message) + \"%80\", // trailing '1' bit padding\r\n \r\n // This can be changed to a preallocated Uint32Array array for greater performance and larger code size\r\n data = [],\r\n dataSize,\r\n \r\n hashBuffer = [],\r\n\r\n a = 0x67452301,\r\n b = 0xefcdab89,\r\n c = ~a,\r\n d = ~b,\r\n e = 0xc3d2e1f0,\r\n hash = [a, b, c, d, e],\r\n\r\n blockStartIndex = 0,\r\n hexHash = \"\";\r\n\r\n /**\r\n * Rotates the value a specified number of bits to the left.\r\n * @param {number} value Value to rotate\r\n * @param {number} shift Bit count to shift.\r\n */\r\n function rotl(value, shift) {\r\n return (value << shift) | (value >>> (32 - shift));\r\n }\r\n\r\n // Message data\r\n for ( ; i < urlEncodedMessage.length; f++) {\r\n data[f >> 2] = data[f >> 2] |\r\n (\r\n (\r\n urlEncodedMessage[i] == \"%\"\r\n // Percent encoded byte\r\n ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)\r\n // Unencoded byte\r\n : urlEncodedMessage.charCodeAt(i++)\r\n )\r\n\r\n // Read bytes in reverse order (big endian words)\r\n << ((3 - (f & 3)) * 8)\r\n );\r\n }\r\n\r\n // f is now the length of the utf8 encoded message\r\n // 7 = 8 bytes (64 bit) for message size, -1 to round down\r\n // >> 6 = integer division with block size\r\n dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;\r\n\r\n // Message size in bits.\r\n // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least\r\n // significant 32 bits are set. -8 is for the '1' bit padding byte.\r\n data[dataSize - 1] = f * 8 - 8;\r\n \r\n // Compute hash\r\n for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {\r\n for (i = 0; i < 80; i++) {\r\n f = rotl(a, 5) + e + (\r\n // Ch\r\n i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :\r\n \r\n // Parity\r\n i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :\r\n \r\n // Maj\r\n i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :\r\n \r\n // Parity\r\n (b ^ c ^ d) + 0xca62c1d6\r\n ) + ( \r\n hashBuffer[i] = i < BLOCK_SIZE_WORDS\r\n // Bitwise OR is used to coerse `undefined` to 0\r\n ? (data[blockStartIndex + i] | 0)\r\n : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)\r\n );\r\n\r\n e = d;\r\n d = c;\r\n c = rotl(b, 30);\r\n b = a;\r\n a = f;\r\n }\r\n\r\n hash[0] = a = ((hash[0] + a) | 0);\r\n hash[1] = b = ((hash[1] + b) | 0);\r\n hash[2] = c = ((hash[2] + c) | 0);\r\n hash[3] = d = ((hash[3] + d) | 0);\r\n hash[4] = e = ((hash[4] + e) | 0);\r\n }\r\n\r\n // Format hex hash\r\n for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {\r\n hexHash += (\r\n (\r\n // Get word (2^3 half-bytes per word)\r\n hash[i >> 3] >>>\r\n\r\n // Append half-bytes in reverse order\r\n ((7 - (i & 7)) * 4)\r\n ) \r\n // Clamp to half-byte\r\n & 0xf\r\n ).toString(16);\r\n }\r\n\r\n return hexHash;\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { sha1 } from \"./sha1\";\r\n\r\n/**\r\n * Inputs a value that might be a valid hash string for Jdenticon and returns it \r\n * if it is determined valid, otherwise a falsy value is returned.\r\n */\r\nexport function isValidHash(hashCandidate) {\r\n return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;\r\n}\r\n\r\n/**\r\n * Computes a hash for the specified value. Currently SHA1 is used. This function\r\n * always returns a valid hash.\r\n */\r\nexport function computeHash(value) {\r\n return sha1(value == null ? \"\" : \"\" + value);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { toCss3Color } from \"../color\";\r\n\r\n/**\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import('../point').Point} Point\r\n */\r\n\r\n/**\r\n * Renderer redirecting drawing commands to a canvas context.\r\n * @implements {Renderer}\r\n */\r\nexport class CanvasRenderer {\r\n /**\r\n * @param {number=} iconSize\r\n */\r\n constructor(ctx, iconSize) {\r\n const canvas = ctx.canvas; \r\n const width = canvas.width;\r\n const height = canvas.height;\r\n \r\n ctx.save();\r\n \r\n if (!iconSize) {\r\n iconSize = Math.min(width, height);\r\n \r\n ctx.translate(\r\n ((width - iconSize) / 2) | 0,\r\n ((height - iconSize) / 2) | 0);\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n this._ctx = ctx;\r\n this.iconSize = iconSize;\r\n \r\n ctx.clearRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const ctx = this._ctx;\r\n const iconSize = this.iconSize;\r\n\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.fillRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} fillColor Fill color on format #rrggbb[aa].\r\n */\r\n beginShape(fillColor) {\r\n const ctx = this._ctx;\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.beginPath();\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.\r\n */\r\n endShape() {\r\n this._ctx.fill();\r\n }\r\n\r\n /**\r\n * Adds a polygon to the rendering queue.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n const ctx = this._ctx;\r\n ctx.moveTo(points[0].x, points[0].y);\r\n for (let i = 1; i < points.length; i++) {\r\n ctx.lineTo(points[i].x, points[i].y);\r\n }\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Adds a circle to the rendering queue.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const ctx = this._ctx,\r\n radius = diameter / 2;\r\n ctx.moveTo(point.x + radius, point.y + radius);\r\n ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() {\r\n this._ctx.restore();\r\n }\r\n}\r\n","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\n\r\n/**\r\n * Draws an identicon to a context.\r\n * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function drawIcon(ctx, hashOrValue, size, config) {\r\n if (!ctx) {\r\n throw new Error(\"No canvas specified.\");\r\n }\r\n \r\n iconGenerator(new CanvasRenderer(ctx, size), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue), \r\n config);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Prepares a measure to be used as a measure in an SVG path, by\r\n * rounding the measure to a single decimal. This reduces the file\r\n * size of the generated SVG with more than 50% in some cases.\r\n */\r\nfunction svgValue(value) {\r\n return ((value * 10 + 0.5) | 0) / 10;\r\n}\r\n\r\n/**\r\n * Represents an SVG path element.\r\n */\r\nexport class SvgPath {\r\n constructor() {\r\n /**\r\n * This property holds the data string (path.d) of the SVG path.\r\n * @type {string}\r\n */\r\n this.dataString = \"\";\r\n }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG path.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n let dataString = \"\";\r\n for (let i = 0; i < points.length; i++) {\r\n dataString += (i ? \"L\" : \"M\") + svgValue(points[i].x) + \" \" + svgValue(points[i].y);\r\n }\r\n this.dataString += dataString + \"Z\";\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG path.\r\n * @param {import('../point').Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const sweepFlag = counterClockwise ? 0 : 1,\r\n svgRadius = svgValue(diameter / 2),\r\n svgDiameter = svgValue(diameter),\r\n svgArc = \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \";\r\n \r\n this.dataString += \r\n \"M\" + svgValue(point.x) + \" \" + svgValue(point.y + diameter / 2) +\r\n svgArc + svgDiameter + \",0\" + \r\n svgArc + (-svgDiameter) + \",0\";\r\n }\r\n}\r\n\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SvgPath } from \"./svgPath\";\r\nimport { parseHex } from \"../../common/parseHex\";\r\n\r\n/**\r\n * @typedef {import(\"../point\").Point} Point\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import(\"./svgElement\").SvgElement} SvgElement\r\n * @typedef {import(\"./svgWriter\").SvgWriter} SvgWriter\r\n */\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @implements {Renderer}\r\n */\r\nexport class SvgRenderer {\r\n /**\r\n * @param {SvgElement|SvgWriter} target \r\n */\r\n constructor(target) {\r\n /**\r\n * @type {SvgPath}\r\n * @private\r\n */\r\n this._path;\r\n\r\n /**\r\n * @type {Object.}\r\n * @private\r\n */\r\n this._pathsByColor = { };\r\n\r\n /**\r\n * @type {SvgElement|SvgWriter}\r\n * @private\r\n */\r\n this._target = target;\r\n\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = target.iconSize;\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const match = /^(#......)(..)?/.exec(fillColor),\r\n opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;\r\n this._target.setBackground(match[1], opacity);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n */\r\n beginShape(color) {\r\n this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath());\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape.\r\n */\r\n endShape() { }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n this._path.addPolygon(points);\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n this._path.addCircle(point, diameter, counterClockwise);\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() { \r\n const pathsByColor = this._pathsByColor;\r\n for (let color in pathsByColor) {\r\n // hasOwnProperty cannot be shadowed in pathsByColor\r\n // eslint-disable-next-line no-prototype-builtins\r\n if (pathsByColor.hasOwnProperty(color)) {\r\n this._target.appendPath(color, pathsByColor[color].dataString);\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const SVG_CONSTANTS = {\r\n XMLNS: \"http://www.w3.org/2000/svg\",\r\n WIDTH: \"width\",\r\n HEIGHT: \"height\",\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgWriter {\r\n /**\r\n * @param {number} iconSize - Icon width and height in pixels.\r\n */\r\n constructor(iconSize) {\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = iconSize;\r\n\r\n /**\r\n * @type {string}\r\n * @private\r\n */\r\n this._s =\r\n '';\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n this._s += '';\r\n }\r\n }\r\n\r\n /**\r\n * Writes a path to the SVG string.\r\n * @param {string} color Fill color on format #rrggbb.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n this._s += '';\r\n }\r\n\r\n /**\r\n * Gets the rendered image as an SVG string.\r\n */\r\n toString() {\r\n return this._s + \"\";\r\n }\r\n}\r\n","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgWriter } from \"../renderer/svg/svgWriter\";\r\n\r\n/**\r\n * Draws an identicon as an SVG string.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n * @returns {string} SVG string\r\n */\r\nexport function toSvg(hashOrValue, size, config) {\r\n const writer = new SvgWriter(size);\r\n iconGenerator(new SvgRenderer(writer), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue),\r\n config);\r\n return writer.toString();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const ICON_TYPE_SVG = 1;\r\n\r\nexport const ICON_TYPE_CANVAS = 2;\r\n\r\nexport const ATTRIBUTES = {\r\n HASH: \"data-jdenticon-hash\",\r\n VALUE: \"data-jdenticon-value\"\r\n};\r\n\r\nexport const ICON_SELECTOR = \"[\" + ATTRIBUTES.HASH +\"],[\" + ATTRIBUTES.VALUE +\"]\";\r\n\r\nexport const documentQuerySelectorAll = /** @type {!Function} */ (\r\n typeof document !== \"undefined\" && document.querySelectorAll.bind(document));\r\n\r\nexport function getIdenticonType(el) {\r\n if (el) {\r\n const tagName = el[\"tagName\"];\r\n\r\n if (/^svg$/i.test(tagName)) {\r\n return ICON_TYPE_SVG;\r\n }\r\n\r\n if (/^canvas$/i.test(tagName) && \"getContext\" in el) {\r\n return ICON_TYPE_CANVAS;\r\n }\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Creates a new element and adds it to the specified parent.\r\n * @param {Element} parentNode\r\n * @param {string} name\r\n * @param {...(string|number)} keyValuePairs\r\n */\r\nfunction SvgElement_append(parentNode, name, ...keyValuePairs) {\r\n const el = document.createElementNS(SVG_CONSTANTS.XMLNS, name);\r\n \r\n for (let i = 0; i + 1 < keyValuePairs.length; i += 2) {\r\n el.setAttribute(\r\n /** @type {string} */(keyValuePairs[i]),\r\n /** @type {string} */(keyValuePairs[i + 1]),\r\n );\r\n }\r\n\r\n parentNode.appendChild(el);\r\n}\r\n\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgElement {\r\n /**\r\n * @param {Element} element - Target element\r\n */\r\n constructor(element) {\r\n // Don't use the clientWidth and clientHeight properties on SVG elements\r\n // since Firefox won't serve a proper value of these properties on SVG\r\n // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811)\r\n // Instead use 100px as a hardcoded size (the svg viewBox will rescale \r\n // the icon to the correct dimensions)\r\n const iconSize = this.iconSize = Math.min(\r\n (Number(element.getAttribute(SVG_CONSTANTS.WIDTH)) || 100),\r\n (Number(element.getAttribute(SVG_CONSTANTS.HEIGHT)) || 100)\r\n );\r\n \r\n /**\r\n * @type {Element}\r\n * @private\r\n */\r\n this._el = element;\r\n \r\n // Clear current SVG child elements\r\n while (element.firstChild) {\r\n element.removeChild(element.firstChild);\r\n }\r\n \r\n // Set viewBox attribute to ensure the svg scales nicely.\r\n element.setAttribute(\"viewBox\", \"0 0 \" + iconSize + \" \" + iconSize);\r\n element.setAttribute(\"preserveAspectRatio\", \"xMidYMid meet\");\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n SvgElement_append(this._el, \"rect\",\r\n SVG_CONSTANTS.WIDTH, \"100%\",\r\n SVG_CONSTANTS.HEIGHT, \"100%\",\r\n \"fill\", fillColor,\r\n \"opacity\", opacity);\r\n }\r\n }\r\n\r\n /**\r\n * Appends a path to the SVG element.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n SvgElement_append(this._el, \"path\",\r\n \"fill\", color,\r\n \"d\", dataString);\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { ATTRIBUTES, ICON_SELECTOR, documentQuerySelectorAll } from \"../common/dom\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgElement } from \"../renderer/svg/svgElement\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\nimport { ICON_TYPE_CANVAS, ICON_TYPE_SVG, getIdenticonType } from \"../common/dom\";\r\n\r\n\r\n/**\r\n * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute.\r\n */\r\nexport function updateAll() {\r\n if (documentQuerySelectorAll) {\r\n update(ICON_SELECTOR);\r\n }\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` or `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * `` or ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function update(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType) {\r\n return iconType == ICON_TYPE_SVG ? \r\n new SvgRenderer(new SvgElement(el)) : \r\n new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext(\"2d\"));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function updateCanvas(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType == ICON_TYPE_CANVAS) {\r\n return new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext(\"2d\"));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function updateSvg(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType == ICON_TYPE_SVG) {\r\n return new SvgRenderer(new SvgElement(el));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified canvas or svg elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * `` or ``, or a CSS selector to such an element.\r\n * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number|undefined} config\r\n * @param {function(Element,number):import(\"../renderer/renderer\").Renderer} rendererFactory - Factory function for creating an icon renderer.\r\n */\r\nfunction renderDomElement(el, hashOrValue, config, rendererFactory) {\r\n if (typeof el === \"string\") {\r\n if (documentQuerySelectorAll) {\r\n const elements = documentQuerySelectorAll(el);\r\n for (let i = 0; i < elements.length; i++) {\r\n renderDomElement(elements[i], hashOrValue, config, rendererFactory);\r\n }\r\n }\r\n return;\r\n }\r\n \r\n // Hash selection. The result from getValidHash or computeHash is \r\n // accepted as a valid hash.\r\n const hash = \r\n // 1. Explicit valid hash\r\n isValidHash(hashOrValue) ||\r\n \r\n // 2. Explicit value (`!= null` catches both null and undefined)\r\n hashOrValue != null && computeHash(hashOrValue) ||\r\n \r\n // 3. `data-jdenticon-hash` attribute\r\n isValidHash(el.getAttribute(ATTRIBUTES.HASH)) ||\r\n \r\n // 4. `data-jdenticon-value` attribute. \r\n // We want to treat an empty attribute as an empty value. \r\n // Some browsers return empty string even if the attribute \r\n // is not specified, so use hasAttribute to determine if \r\n // the attribute is specified.\r\n el.hasAttribute(ATTRIBUTES.VALUE) && computeHash(el.getAttribute(ATTRIBUTES.VALUE));\r\n \r\n if (!hash) {\r\n // No hash specified. Don't render an icon.\r\n return;\r\n }\r\n \r\n const renderer = rendererFactory(el, getIdenticonType(el));\r\n if (renderer) {\r\n // Draw icon\r\n iconGenerator(renderer, hash, config);\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// This file is compiled to dist/jdenticon-module.mjs\r\n\r\nexport { configure } from \"./apis/configure\";\r\nexport { drawIcon } from \"./apis/drawIcon\";\r\nexport { toSvg } from \"./apis/toSvg\";\r\nexport { update, updateCanvas, updateSvg } from \"./apis/update\";\r\n\r\n/**\r\n * Specifies the version of the Jdenticon package in use.\r\n * @type {string}\r\n */\r\nexport const version = \"#version#\";\r\n\r\n/**\r\n * Specifies which bundle of Jdenticon that is used.\r\n * @type {string}\r\n */\r\nexport const bundle = \"browser-esm\";\r\n","\n//# sourceMappingURL=jdenticon-module.mjs.map\n"]} \ No newline at end of file diff --git a/www/vendor/jdenticon-node.js b/www/vendor/jdenticon-node.js new file mode 100644 index 0000000..27e0d8e --- /dev/null +++ b/www/vendor/jdenticon-node.js @@ -0,0 +1,1266 @@ +/** + * Jdenticon 3.1.0 + * http://jdenticon.com + * + * Built: 2020-12-12T13:51:48.709Z + * + * MIT License + * + * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +'use strict'; + +var canvasRenderer = require('canvas-renderer'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var canvasRenderer__default = /*#__PURE__*/_interopDefaultLegacy(canvasRenderer); + +/** + * Parses a substring of the hash as a number. + * @param {number} startPosition + * @param {number=} octets + */ +function parseHex(hash, startPosition, octets) { + return parseInt(hash.substr(startPosition, octets), 16); +} + +function decToHex(v) { + v |= 0; // Ensure integer value + return v < 0 ? "00" : + v < 16 ? "0" + v.toString(16) : + v < 256 ? v.toString(16) : + "ff"; +} + +function hueToRgb(m1, m2, h) { + h = h < 0 ? h + 6 : h > 6 ? h - 6 : h; + return decToHex(255 * ( + h < 1 ? m1 + (m2 - m1) * h : + h < 3 ? m2 : + h < 4 ? m1 + (m2 - m1) * (4 - h) : + m1)); +} + +/** + * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported. + * @returns {string} + */ +function parseColor(color) { + if (/^#[0-9a-f]{3,8}$/i.test(color)) { + let result; + const colorLength = color.length; + + if (colorLength < 6) { + const r = color[1], + g = color[2], + b = color[3], + a = color[4] || ""; + result = "#" + r + r + g + g + b + b + a + a; + } + if (colorLength == 7 || colorLength > 8) { + result = color; + } + + return result; + } +} + +/** + * Converts a hexadecimal color to a CSS3 compatible color. + * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA" + * @returns {string} + */ +function toCss3Color(hexColor) { + const a = parseHex(hexColor, 7, 2); + let result; + + if (isNaN(a)) { + result = hexColor; + } else { + const r = parseHex(hexColor, 1, 2), + g = parseHex(hexColor, 3, 2), + b = parseHex(hexColor, 5, 2); + result = "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")"; + } + + return result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function hsl(hue, saturation, lightness) { + // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color + let result; + + if (saturation == 0) { + const partialHex = decToHex(lightness * 255); + result = partialHex + partialHex + partialHex; + } + else { + const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation, + m1 = lightness * 2 - m2; + result = + hueToRgb(m1, m2, hue * 6 + 2) + + hueToRgb(m1, m2, hue * 6) + + hueToRgb(m1, m2, hue * 6 - 2); + } + + return "#" + result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the "dark" hues + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function correctedHsl(hue, saturation, lightness) { + // The corrector specifies the perceived middle lightness for each hue + const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ], + corrector = correctors[(hue * 6 + 0.5) | 0]; + + // Adjust the input lightness relative to the corrector + lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2; + + return hsl(hue, saturation, lightness); +} + +// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for +// backward compatibility. + +const GLOBAL = + typeof window !== "undefined" ? window : + typeof self !== "undefined" ? self : + typeof global !== "undefined" ? global : + {}; + +/** + * @typedef {Object} ParsedConfiguration + * @property {number} colorSaturation + * @property {number} grayscaleSaturation + * @property {string} backColor + * @property {number} iconPadding + * @property {function(number):number} hue + * @property {function(number):number} colorLightness + * @property {function(number):number} grayscaleLightness + */ + +const CONFIG_PROPERTIES = { + GLOBAL: "jdenticon_config", + MODULE: "config", +}; + +var rootConfigurationHolder = {}; + +/** + * Defines the deprecated `config` property on the root Jdenticon object. When the property is set a warning is + * printed in the console. To minimize bundle size, this is only used in Node bundles. + * @param {!Object} rootObject + */ +function defineConfigPropertyWithWarn(rootObject) { + Object.defineProperty(rootObject, CONFIG_PROPERTIES.MODULE, { + configurable: true, + get: () => rootConfigurationHolder[CONFIG_PROPERTIES.MODULE], + set: newConfiguration => { + rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration; + console.warn("jdenticon.config is deprecated. Use jdenticon.configure() instead."); + }, + }); +} + +/** + * Sets a new icon style configuration. The new configuration is not merged with the previous one. * + * @param {Object} newConfiguration - New configuration object. + */ +function configure(newConfiguration) { + if (arguments.length) { + rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration; + } + return rootConfigurationHolder[CONFIG_PROPERTIES.MODULE]; +} + +/** + * Gets the normalized current Jdenticon color configuration. Missing fields have default values. + * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A + * local configuration overrides the global configuration in it entirety. This parameter can for backward + * compatibility also contain a padding value. A padding value only overrides the global padding, not the + * entire global configuration. + * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor + * explicitly to the API method. + * @returns {ParsedConfiguration} + */ +function getConfiguration(paddingOrLocalConfig, defaultPadding) { + const configObject = + typeof paddingOrLocalConfig == "object" && paddingOrLocalConfig || + rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] || + GLOBAL[CONFIG_PROPERTIES.GLOBAL] || + { }, + + lightnessConfig = configObject["lightness"] || { }, + + // In versions < 2.1.0 there was no grayscale saturation - + // saturation was the color saturation. + saturation = configObject["saturation"] || { }, + colorSaturation = "color" in saturation ? saturation["color"] : saturation, + grayscaleSaturation = saturation["grayscale"], + + backColor = configObject["backColor"], + padding = configObject["padding"]; + + /** + * Creates a lightness range. + */ + function lightness(configName, defaultRange) { + let range = lightnessConfig[configName]; + + // Check if the lightness range is an array-like object. This way we ensure the + // array contain two values at the same time. + if (!(range && range.length > 1)) { + range = defaultRange; + } + + /** + * Gets a lightness relative the specified value in the specified lightness range. + */ + return function (value) { + value = range[0] + value * (range[1] - range[0]); + return value < 0 ? 0 : value > 1 ? 1 : value; + }; + } + + /** + * Gets a hue allowed by the configured hue restriction, + * provided the originally computed hue. + */ + function hueFunction(originalHue) { + const hueConfig = configObject["hues"]; + let hue; + + // Check if 'hues' is an array-like object. This way we also ensure that + // the array is not empty, which would mean no hue restriction. + if (hueConfig && hueConfig.length > 0) { + // originalHue is in the range [0, 1] + // Multiply with 0.999 to change the range to [0, 1) and then truncate the index. + hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)]; + } + + return typeof hue == "number" ? + + // A hue was specified. We need to convert the hue from + // degrees on any turn - e.g. 746° is a perfectly valid hue - + // to turns in the range [0, 1). + ((((hue / 360) % 1) + 1) % 1) : + + // No hue configured => use original hue + originalHue; + } + + return { + hue: hueFunction, + colorSaturation: typeof colorSaturation == "number" ? colorSaturation : 0.5, + grayscaleSaturation: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0, + colorLightness: lightness("color", [0.4, 0.8]), + grayscaleLightness: lightness("grayscale", [0.3, 0.9]), + backColor: parseColor(backColor), + iconPadding: + typeof paddingOrLocalConfig == "number" ? paddingOrLocalConfig : + typeof padding == "number" ? padding : + defaultPadding + } +} + +/** + * Represents a point. + */ +class Point { + /** + * @param {number} x + * @param {number} y + */ + constructor(x, y) { + this.x = x; + this.y = y; + } +} + +/** + * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, + * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly. + */ +class Transform { + /** + * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle. + * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle. + * @param {number} size The size of the transformed rectangle. + * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad + */ + constructor(x, y, size, rotation) { + this._x = x; + this._y = y; + this._size = size; + this._rotation = rotation; + } + + /** + * Transforms the specified point based on the translation and rotation specification for this Transform. + * @param {number} x x-coordinate + * @param {number} y y-coordinate + * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + */ + transformIconPoint(x, y, w, h) { + const right = this._x + this._size, + bottom = this._y + this._size, + rotation = this._rotation; + return rotation === 1 ? new Point(right - y - (h || 0), this._y + x) : + rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) : + rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) : + new Point(this._x + x, this._y + y); + } +} + +const NO_TRANSFORM = new Transform(0, 0, 0, 0); + + + +/** + * Provides helper functions for rendering common basic shapes. + */ +class Graphics { + /** + * @param {Renderer} renderer + */ + constructor(renderer) { + /** + * @type {Renderer} + * @private + */ + this._renderer = renderer; + + /** + * @type {Transform} + */ + this.currentTransform = NO_TRANSFORM; + } + + /** + * Adds a polygon to the underlying renderer. + * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ] + * @param {boolean=} invert Specifies if the polygon will be inverted. + */ + addPolygon(points, invert) { + const di = invert ? -2 : 2, + transformedPoints = []; + + for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) { + transformedPoints.push(this.currentTransform.transformIconPoint(points[i], points[i + 1])); + } + + this._renderer.addPolygon(transformedPoints); + } + + /** + * Adds a polygon to the underlying renderer. + * Source: http://stackoverflow.com/a/2173084 + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} size The size of the ellipse. + * @param {boolean=} invert Specifies if the ellipse will be inverted. + */ + addCircle(x, y, size, invert) { + const p = this.currentTransform.transformIconPoint(x, y, size, size); + this._renderer.addCircle(p, size, invert); + } + + /** + * Adds a rectangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle. + * @param {number} w The width of the rectangle. + * @param {number} h The height of the rectangle. + * @param {boolean=} invert Specifies if the rectangle will be inverted. + */ + addRectangle(x, y, w, h, invert) { + this.addPolygon([ + x, y, + x + w, y, + x + w, y + h, + x, y + h + ], invert); + } + + /** + * Adds a right triangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} w The width of the triangle. + * @param {number} h The height of the triangle. + * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle. + * @param {boolean=} invert Specifies if the triangle will be inverted. + */ + addTriangle(x, y, w, h, r, invert) { + const points = [ + x + w, y, + x + w, y + h, + x, y + h, + x, y + ]; + points.splice(((r || 0) % 4) * 2, 2); + this.addPolygon(points, invert); + } + + /** + * Adds a rhombus to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} w The width of the rhombus. + * @param {number} h The height of the rhombus. + * @param {boolean=} invert Specifies if the rhombus will be inverted. + */ + addRhombus(x, y, w, h, invert) { + this.addPolygon([ + x + w / 2, y, + x + w, y + h / 2, + x + w / 2, y + h, + x, y + h / 2 + ], invert); + } +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + * @param {number} positionIndex + */ +function centerShape(index, g, cell, positionIndex) { + index = index % 14; + + let k, m, w, h, inner, outer; + + !index ? ( + k = cell * 0.42, + g.addPolygon([ + 0, 0, + cell, 0, + cell, cell - k * 2, + cell - k, cell, + 0, cell + ])) : + + index == 1 ? ( + w = 0 | (cell * 0.5), + h = 0 | (cell * 0.8), + + g.addTriangle(cell - w, 0, w, h, 2)) : + + index == 2 ? ( + w = 0 | (cell / 3), + g.addRectangle(w, w, cell - w, cell - w)) : + + index == 3 ? ( + inner = cell * 0.1, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 6 ? 1 : + cell < 8 ? 2 : + (0 | (cell * 0.25)), + + inner = + inner > 1 ? (0 | inner) : // large icon => truncate decimals + inner > 0.5 ? 1 : // medium size icon => fixed width + inner, // small icon => anti-aliased border + + g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer)) : + + index == 4 ? ( + m = 0 | (cell * 0.15), + w = 0 | (cell * 0.5), + g.addCircle(cell - w - m, cell - w - m, w)) : + + index == 5 ? ( + inner = cell * 0.1, + outer = inner * 4, + + // Align edge to nearest pixel in large icons + outer > 3 && (outer = 0 | outer), + + g.addRectangle(0, 0, cell, cell), + g.addPolygon([ + outer, outer, + cell - inner, outer, + outer + (cell - outer - inner) / 2, cell - inner + ], true)) : + + index == 6 ? + g.addPolygon([ + 0, 0, + cell, 0, + cell, cell * 0.7, + cell * 0.4, cell * 0.4, + cell * 0.7, cell, + 0, cell + ]) : + + index == 7 ? + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 8 ? ( + g.addRectangle(0, 0, cell, cell / 2), + g.addRectangle(0, cell / 2, cell / 2, cell / 2), + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1)) : + + index == 9 ? ( + inner = cell * 0.14, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 4 ? 1 : + cell < 6 ? 2 : + (0 | (cell * 0.35)), + + inner = + cell < 8 ? inner : // small icon => anti-aliased border + (0 | inner), // large icon => truncate decimals + + g.addRectangle(0, 0, cell, cell), + g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true)) : + + index == 10 ? ( + inner = cell * 0.12, + outer = inner * 3, + + g.addRectangle(0, 0, cell, cell), + g.addCircle(outer, outer, cell - inner - outer, true)) : + + index == 11 ? + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 12 ? ( + m = cell * 0.25, + g.addRectangle(0, 0, cell, cell), + g.addRhombus(m, m, cell - m, cell - m, true)) : + + // 13 + ( + !positionIndex && ( + m = cell * 0.4, w = cell * 1.2, + g.addCircle(m, m, w) + ) + ); +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + */ +function outerShape(index, g, cell) { + index = index % 4; + + let m; + + !index ? + g.addTriangle(0, 0, cell, cell, 0) : + + index == 1 ? + g.addTriangle(0, cell / 2, cell, cell / 2, 0) : + + index == 2 ? + g.addRhombus(0, 0, cell, cell) : + + // 3 + ( + m = cell / 6, + g.addCircle(m, m, cell - 2 * m) + ); +} + +/** + * Gets a set of identicon color candidates for a specified hue and config. + * @param {number} hue + * @param {ParsedConfiguration} config + */ +function colorTheme(hue, config) { + hue = config.hue(hue); + return [ + // Dark gray + correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)), + // Mid color + correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)), + // Light gray + correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)), + // Light color + correctedHsl(hue, config.colorSaturation, config.colorLightness(1)), + // Dark color + correctedHsl(hue, config.colorSaturation, config.colorLightness(0)) + ]; +} + +/** + * Draws an identicon to a specified renderer. + * @param {Renderer} renderer + * @param {string} hash + * @param {Object|number=} config + */ +function iconGenerator(renderer, hash, config) { + const parsedConfig = getConfiguration(config, 0.08); + + // Set background color + if (parsedConfig.backColor) { + renderer.setBackground(parsedConfig.backColor); + } + + // Calculate padding and round to nearest integer + let size = renderer.iconSize; + const padding = (0.5 + size * parsedConfig.iconPadding) | 0; + size -= padding * 2; + + const graphics = new Graphics(renderer); + + // Calculate cell size and ensure it is an integer + const cell = 0 | (size / 4); + + // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon + const x = 0 | (padding + size / 2 - cell * 2); + const y = 0 | (padding + size / 2 - cell * 2); + + function renderShape(colorIndex, shapes, index, rotationIndex, positions) { + const shapeIndex = parseHex(hash, index, 1); + let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0; + + renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]); + + for (let i = 0; i < positions.length; i++) { + graphics.currentTransform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4); + shapes(shapeIndex, graphics, cell, i); + } + + renderer.endShape(); + } + + // AVAILABLE COLORS + const hue = parseHex(hash, -7) / 0xfffffff, + + // Available colors for this icon + availableColors = colorTheme(hue, parsedConfig), + + // The index of the selected colors + selectedColorIndexes = []; + + let index; + + function isDuplicate(values) { + if (values.indexOf(index) >= 0) { + for (let i = 0; i < values.length; i++) { + if (selectedColorIndexes.indexOf(values[i]) >= 0) { + return true; + } + } + } + } + + for (let i = 0; i < 3; i++) { + index = parseHex(hash, 8 + i, 1) % availableColors.length; + if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo + isDuplicate([2, 3])) { // Disallow light gray and light color combo + index = 1; + } + selectedColorIndexes.push(index); + } + + // ACTUAL RENDERING + // Sides + renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]); + // Corners + renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]); + // Center + renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]); + + renderer.finish(); +} + +/** + * Computes a SHA1 hash for any value and returns it as a hexadecimal string. + * + * This function is optimized for minimal code size and rather short messages. + * + * @param {string} message + */ +function sha1(message) { + const HASH_SIZE_HALF_BYTES = 40; + const BLOCK_SIZE_WORDS = 16; + + // Variables + // `var` is used to be able to minimize the number of `var` keywords. + var i = 0, + f = 0, + + // Use `encodeURI` to UTF8 encode the message without any additional libraries + // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky + // since `unescape` is deprecated. + urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding + + // This can be changed to a preallocated Uint32Array array for greater performance and larger code size + data = [], + dataSize, + + hashBuffer = [], + + a = 0x67452301, + b = 0xefcdab89, + c = ~a, + d = ~b, + e = 0xc3d2e1f0, + hash = [a, b, c, d, e], + + blockStartIndex = 0, + hexHash = ""; + + /** + * Rotates the value a specified number of bits to the left. + * @param {number} value Value to rotate + * @param {number} shift Bit count to shift. + */ + function rotl(value, shift) { + return (value << shift) | (value >>> (32 - shift)); + } + + // Message data + for ( ; i < urlEncodedMessage.length; f++) { + data[f >> 2] = data[f >> 2] | + ( + ( + urlEncodedMessage[i] == "%" + // Percent encoded byte + ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16) + // Unencoded byte + : urlEncodedMessage.charCodeAt(i++) + ) + + // Read bytes in reverse order (big endian words) + << ((3 - (f & 3)) * 8) + ); + } + + // f is now the length of the utf8 encoded message + // 7 = 8 bytes (64 bit) for message size, -1 to round down + // >> 6 = integer division with block size + dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS; + + // Message size in bits. + // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least + // significant 32 bits are set. -8 is for the '1' bit padding byte. + data[dataSize - 1] = f * 8 - 8; + + // Compute hash + for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) { + for (i = 0; i < 80; i++) { + f = rotl(a, 5) + e + ( + // Ch + i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 : + + // Parity + i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 : + + // Maj + i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc : + + // Parity + (b ^ c ^ d) + 0xca62c1d6 + ) + ( + hashBuffer[i] = i < BLOCK_SIZE_WORDS + // Bitwise OR is used to coerse `undefined` to 0 + ? (data[blockStartIndex + i] | 0) + : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1) + ); + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = f; + } + + hash[0] = a = ((hash[0] + a) | 0); + hash[1] = b = ((hash[1] + b) | 0); + hash[2] = c = ((hash[2] + c) | 0); + hash[3] = d = ((hash[3] + d) | 0); + hash[4] = e = ((hash[4] + e) | 0); + } + + // Format hex hash + for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) { + hexHash += ( + ( + // Get word (2^3 half-bytes per word) + hash[i >> 3] >>> + + // Append half-bytes in reverse order + ((7 - (i & 7)) * 4) + ) + // Clamp to half-byte + & 0xf + ).toString(16); + } + + return hexHash; +} + +/** + * Inputs a value that might be a valid hash string for Jdenticon and returns it + * if it is determined valid, otherwise a falsy value is returned. + */ +function isValidHash(hashCandidate) { + return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate; +} + +/** + * Computes a hash for the specified value. Currently SHA1 is used. This function + * always returns a valid hash. + */ +function computeHash(value) { + return sha1(value == null ? "" : "" + value); +} + + + +/** + * Renderer redirecting drawing commands to a canvas context. + * @implements {Renderer} + */ +class CanvasRenderer { + /** + * @param {number=} iconSize + */ + constructor(ctx, iconSize) { + const canvas = ctx.canvas; + const width = canvas.width; + const height = canvas.height; + + ctx.save(); + + if (!iconSize) { + iconSize = Math.min(width, height); + + ctx.translate( + ((width - iconSize) / 2) | 0, + ((height - iconSize) / 2) | 0); + } + + /** + * @private + */ + this._ctx = ctx; + this.iconSize = iconSize; + + ctx.clearRect(0, 0, iconSize, iconSize); + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + setBackground(fillColor) { + const ctx = this._ctx; + const iconSize = this.iconSize; + + ctx.fillStyle = toCss3Color(fillColor); + ctx.fillRect(0, 0, iconSize, iconSize); + } + + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} fillColor Fill color on format #rrggbb[aa]. + */ + beginShape(fillColor) { + const ctx = this._ctx; + ctx.fillStyle = toCss3Color(fillColor); + ctx.beginPath(); + } + + /** + * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas. + */ + endShape() { + this._ctx.fill(); + } + + /** + * Adds a polygon to the rendering queue. + * @param points An array of Point objects. + */ + addPolygon(points) { + const ctx = this._ctx; + ctx.moveTo(points[0].x, points[0].y); + for (let i = 1; i < points.length; i++) { + ctx.lineTo(points[i].x, points[i].y); + } + ctx.closePath(); + } + + /** + * Adds a circle to the rendering queue. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle(point, diameter, counterClockwise) { + const ctx = this._ctx, + radius = diameter / 2; + ctx.moveTo(point.x + radius, point.y + radius); + ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise); + ctx.closePath(); + } + + /** + * Called when the icon has been completely drawn. + */ + finish() { + this._ctx.restore(); + } +} + +/** + * Draws an identicon to a context. + * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0). + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function drawIcon(ctx, hashOrValue, size, config) { + if (!ctx) { + throw new Error("No canvas specified."); + } + + iconGenerator(new CanvasRenderer(ctx, size), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); +} + +/** + * Draws an identicon as PNG. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + * @returns {Buffer} PNG data + */ +function toPng(hashOrValue, size, config) { + const canvas = canvasRenderer__default['default'].createCanvas(size, size); + const ctx = canvas.getContext("2d"); + + iconGenerator(new CanvasRenderer(ctx, size), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); + + return canvas.toPng({ "Software": "Jdenticon" }); +} + +/** + * Prepares a measure to be used as a measure in an SVG path, by + * rounding the measure to a single decimal. This reduces the file + * size of the generated SVG with more than 50% in some cases. + */ +function svgValue(value) { + return ((value * 10 + 0.5) | 0) / 10; +} + +/** + * Represents an SVG path element. + */ +class SvgPath { + constructor() { + /** + * This property holds the data string (path.d) of the SVG path. + * @type {string} + */ + this.dataString = ""; + } + + /** + * Adds a polygon with the current fill color to the SVG path. + * @param points An array of Point objects. + */ + addPolygon(points) { + let dataString = ""; + for (let i = 0; i < points.length; i++) { + dataString += (i ? "L" : "M") + svgValue(points[i].x) + " " + svgValue(points[i].y); + } + this.dataString += dataString + "Z"; + } + + /** + * Adds a circle with the current fill color to the SVG path. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle(point, diameter, counterClockwise) { + const sweepFlag = counterClockwise ? 0 : 1, + svgRadius = svgValue(diameter / 2), + svgDiameter = svgValue(diameter), + svgArc = "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " "; + + this.dataString += + "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) + + svgArc + svgDiameter + ",0" + + svgArc + (-svgDiameter) + ",0"; + } +} + + + +/** + * Renderer producing SVG output. + * @implements {Renderer} + */ +class SvgRenderer { + /** + * @param {SvgElement|SvgWriter} target + */ + constructor(target) { + /** + * @type {SvgPath} + * @private + */ + this._path; + + /** + * @type {Object.} + * @private + */ + this._pathsByColor = { }; + + /** + * @type {SvgElement|SvgWriter} + * @private + */ + this._target = target; + + /** + * @type {number} + */ + this.iconSize = target.iconSize; + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + setBackground(fillColor) { + const match = /^(#......)(..)?/.exec(fillColor), + opacity = match[2] ? parseHex(match[2], 0) / 255 : 1; + this._target.setBackground(match[1], opacity); + } + + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} color Fill color on format #xxxxxx. + */ + beginShape(color) { + this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath()); + } + + /** + * Marks the end of the currently drawn shape. + */ + endShape() { } + + /** + * Adds a polygon with the current fill color to the SVG. + * @param points An array of Point objects. + */ + addPolygon(points) { + this._path.addPolygon(points); + } + + /** + * Adds a circle with the current fill color to the SVG. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle(point, diameter, counterClockwise) { + this._path.addCircle(point, diameter, counterClockwise); + } + + /** + * Called when the icon has been completely drawn. + */ + finish() { + const pathsByColor = this._pathsByColor; + for (let color in pathsByColor) { + // hasOwnProperty cannot be shadowed in pathsByColor + // eslint-disable-next-line no-prototype-builtins + if (pathsByColor.hasOwnProperty(color)) { + this._target.appendPath(color, pathsByColor[color].dataString); + } + } + } +} + +const SVG_CONSTANTS = { + XMLNS: "http://www.w3.org/2000/svg", + WIDTH: "width", + HEIGHT: "height", +}; + +/** + * Renderer producing SVG output. + */ +class SvgWriter { + /** + * @param {number} iconSize - Icon width and height in pixels. + */ + constructor(iconSize) { + /** + * @type {number} + */ + this.iconSize = iconSize; + + /** + * @type {string} + * @private + */ + this._s = + ''; + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ + setBackground(fillColor, opacity) { + if (opacity) { + this._s += ''; + } + } + + /** + * Writes a path to the SVG string. + * @param {string} color Fill color on format #rrggbb. + * @param {string} dataString The SVG path data string. + */ + appendPath(color, dataString) { + this._s += ''; + } + + /** + * Gets the rendered image as an SVG string. + */ + toString() { + return this._s + ""; + } +} + +/** + * Draws an identicon as an SVG string. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + * @returns {string} SVG string + */ +function toSvg(hashOrValue, size, config) { + const writer = new SvgWriter(size); + iconGenerator(new SvgRenderer(writer), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); + return writer.toString(); +} + +// This file is compiled to dist/jdenticon-node.js + +if (typeof process === "undefined" && + typeof window !== "undefined" && + typeof document !== "undefined" +) { + console.warn( + "Jdenticon: 'dist/jdenticon-node.js' is only intended for Node.js environments and will increase your " + + "bundle size when included in browser bundles. If you want to run Jdenticon in the browser, please add a " + + "reference to 'dist/jdenticon.js' or 'dist/jdenticon.min.js' instead."); +} + +/** + * @throws {Error} + */ +function jdenticon() { + throw new Error("jdenticon() is not supported on Node.js."); +} + +defineConfigPropertyWithWarn(jdenticon); + +jdenticon.configure = configure; +jdenticon.drawIcon = drawIcon; +jdenticon.toPng = toPng; +jdenticon.toSvg = toSvg; + +/** + * Specifies the version of the Jdenticon package in use. + * @type {string} + */ +jdenticon.version = "3.1.0"; + +/** + * Specifies which bundle of Jdenticon that is used. + * @type {string} + */ +jdenticon.bundle = "node-cjs"; + +/** + * @throws {Error} + */ +jdenticon.update = function update() { + throw new Error("jdenticon.update() is not supported on Node.js."); +}; + +/** + * @throws {Error} + */ +jdenticon.updateCanvas = function updateCanvas() { + throw new Error("jdenticon.updateCanvas() is not supported on Node.js."); +}; + +/** + * @throws {Error} + */ +jdenticon.updateSvg = function updateSvg() { + throw new Error("jdenticon.updateSvg() is not supported on Node.js."); +}; + +module.exports = jdenticon; +//# sourceMappingURL=jdenticon-node.js.map diff --git a/www/vendor/jdenticon-node.js.map b/www/vendor/jdenticon-node.js.map new file mode 100644 index 0000000..cd15848 --- /dev/null +++ b/www/vendor/jdenticon-node.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["replacement/1","src/common/parseHex.js","src/renderer/color.js","src/common/global.js","src/common/configuration.js","src/renderer/point.js","src/renderer/transform.js","src/renderer/graphics.js","src/renderer/shapes.js","src/renderer/colorTheme.js","src/renderer/iconGenerator.js","src/common/sha1.js","src/common/hashUtils.js","src/renderer/canvas/canvasRenderer.js","src/apis/drawIcon.js","src/apis/toPng.js","src/renderer/svg/svgPath.js","src/renderer/svg/svgRenderer.js","src/renderer/svg/constants.js","src/renderer/svg/svgWriter.js","src/apis/toSvg.js","src/node-cjs.js","replacement/2"],"names":["canvasRenderer"],"mappings":"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","file":"jdenticon-node.js","sourcesContent":["/**\r\n * Jdenticon 3.1.0\r\n * http://jdenticon.com\r\n *\r\n * Built: 2020-12-12T13:51:48.709Z\r\n * \r\n * MIT License\r\n * \r\n * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi\r\n * \r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n * \r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n * \r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Parses a substring of the hash as a number.\r\n * @param {number} startPosition \r\n * @param {number=} octets\r\n */\r\nexport function parseHex(hash, startPosition, octets) {\r\n return parseInt(hash.substr(startPosition, octets), 16);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseHex } from \"../common/parseHex\";\r\n\r\nfunction decToHex(v) {\r\n v |= 0; // Ensure integer value\r\n return v < 0 ? \"00\" :\r\n v < 16 ? \"0\" + v.toString(16) :\r\n v < 256 ? v.toString(16) :\r\n \"ff\";\r\n}\r\n\r\nfunction hueToRgb(m1, m2, h) {\r\n h = h < 0 ? h + 6 : h > 6 ? h - 6 : h;\r\n return decToHex(255 * (\r\n h < 1 ? m1 + (m2 - m1) * h :\r\n h < 3 ? m2 :\r\n h < 4 ? m1 + (m2 - m1) * (4 - h) :\r\n m1));\r\n}\r\n\r\n/**\r\n * @param {number} r Red channel [0, 255]\r\n * @param {number} g Green channel [0, 255]\r\n * @param {number} b Blue channel [0, 255]\r\n */\r\nexport function rgb(r, g, b) {\r\n return \"#\" + decToHex(r) + decToHex(g) + decToHex(b);\r\n}\r\n\r\n/**\r\n * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.\r\n * @returns {string}\r\n */\r\nexport function parseColor(color) {\r\n if (/^#[0-9a-f]{3,8}$/i.test(color)) {\r\n let result;\r\n const colorLength = color.length;\r\n\r\n if (colorLength < 6) {\r\n const r = color[1],\r\n g = color[2],\r\n b = color[3],\r\n a = color[4] || \"\";\r\n result = \"#\" + r + r + g + g + b + b + a + a;\r\n }\r\n if (colorLength == 7 || colorLength > 8) {\r\n result = color;\r\n }\r\n \r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * Converts a hexadecimal color to a CSS3 compatible color.\r\n * @param {string} hexColor Color on the format \"#RRGGBB\" or \"#RRGGBBAA\"\r\n * @returns {string}\r\n */\r\nexport function toCss3Color(hexColor) {\r\n const a = parseHex(hexColor, 7, 2);\r\n let result;\r\n\r\n if (isNaN(a)) {\r\n result = hexColor;\r\n } else {\r\n const r = parseHex(hexColor, 1, 2),\r\n g = parseHex(hexColor, 3, 2),\r\n b = parseHex(hexColor, 5, 2);\r\n result = \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (a / 255).toFixed(2) + \")\";\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color.\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function hsl(hue, saturation, lightness) {\r\n // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color\r\n let result;\r\n\r\n if (saturation == 0) {\r\n const partialHex = decToHex(lightness * 255);\r\n result = partialHex + partialHex + partialHex;\r\n }\r\n else {\r\n const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation,\r\n m1 = lightness * 2 - m2;\r\n result =\r\n hueToRgb(m1, m2, hue * 6 + 2) +\r\n hueToRgb(m1, m2, hue * 6) +\r\n hueToRgb(m1, m2, hue * 6 - 2);\r\n }\r\n\r\n return \"#\" + result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the \"dark\" hues\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function correctedHsl(hue, saturation, lightness) {\r\n // The corrector specifies the perceived middle lightness for each hue\r\n const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],\r\n corrector = correctors[(hue * 6 + 0.5) | 0];\r\n \r\n // Adjust the input lightness relative to the corrector\r\n lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2;\r\n \r\n return hsl(hue, saturation, lightness);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for\r\n// backward compatibility.\r\n\r\nexport const GLOBAL = \r\n typeof window !== \"undefined\" ? window :\r\n typeof self !== \"undefined\" ? self :\r\n typeof global !== \"undefined\" ? global :\r\n {};\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseColor } from \"../renderer/color\";\r\nimport { GLOBAL } from \"./global\";\r\n\r\n/**\r\n * @typedef {Object} ParsedConfiguration\r\n * @property {number} colorSaturation\r\n * @property {number} grayscaleSaturation\r\n * @property {string} backColor\r\n * @property {number} iconPadding\r\n * @property {function(number):number} hue\r\n * @property {function(number):number} colorLightness\r\n * @property {function(number):number} grayscaleLightness\r\n */\r\n\r\nexport const CONFIG_PROPERTIES = {\r\n GLOBAL: \"jdenticon_config\",\r\n MODULE: \"config\",\r\n};\r\n\r\nvar rootConfigurationHolder = {};\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object. When the property is set a warning is \r\n * printed in the console. To minimize bundle size, this is only used in Node bundles.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigPropertyWithWarn(rootObject) {\r\n Object.defineProperty(rootObject, CONFIG_PROPERTIES.MODULE, {\r\n configurable: true,\r\n get: () => rootConfigurationHolder[CONFIG_PROPERTIES.MODULE],\r\n set: newConfiguration => {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n console.warn(\"jdenticon.config is deprecated. Use jdenticon.configure() instead.\");\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console\r\n * when it is being used.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigProperty(rootObject) {\r\n rootConfigurationHolder = rootObject;\r\n}\r\n\r\n/**\r\n * Sets a new icon style configuration. The new configuration is not merged with the previous one. * \r\n * @param {Object} newConfiguration - New configuration object.\r\n */\r\nexport function configure(newConfiguration) {\r\n if (arguments.length) {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n }\r\n return rootConfigurationHolder[CONFIG_PROPERTIES.MODULE];\r\n}\r\n\r\n/**\r\n * Gets the normalized current Jdenticon color configuration. Missing fields have default values.\r\n * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A\r\n * local configuration overrides the global configuration in it entirety. This parameter can for backward\r\n * compatibility also contain a padding value. A padding value only overrides the global padding, not the\r\n * entire global configuration.\r\n * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor\r\n * explicitly to the API method.\r\n * @returns {ParsedConfiguration}\r\n */\r\nexport function getConfiguration(paddingOrLocalConfig, defaultPadding) {\r\n const configObject = \r\n typeof paddingOrLocalConfig == \"object\" && paddingOrLocalConfig ||\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] ||\r\n GLOBAL[CONFIG_PROPERTIES.GLOBAL] ||\r\n { },\r\n\r\n lightnessConfig = configObject[\"lightness\"] || { },\r\n \r\n // In versions < 2.1.0 there was no grayscale saturation -\r\n // saturation was the color saturation.\r\n saturation = configObject[\"saturation\"] || { },\r\n colorSaturation = \"color\" in saturation ? saturation[\"color\"] : saturation,\r\n grayscaleSaturation = saturation[\"grayscale\"],\r\n\r\n backColor = configObject[\"backColor\"],\r\n padding = configObject[\"padding\"];\r\n \r\n /**\r\n * Creates a lightness range.\r\n */\r\n function lightness(configName, defaultRange) {\r\n let range = lightnessConfig[configName];\r\n \r\n // Check if the lightness range is an array-like object. This way we ensure the\r\n // array contain two values at the same time.\r\n if (!(range && range.length > 1)) {\r\n range = defaultRange;\r\n }\r\n\r\n /**\r\n * Gets a lightness relative the specified value in the specified lightness range.\r\n */\r\n return function (value) {\r\n value = range[0] + value * (range[1] - range[0]);\r\n return value < 0 ? 0 : value > 1 ? 1 : value;\r\n };\r\n }\r\n\r\n /**\r\n * Gets a hue allowed by the configured hue restriction,\r\n * provided the originally computed hue.\r\n */\r\n function hueFunction(originalHue) {\r\n const hueConfig = configObject[\"hues\"];\r\n let hue;\r\n \r\n // Check if 'hues' is an array-like object. This way we also ensure that\r\n // the array is not empty, which would mean no hue restriction.\r\n if (hueConfig && hueConfig.length > 0) {\r\n // originalHue is in the range [0, 1]\r\n // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.\r\n hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];\r\n }\r\n\r\n return typeof hue == \"number\" ?\r\n \r\n // A hue was specified. We need to convert the hue from\r\n // degrees on any turn - e.g. 746° is a perfectly valid hue -\r\n // to turns in the range [0, 1).\r\n ((((hue / 360) % 1) + 1) % 1) :\r\n\r\n // No hue configured => use original hue\r\n originalHue;\r\n }\r\n \r\n return {\r\n hue: hueFunction,\r\n colorSaturation: typeof colorSaturation == \"number\" ? colorSaturation : 0.5,\r\n grayscaleSaturation: typeof grayscaleSaturation == \"number\" ? grayscaleSaturation : 0,\r\n colorLightness: lightness(\"color\", [0.4, 0.8]),\r\n grayscaleLightness: lightness(\"grayscale\", [0.3, 0.9]),\r\n backColor: parseColor(backColor),\r\n iconPadding: \r\n typeof paddingOrLocalConfig == \"number\" ? paddingOrLocalConfig : \r\n typeof padding == \"number\" ? padding : \r\n defaultPadding\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Represents a point.\r\n */\r\nexport class Point {\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n */\r\n constructor(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Point } from \"./point\";\r\n\r\n/**\r\n * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, \r\n * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.\r\n */\r\nexport class Transform {\r\n /**\r\n * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} size The size of the transformed rectangle.\r\n * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad\r\n */\r\n constructor(x, y, size, rotation) {\r\n this._x = x;\r\n this._y = y;\r\n this._size = size;\r\n this._rotation = rotation;\r\n }\r\n\r\n /**\r\n * Transforms the specified point based on the translation and rotation specification for this Transform.\r\n * @param {number} x x-coordinate\r\n * @param {number} y y-coordinate\r\n * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n */\r\n transformIconPoint(x, y, w, h) {\r\n const right = this._x + this._size,\r\n bottom = this._y + this._size,\r\n rotation = this._rotation;\r\n return rotation === 1 ? new Point(right - y - (h || 0), this._y + x) :\r\n rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :\r\n rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) :\r\n new Point(this._x + x, this._y + y);\r\n }\r\n}\r\n\r\nexport const NO_TRANSFORM = new Transform(0, 0, 0, 0);\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { NO_TRANSFORM } from \"./transform\";\r\n\r\n/**\r\n * @typedef {import(\"./renderer\").Renderer} Renderer\r\n * @typedef {import(\"./transform\").Transform} Transform\r\n */\r\n\r\n/**\r\n * Provides helper functions for rendering common basic shapes.\r\n */\r\nexport class Graphics {\r\n /**\r\n * @param {Renderer} renderer \r\n */\r\n constructor(renderer) {\r\n /**\r\n * @type {Renderer}\r\n * @private\r\n */\r\n this._renderer = renderer;\r\n\r\n /**\r\n * @type {Transform}\r\n */\r\n this.currentTransform = NO_TRANSFORM;\r\n }\r\n\r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]\r\n * @param {boolean=} invert Specifies if the polygon will be inverted.\r\n */\r\n addPolygon(points, invert) {\r\n const di = invert ? -2 : 2,\r\n transformedPoints = [];\r\n \r\n for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {\r\n transformedPoints.push(this.currentTransform.transformIconPoint(points[i], points[i + 1]));\r\n }\r\n \r\n this._renderer.addPolygon(transformedPoints);\r\n }\r\n \r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * Source: http://stackoverflow.com/a/2173084\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} size The size of the ellipse.\r\n * @param {boolean=} invert Specifies if the ellipse will be inverted.\r\n */\r\n addCircle(x, y, size, invert) {\r\n const p = this.currentTransform.transformIconPoint(x, y, size, size);\r\n this._renderer.addCircle(p, size, invert);\r\n }\r\n\r\n /**\r\n * Adds a rectangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle.\r\n * @param {number} w The width of the rectangle.\r\n * @param {number} h The height of the rectangle.\r\n * @param {boolean=} invert Specifies if the rectangle will be inverted.\r\n */\r\n addRectangle(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x, y, \r\n x + w, y,\r\n x + w, y + h,\r\n x, y + h\r\n ], invert);\r\n }\r\n\r\n /**\r\n * Adds a right triangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} w The width of the triangle.\r\n * @param {number} h The height of the triangle.\r\n * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.\r\n * @param {boolean=} invert Specifies if the triangle will be inverted.\r\n */\r\n addTriangle(x, y, w, h, r, invert) {\r\n const points = [\r\n x + w, y, \r\n x + w, y + h, \r\n x, y + h,\r\n x, y\r\n ];\r\n points.splice(((r || 0) % 4) * 2, 2);\r\n this.addPolygon(points, invert);\r\n }\r\n\r\n /**\r\n * Adds a rhombus to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} w The width of the rhombus.\r\n * @param {number} h The height of the rhombus.\r\n * @param {boolean=} invert Specifies if the rhombus will be inverted.\r\n */\r\n addRhombus(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x + w / 2, y,\r\n x + w, y + h / 2,\r\n x + w / 2, y + h,\r\n x, y + h / 2\r\n ], invert);\r\n }\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n * @param {number} positionIndex\r\n * @typedef {import('./graphics').Graphics} Graphics\r\n */\r\nexport function centerShape(index, g, cell, positionIndex) {\r\n index = index % 14;\r\n\r\n let k, m, w, h, inner, outer;\r\n\r\n !index ? (\r\n k = cell * 0.42,\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell - k * 2,\r\n cell - k, cell,\r\n 0, cell\r\n ])) :\r\n\r\n index == 1 ? (\r\n w = 0 | (cell * 0.5), \r\n h = 0 | (cell * 0.8),\r\n\r\n g.addTriangle(cell - w, 0, w, h, 2)) :\r\n\r\n index == 2 ? (\r\n w = 0 | (cell / 3),\r\n g.addRectangle(w, w, cell - w, cell - w)) :\r\n\r\n index == 3 ? (\r\n inner = cell * 0.1,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 6 ? 1 :\r\n cell < 8 ? 2 :\r\n (0 | (cell * 0.25)),\r\n \r\n inner = \r\n inner > 1 ? (0 | inner) : // large icon => truncate decimals\r\n inner > 0.5 ? 1 : // medium size icon => fixed width\r\n inner, // small icon => anti-aliased border\r\n\r\n g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer)) :\r\n\r\n index == 4 ? (\r\n m = 0 | (cell * 0.15),\r\n w = 0 | (cell * 0.5),\r\n g.addCircle(cell - w - m, cell - w - m, w)) :\r\n\r\n index == 5 ? (\r\n inner = cell * 0.1,\r\n outer = inner * 4,\r\n\r\n // Align edge to nearest pixel in large icons\r\n outer > 3 && (outer = 0 | outer),\r\n \r\n g.addRectangle(0, 0, cell, cell),\r\n g.addPolygon([\r\n outer, outer,\r\n cell - inner, outer,\r\n outer + (cell - outer - inner) / 2, cell - inner\r\n ], true)) :\r\n\r\n index == 6 ? \r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell * 0.7,\r\n cell * 0.4, cell * 0.4,\r\n cell * 0.7, cell,\r\n 0, cell\r\n ]) :\r\n\r\n index == 7 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 8 ? (\r\n g.addRectangle(0, 0, cell, cell / 2),\r\n g.addRectangle(0, cell / 2, cell / 2, cell / 2),\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1)) :\r\n\r\n index == 9 ? (\r\n inner = cell * 0.14,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 4 ? 1 :\r\n cell < 6 ? 2 :\r\n (0 | (cell * 0.35)),\r\n\r\n inner = \r\n cell < 8 ? inner : // small icon => anti-aliased border\r\n (0 | inner), // large icon => truncate decimals\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true)) :\r\n\r\n index == 10 ? (\r\n inner = cell * 0.12,\r\n outer = inner * 3,\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addCircle(outer, outer, cell - inner - outer, true)) :\r\n\r\n index == 11 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 12 ? (\r\n m = cell * 0.25,\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRhombus(m, m, cell - m, cell - m, true)) :\r\n\r\n // 13\r\n (\r\n !positionIndex && (\r\n m = cell * 0.4, w = cell * 1.2,\r\n g.addCircle(m, m, w)\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n */\r\nexport function outerShape(index, g, cell) {\r\n index = index % 4;\r\n\r\n let m;\r\n\r\n !index ?\r\n g.addTriangle(0, 0, cell, cell, 0) :\r\n \r\n index == 1 ?\r\n g.addTriangle(0, cell / 2, cell, cell / 2, 0) :\r\n\r\n index == 2 ?\r\n g.addRhombus(0, 0, cell, cell) :\r\n\r\n // 3\r\n (\r\n m = cell / 6,\r\n g.addCircle(m, m, cell - 2 * m)\r\n );\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { correctedHsl } from \"./color\";\r\n\r\n/**\r\n * Gets a set of identicon color candidates for a specified hue and config.\r\n * @param {number} hue\r\n * @param {import(\"../common/configuration\").ParsedConfiguration} config\r\n */\r\nexport function colorTheme(hue, config) {\r\n hue = config.hue(hue);\r\n return [\r\n // Dark gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)),\r\n // Mid color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)),\r\n // Light gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)),\r\n // Light color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(1)),\r\n // Dark color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0))\r\n ];\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Transform } from \"./transform\";\r\nimport { Graphics } from \"./graphics\";\r\nimport { centerShape, outerShape } from \"./shapes\";\r\nimport { colorTheme } from \"./colorTheme\";\r\nimport { parseHex } from \"../common/parseHex\";\r\nimport { getConfiguration } from \"../common/configuration\";\r\n \r\n/**\r\n * Draws an identicon to a specified renderer.\r\n * @param {import('./renderer').Renderer} renderer\r\n * @param {string} hash\r\n * @param {Object|number=} config\r\n */\r\nexport function iconGenerator(renderer, hash, config) {\r\n const parsedConfig = getConfiguration(config, 0.08);\r\n\r\n // Set background color\r\n if (parsedConfig.backColor) {\r\n renderer.setBackground(parsedConfig.backColor);\r\n }\r\n \r\n // Calculate padding and round to nearest integer\r\n let size = renderer.iconSize;\r\n const padding = (0.5 + size * parsedConfig.iconPadding) | 0;\r\n size -= padding * 2;\r\n \r\n const graphics = new Graphics(renderer);\r\n \r\n // Calculate cell size and ensure it is an integer\r\n const cell = 0 | (size / 4);\r\n \r\n // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon\r\n const x = 0 | (padding + size / 2 - cell * 2);\r\n const y = 0 | (padding + size / 2 - cell * 2);\r\n\r\n function renderShape(colorIndex, shapes, index, rotationIndex, positions) {\r\n const shapeIndex = parseHex(hash, index, 1);\r\n let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0;\r\n \r\n renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]);\r\n \r\n for (let i = 0; i < positions.length; i++) {\r\n graphics.currentTransform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);\r\n shapes(shapeIndex, graphics, cell, i);\r\n }\r\n \r\n renderer.endShape();\r\n }\r\n\r\n // AVAILABLE COLORS\r\n const hue = parseHex(hash, -7) / 0xfffffff,\r\n \r\n // Available colors for this icon\r\n availableColors = colorTheme(hue, parsedConfig),\r\n\r\n // The index of the selected colors\r\n selectedColorIndexes = [];\r\n\r\n let index;\r\n\r\n function isDuplicate(values) {\r\n if (values.indexOf(index) >= 0) {\r\n for (let i = 0; i < values.length; i++) {\r\n if (selectedColorIndexes.indexOf(values[i]) >= 0) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < 3; i++) {\r\n index = parseHex(hash, 8 + i, 1) % availableColors.length;\r\n if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo\r\n isDuplicate([2, 3])) { // Disallow light gray and light color combo\r\n index = 1;\r\n }\r\n selectedColorIndexes.push(index);\r\n }\r\n\r\n // ACTUAL RENDERING\r\n // Sides\r\n renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);\r\n // Corners\r\n renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);\r\n // Center\r\n renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);\r\n \r\n renderer.finish();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Computes a SHA1 hash for any value and returns it as a hexadecimal string.\r\n * \r\n * This function is optimized for minimal code size and rather short messages.\r\n * \r\n * @param {string} message \r\n */\r\nexport function sha1(message) {\r\n const HASH_SIZE_HALF_BYTES = 40;\r\n const BLOCK_SIZE_WORDS = 16;\r\n\r\n // Variables\r\n // `var` is used to be able to minimize the number of `var` keywords.\r\n var i = 0,\r\n f = 0,\r\n \r\n // Use `encodeURI` to UTF8 encode the message without any additional libraries\r\n // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky\r\n // since `unescape` is deprecated.\r\n urlEncodedMessage = encodeURI(message) + \"%80\", // trailing '1' bit padding\r\n \r\n // This can be changed to a preallocated Uint32Array array for greater performance and larger code size\r\n data = [],\r\n dataSize,\r\n \r\n hashBuffer = [],\r\n\r\n a = 0x67452301,\r\n b = 0xefcdab89,\r\n c = ~a,\r\n d = ~b,\r\n e = 0xc3d2e1f0,\r\n hash = [a, b, c, d, e],\r\n\r\n blockStartIndex = 0,\r\n hexHash = \"\";\r\n\r\n /**\r\n * Rotates the value a specified number of bits to the left.\r\n * @param {number} value Value to rotate\r\n * @param {number} shift Bit count to shift.\r\n */\r\n function rotl(value, shift) {\r\n return (value << shift) | (value >>> (32 - shift));\r\n }\r\n\r\n // Message data\r\n for ( ; i < urlEncodedMessage.length; f++) {\r\n data[f >> 2] = data[f >> 2] |\r\n (\r\n (\r\n urlEncodedMessage[i] == \"%\"\r\n // Percent encoded byte\r\n ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)\r\n // Unencoded byte\r\n : urlEncodedMessage.charCodeAt(i++)\r\n )\r\n\r\n // Read bytes in reverse order (big endian words)\r\n << ((3 - (f & 3)) * 8)\r\n );\r\n }\r\n\r\n // f is now the length of the utf8 encoded message\r\n // 7 = 8 bytes (64 bit) for message size, -1 to round down\r\n // >> 6 = integer division with block size\r\n dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;\r\n\r\n // Message size in bits.\r\n // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least\r\n // significant 32 bits are set. -8 is for the '1' bit padding byte.\r\n data[dataSize - 1] = f * 8 - 8;\r\n \r\n // Compute hash\r\n for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {\r\n for (i = 0; i < 80; i++) {\r\n f = rotl(a, 5) + e + (\r\n // Ch\r\n i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :\r\n \r\n // Parity\r\n i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :\r\n \r\n // Maj\r\n i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :\r\n \r\n // Parity\r\n (b ^ c ^ d) + 0xca62c1d6\r\n ) + ( \r\n hashBuffer[i] = i < BLOCK_SIZE_WORDS\r\n // Bitwise OR is used to coerse `undefined` to 0\r\n ? (data[blockStartIndex + i] | 0)\r\n : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)\r\n );\r\n\r\n e = d;\r\n d = c;\r\n c = rotl(b, 30);\r\n b = a;\r\n a = f;\r\n }\r\n\r\n hash[0] = a = ((hash[0] + a) | 0);\r\n hash[1] = b = ((hash[1] + b) | 0);\r\n hash[2] = c = ((hash[2] + c) | 0);\r\n hash[3] = d = ((hash[3] + d) | 0);\r\n hash[4] = e = ((hash[4] + e) | 0);\r\n }\r\n\r\n // Format hex hash\r\n for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {\r\n hexHash += (\r\n (\r\n // Get word (2^3 half-bytes per word)\r\n hash[i >> 3] >>>\r\n\r\n // Append half-bytes in reverse order\r\n ((7 - (i & 7)) * 4)\r\n ) \r\n // Clamp to half-byte\r\n & 0xf\r\n ).toString(16);\r\n }\r\n\r\n return hexHash;\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { sha1 } from \"./sha1\";\r\n\r\n/**\r\n * Inputs a value that might be a valid hash string for Jdenticon and returns it \r\n * if it is determined valid, otherwise a falsy value is returned.\r\n */\r\nexport function isValidHash(hashCandidate) {\r\n return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;\r\n}\r\n\r\n/**\r\n * Computes a hash for the specified value. Currently SHA1 is used. This function\r\n * always returns a valid hash.\r\n */\r\nexport function computeHash(value) {\r\n return sha1(value == null ? \"\" : \"\" + value);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { toCss3Color } from \"../color\";\r\n\r\n/**\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import('../point').Point} Point\r\n */\r\n\r\n/**\r\n * Renderer redirecting drawing commands to a canvas context.\r\n * @implements {Renderer}\r\n */\r\nexport class CanvasRenderer {\r\n /**\r\n * @param {number=} iconSize\r\n */\r\n constructor(ctx, iconSize) {\r\n const canvas = ctx.canvas; \r\n const width = canvas.width;\r\n const height = canvas.height;\r\n \r\n ctx.save();\r\n \r\n if (!iconSize) {\r\n iconSize = Math.min(width, height);\r\n \r\n ctx.translate(\r\n ((width - iconSize) / 2) | 0,\r\n ((height - iconSize) / 2) | 0);\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n this._ctx = ctx;\r\n this.iconSize = iconSize;\r\n \r\n ctx.clearRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const ctx = this._ctx;\r\n const iconSize = this.iconSize;\r\n\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.fillRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} fillColor Fill color on format #rrggbb[aa].\r\n */\r\n beginShape(fillColor) {\r\n const ctx = this._ctx;\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.beginPath();\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.\r\n */\r\n endShape() {\r\n this._ctx.fill();\r\n }\r\n\r\n /**\r\n * Adds a polygon to the rendering queue.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n const ctx = this._ctx;\r\n ctx.moveTo(points[0].x, points[0].y);\r\n for (let i = 1; i < points.length; i++) {\r\n ctx.lineTo(points[i].x, points[i].y);\r\n }\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Adds a circle to the rendering queue.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const ctx = this._ctx,\r\n radius = diameter / 2;\r\n ctx.moveTo(point.x + radius, point.y + radius);\r\n ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() {\r\n this._ctx.restore();\r\n }\r\n}\r\n","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\n\r\n/**\r\n * Draws an identicon to a context.\r\n * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function drawIcon(ctx, hashOrValue, size, config) {\r\n if (!ctx) {\r\n throw new Error(\"No canvas specified.\");\r\n }\r\n \r\n iconGenerator(new CanvasRenderer(ctx, size), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue), \r\n config);\r\n}\r\n","import canvasRenderer from \"canvas-renderer\";\r\nimport { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\n\r\n/**\r\n * Draws an identicon as PNG.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n * @returns {Buffer} PNG data\r\n */\r\nexport function toPng(hashOrValue, size, config) {\r\n const canvas = canvasRenderer.createCanvas(size, size);\r\n const ctx = canvas.getContext(\"2d\");\r\n \r\n iconGenerator(new CanvasRenderer(ctx, size), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue), \r\n config);\r\n \r\n return canvas.toPng({ \"Software\": \"Jdenticon\" });\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Prepares a measure to be used as a measure in an SVG path, by\r\n * rounding the measure to a single decimal. This reduces the file\r\n * size of the generated SVG with more than 50% in some cases.\r\n */\r\nfunction svgValue(value) {\r\n return ((value * 10 + 0.5) | 0) / 10;\r\n}\r\n\r\n/**\r\n * Represents an SVG path element.\r\n */\r\nexport class SvgPath {\r\n constructor() {\r\n /**\r\n * This property holds the data string (path.d) of the SVG path.\r\n * @type {string}\r\n */\r\n this.dataString = \"\";\r\n }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG path.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n let dataString = \"\";\r\n for (let i = 0; i < points.length; i++) {\r\n dataString += (i ? \"L\" : \"M\") + svgValue(points[i].x) + \" \" + svgValue(points[i].y);\r\n }\r\n this.dataString += dataString + \"Z\";\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG path.\r\n * @param {import('../point').Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const sweepFlag = counterClockwise ? 0 : 1,\r\n svgRadius = svgValue(diameter / 2),\r\n svgDiameter = svgValue(diameter),\r\n svgArc = \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \";\r\n \r\n this.dataString += \r\n \"M\" + svgValue(point.x) + \" \" + svgValue(point.y + diameter / 2) +\r\n svgArc + svgDiameter + \",0\" + \r\n svgArc + (-svgDiameter) + \",0\";\r\n }\r\n}\r\n\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SvgPath } from \"./svgPath\";\r\nimport { parseHex } from \"../../common/parseHex\";\r\n\r\n/**\r\n * @typedef {import(\"../point\").Point} Point\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import(\"./svgElement\").SvgElement} SvgElement\r\n * @typedef {import(\"./svgWriter\").SvgWriter} SvgWriter\r\n */\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @implements {Renderer}\r\n */\r\nexport class SvgRenderer {\r\n /**\r\n * @param {SvgElement|SvgWriter} target \r\n */\r\n constructor(target) {\r\n /**\r\n * @type {SvgPath}\r\n * @private\r\n */\r\n this._path;\r\n\r\n /**\r\n * @type {Object.}\r\n * @private\r\n */\r\n this._pathsByColor = { };\r\n\r\n /**\r\n * @type {SvgElement|SvgWriter}\r\n * @private\r\n */\r\n this._target = target;\r\n\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = target.iconSize;\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const match = /^(#......)(..)?/.exec(fillColor),\r\n opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;\r\n this._target.setBackground(match[1], opacity);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n */\r\n beginShape(color) {\r\n this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath());\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape.\r\n */\r\n endShape() { }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n this._path.addPolygon(points);\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n this._path.addCircle(point, diameter, counterClockwise);\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() { \r\n const pathsByColor = this._pathsByColor;\r\n for (let color in pathsByColor) {\r\n // hasOwnProperty cannot be shadowed in pathsByColor\r\n // eslint-disable-next-line no-prototype-builtins\r\n if (pathsByColor.hasOwnProperty(color)) {\r\n this._target.appendPath(color, pathsByColor[color].dataString);\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const SVG_CONSTANTS = {\r\n XMLNS: \"http://www.w3.org/2000/svg\",\r\n WIDTH: \"width\",\r\n HEIGHT: \"height\",\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgWriter {\r\n /**\r\n * @param {number} iconSize - Icon width and height in pixels.\r\n */\r\n constructor(iconSize) {\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = iconSize;\r\n\r\n /**\r\n * @type {string}\r\n * @private\r\n */\r\n this._s =\r\n '';\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n this._s += '';\r\n }\r\n }\r\n\r\n /**\r\n * Writes a path to the SVG string.\r\n * @param {string} color Fill color on format #rrggbb.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n this._s += '';\r\n }\r\n\r\n /**\r\n * Gets the rendered image as an SVG string.\r\n */\r\n toString() {\r\n return this._s + \"\";\r\n }\r\n}\r\n","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgWriter } from \"../renderer/svg/svgWriter\";\r\n\r\n/**\r\n * Draws an identicon as an SVG string.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n * @returns {string} SVG string\r\n */\r\nexport function toSvg(hashOrValue, size, config) {\r\n const writer = new SvgWriter(size);\r\n iconGenerator(new SvgRenderer(writer), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue),\r\n config);\r\n return writer.toString();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// This file is compiled to dist/jdenticon-node.js\r\n\r\nif (typeof process === \"undefined\" &&\r\n typeof window !== \"undefined\" &&\r\n typeof document !== \"undefined\"\r\n) {\r\n console.warn(\r\n \"Jdenticon: 'dist/jdenticon-node.js' is only intended for Node.js environments and will increase your \" +\r\n \"bundle size when included in browser bundles. If you want to run Jdenticon in the browser, please add a \" +\r\n \"reference to 'dist/jdenticon.js' or 'dist/jdenticon.min.js' instead.\");\r\n}\r\n\r\nimport { defineConfigPropertyWithWarn } from \"./common/configuration\";\r\nimport { configure } from \"./apis/configure\";\r\nimport { drawIcon } from \"./apis/drawIcon\";\r\nimport { toPng } from \"./apis/toPng\";\r\nimport { toSvg } from \"./apis/toSvg\";\r\n\r\n/**\r\n * @throws {Error}\r\n */\r\nfunction jdenticon() {\r\n throw new Error(\"jdenticon() is not supported on Node.js.\");\r\n}\r\n\r\ndefineConfigPropertyWithWarn(jdenticon);\r\n\r\njdenticon.configure = configure;\r\njdenticon.drawIcon = drawIcon;\r\njdenticon.toPng = toPng;\r\njdenticon.toSvg = toSvg;\r\n\r\n/**\r\n * Specifies the version of the Jdenticon package in use.\r\n * @type {string}\r\n */\r\njdenticon.version = \"#version#\";\r\n\r\n/**\r\n * Specifies which bundle of Jdenticon that is used.\r\n * @type {string}\r\n */\r\njdenticon.bundle = \"node-cjs\";\r\n\r\n/**\r\n * @throws {Error}\r\n */\r\njdenticon.update = function update() {\r\n throw new Error(\"jdenticon.update() is not supported on Node.js.\");\r\n};\r\n\r\n/**\r\n * @throws {Error}\r\n */\r\njdenticon.updateCanvas = function updateCanvas() {\r\n throw new Error(\"jdenticon.updateCanvas() is not supported on Node.js.\");\r\n};\r\n\r\n/**\r\n * @throws {Error}\r\n */\r\njdenticon.updateSvg = function updateSvg() {\r\n throw new Error(\"jdenticon.updateSvg() is not supported on Node.js.\");\r\n};\r\n\r\nmodule.exports = jdenticon;","\n//# sourceMappingURL=jdenticon-node.js.map\n"]} \ No newline at end of file diff --git a/www/vendor/jdenticon-node.mjs b/www/vendor/jdenticon-node.mjs new file mode 100644 index 0000000..0bb10ba --- /dev/null +++ b/www/vendor/jdenticon-node.mjs @@ -0,0 +1,1230 @@ +/** + * Jdenticon 3.1.0 + * http://jdenticon.com + * + * Built: 2020-12-12T13:51:48.709Z + * + * MIT License + * + * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import canvasRenderer from 'canvas-renderer'; + +/** + * Parses a substring of the hash as a number. + * @param {number} startPosition + * @param {number=} octets + */ +function parseHex(hash, startPosition, octets) { + return parseInt(hash.substr(startPosition, octets), 16); +} + +function decToHex(v) { + v |= 0; // Ensure integer value + return v < 0 ? "00" : + v < 16 ? "0" + v.toString(16) : + v < 256 ? v.toString(16) : + "ff"; +} + +function hueToRgb(m1, m2, h) { + h = h < 0 ? h + 6 : h > 6 ? h - 6 : h; + return decToHex(255 * ( + h < 1 ? m1 + (m2 - m1) * h : + h < 3 ? m2 : + h < 4 ? m1 + (m2 - m1) * (4 - h) : + m1)); +} + +/** + * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported. + * @returns {string} + */ +function parseColor(color) { + if (/^#[0-9a-f]{3,8}$/i.test(color)) { + let result; + const colorLength = color.length; + + if (colorLength < 6) { + const r = color[1], + g = color[2], + b = color[3], + a = color[4] || ""; + result = "#" + r + r + g + g + b + b + a + a; + } + if (colorLength == 7 || colorLength > 8) { + result = color; + } + + return result; + } +} + +/** + * Converts a hexadecimal color to a CSS3 compatible color. + * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA" + * @returns {string} + */ +function toCss3Color(hexColor) { + const a = parseHex(hexColor, 7, 2); + let result; + + if (isNaN(a)) { + result = hexColor; + } else { + const r = parseHex(hexColor, 1, 2), + g = parseHex(hexColor, 3, 2), + b = parseHex(hexColor, 5, 2); + result = "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")"; + } + + return result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function hsl(hue, saturation, lightness) { + // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color + let result; + + if (saturation == 0) { + const partialHex = decToHex(lightness * 255); + result = partialHex + partialHex + partialHex; + } + else { + const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation, + m1 = lightness * 2 - m2; + result = + hueToRgb(m1, m2, hue * 6 + 2) + + hueToRgb(m1, m2, hue * 6) + + hueToRgb(m1, m2, hue * 6 - 2); + } + + return "#" + result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the "dark" hues + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function correctedHsl(hue, saturation, lightness) { + // The corrector specifies the perceived middle lightness for each hue + const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ], + corrector = correctors[(hue * 6 + 0.5) | 0]; + + // Adjust the input lightness relative to the corrector + lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2; + + return hsl(hue, saturation, lightness); +} + +// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for +// backward compatibility. + +const GLOBAL = + typeof window !== "undefined" ? window : + typeof self !== "undefined" ? self : + typeof global !== "undefined" ? global : + {}; + +/** + * @typedef {Object} ParsedConfiguration + * @property {number} colorSaturation + * @property {number} grayscaleSaturation + * @property {string} backColor + * @property {number} iconPadding + * @property {function(number):number} hue + * @property {function(number):number} colorLightness + * @property {function(number):number} grayscaleLightness + */ + +const CONFIG_PROPERTIES = { + GLOBAL: "jdenticon_config", + MODULE: "config", +}; + +var rootConfigurationHolder = {}; + +/** + * Sets a new icon style configuration. The new configuration is not merged with the previous one. * + * @param {Object} newConfiguration - New configuration object. + */ +function configure(newConfiguration) { + if (arguments.length) { + rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration; + } + return rootConfigurationHolder[CONFIG_PROPERTIES.MODULE]; +} + +/** + * Gets the normalized current Jdenticon color configuration. Missing fields have default values. + * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A + * local configuration overrides the global configuration in it entirety. This parameter can for backward + * compatibility also contain a padding value. A padding value only overrides the global padding, not the + * entire global configuration. + * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor + * explicitly to the API method. + * @returns {ParsedConfiguration} + */ +function getConfiguration(paddingOrLocalConfig, defaultPadding) { + const configObject = + typeof paddingOrLocalConfig == "object" && paddingOrLocalConfig || + rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] || + GLOBAL[CONFIG_PROPERTIES.GLOBAL] || + { }, + + lightnessConfig = configObject["lightness"] || { }, + + // In versions < 2.1.0 there was no grayscale saturation - + // saturation was the color saturation. + saturation = configObject["saturation"] || { }, + colorSaturation = "color" in saturation ? saturation["color"] : saturation, + grayscaleSaturation = saturation["grayscale"], + + backColor = configObject["backColor"], + padding = configObject["padding"]; + + /** + * Creates a lightness range. + */ + function lightness(configName, defaultRange) { + let range = lightnessConfig[configName]; + + // Check if the lightness range is an array-like object. This way we ensure the + // array contain two values at the same time. + if (!(range && range.length > 1)) { + range = defaultRange; + } + + /** + * Gets a lightness relative the specified value in the specified lightness range. + */ + return function (value) { + value = range[0] + value * (range[1] - range[0]); + return value < 0 ? 0 : value > 1 ? 1 : value; + }; + } + + /** + * Gets a hue allowed by the configured hue restriction, + * provided the originally computed hue. + */ + function hueFunction(originalHue) { + const hueConfig = configObject["hues"]; + let hue; + + // Check if 'hues' is an array-like object. This way we also ensure that + // the array is not empty, which would mean no hue restriction. + if (hueConfig && hueConfig.length > 0) { + // originalHue is in the range [0, 1] + // Multiply with 0.999 to change the range to [0, 1) and then truncate the index. + hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)]; + } + + return typeof hue == "number" ? + + // A hue was specified. We need to convert the hue from + // degrees on any turn - e.g. 746° is a perfectly valid hue - + // to turns in the range [0, 1). + ((((hue / 360) % 1) + 1) % 1) : + + // No hue configured => use original hue + originalHue; + } + + return { + hue: hueFunction, + colorSaturation: typeof colorSaturation == "number" ? colorSaturation : 0.5, + grayscaleSaturation: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0, + colorLightness: lightness("color", [0.4, 0.8]), + grayscaleLightness: lightness("grayscale", [0.3, 0.9]), + backColor: parseColor(backColor), + iconPadding: + typeof paddingOrLocalConfig == "number" ? paddingOrLocalConfig : + typeof padding == "number" ? padding : + defaultPadding + } +} + +/** + * Represents a point. + */ +class Point { + /** + * @param {number} x + * @param {number} y + */ + constructor(x, y) { + this.x = x; + this.y = y; + } +} + +/** + * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, + * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly. + */ +class Transform { + /** + * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle. + * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle. + * @param {number} size The size of the transformed rectangle. + * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad + */ + constructor(x, y, size, rotation) { + this._x = x; + this._y = y; + this._size = size; + this._rotation = rotation; + } + + /** + * Transforms the specified point based on the translation and rotation specification for this Transform. + * @param {number} x x-coordinate + * @param {number} y y-coordinate + * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + */ + transformIconPoint(x, y, w, h) { + const right = this._x + this._size, + bottom = this._y + this._size, + rotation = this._rotation; + return rotation === 1 ? new Point(right - y - (h || 0), this._y + x) : + rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) : + rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) : + new Point(this._x + x, this._y + y); + } +} + +const NO_TRANSFORM = new Transform(0, 0, 0, 0); + + + +/** + * Provides helper functions for rendering common basic shapes. + */ +class Graphics { + /** + * @param {Renderer} renderer + */ + constructor(renderer) { + /** + * @type {Renderer} + * @private + */ + this._renderer = renderer; + + /** + * @type {Transform} + */ + this.currentTransform = NO_TRANSFORM; + } + + /** + * Adds a polygon to the underlying renderer. + * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ] + * @param {boolean=} invert Specifies if the polygon will be inverted. + */ + addPolygon(points, invert) { + const di = invert ? -2 : 2, + transformedPoints = []; + + for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) { + transformedPoints.push(this.currentTransform.transformIconPoint(points[i], points[i + 1])); + } + + this._renderer.addPolygon(transformedPoints); + } + + /** + * Adds a polygon to the underlying renderer. + * Source: http://stackoverflow.com/a/2173084 + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} size The size of the ellipse. + * @param {boolean=} invert Specifies if the ellipse will be inverted. + */ + addCircle(x, y, size, invert) { + const p = this.currentTransform.transformIconPoint(x, y, size, size); + this._renderer.addCircle(p, size, invert); + } + + /** + * Adds a rectangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle. + * @param {number} w The width of the rectangle. + * @param {number} h The height of the rectangle. + * @param {boolean=} invert Specifies if the rectangle will be inverted. + */ + addRectangle(x, y, w, h, invert) { + this.addPolygon([ + x, y, + x + w, y, + x + w, y + h, + x, y + h + ], invert); + } + + /** + * Adds a right triangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} w The width of the triangle. + * @param {number} h The height of the triangle. + * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle. + * @param {boolean=} invert Specifies if the triangle will be inverted. + */ + addTriangle(x, y, w, h, r, invert) { + const points = [ + x + w, y, + x + w, y + h, + x, y + h, + x, y + ]; + points.splice(((r || 0) % 4) * 2, 2); + this.addPolygon(points, invert); + } + + /** + * Adds a rhombus to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} w The width of the rhombus. + * @param {number} h The height of the rhombus. + * @param {boolean=} invert Specifies if the rhombus will be inverted. + */ + addRhombus(x, y, w, h, invert) { + this.addPolygon([ + x + w / 2, y, + x + w, y + h / 2, + x + w / 2, y + h, + x, y + h / 2 + ], invert); + } +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + * @param {number} positionIndex + */ +function centerShape(index, g, cell, positionIndex) { + index = index % 14; + + let k, m, w, h, inner, outer; + + !index ? ( + k = cell * 0.42, + g.addPolygon([ + 0, 0, + cell, 0, + cell, cell - k * 2, + cell - k, cell, + 0, cell + ])) : + + index == 1 ? ( + w = 0 | (cell * 0.5), + h = 0 | (cell * 0.8), + + g.addTriangle(cell - w, 0, w, h, 2)) : + + index == 2 ? ( + w = 0 | (cell / 3), + g.addRectangle(w, w, cell - w, cell - w)) : + + index == 3 ? ( + inner = cell * 0.1, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 6 ? 1 : + cell < 8 ? 2 : + (0 | (cell * 0.25)), + + inner = + inner > 1 ? (0 | inner) : // large icon => truncate decimals + inner > 0.5 ? 1 : // medium size icon => fixed width + inner, // small icon => anti-aliased border + + g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer)) : + + index == 4 ? ( + m = 0 | (cell * 0.15), + w = 0 | (cell * 0.5), + g.addCircle(cell - w - m, cell - w - m, w)) : + + index == 5 ? ( + inner = cell * 0.1, + outer = inner * 4, + + // Align edge to nearest pixel in large icons + outer > 3 && (outer = 0 | outer), + + g.addRectangle(0, 0, cell, cell), + g.addPolygon([ + outer, outer, + cell - inner, outer, + outer + (cell - outer - inner) / 2, cell - inner + ], true)) : + + index == 6 ? + g.addPolygon([ + 0, 0, + cell, 0, + cell, cell * 0.7, + cell * 0.4, cell * 0.4, + cell * 0.7, cell, + 0, cell + ]) : + + index == 7 ? + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 8 ? ( + g.addRectangle(0, 0, cell, cell / 2), + g.addRectangle(0, cell / 2, cell / 2, cell / 2), + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1)) : + + index == 9 ? ( + inner = cell * 0.14, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 4 ? 1 : + cell < 6 ? 2 : + (0 | (cell * 0.35)), + + inner = + cell < 8 ? inner : // small icon => anti-aliased border + (0 | inner), // large icon => truncate decimals + + g.addRectangle(0, 0, cell, cell), + g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true)) : + + index == 10 ? ( + inner = cell * 0.12, + outer = inner * 3, + + g.addRectangle(0, 0, cell, cell), + g.addCircle(outer, outer, cell - inner - outer, true)) : + + index == 11 ? + g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 12 ? ( + m = cell * 0.25, + g.addRectangle(0, 0, cell, cell), + g.addRhombus(m, m, cell - m, cell - m, true)) : + + // 13 + ( + !positionIndex && ( + m = cell * 0.4, w = cell * 1.2, + g.addCircle(m, m, w) + ) + ); +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + */ +function outerShape(index, g, cell) { + index = index % 4; + + let m; + + !index ? + g.addTriangle(0, 0, cell, cell, 0) : + + index == 1 ? + g.addTriangle(0, cell / 2, cell, cell / 2, 0) : + + index == 2 ? + g.addRhombus(0, 0, cell, cell) : + + // 3 + ( + m = cell / 6, + g.addCircle(m, m, cell - 2 * m) + ); +} + +/** + * Gets a set of identicon color candidates for a specified hue and config. + * @param {number} hue + * @param {ParsedConfiguration} config + */ +function colorTheme(hue, config) { + hue = config.hue(hue); + return [ + // Dark gray + correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)), + // Mid color + correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)), + // Light gray + correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)), + // Light color + correctedHsl(hue, config.colorSaturation, config.colorLightness(1)), + // Dark color + correctedHsl(hue, config.colorSaturation, config.colorLightness(0)) + ]; +} + +/** + * Draws an identicon to a specified renderer. + * @param {Renderer} renderer + * @param {string} hash + * @param {Object|number=} config + */ +function iconGenerator(renderer, hash, config) { + const parsedConfig = getConfiguration(config, 0.08); + + // Set background color + if (parsedConfig.backColor) { + renderer.setBackground(parsedConfig.backColor); + } + + // Calculate padding and round to nearest integer + let size = renderer.iconSize; + const padding = (0.5 + size * parsedConfig.iconPadding) | 0; + size -= padding * 2; + + const graphics = new Graphics(renderer); + + // Calculate cell size and ensure it is an integer + const cell = 0 | (size / 4); + + // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon + const x = 0 | (padding + size / 2 - cell * 2); + const y = 0 | (padding + size / 2 - cell * 2); + + function renderShape(colorIndex, shapes, index, rotationIndex, positions) { + const shapeIndex = parseHex(hash, index, 1); + let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0; + + renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]); + + for (let i = 0; i < positions.length; i++) { + graphics.currentTransform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4); + shapes(shapeIndex, graphics, cell, i); + } + + renderer.endShape(); + } + + // AVAILABLE COLORS + const hue = parseHex(hash, -7) / 0xfffffff, + + // Available colors for this icon + availableColors = colorTheme(hue, parsedConfig), + + // The index of the selected colors + selectedColorIndexes = []; + + let index; + + function isDuplicate(values) { + if (values.indexOf(index) >= 0) { + for (let i = 0; i < values.length; i++) { + if (selectedColorIndexes.indexOf(values[i]) >= 0) { + return true; + } + } + } + } + + for (let i = 0; i < 3; i++) { + index = parseHex(hash, 8 + i, 1) % availableColors.length; + if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo + isDuplicate([2, 3])) { // Disallow light gray and light color combo + index = 1; + } + selectedColorIndexes.push(index); + } + + // ACTUAL RENDERING + // Sides + renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]); + // Corners + renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]); + // Center + renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]); + + renderer.finish(); +} + +/** + * Computes a SHA1 hash for any value and returns it as a hexadecimal string. + * + * This function is optimized for minimal code size and rather short messages. + * + * @param {string} message + */ +function sha1(message) { + const HASH_SIZE_HALF_BYTES = 40; + const BLOCK_SIZE_WORDS = 16; + + // Variables + // `var` is used to be able to minimize the number of `var` keywords. + var i = 0, + f = 0, + + // Use `encodeURI` to UTF8 encode the message without any additional libraries + // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky + // since `unescape` is deprecated. + urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding + + // This can be changed to a preallocated Uint32Array array for greater performance and larger code size + data = [], + dataSize, + + hashBuffer = [], + + a = 0x67452301, + b = 0xefcdab89, + c = ~a, + d = ~b, + e = 0xc3d2e1f0, + hash = [a, b, c, d, e], + + blockStartIndex = 0, + hexHash = ""; + + /** + * Rotates the value a specified number of bits to the left. + * @param {number} value Value to rotate + * @param {number} shift Bit count to shift. + */ + function rotl(value, shift) { + return (value << shift) | (value >>> (32 - shift)); + } + + // Message data + for ( ; i < urlEncodedMessage.length; f++) { + data[f >> 2] = data[f >> 2] | + ( + ( + urlEncodedMessage[i] == "%" + // Percent encoded byte + ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16) + // Unencoded byte + : urlEncodedMessage.charCodeAt(i++) + ) + + // Read bytes in reverse order (big endian words) + << ((3 - (f & 3)) * 8) + ); + } + + // f is now the length of the utf8 encoded message + // 7 = 8 bytes (64 bit) for message size, -1 to round down + // >> 6 = integer division with block size + dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS; + + // Message size in bits. + // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least + // significant 32 bits are set. -8 is for the '1' bit padding byte. + data[dataSize - 1] = f * 8 - 8; + + // Compute hash + for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) { + for (i = 0; i < 80; i++) { + f = rotl(a, 5) + e + ( + // Ch + i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 : + + // Parity + i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 : + + // Maj + i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc : + + // Parity + (b ^ c ^ d) + 0xca62c1d6 + ) + ( + hashBuffer[i] = i < BLOCK_SIZE_WORDS + // Bitwise OR is used to coerse `undefined` to 0 + ? (data[blockStartIndex + i] | 0) + : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1) + ); + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = f; + } + + hash[0] = a = ((hash[0] + a) | 0); + hash[1] = b = ((hash[1] + b) | 0); + hash[2] = c = ((hash[2] + c) | 0); + hash[3] = d = ((hash[3] + d) | 0); + hash[4] = e = ((hash[4] + e) | 0); + } + + // Format hex hash + for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) { + hexHash += ( + ( + // Get word (2^3 half-bytes per word) + hash[i >> 3] >>> + + // Append half-bytes in reverse order + ((7 - (i & 7)) * 4) + ) + // Clamp to half-byte + & 0xf + ).toString(16); + } + + return hexHash; +} + +/** + * Inputs a value that might be a valid hash string for Jdenticon and returns it + * if it is determined valid, otherwise a falsy value is returned. + */ +function isValidHash(hashCandidate) { + return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate; +} + +/** + * Computes a hash for the specified value. Currently SHA1 is used. This function + * always returns a valid hash. + */ +function computeHash(value) { + return sha1(value == null ? "" : "" + value); +} + + + +/** + * Renderer redirecting drawing commands to a canvas context. + * @implements {Renderer} + */ +class CanvasRenderer { + /** + * @param {number=} iconSize + */ + constructor(ctx, iconSize) { + const canvas = ctx.canvas; + const width = canvas.width; + const height = canvas.height; + + ctx.save(); + + if (!iconSize) { + iconSize = Math.min(width, height); + + ctx.translate( + ((width - iconSize) / 2) | 0, + ((height - iconSize) / 2) | 0); + } + + /** + * @private + */ + this._ctx = ctx; + this.iconSize = iconSize; + + ctx.clearRect(0, 0, iconSize, iconSize); + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + setBackground(fillColor) { + const ctx = this._ctx; + const iconSize = this.iconSize; + + ctx.fillStyle = toCss3Color(fillColor); + ctx.fillRect(0, 0, iconSize, iconSize); + } + + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} fillColor Fill color on format #rrggbb[aa]. + */ + beginShape(fillColor) { + const ctx = this._ctx; + ctx.fillStyle = toCss3Color(fillColor); + ctx.beginPath(); + } + + /** + * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas. + */ + endShape() { + this._ctx.fill(); + } + + /** + * Adds a polygon to the rendering queue. + * @param points An array of Point objects. + */ + addPolygon(points) { + const ctx = this._ctx; + ctx.moveTo(points[0].x, points[0].y); + for (let i = 1; i < points.length; i++) { + ctx.lineTo(points[i].x, points[i].y); + } + ctx.closePath(); + } + + /** + * Adds a circle to the rendering queue. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle(point, diameter, counterClockwise) { + const ctx = this._ctx, + radius = diameter / 2; + ctx.moveTo(point.x + radius, point.y + radius); + ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise); + ctx.closePath(); + } + + /** + * Called when the icon has been completely drawn. + */ + finish() { + this._ctx.restore(); + } +} + +/** + * Draws an identicon to a context. + * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0). + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function drawIcon(ctx, hashOrValue, size, config) { + if (!ctx) { + throw new Error("No canvas specified."); + } + + iconGenerator(new CanvasRenderer(ctx, size), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); +} + +/** + * Draws an identicon as PNG. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + * @returns {Buffer} PNG data + */ +function toPng(hashOrValue, size, config) { + const canvas = canvasRenderer.createCanvas(size, size); + const ctx = canvas.getContext("2d"); + + iconGenerator(new CanvasRenderer(ctx, size), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); + + return canvas.toPng({ "Software": "Jdenticon" }); +} + +/** + * Prepares a measure to be used as a measure in an SVG path, by + * rounding the measure to a single decimal. This reduces the file + * size of the generated SVG with more than 50% in some cases. + */ +function svgValue(value) { + return ((value * 10 + 0.5) | 0) / 10; +} + +/** + * Represents an SVG path element. + */ +class SvgPath { + constructor() { + /** + * This property holds the data string (path.d) of the SVG path. + * @type {string} + */ + this.dataString = ""; + } + + /** + * Adds a polygon with the current fill color to the SVG path. + * @param points An array of Point objects. + */ + addPolygon(points) { + let dataString = ""; + for (let i = 0; i < points.length; i++) { + dataString += (i ? "L" : "M") + svgValue(points[i].x) + " " + svgValue(points[i].y); + } + this.dataString += dataString + "Z"; + } + + /** + * Adds a circle with the current fill color to the SVG path. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle(point, diameter, counterClockwise) { + const sweepFlag = counterClockwise ? 0 : 1, + svgRadius = svgValue(diameter / 2), + svgDiameter = svgValue(diameter), + svgArc = "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " "; + + this.dataString += + "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) + + svgArc + svgDiameter + ",0" + + svgArc + (-svgDiameter) + ",0"; + } +} + + + +/** + * Renderer producing SVG output. + * @implements {Renderer} + */ +class SvgRenderer { + /** + * @param {SvgElement|SvgWriter} target + */ + constructor(target) { + /** + * @type {SvgPath} + * @private + */ + this._path; + + /** + * @type {Object.} + * @private + */ + this._pathsByColor = { }; + + /** + * @type {SvgElement|SvgWriter} + * @private + */ + this._target = target; + + /** + * @type {number} + */ + this.iconSize = target.iconSize; + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ + setBackground(fillColor) { + const match = /^(#......)(..)?/.exec(fillColor), + opacity = match[2] ? parseHex(match[2], 0) / 255 : 1; + this._target.setBackground(match[1], opacity); + } + + /** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} color Fill color on format #xxxxxx. + */ + beginShape(color) { + this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath()); + } + + /** + * Marks the end of the currently drawn shape. + */ + endShape() { } + + /** + * Adds a polygon with the current fill color to the SVG. + * @param points An array of Point objects. + */ + addPolygon(points) { + this._path.addPolygon(points); + } + + /** + * Adds a circle with the current fill color to the SVG. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ + addCircle(point, diameter, counterClockwise) { + this._path.addCircle(point, diameter, counterClockwise); + } + + /** + * Called when the icon has been completely drawn. + */ + finish() { + const pathsByColor = this._pathsByColor; + for (let color in pathsByColor) { + // hasOwnProperty cannot be shadowed in pathsByColor + // eslint-disable-next-line no-prototype-builtins + if (pathsByColor.hasOwnProperty(color)) { + this._target.appendPath(color, pathsByColor[color].dataString); + } + } + } +} + +const SVG_CONSTANTS = { + XMLNS: "http://www.w3.org/2000/svg", + WIDTH: "width", + HEIGHT: "height", +}; + +/** + * Renderer producing SVG output. + */ +class SvgWriter { + /** + * @param {number} iconSize - Icon width and height in pixels. + */ + constructor(iconSize) { + /** + * @type {number} + */ + this.iconSize = iconSize; + + /** + * @type {string} + * @private + */ + this._s = + ''; + } + + /** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ + setBackground(fillColor, opacity) { + if (opacity) { + this._s += ''; + } + } + + /** + * Writes a path to the SVG string. + * @param {string} color Fill color on format #rrggbb. + * @param {string} dataString The SVG path data string. + */ + appendPath(color, dataString) { + this._s += ''; + } + + /** + * Gets the rendered image as an SVG string. + */ + toString() { + return this._s + ""; + } +} + +/** + * Draws an identicon as an SVG string. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + * @returns {string} SVG string + */ +function toSvg(hashOrValue, size, config) { + const writer = new SvgWriter(size); + iconGenerator(new SvgRenderer(writer), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); + return writer.toString(); +} + +// This file is compiled to dist/jdenticon-node.mjs + +if (typeof process === "undefined" && + typeof window !== "undefined" && + typeof document !== "undefined" +) { + console.warn( + "Jdenticon: 'dist/jdenticon-node.mjs' is only intended for Node.js environments and will increase your " + + "bundle size when included in browser bundles. If you want to run Jdenticon in the browser, please add a " + + "reference to 'dist/jdenticon.js' or 'dist/jdenticon.min.js' instead."); +} + +/** + * Specifies the version of the Jdenticon package in use. + * @type {string} + */ +const version = "3.1.0"; + +/** + * Specifies which bundle of Jdenticon that is used. + * @type {string} + */ +const bundle = "node-esm"; + +/** + * @throws {Error} + */ +function update() { + throw new Error("jdenticon.update() is not supported on Node.js."); +} + +/** + * @throws {Error} + */ +function updateCanvas() { + throw new Error("jdenticon.updateCanvas() is not supported on Node.js."); +} + +/** + * @throws {Error} + */ +function updateSvg() { + throw new Error("jdenticon.updateSvg() is not supported on Node.js."); +} + +export { bundle, configure, drawIcon, toPng, toSvg, update, updateCanvas, updateSvg, version }; +//# sourceMappingURL=jdenticon-node.mjs.map diff --git a/www/vendor/jdenticon-node.mjs.map b/www/vendor/jdenticon-node.mjs.map new file mode 100644 index 0000000..74df24f --- /dev/null +++ b/www/vendor/jdenticon-node.mjs.map @@ -0,0 +1 @@ +{"version":3,"sources":["replacement/1","src/common/parseHex.js","src/renderer/color.js","src/common/global.js","src/common/configuration.js","src/renderer/point.js","src/renderer/transform.js","src/renderer/graphics.js","src/renderer/shapes.js","src/renderer/colorTheme.js","src/renderer/iconGenerator.js","src/common/sha1.js","src/common/hashUtils.js","src/renderer/canvas/canvasRenderer.js","src/apis/drawIcon.js","src/apis/toPng.js","src/renderer/svg/svgPath.js","src/renderer/svg/svgRenderer.js","src/renderer/svg/constants.js","src/renderer/svg/svgWriter.js","src/apis/toSvg.js","src/node-esm.js","replacement/2"],"names":[],"mappings":"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","file":"jdenticon-node.mjs","sourcesContent":["/**\r\n * Jdenticon 3.1.0\r\n * http://jdenticon.com\r\n *\r\n * Built: 2020-12-12T13:51:48.709Z\r\n * \r\n * MIT License\r\n * \r\n * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi\r\n * \r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n * \r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n * \r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Parses a substring of the hash as a number.\r\n * @param {number} startPosition \r\n * @param {number=} octets\r\n */\r\nexport function parseHex(hash, startPosition, octets) {\r\n return parseInt(hash.substr(startPosition, octets), 16);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseHex } from \"../common/parseHex\";\r\n\r\nfunction decToHex(v) {\r\n v |= 0; // Ensure integer value\r\n return v < 0 ? \"00\" :\r\n v < 16 ? \"0\" + v.toString(16) :\r\n v < 256 ? v.toString(16) :\r\n \"ff\";\r\n}\r\n\r\nfunction hueToRgb(m1, m2, h) {\r\n h = h < 0 ? h + 6 : h > 6 ? h - 6 : h;\r\n return decToHex(255 * (\r\n h < 1 ? m1 + (m2 - m1) * h :\r\n h < 3 ? m2 :\r\n h < 4 ? m1 + (m2 - m1) * (4 - h) :\r\n m1));\r\n}\r\n\r\n/**\r\n * @param {number} r Red channel [0, 255]\r\n * @param {number} g Green channel [0, 255]\r\n * @param {number} b Blue channel [0, 255]\r\n */\r\nexport function rgb(r, g, b) {\r\n return \"#\" + decToHex(r) + decToHex(g) + decToHex(b);\r\n}\r\n\r\n/**\r\n * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.\r\n * @returns {string}\r\n */\r\nexport function parseColor(color) {\r\n if (/^#[0-9a-f]{3,8}$/i.test(color)) {\r\n let result;\r\n const colorLength = color.length;\r\n\r\n if (colorLength < 6) {\r\n const r = color[1],\r\n g = color[2],\r\n b = color[3],\r\n a = color[4] || \"\";\r\n result = \"#\" + r + r + g + g + b + b + a + a;\r\n }\r\n if (colorLength == 7 || colorLength > 8) {\r\n result = color;\r\n }\r\n \r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * Converts a hexadecimal color to a CSS3 compatible color.\r\n * @param {string} hexColor Color on the format \"#RRGGBB\" or \"#RRGGBBAA\"\r\n * @returns {string}\r\n */\r\nexport function toCss3Color(hexColor) {\r\n const a = parseHex(hexColor, 7, 2);\r\n let result;\r\n\r\n if (isNaN(a)) {\r\n result = hexColor;\r\n } else {\r\n const r = parseHex(hexColor, 1, 2),\r\n g = parseHex(hexColor, 3, 2),\r\n b = parseHex(hexColor, 5, 2);\r\n result = \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (a / 255).toFixed(2) + \")\";\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color.\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function hsl(hue, saturation, lightness) {\r\n // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color\r\n let result;\r\n\r\n if (saturation == 0) {\r\n const partialHex = decToHex(lightness * 255);\r\n result = partialHex + partialHex + partialHex;\r\n }\r\n else {\r\n const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation,\r\n m1 = lightness * 2 - m2;\r\n result =\r\n hueToRgb(m1, m2, hue * 6 + 2) +\r\n hueToRgb(m1, m2, hue * 6) +\r\n hueToRgb(m1, m2, hue * 6 - 2);\r\n }\r\n\r\n return \"#\" + result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the \"dark\" hues\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function correctedHsl(hue, saturation, lightness) {\r\n // The corrector specifies the perceived middle lightness for each hue\r\n const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],\r\n corrector = correctors[(hue * 6 + 0.5) | 0];\r\n \r\n // Adjust the input lightness relative to the corrector\r\n lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2;\r\n \r\n return hsl(hue, saturation, lightness);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for\r\n// backward compatibility.\r\n\r\nexport const GLOBAL = \r\n typeof window !== \"undefined\" ? window :\r\n typeof self !== \"undefined\" ? self :\r\n typeof global !== \"undefined\" ? global :\r\n {};\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseColor } from \"../renderer/color\";\r\nimport { GLOBAL } from \"./global\";\r\n\r\n/**\r\n * @typedef {Object} ParsedConfiguration\r\n * @property {number} colorSaturation\r\n * @property {number} grayscaleSaturation\r\n * @property {string} backColor\r\n * @property {number} iconPadding\r\n * @property {function(number):number} hue\r\n * @property {function(number):number} colorLightness\r\n * @property {function(number):number} grayscaleLightness\r\n */\r\n\r\nexport const CONFIG_PROPERTIES = {\r\n GLOBAL: \"jdenticon_config\",\r\n MODULE: \"config\",\r\n};\r\n\r\nvar rootConfigurationHolder = {};\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object. When the property is set a warning is \r\n * printed in the console. To minimize bundle size, this is only used in Node bundles.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigPropertyWithWarn(rootObject) {\r\n Object.defineProperty(rootObject, CONFIG_PROPERTIES.MODULE, {\r\n configurable: true,\r\n get: () => rootConfigurationHolder[CONFIG_PROPERTIES.MODULE],\r\n set: newConfiguration => {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n console.warn(\"jdenticon.config is deprecated. Use jdenticon.configure() instead.\");\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console\r\n * when it is being used.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigProperty(rootObject) {\r\n rootConfigurationHolder = rootObject;\r\n}\r\n\r\n/**\r\n * Sets a new icon style configuration. The new configuration is not merged with the previous one. * \r\n * @param {Object} newConfiguration - New configuration object.\r\n */\r\nexport function configure(newConfiguration) {\r\n if (arguments.length) {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n }\r\n return rootConfigurationHolder[CONFIG_PROPERTIES.MODULE];\r\n}\r\n\r\n/**\r\n * Gets the normalized current Jdenticon color configuration. Missing fields have default values.\r\n * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A\r\n * local configuration overrides the global configuration in it entirety. This parameter can for backward\r\n * compatibility also contain a padding value. A padding value only overrides the global padding, not the\r\n * entire global configuration.\r\n * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor\r\n * explicitly to the API method.\r\n * @returns {ParsedConfiguration}\r\n */\r\nexport function getConfiguration(paddingOrLocalConfig, defaultPadding) {\r\n const configObject = \r\n typeof paddingOrLocalConfig == \"object\" && paddingOrLocalConfig ||\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] ||\r\n GLOBAL[CONFIG_PROPERTIES.GLOBAL] ||\r\n { },\r\n\r\n lightnessConfig = configObject[\"lightness\"] || { },\r\n \r\n // In versions < 2.1.0 there was no grayscale saturation -\r\n // saturation was the color saturation.\r\n saturation = configObject[\"saturation\"] || { },\r\n colorSaturation = \"color\" in saturation ? saturation[\"color\"] : saturation,\r\n grayscaleSaturation = saturation[\"grayscale\"],\r\n\r\n backColor = configObject[\"backColor\"],\r\n padding = configObject[\"padding\"];\r\n \r\n /**\r\n * Creates a lightness range.\r\n */\r\n function lightness(configName, defaultRange) {\r\n let range = lightnessConfig[configName];\r\n \r\n // Check if the lightness range is an array-like object. This way we ensure the\r\n // array contain two values at the same time.\r\n if (!(range && range.length > 1)) {\r\n range = defaultRange;\r\n }\r\n\r\n /**\r\n * Gets a lightness relative the specified value in the specified lightness range.\r\n */\r\n return function (value) {\r\n value = range[0] + value * (range[1] - range[0]);\r\n return value < 0 ? 0 : value > 1 ? 1 : value;\r\n };\r\n }\r\n\r\n /**\r\n * Gets a hue allowed by the configured hue restriction,\r\n * provided the originally computed hue.\r\n */\r\n function hueFunction(originalHue) {\r\n const hueConfig = configObject[\"hues\"];\r\n let hue;\r\n \r\n // Check if 'hues' is an array-like object. This way we also ensure that\r\n // the array is not empty, which would mean no hue restriction.\r\n if (hueConfig && hueConfig.length > 0) {\r\n // originalHue is in the range [0, 1]\r\n // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.\r\n hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];\r\n }\r\n\r\n return typeof hue == \"number\" ?\r\n \r\n // A hue was specified. We need to convert the hue from\r\n // degrees on any turn - e.g. 746° is a perfectly valid hue -\r\n // to turns in the range [0, 1).\r\n ((((hue / 360) % 1) + 1) % 1) :\r\n\r\n // No hue configured => use original hue\r\n originalHue;\r\n }\r\n \r\n return {\r\n hue: hueFunction,\r\n colorSaturation: typeof colorSaturation == \"number\" ? colorSaturation : 0.5,\r\n grayscaleSaturation: typeof grayscaleSaturation == \"number\" ? grayscaleSaturation : 0,\r\n colorLightness: lightness(\"color\", [0.4, 0.8]),\r\n grayscaleLightness: lightness(\"grayscale\", [0.3, 0.9]),\r\n backColor: parseColor(backColor),\r\n iconPadding: \r\n typeof paddingOrLocalConfig == \"number\" ? paddingOrLocalConfig : \r\n typeof padding == \"number\" ? padding : \r\n defaultPadding\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Represents a point.\r\n */\r\nexport class Point {\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n */\r\n constructor(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Point } from \"./point\";\r\n\r\n/**\r\n * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, \r\n * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.\r\n */\r\nexport class Transform {\r\n /**\r\n * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} size The size of the transformed rectangle.\r\n * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad\r\n */\r\n constructor(x, y, size, rotation) {\r\n this._x = x;\r\n this._y = y;\r\n this._size = size;\r\n this._rotation = rotation;\r\n }\r\n\r\n /**\r\n * Transforms the specified point based on the translation and rotation specification for this Transform.\r\n * @param {number} x x-coordinate\r\n * @param {number} y y-coordinate\r\n * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n */\r\n transformIconPoint(x, y, w, h) {\r\n const right = this._x + this._size,\r\n bottom = this._y + this._size,\r\n rotation = this._rotation;\r\n return rotation === 1 ? new Point(right - y - (h || 0), this._y + x) :\r\n rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :\r\n rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) :\r\n new Point(this._x + x, this._y + y);\r\n }\r\n}\r\n\r\nexport const NO_TRANSFORM = new Transform(0, 0, 0, 0);\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { NO_TRANSFORM } from \"./transform\";\r\n\r\n/**\r\n * @typedef {import(\"./renderer\").Renderer} Renderer\r\n * @typedef {import(\"./transform\").Transform} Transform\r\n */\r\n\r\n/**\r\n * Provides helper functions for rendering common basic shapes.\r\n */\r\nexport class Graphics {\r\n /**\r\n * @param {Renderer} renderer \r\n */\r\n constructor(renderer) {\r\n /**\r\n * @type {Renderer}\r\n * @private\r\n */\r\n this._renderer = renderer;\r\n\r\n /**\r\n * @type {Transform}\r\n */\r\n this.currentTransform = NO_TRANSFORM;\r\n }\r\n\r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]\r\n * @param {boolean=} invert Specifies if the polygon will be inverted.\r\n */\r\n addPolygon(points, invert) {\r\n const di = invert ? -2 : 2,\r\n transformedPoints = [];\r\n \r\n for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {\r\n transformedPoints.push(this.currentTransform.transformIconPoint(points[i], points[i + 1]));\r\n }\r\n \r\n this._renderer.addPolygon(transformedPoints);\r\n }\r\n \r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * Source: http://stackoverflow.com/a/2173084\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} size The size of the ellipse.\r\n * @param {boolean=} invert Specifies if the ellipse will be inverted.\r\n */\r\n addCircle(x, y, size, invert) {\r\n const p = this.currentTransform.transformIconPoint(x, y, size, size);\r\n this._renderer.addCircle(p, size, invert);\r\n }\r\n\r\n /**\r\n * Adds a rectangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle.\r\n * @param {number} w The width of the rectangle.\r\n * @param {number} h The height of the rectangle.\r\n * @param {boolean=} invert Specifies if the rectangle will be inverted.\r\n */\r\n addRectangle(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x, y, \r\n x + w, y,\r\n x + w, y + h,\r\n x, y + h\r\n ], invert);\r\n }\r\n\r\n /**\r\n * Adds a right triangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} w The width of the triangle.\r\n * @param {number} h The height of the triangle.\r\n * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.\r\n * @param {boolean=} invert Specifies if the triangle will be inverted.\r\n */\r\n addTriangle(x, y, w, h, r, invert) {\r\n const points = [\r\n x + w, y, \r\n x + w, y + h, \r\n x, y + h,\r\n x, y\r\n ];\r\n points.splice(((r || 0) % 4) * 2, 2);\r\n this.addPolygon(points, invert);\r\n }\r\n\r\n /**\r\n * Adds a rhombus to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} w The width of the rhombus.\r\n * @param {number} h The height of the rhombus.\r\n * @param {boolean=} invert Specifies if the rhombus will be inverted.\r\n */\r\n addRhombus(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x + w / 2, y,\r\n x + w, y + h / 2,\r\n x + w / 2, y + h,\r\n x, y + h / 2\r\n ], invert);\r\n }\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n * @param {number} positionIndex\r\n * @typedef {import('./graphics').Graphics} Graphics\r\n */\r\nexport function centerShape(index, g, cell, positionIndex) {\r\n index = index % 14;\r\n\r\n let k, m, w, h, inner, outer;\r\n\r\n !index ? (\r\n k = cell * 0.42,\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell - k * 2,\r\n cell - k, cell,\r\n 0, cell\r\n ])) :\r\n\r\n index == 1 ? (\r\n w = 0 | (cell * 0.5), \r\n h = 0 | (cell * 0.8),\r\n\r\n g.addTriangle(cell - w, 0, w, h, 2)) :\r\n\r\n index == 2 ? (\r\n w = 0 | (cell / 3),\r\n g.addRectangle(w, w, cell - w, cell - w)) :\r\n\r\n index == 3 ? (\r\n inner = cell * 0.1,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 6 ? 1 :\r\n cell < 8 ? 2 :\r\n (0 | (cell * 0.25)),\r\n \r\n inner = \r\n inner > 1 ? (0 | inner) : // large icon => truncate decimals\r\n inner > 0.5 ? 1 : // medium size icon => fixed width\r\n inner, // small icon => anti-aliased border\r\n\r\n g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer)) :\r\n\r\n index == 4 ? (\r\n m = 0 | (cell * 0.15),\r\n w = 0 | (cell * 0.5),\r\n g.addCircle(cell - w - m, cell - w - m, w)) :\r\n\r\n index == 5 ? (\r\n inner = cell * 0.1,\r\n outer = inner * 4,\r\n\r\n // Align edge to nearest pixel in large icons\r\n outer > 3 && (outer = 0 | outer),\r\n \r\n g.addRectangle(0, 0, cell, cell),\r\n g.addPolygon([\r\n outer, outer,\r\n cell - inner, outer,\r\n outer + (cell - outer - inner) / 2, cell - inner\r\n ], true)) :\r\n\r\n index == 6 ? \r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell * 0.7,\r\n cell * 0.4, cell * 0.4,\r\n cell * 0.7, cell,\r\n 0, cell\r\n ]) :\r\n\r\n index == 7 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 8 ? (\r\n g.addRectangle(0, 0, cell, cell / 2),\r\n g.addRectangle(0, cell / 2, cell / 2, cell / 2),\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1)) :\r\n\r\n index == 9 ? (\r\n inner = cell * 0.14,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 4 ? 1 :\r\n cell < 6 ? 2 :\r\n (0 | (cell * 0.35)),\r\n\r\n inner = \r\n cell < 8 ? inner : // small icon => anti-aliased border\r\n (0 | inner), // large icon => truncate decimals\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true)) :\r\n\r\n index == 10 ? (\r\n inner = cell * 0.12,\r\n outer = inner * 3,\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addCircle(outer, outer, cell - inner - outer, true)) :\r\n\r\n index == 11 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 12 ? (\r\n m = cell * 0.25,\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRhombus(m, m, cell - m, cell - m, true)) :\r\n\r\n // 13\r\n (\r\n !positionIndex && (\r\n m = cell * 0.4, w = cell * 1.2,\r\n g.addCircle(m, m, w)\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n */\r\nexport function outerShape(index, g, cell) {\r\n index = index % 4;\r\n\r\n let m;\r\n\r\n !index ?\r\n g.addTriangle(0, 0, cell, cell, 0) :\r\n \r\n index == 1 ?\r\n g.addTriangle(0, cell / 2, cell, cell / 2, 0) :\r\n\r\n index == 2 ?\r\n g.addRhombus(0, 0, cell, cell) :\r\n\r\n // 3\r\n (\r\n m = cell / 6,\r\n g.addCircle(m, m, cell - 2 * m)\r\n );\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { correctedHsl } from \"./color\";\r\n\r\n/**\r\n * Gets a set of identicon color candidates for a specified hue and config.\r\n * @param {number} hue\r\n * @param {import(\"../common/configuration\").ParsedConfiguration} config\r\n */\r\nexport function colorTheme(hue, config) {\r\n hue = config.hue(hue);\r\n return [\r\n // Dark gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)),\r\n // Mid color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)),\r\n // Light gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)),\r\n // Light color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(1)),\r\n // Dark color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0))\r\n ];\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Transform } from \"./transform\";\r\nimport { Graphics } from \"./graphics\";\r\nimport { centerShape, outerShape } from \"./shapes\";\r\nimport { colorTheme } from \"./colorTheme\";\r\nimport { parseHex } from \"../common/parseHex\";\r\nimport { getConfiguration } from \"../common/configuration\";\r\n \r\n/**\r\n * Draws an identicon to a specified renderer.\r\n * @param {import('./renderer').Renderer} renderer\r\n * @param {string} hash\r\n * @param {Object|number=} config\r\n */\r\nexport function iconGenerator(renderer, hash, config) {\r\n const parsedConfig = getConfiguration(config, 0.08);\r\n\r\n // Set background color\r\n if (parsedConfig.backColor) {\r\n renderer.setBackground(parsedConfig.backColor);\r\n }\r\n \r\n // Calculate padding and round to nearest integer\r\n let size = renderer.iconSize;\r\n const padding = (0.5 + size * parsedConfig.iconPadding) | 0;\r\n size -= padding * 2;\r\n \r\n const graphics = new Graphics(renderer);\r\n \r\n // Calculate cell size and ensure it is an integer\r\n const cell = 0 | (size / 4);\r\n \r\n // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon\r\n const x = 0 | (padding + size / 2 - cell * 2);\r\n const y = 0 | (padding + size / 2 - cell * 2);\r\n\r\n function renderShape(colorIndex, shapes, index, rotationIndex, positions) {\r\n const shapeIndex = parseHex(hash, index, 1);\r\n let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0;\r\n \r\n renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]);\r\n \r\n for (let i = 0; i < positions.length; i++) {\r\n graphics.currentTransform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);\r\n shapes(shapeIndex, graphics, cell, i);\r\n }\r\n \r\n renderer.endShape();\r\n }\r\n\r\n // AVAILABLE COLORS\r\n const hue = parseHex(hash, -7) / 0xfffffff,\r\n \r\n // Available colors for this icon\r\n availableColors = colorTheme(hue, parsedConfig),\r\n\r\n // The index of the selected colors\r\n selectedColorIndexes = [];\r\n\r\n let index;\r\n\r\n function isDuplicate(values) {\r\n if (values.indexOf(index) >= 0) {\r\n for (let i = 0; i < values.length; i++) {\r\n if (selectedColorIndexes.indexOf(values[i]) >= 0) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < 3; i++) {\r\n index = parseHex(hash, 8 + i, 1) % availableColors.length;\r\n if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo\r\n isDuplicate([2, 3])) { // Disallow light gray and light color combo\r\n index = 1;\r\n }\r\n selectedColorIndexes.push(index);\r\n }\r\n\r\n // ACTUAL RENDERING\r\n // Sides\r\n renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);\r\n // Corners\r\n renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);\r\n // Center\r\n renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);\r\n \r\n renderer.finish();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Computes a SHA1 hash for any value and returns it as a hexadecimal string.\r\n * \r\n * This function is optimized for minimal code size and rather short messages.\r\n * \r\n * @param {string} message \r\n */\r\nexport function sha1(message) {\r\n const HASH_SIZE_HALF_BYTES = 40;\r\n const BLOCK_SIZE_WORDS = 16;\r\n\r\n // Variables\r\n // `var` is used to be able to minimize the number of `var` keywords.\r\n var i = 0,\r\n f = 0,\r\n \r\n // Use `encodeURI` to UTF8 encode the message without any additional libraries\r\n // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky\r\n // since `unescape` is deprecated.\r\n urlEncodedMessage = encodeURI(message) + \"%80\", // trailing '1' bit padding\r\n \r\n // This can be changed to a preallocated Uint32Array array for greater performance and larger code size\r\n data = [],\r\n dataSize,\r\n \r\n hashBuffer = [],\r\n\r\n a = 0x67452301,\r\n b = 0xefcdab89,\r\n c = ~a,\r\n d = ~b,\r\n e = 0xc3d2e1f0,\r\n hash = [a, b, c, d, e],\r\n\r\n blockStartIndex = 0,\r\n hexHash = \"\";\r\n\r\n /**\r\n * Rotates the value a specified number of bits to the left.\r\n * @param {number} value Value to rotate\r\n * @param {number} shift Bit count to shift.\r\n */\r\n function rotl(value, shift) {\r\n return (value << shift) | (value >>> (32 - shift));\r\n }\r\n\r\n // Message data\r\n for ( ; i < urlEncodedMessage.length; f++) {\r\n data[f >> 2] = data[f >> 2] |\r\n (\r\n (\r\n urlEncodedMessage[i] == \"%\"\r\n // Percent encoded byte\r\n ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)\r\n // Unencoded byte\r\n : urlEncodedMessage.charCodeAt(i++)\r\n )\r\n\r\n // Read bytes in reverse order (big endian words)\r\n << ((3 - (f & 3)) * 8)\r\n );\r\n }\r\n\r\n // f is now the length of the utf8 encoded message\r\n // 7 = 8 bytes (64 bit) for message size, -1 to round down\r\n // >> 6 = integer division with block size\r\n dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;\r\n\r\n // Message size in bits.\r\n // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least\r\n // significant 32 bits are set. -8 is for the '1' bit padding byte.\r\n data[dataSize - 1] = f * 8 - 8;\r\n \r\n // Compute hash\r\n for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {\r\n for (i = 0; i < 80; i++) {\r\n f = rotl(a, 5) + e + (\r\n // Ch\r\n i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :\r\n \r\n // Parity\r\n i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :\r\n \r\n // Maj\r\n i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :\r\n \r\n // Parity\r\n (b ^ c ^ d) + 0xca62c1d6\r\n ) + ( \r\n hashBuffer[i] = i < BLOCK_SIZE_WORDS\r\n // Bitwise OR is used to coerse `undefined` to 0\r\n ? (data[blockStartIndex + i] | 0)\r\n : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)\r\n );\r\n\r\n e = d;\r\n d = c;\r\n c = rotl(b, 30);\r\n b = a;\r\n a = f;\r\n }\r\n\r\n hash[0] = a = ((hash[0] + a) | 0);\r\n hash[1] = b = ((hash[1] + b) | 0);\r\n hash[2] = c = ((hash[2] + c) | 0);\r\n hash[3] = d = ((hash[3] + d) | 0);\r\n hash[4] = e = ((hash[4] + e) | 0);\r\n }\r\n\r\n // Format hex hash\r\n for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {\r\n hexHash += (\r\n (\r\n // Get word (2^3 half-bytes per word)\r\n hash[i >> 3] >>>\r\n\r\n // Append half-bytes in reverse order\r\n ((7 - (i & 7)) * 4)\r\n ) \r\n // Clamp to half-byte\r\n & 0xf\r\n ).toString(16);\r\n }\r\n\r\n return hexHash;\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { sha1 } from \"./sha1\";\r\n\r\n/**\r\n * Inputs a value that might be a valid hash string for Jdenticon and returns it \r\n * if it is determined valid, otherwise a falsy value is returned.\r\n */\r\nexport function isValidHash(hashCandidate) {\r\n return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;\r\n}\r\n\r\n/**\r\n * Computes a hash for the specified value. Currently SHA1 is used. This function\r\n * always returns a valid hash.\r\n */\r\nexport function computeHash(value) {\r\n return sha1(value == null ? \"\" : \"\" + value);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { toCss3Color } from \"../color\";\r\n\r\n/**\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import('../point').Point} Point\r\n */\r\n\r\n/**\r\n * Renderer redirecting drawing commands to a canvas context.\r\n * @implements {Renderer}\r\n */\r\nexport class CanvasRenderer {\r\n /**\r\n * @param {number=} iconSize\r\n */\r\n constructor(ctx, iconSize) {\r\n const canvas = ctx.canvas; \r\n const width = canvas.width;\r\n const height = canvas.height;\r\n \r\n ctx.save();\r\n \r\n if (!iconSize) {\r\n iconSize = Math.min(width, height);\r\n \r\n ctx.translate(\r\n ((width - iconSize) / 2) | 0,\r\n ((height - iconSize) / 2) | 0);\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n this._ctx = ctx;\r\n this.iconSize = iconSize;\r\n \r\n ctx.clearRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const ctx = this._ctx;\r\n const iconSize = this.iconSize;\r\n\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.fillRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} fillColor Fill color on format #rrggbb[aa].\r\n */\r\n beginShape(fillColor) {\r\n const ctx = this._ctx;\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.beginPath();\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.\r\n */\r\n endShape() {\r\n this._ctx.fill();\r\n }\r\n\r\n /**\r\n * Adds a polygon to the rendering queue.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n const ctx = this._ctx;\r\n ctx.moveTo(points[0].x, points[0].y);\r\n for (let i = 1; i < points.length; i++) {\r\n ctx.lineTo(points[i].x, points[i].y);\r\n }\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Adds a circle to the rendering queue.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const ctx = this._ctx,\r\n radius = diameter / 2;\r\n ctx.moveTo(point.x + radius, point.y + radius);\r\n ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() {\r\n this._ctx.restore();\r\n }\r\n}\r\n","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\n\r\n/**\r\n * Draws an identicon to a context.\r\n * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function drawIcon(ctx, hashOrValue, size, config) {\r\n if (!ctx) {\r\n throw new Error(\"No canvas specified.\");\r\n }\r\n \r\n iconGenerator(new CanvasRenderer(ctx, size), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue), \r\n config);\r\n}\r\n","import canvasRenderer from \"canvas-renderer\";\r\nimport { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\n\r\n/**\r\n * Draws an identicon as PNG.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n * @returns {Buffer} PNG data\r\n */\r\nexport function toPng(hashOrValue, size, config) {\r\n const canvas = canvasRenderer.createCanvas(size, size);\r\n const ctx = canvas.getContext(\"2d\");\r\n \r\n iconGenerator(new CanvasRenderer(ctx, size), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue), \r\n config);\r\n \r\n return canvas.toPng({ \"Software\": \"Jdenticon\" });\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Prepares a measure to be used as a measure in an SVG path, by\r\n * rounding the measure to a single decimal. This reduces the file\r\n * size of the generated SVG with more than 50% in some cases.\r\n */\r\nfunction svgValue(value) {\r\n return ((value * 10 + 0.5) | 0) / 10;\r\n}\r\n\r\n/**\r\n * Represents an SVG path element.\r\n */\r\nexport class SvgPath {\r\n constructor() {\r\n /**\r\n * This property holds the data string (path.d) of the SVG path.\r\n * @type {string}\r\n */\r\n this.dataString = \"\";\r\n }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG path.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n let dataString = \"\";\r\n for (let i = 0; i < points.length; i++) {\r\n dataString += (i ? \"L\" : \"M\") + svgValue(points[i].x) + \" \" + svgValue(points[i].y);\r\n }\r\n this.dataString += dataString + \"Z\";\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG path.\r\n * @param {import('../point').Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const sweepFlag = counterClockwise ? 0 : 1,\r\n svgRadius = svgValue(diameter / 2),\r\n svgDiameter = svgValue(diameter),\r\n svgArc = \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \";\r\n \r\n this.dataString += \r\n \"M\" + svgValue(point.x) + \" \" + svgValue(point.y + diameter / 2) +\r\n svgArc + svgDiameter + \",0\" + \r\n svgArc + (-svgDiameter) + \",0\";\r\n }\r\n}\r\n\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SvgPath } from \"./svgPath\";\r\nimport { parseHex } from \"../../common/parseHex\";\r\n\r\n/**\r\n * @typedef {import(\"../point\").Point} Point\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import(\"./svgElement\").SvgElement} SvgElement\r\n * @typedef {import(\"./svgWriter\").SvgWriter} SvgWriter\r\n */\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @implements {Renderer}\r\n */\r\nexport class SvgRenderer {\r\n /**\r\n * @param {SvgElement|SvgWriter} target \r\n */\r\n constructor(target) {\r\n /**\r\n * @type {SvgPath}\r\n * @private\r\n */\r\n this._path;\r\n\r\n /**\r\n * @type {Object.}\r\n * @private\r\n */\r\n this._pathsByColor = { };\r\n\r\n /**\r\n * @type {SvgElement|SvgWriter}\r\n * @private\r\n */\r\n this._target = target;\r\n\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = target.iconSize;\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const match = /^(#......)(..)?/.exec(fillColor),\r\n opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;\r\n this._target.setBackground(match[1], opacity);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n */\r\n beginShape(color) {\r\n this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath());\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape.\r\n */\r\n endShape() { }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n this._path.addPolygon(points);\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n this._path.addCircle(point, diameter, counterClockwise);\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() { \r\n const pathsByColor = this._pathsByColor;\r\n for (let color in pathsByColor) {\r\n // hasOwnProperty cannot be shadowed in pathsByColor\r\n // eslint-disable-next-line no-prototype-builtins\r\n if (pathsByColor.hasOwnProperty(color)) {\r\n this._target.appendPath(color, pathsByColor[color].dataString);\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const SVG_CONSTANTS = {\r\n XMLNS: \"http://www.w3.org/2000/svg\",\r\n WIDTH: \"width\",\r\n HEIGHT: \"height\",\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgWriter {\r\n /**\r\n * @param {number} iconSize - Icon width and height in pixels.\r\n */\r\n constructor(iconSize) {\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = iconSize;\r\n\r\n /**\r\n * @type {string}\r\n * @private\r\n */\r\n this._s =\r\n '';\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n this._s += '';\r\n }\r\n }\r\n\r\n /**\r\n * Writes a path to the SVG string.\r\n * @param {string} color Fill color on format #rrggbb.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n this._s += '';\r\n }\r\n\r\n /**\r\n * Gets the rendered image as an SVG string.\r\n */\r\n toString() {\r\n return this._s + \"\";\r\n }\r\n}\r\n","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgWriter } from \"../renderer/svg/svgWriter\";\r\n\r\n/**\r\n * Draws an identicon as an SVG string.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n * @returns {string} SVG string\r\n */\r\nexport function toSvg(hashOrValue, size, config) {\r\n const writer = new SvgWriter(size);\r\n iconGenerator(new SvgRenderer(writer), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue),\r\n config);\r\n return writer.toString();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// This file is compiled to dist/jdenticon-node.mjs\r\n\r\nif (typeof process === \"undefined\" &&\r\n typeof window !== \"undefined\" &&\r\n typeof document !== \"undefined\"\r\n) {\r\n console.warn(\r\n \"Jdenticon: 'dist/jdenticon-node.mjs' is only intended for Node.js environments and will increase your \" +\r\n \"bundle size when included in browser bundles. If you want to run Jdenticon in the browser, please add a \" +\r\n \"reference to 'dist/jdenticon.js' or 'dist/jdenticon.min.js' instead.\");\r\n}\r\n\r\nexport { configure } from \"./apis/configure\";\r\nexport { drawIcon } from \"./apis/drawIcon\";\r\nexport { toPng } from \"./apis/toPng\";\r\nexport { toSvg } from \"./apis/toSvg\";\r\n\r\n/**\r\n * Specifies the version of the Jdenticon package in use.\r\n * @type {string}\r\n */\r\nexport const version = \"#version#\";\r\n\r\n/**\r\n * Specifies which bundle of Jdenticon that is used.\r\n * @type {string}\r\n */\r\nexport const bundle = \"node-esm\";\r\n\r\n/**\r\n * @throws {Error}\r\n */\r\nexport function update() {\r\n throw new Error(\"jdenticon.update() is not supported on Node.js.\");\r\n}\r\n\r\n/**\r\n * @throws {Error}\r\n */\r\nexport function updateCanvas() {\r\n throw new Error(\"jdenticon.updateCanvas() is not supported on Node.js.\");\r\n}\r\n\r\n/**\r\n * @throws {Error}\r\n */\r\nexport function updateSvg() {\r\n throw new Error(\"jdenticon.updateSvg() is not supported on Node.js.\");\r\n}\r\n","\n//# sourceMappingURL=jdenticon-node.mjs.map\n"]} \ No newline at end of file diff --git a/www/vendor/jdenticon.js b/www/vendor/jdenticon.js new file mode 100644 index 0000000..c58eb36 --- /dev/null +++ b/www/vendor/jdenticon.js @@ -0,0 +1,1462 @@ +/** + * Jdenticon 3.1.0 + * http://jdenticon.com + * + * Built: 2020-12-12T13:51:48.709Z + * + * MIT License + * + * Copyright (c) 2014-2020 Daniel Mester Pirttijärvi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +(function (umdGlobal, factory) { + var jdenticon = factory(umdGlobal); + + // Node.js + if (typeof module !== "undefined" && "exports" in module) { + module["exports"] = jdenticon; + } + // RequireJS + else if (typeof define === "function" && define["amd"]) { + define([], function () { return jdenticon; }); + } + // No module loader + else { + umdGlobal["jdenticon"] = jdenticon; + } +})(typeof self !== "undefined" ? self : this, function (umdGlobal) { +'use strict'; + +/** + * Parses a substring of the hash as a number. + * @param {number} startPosition + * @param {number=} octets + */ +function parseHex(hash, startPosition, octets) { + return parseInt(hash.substr(startPosition, octets), 16); +} + +function decToHex(v) { + v |= 0; // Ensure integer value + return v < 0 ? "00" : + v < 16 ? "0" + v.toString(16) : + v < 256 ? v.toString(16) : + "ff"; +} + +function hueToRgb(m1, m2, h) { + h = h < 0 ? h + 6 : h > 6 ? h - 6 : h; + return decToHex(255 * ( + h < 1 ? m1 + (m2 - m1) * h : + h < 3 ? m2 : + h < 4 ? m1 + (m2 - m1) * (4 - h) : + m1)); +} + +/** + * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported. + * @returns {string} + */ +function parseColor(color) { + if (/^#[0-9a-f]{3,8}$/i.test(color)) { + var result; + var colorLength = color.length; + + if (colorLength < 6) { + var r = color[1], + g = color[2], + b = color[3], + a = color[4] || ""; + result = "#" + r + r + g + g + b + b + a + a; + } + if (colorLength == 7 || colorLength > 8) { + result = color; + } + + return result; + } +} + +/** + * Converts a hexadecimal color to a CSS3 compatible color. + * @param {string} hexColor Color on the format "#RRGGBB" or "#RRGGBBAA" + * @returns {string} + */ +function toCss3Color(hexColor) { + var a = parseHex(hexColor, 7, 2); + var result; + + if (isNaN(a)) { + result = hexColor; + } else { + var r = parseHex(hexColor, 1, 2), + g = parseHex(hexColor, 3, 2), + b = parseHex(hexColor, 5, 2); + result = "rgba(" + r + "," + g + "," + b + "," + (a / 255).toFixed(2) + ")"; + } + + return result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function hsl(hue, saturation, lightness) { + // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color + var result; + + if (saturation == 0) { + var partialHex = decToHex(lightness * 255); + result = partialHex + partialHex + partialHex; + } + else { + var m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation, + m1 = lightness * 2 - m2; + result = + hueToRgb(m1, m2, hue * 6 + 2) + + hueToRgb(m1, m2, hue * 6) + + hueToRgb(m1, m2, hue * 6 - 2); + } + + return "#" + result; +} + +/** + * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the "dark" hues + * @param {number} hue Hue in range [0, 1] + * @param {number} saturation Saturation in range [0, 1] + * @param {number} lightness Lightness in range [0, 1] + * @returns {string} + */ +function correctedHsl(hue, saturation, lightness) { + // The corrector specifies the perceived middle lightness for each hue + var correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ], + corrector = correctors[(hue * 6 + 0.5) | 0]; + + // Adjust the input lightness relative to the corrector + lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2; + + return hsl(hue, saturation, lightness); +} + +/* global umdGlobal */ + +// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for +// backward compatibility. +var GLOBAL = umdGlobal; + +/** + * @typedef {Object} ParsedConfiguration + * @property {number} colorSaturation + * @property {number} grayscaleSaturation + * @property {string} backColor + * @property {number} iconPadding + * @property {function(number):number} hue + * @property {function(number):number} colorLightness + * @property {function(number):number} grayscaleLightness + */ + +var CONFIG_PROPERTIES = { + G/*GLOBAL*/: "jdenticon_config", + n/*MODULE*/: "config", +}; + +var rootConfigurationHolder = {}; + +/** + * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console + * when it is being used. + * @param {!Object} rootObject + */ +function defineConfigProperty(rootObject) { + rootConfigurationHolder = rootObject; +} + +/** + * Sets a new icon style configuration. The new configuration is not merged with the previous one. * + * @param {Object} newConfiguration - New configuration object. + */ +function configure(newConfiguration) { + if (arguments.length) { + rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] = newConfiguration; + } + return rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/]; +} + +/** + * Gets the normalized current Jdenticon color configuration. Missing fields have default values. + * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A + * local configuration overrides the global configuration in it entirety. This parameter can for backward + * compatibility also contain a padding value. A padding value only overrides the global padding, not the + * entire global configuration. + * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor + * explicitly to the API method. + * @returns {ParsedConfiguration} + */ +function getConfiguration(paddingOrLocalConfig, defaultPadding) { + var configObject = + typeof paddingOrLocalConfig == "object" && paddingOrLocalConfig || + rootConfigurationHolder[CONFIG_PROPERTIES.n/*MODULE*/] || + GLOBAL[CONFIG_PROPERTIES.G/*GLOBAL*/] || + { }, + + lightnessConfig = configObject["lightness"] || { }, + + // In versions < 2.1.0 there was no grayscale saturation - + // saturation was the color saturation. + saturation = configObject["saturation"] || { }, + colorSaturation = "color" in saturation ? saturation["color"] : saturation, + grayscaleSaturation = saturation["grayscale"], + + backColor = configObject["backColor"], + padding = configObject["padding"]; + + /** + * Creates a lightness range. + */ + function lightness(configName, defaultRange) { + var range = lightnessConfig[configName]; + + // Check if the lightness range is an array-like object. This way we ensure the + // array contain two values at the same time. + if (!(range && range.length > 1)) { + range = defaultRange; + } + + /** + * Gets a lightness relative the specified value in the specified lightness range. + */ + return function (value) { + value = range[0] + value * (range[1] - range[0]); + return value < 0 ? 0 : value > 1 ? 1 : value; + }; + } + + /** + * Gets a hue allowed by the configured hue restriction, + * provided the originally computed hue. + */ + function hueFunction(originalHue) { + var hueConfig = configObject["hues"]; + var hue; + + // Check if 'hues' is an array-like object. This way we also ensure that + // the array is not empty, which would mean no hue restriction. + if (hueConfig && hueConfig.length > 0) { + // originalHue is in the range [0, 1] + // Multiply with 0.999 to change the range to [0, 1) and then truncate the index. + hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)]; + } + + return typeof hue == "number" ? + + // A hue was specified. We need to convert the hue from + // degrees on any turn - e.g. 746° is a perfectly valid hue - + // to turns in the range [0, 1). + ((((hue / 360) % 1) + 1) % 1) : + + // No hue configured => use original hue + originalHue; + } + + return { + X/*hue*/: hueFunction, + p/*colorSaturation*/: typeof colorSaturation == "number" ? colorSaturation : 0.5, + H/*grayscaleSaturation*/: typeof grayscaleSaturation == "number" ? grayscaleSaturation : 0, + q/*colorLightness*/: lightness("color", [0.4, 0.8]), + I/*grayscaleLightness*/: lightness("grayscale", [0.3, 0.9]), + J/*backColor*/: parseColor(backColor), + Y/*iconPadding*/: + typeof paddingOrLocalConfig == "number" ? paddingOrLocalConfig : + typeof padding == "number" ? padding : + defaultPadding + } +} + +var ICON_TYPE_SVG = 1; + +var ICON_TYPE_CANVAS = 2; + +var ATTRIBUTES = { + t/*HASH*/: "data-jdenticon-hash", + o/*VALUE*/: "data-jdenticon-value" +}; + +var ICON_SELECTOR = "[" + ATTRIBUTES.t/*HASH*/ +"],[" + ATTRIBUTES.o/*VALUE*/ +"]"; + +var documentQuerySelectorAll = /** @type {!Function} */ ( + typeof document !== "undefined" && document.querySelectorAll.bind(document)); + +function getIdenticonType(el) { + if (el) { + var tagName = el["tagName"]; + + if (/^svg$/i.test(tagName)) { + return ICON_TYPE_SVG; + } + + if (/^canvas$/i.test(tagName) && "getContext" in el) { + return ICON_TYPE_CANVAS; + } + } +} + +function observer(updateCallback) { + if (typeof MutationObserver != "undefined") { + var mutationObserver = new MutationObserver(function onmutation(mutations) { + for (var mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) { + var mutation = mutations[mutationIndex]; + var addedNodes = mutation.addedNodes; + + for (var addedNodeIndex = 0; addedNodes && addedNodeIndex < addedNodes.length; addedNodeIndex++) { + var addedNode = addedNodes[addedNodeIndex]; + + // Skip other types of nodes than element nodes, since they might not support + // the querySelectorAll method => runtime error. + if (addedNode.nodeType == 1) { + if (getIdenticonType(addedNode)) { + updateCallback(addedNode); + } + else { + var icons = /** @type {Element} */(addedNode).querySelectorAll(ICON_SELECTOR); + for (var iconIndex = 0; iconIndex < icons.length; iconIndex++) { + updateCallback(icons[iconIndex]); + } + } + } + } + + if (mutation.type == "attributes" && getIdenticonType(mutation.target)) { + updateCallback(mutation.target); + } + } + }); + + mutationObserver.observe(document.body, { + "childList": true, + "attributes": true, + "attributeFilter": [ATTRIBUTES.o/*VALUE*/, ATTRIBUTES.t/*HASH*/, "width", "height"], + "subtree": true, + }); + } +} + +/** + * Represents a point. + */ +function Point(x, y) { + this.x = x; + this.y = y; +} + +/** + * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, + * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly. + */ +function Transform(x, y, size, rotation) { + this.u/*_x*/ = x; + this.v/*_y*/ = y; + this.K/*_size*/ = size; + this.Z/*_rotation*/ = rotation; +} + +/** + * Transforms the specified point based on the translation and rotation specification for this Transform. + * @param {number} x x-coordinate + * @param {number} y y-coordinate + * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle. + */ +Transform.prototype.L/*transformIconPoint*/ = function transformIconPoint (x, y, w, h) { + var right = this.u/*_x*/ + this.K/*_size*/, + bottom = this.v/*_y*/ + this.K/*_size*/, + rotation = this.Z/*_rotation*/; + return rotation === 1 ? new Point(right - y - (h || 0), this.v/*_y*/ + x) : + rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) : + rotation === 3 ? new Point(this.u/*_x*/ + y, bottom - x - (w || 0)) : + new Point(this.u/*_x*/ + x, this.v/*_y*/ + y); +}; + +var NO_TRANSFORM = new Transform(0, 0, 0, 0); + + + +/** + * Provides helper functions for rendering common basic shapes. + */ +function Graphics(renderer) { + /** + * @type {Renderer} + * @private + */ + this.M/*_renderer*/ = renderer; + + /** + * @type {Transform} + */ + this.A/*currentTransform*/ = NO_TRANSFORM; +} +var Graphics__prototype = Graphics.prototype; + +/** + * Adds a polygon to the underlying renderer. + * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ] + * @param {boolean=} invert Specifies if the polygon will be inverted. + */ +Graphics__prototype.g/*addPolygon*/ = function addPolygon (points, invert) { + var this$1 = this; + + var di = invert ? -2 : 2, + transformedPoints = []; + + for (var i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) { + transformedPoints.push(this$1.A/*currentTransform*/.L/*transformIconPoint*/(points[i], points[i + 1])); + } + + this.M/*_renderer*/.g/*addPolygon*/(transformedPoints); +}; + +/** + * Adds a polygon to the underlying renderer. + * Source: http://stackoverflow.com/a/2173084 + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse. + * @param {number} size The size of the ellipse. + * @param {boolean=} invert Specifies if the ellipse will be inverted. + */ +Graphics__prototype.h/*addCircle*/ = function addCircle (x, y, size, invert) { + var p = this.A/*currentTransform*/.L/*transformIconPoint*/(x, y, size, size); + this.M/*_renderer*/.h/*addCircle*/(p, size, invert); +}; + +/** + * Adds a rectangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle. + * @param {number} w The width of the rectangle. + * @param {number} h The height of the rectangle. + * @param {boolean=} invert Specifies if the rectangle will be inverted. + */ +Graphics__prototype.i/*addRectangle*/ = function addRectangle (x, y, w, h, invert) { + this.g/*addPolygon*/([ + x, y, + x + w, y, + x + w, y + h, + x, y + h + ], invert); +}; + +/** + * Adds a right triangle to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle. + * @param {number} w The width of the triangle. + * @param {number} h The height of the triangle. + * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle. + * @param {boolean=} invert Specifies if the triangle will be inverted. + */ +Graphics__prototype.j/*addTriangle*/ = function addTriangle (x, y, w, h, r, invert) { + var points = [ + x + w, y, + x + w, y + h, + x, y + h, + x, y + ]; + points.splice(((r || 0) % 4) * 2, 2); + this.g/*addPolygon*/(points, invert); +}; + +/** + * Adds a rhombus to the underlying renderer. + * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus. + * @param {number} w The width of the rhombus. + * @param {number} h The height of the rhombus. + * @param {boolean=} invert Specifies if the rhombus will be inverted. + */ +Graphics__prototype.N/*addRhombus*/ = function addRhombus (x, y, w, h, invert) { + this.g/*addPolygon*/([ + x + w / 2, y, + x + w, y + h / 2, + x + w / 2, y + h, + x, y + h / 2 + ], invert); +}; + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + * @param {number} positionIndex + */ +function centerShape(index, g, cell, positionIndex) { + index = index % 14; + + var k, m, w, h, inner, outer; + + !index ? ( + k = cell * 0.42, + g.g/*addPolygon*/([ + 0, 0, + cell, 0, + cell, cell - k * 2, + cell - k, cell, + 0, cell + ])) : + + index == 1 ? ( + w = 0 | (cell * 0.5), + h = 0 | (cell * 0.8), + + g.j/*addTriangle*/(cell - w, 0, w, h, 2)) : + + index == 2 ? ( + w = 0 | (cell / 3), + g.i/*addRectangle*/(w, w, cell - w, cell - w)) : + + index == 3 ? ( + inner = cell * 0.1, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 6 ? 1 : + cell < 8 ? 2 : + (0 | (cell * 0.25)), + + inner = + inner > 1 ? (0 | inner) : // large icon => truncate decimals + inner > 0.5 ? 1 : // medium size icon => fixed width + inner, // small icon => anti-aliased border + + g.i/*addRectangle*/(outer, outer, cell - inner - outer, cell - inner - outer)) : + + index == 4 ? ( + m = 0 | (cell * 0.15), + w = 0 | (cell * 0.5), + g.h/*addCircle*/(cell - w - m, cell - w - m, w)) : + + index == 5 ? ( + inner = cell * 0.1, + outer = inner * 4, + + // Align edge to nearest pixel in large icons + outer > 3 && (outer = 0 | outer), + + g.i/*addRectangle*/(0, 0, cell, cell), + g.g/*addPolygon*/([ + outer, outer, + cell - inner, outer, + outer + (cell - outer - inner) / 2, cell - inner + ], true)) : + + index == 6 ? + g.g/*addPolygon*/([ + 0, 0, + cell, 0, + cell, cell * 0.7, + cell * 0.4, cell * 0.4, + cell * 0.7, cell, + 0, cell + ]) : + + index == 7 ? + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 8 ? ( + g.i/*addRectangle*/(0, 0, cell, cell / 2), + g.i/*addRectangle*/(0, cell / 2, cell / 2, cell / 2), + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 1)) : + + index == 9 ? ( + inner = cell * 0.14, + // Use fixed outer border widths in small icons to ensure the border is drawn + outer = + cell < 4 ? 1 : + cell < 6 ? 2 : + (0 | (cell * 0.35)), + + inner = + cell < 8 ? inner : // small icon => anti-aliased border + (0 | inner), // large icon => truncate decimals + + g.i/*addRectangle*/(0, 0, cell, cell), + g.i/*addRectangle*/(outer, outer, cell - outer - inner, cell - outer - inner, true)) : + + index == 10 ? ( + inner = cell * 0.12, + outer = inner * 3, + + g.i/*addRectangle*/(0, 0, cell, cell), + g.h/*addCircle*/(outer, outer, cell - inner - outer, true)) : + + index == 11 ? + g.j/*addTriangle*/(cell / 2, cell / 2, cell / 2, cell / 2, 3) : + + index == 12 ? ( + m = cell * 0.25, + g.i/*addRectangle*/(0, 0, cell, cell), + g.N/*addRhombus*/(m, m, cell - m, cell - m, true)) : + + // 13 + ( + !positionIndex && ( + m = cell * 0.4, w = cell * 1.2, + g.h/*addCircle*/(m, m, w) + ) + ); +} + +/** + * @param {number} index + * @param {Graphics} g + * @param {number} cell + */ +function outerShape(index, g, cell) { + index = index % 4; + + var m; + + !index ? + g.j/*addTriangle*/(0, 0, cell, cell, 0) : + + index == 1 ? + g.j/*addTriangle*/(0, cell / 2, cell, cell / 2, 0) : + + index == 2 ? + g.N/*addRhombus*/(0, 0, cell, cell) : + + // 3 + ( + m = cell / 6, + g.h/*addCircle*/(m, m, cell - 2 * m) + ); +} + +/** + * Gets a set of identicon color candidates for a specified hue and config. + * @param {number} hue + * @param {ParsedConfiguration} config + */ +function colorTheme(hue, config) { + hue = config.X/*hue*/(hue); + return [ + // Dark gray + correctedHsl(hue, config.H/*grayscaleSaturation*/, config.I/*grayscaleLightness*/(0)), + // Mid color + correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(0.5)), + // Light gray + correctedHsl(hue, config.H/*grayscaleSaturation*/, config.I/*grayscaleLightness*/(1)), + // Light color + correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(1)), + // Dark color + correctedHsl(hue, config.p/*colorSaturation*/, config.q/*colorLightness*/(0)) + ]; +} + +/** + * Draws an identicon to a specified renderer. + * @param {Renderer} renderer + * @param {string} hash + * @param {Object|number=} config + */ +function iconGenerator(renderer, hash, config) { + var parsedConfig = getConfiguration(config, 0.08); + + // Set background color + if (parsedConfig.J/*backColor*/) { + renderer.m/*setBackground*/(parsedConfig.J/*backColor*/); + } + + // Calculate padding and round to nearest integer + var size = renderer.k/*iconSize*/; + var padding = (0.5 + size * parsedConfig.Y/*iconPadding*/) | 0; + size -= padding * 2; + + var graphics = new Graphics(renderer); + + // Calculate cell size and ensure it is an integer + var cell = 0 | (size / 4); + + // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon + var x = 0 | (padding + size / 2 - cell * 2); + var y = 0 | (padding + size / 2 - cell * 2); + + function renderShape(colorIndex, shapes, index, rotationIndex, positions) { + var shapeIndex = parseHex(hash, index, 1); + var r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0; + + renderer.O/*beginShape*/(availableColors[selectedColorIndexes[colorIndex]]); + + for (var i = 0; i < positions.length; i++) { + graphics.A/*currentTransform*/ = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4); + shapes(shapeIndex, graphics, cell, i); + } + + renderer.P/*endShape*/(); + } + + // AVAILABLE COLORS + var hue = parseHex(hash, -7) / 0xfffffff, + + // Available colors for this icon + availableColors = colorTheme(hue, parsedConfig), + + // The index of the selected colors + selectedColorIndexes = []; + + var index; + + function isDuplicate(values) { + if (values.indexOf(index) >= 0) { + for (var i = 0; i < values.length; i++) { + if (selectedColorIndexes.indexOf(values[i]) >= 0) { + return true; + } + } + } + } + + for (var i = 0; i < 3; i++) { + index = parseHex(hash, 8 + i, 1) % availableColors.length; + if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo + isDuplicate([2, 3])) { // Disallow light gray and light color combo + index = 1; + } + selectedColorIndexes.push(index); + } + + // ACTUAL RENDERING + // Sides + renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]); + // Corners + renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]); + // Center + renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]); + + renderer.finish(); +} + +/** + * Computes a SHA1 hash for any value and returns it as a hexadecimal string. + * + * This function is optimized for minimal code size and rather short messages. + * + * @param {string} message + */ +function sha1(message) { + var HASH_SIZE_HALF_BYTES = 40; + var BLOCK_SIZE_WORDS = 16; + + // Variables + // `var` is used to be able to minimize the number of `var` keywords. + var i = 0, + f = 0, + + // Use `encodeURI` to UTF8 encode the message without any additional libraries + // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky + // since `unescape` is deprecated. + urlEncodedMessage = encodeURI(message) + "%80", // trailing '1' bit padding + + // This can be changed to a preallocated Uint32Array array for greater performance and larger code size + data = [], + dataSize, + + hashBuffer = [], + + a = 0x67452301, + b = 0xefcdab89, + c = ~a, + d = ~b, + e = 0xc3d2e1f0, + hash = [a, b, c, d, e], + + blockStartIndex = 0, + hexHash = ""; + + /** + * Rotates the value a specified number of bits to the left. + * @param {number} value Value to rotate + * @param {number} shift Bit count to shift. + */ + function rotl(value, shift) { + return (value << shift) | (value >>> (32 - shift)); + } + + // Message data + for ( ; i < urlEncodedMessage.length; f++) { + data[f >> 2] = data[f >> 2] | + ( + ( + urlEncodedMessage[i] == "%" + // Percent encoded byte + ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16) + // Unencoded byte + : urlEncodedMessage.charCodeAt(i++) + ) + + // Read bytes in reverse order (big endian words) + << ((3 - (f & 3)) * 8) + ); + } + + // f is now the length of the utf8 encoded message + // 7 = 8 bytes (64 bit) for message size, -1 to round down + // >> 6 = integer division with block size + dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS; + + // Message size in bits. + // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least + // significant 32 bits are set. -8 is for the '1' bit padding byte. + data[dataSize - 1] = f * 8 - 8; + + // Compute hash + for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) { + for (i = 0; i < 80; i++) { + f = rotl(a, 5) + e + ( + // Ch + i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 : + + // Parity + i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 : + + // Maj + i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc : + + // Parity + (b ^ c ^ d) + 0xca62c1d6 + ) + ( + hashBuffer[i] = i < BLOCK_SIZE_WORDS + // Bitwise OR is used to coerse `undefined` to 0 + ? (data[blockStartIndex + i] | 0) + : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1) + ); + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = f; + } + + hash[0] = a = ((hash[0] + a) | 0); + hash[1] = b = ((hash[1] + b) | 0); + hash[2] = c = ((hash[2] + c) | 0); + hash[3] = d = ((hash[3] + d) | 0); + hash[4] = e = ((hash[4] + e) | 0); + } + + // Format hex hash + for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) { + hexHash += ( + ( + // Get word (2^3 half-bytes per word) + hash[i >> 3] >>> + + // Append half-bytes in reverse order + ((7 - (i & 7)) * 4) + ) + // Clamp to half-byte + & 0xf + ).toString(16); + } + + return hexHash; +} + +/** + * Inputs a value that might be a valid hash string for Jdenticon and returns it + * if it is determined valid, otherwise a falsy value is returned. + */ +function isValidHash(hashCandidate) { + return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate; +} + +/** + * Computes a hash for the specified value. Currently SHA1 is used. This function + * always returns a valid hash. + */ +function computeHash(value) { + return sha1(value == null ? "" : "" + value); +} + + + +/** + * Renderer redirecting drawing commands to a canvas context. + * @implements {Renderer} + */ +function CanvasRenderer(ctx, iconSize) { + var canvas = ctx.canvas; + var width = canvas.width; + var height = canvas.height; + + ctx.save(); + + if (!iconSize) { + iconSize = Math.min(width, height); + + ctx.translate( + ((width - iconSize) / 2) | 0, + ((height - iconSize) / 2) | 0); + } + + /** + * @private + */ + this.l/*_ctx*/ = ctx; + this.k/*iconSize*/ = iconSize; + + ctx.clearRect(0, 0, iconSize, iconSize); +} +var CanvasRenderer__prototype = CanvasRenderer.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ +CanvasRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) { + var ctx = this.l/*_ctx*/; + var iconSize = this.k/*iconSize*/; + + ctx.fillStyle = toCss3Color(fillColor); + ctx.fillRect(0, 0, iconSize, iconSize); +}; + +/** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} fillColor Fill color on format #rrggbb[aa]. + */ +CanvasRenderer__prototype.O/*beginShape*/ = function beginShape (fillColor) { + var ctx = this.l/*_ctx*/; + ctx.fillStyle = toCss3Color(fillColor); + ctx.beginPath(); +}; + +/** + * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas. + */ +CanvasRenderer__prototype.P/*endShape*/ = function endShape () { + this.l/*_ctx*/.fill(); +}; + +/** + * Adds a polygon to the rendering queue. + * @param points An array of Point objects. + */ +CanvasRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) { + var ctx = this.l/*_ctx*/; + ctx.moveTo(points[0].x, points[0].y); + for (var i = 1; i < points.length; i++) { + ctx.lineTo(points[i].x, points[i].y); + } + ctx.closePath(); +}; + +/** + * Adds a circle to the rendering queue. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ +CanvasRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) { + var ctx = this.l/*_ctx*/, + radius = diameter / 2; + ctx.moveTo(point.x + radius, point.y + radius); + ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise); + ctx.closePath(); +}; + +/** + * Called when the icon has been completely drawn. + */ +CanvasRenderer__prototype.finish = function finish () { + this.l/*_ctx*/.restore(); +}; + +/** + * Draws an identicon to a context. + * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0). + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function drawIcon(ctx, hashOrValue, size, config) { + if (!ctx) { + throw new Error("No canvas specified."); + } + + iconGenerator(new CanvasRenderer(ctx, size), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); +} + +/** + * Prepares a measure to be used as a measure in an SVG path, by + * rounding the measure to a single decimal. This reduces the file + * size of the generated SVG with more than 50% in some cases. + */ +function svgValue(value) { + return ((value * 10 + 0.5) | 0) / 10; +} + +/** + * Represents an SVG path element. + */ +function SvgPath() { + /** + * This property holds the data string (path.d) of the SVG path. + * @type {string} + */ + this.B/*dataString*/ = ""; +} +var SvgPath__prototype = SvgPath.prototype; + +/** + * Adds a polygon with the current fill color to the SVG path. + * @param points An array of Point objects. + */ +SvgPath__prototype.g/*addPolygon*/ = function addPolygon (points) { + var dataString = ""; + for (var i = 0; i < points.length; i++) { + dataString += (i ? "L" : "M") + svgValue(points[i].x) + " " + svgValue(points[i].y); + } + this.B/*dataString*/ += dataString + "Z"; +}; + +/** + * Adds a circle with the current fill color to the SVG path. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ +SvgPath__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) { + var sweepFlag = counterClockwise ? 0 : 1, + svgRadius = svgValue(diameter / 2), + svgDiameter = svgValue(diameter), + svgArc = "a" + svgRadius + "," + svgRadius + " 0 1," + sweepFlag + " "; + + this.B/*dataString*/ += + "M" + svgValue(point.x) + " " + svgValue(point.y + diameter / 2) + + svgArc + svgDiameter + ",0" + + svgArc + (-svgDiameter) + ",0"; +}; + + + +/** + * Renderer producing SVG output. + * @implements {Renderer} + */ +function SvgRenderer(target) { + /** + * @type {SvgPath} + * @private + */ + this.C/*_path*/; + + /** + * @type {Object.} + * @private + */ + this.D/*_pathsByColor*/ = { }; + + /** + * @type {SvgElement|SvgWriter} + * @private + */ + this.R/*_target*/ = target; + + /** + * @type {number} + */ + this.k/*iconSize*/ = target.k/*iconSize*/; +} +var SvgRenderer__prototype = SvgRenderer.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb[aa]. + */ +SvgRenderer__prototype.m/*setBackground*/ = function setBackground (fillColor) { + var match = /^(#......)(..)?/.exec(fillColor), + opacity = match[2] ? parseHex(match[2], 0) / 255 : 1; + this.R/*_target*/.m/*setBackground*/(match[1], opacity); +}; + +/** + * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape. + * @param {string} color Fill color on format #xxxxxx. + */ +SvgRenderer__prototype.O/*beginShape*/ = function beginShape (color) { + this.C/*_path*/ = this.D/*_pathsByColor*/[color] || (this.D/*_pathsByColor*/[color] = new SvgPath()); +}; + +/** + * Marks the end of the currently drawn shape. + */ +SvgRenderer__prototype.P/*endShape*/ = function endShape () { }; + +/** + * Adds a polygon with the current fill color to the SVG. + * @param points An array of Point objects. + */ +SvgRenderer__prototype.g/*addPolygon*/ = function addPolygon (points) { + this.C/*_path*/.g/*addPolygon*/(points); +}; + +/** + * Adds a circle with the current fill color to the SVG. + * @param {Point} point The upper left corner of the circle bounding box. + * @param {number} diameter The diameter of the circle. + * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path). + */ +SvgRenderer__prototype.h/*addCircle*/ = function addCircle (point, diameter, counterClockwise) { + this.C/*_path*/.h/*addCircle*/(point, diameter, counterClockwise); +}; + +/** + * Called when the icon has been completely drawn. + */ +SvgRenderer__prototype.finish = function finish () { + var this$1 = this; + + var pathsByColor = this.D/*_pathsByColor*/; + for (var color in pathsByColor) { + // hasOwnProperty cannot be shadowed in pathsByColor + // eslint-disable-next-line no-prototype-builtins + if (pathsByColor.hasOwnProperty(color)) { + this$1.R/*_target*/.S/*appendPath*/(color, pathsByColor[color].B/*dataString*/); + } + } +}; + +var SVG_CONSTANTS = { + T/*XMLNS*/: "http://www.w3.org/2000/svg", + U/*WIDTH*/: "width", + V/*HEIGHT*/: "height", +}; + +/** + * Renderer producing SVG output. + */ +function SvgWriter(iconSize) { + /** + * @type {number} + */ + this.k/*iconSize*/ = iconSize; + + /** + * @type {string} + * @private + */ + this.F/*_s*/ = + ''; +} +var SvgWriter__prototype = SvgWriter.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ +SvgWriter__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) { + if (opacity) { + this.F/*_s*/ += ''; + } +}; + +/** + * Writes a path to the SVG string. + * @param {string} color Fill color on format #rrggbb. + * @param {string} dataString The SVG path data string. + */ +SvgWriter__prototype.S/*appendPath*/ = function appendPath (color, dataString) { + this.F/*_s*/ += ''; +}; + +/** + * Gets the rendered image as an SVG string. + */ +SvgWriter__prototype.toString = function toString () { + return this.F/*_s*/ + ""; +}; + +/** + * Draws an identicon as an SVG string. + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. + * @param {number} size - Icon size in pixels. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + * @returns {string} SVG string + */ +function toSvg(hashOrValue, size, config) { + var writer = new SvgWriter(size); + iconGenerator(new SvgRenderer(writer), + isValidHash(hashOrValue) || computeHash(hashOrValue), + config); + return writer.toString(); +} + +/** + * Creates a new element and adds it to the specified parent. + * @param {Element} parentNode + * @param {string} name + * @param {...(string|number)} keyValuePairs + */ +function SvgElement_append(parentNode, name) { + var keyValuePairs = [], len = arguments.length - 2; + while ( len-- > 0 ) keyValuePairs[ len ] = arguments[ len + 2 ]; + + var el = document.createElementNS(SVG_CONSTANTS.T/*XMLNS*/, name); + + for (var i = 0; i + 1 < keyValuePairs.length; i += 2) { + el.setAttribute( + /** @type {string} */(keyValuePairs[i]), + /** @type {string} */(keyValuePairs[i + 1]) + ); + } + + parentNode.appendChild(el); +} + + +/** + * Renderer producing SVG output. + */ +function SvgElement(element) { + // Don't use the clientWidth and clientHeight properties on SVG elements + // since Firefox won't serve a proper value of these properties on SVG + // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811) + // Instead use 100px as a hardcoded size (the svg viewBox will rescale + // the icon to the correct dimensions) + var iconSize = this.k/*iconSize*/ = Math.min( + (Number(element.getAttribute(SVG_CONSTANTS.U/*WIDTH*/)) || 100), + (Number(element.getAttribute(SVG_CONSTANTS.V/*HEIGHT*/)) || 100) + ); + + /** + * @type {Element} + * @private + */ + this.W/*_el*/ = element; + + // Clear current SVG child elements + while (element.firstChild) { + element.removeChild(element.firstChild); + } + + // Set viewBox attribute to ensure the svg scales nicely. + element.setAttribute("viewBox", "0 0 " + iconSize + " " + iconSize); + element.setAttribute("preserveAspectRatio", "xMidYMid meet"); +} +var SvgElement__prototype = SvgElement.prototype; + +/** + * Fills the background with the specified color. + * @param {string} fillColor Fill color on the format #rrggbb. + * @param {number} opacity Opacity in the range [0.0, 1.0]. + */ +SvgElement__prototype.m/*setBackground*/ = function setBackground (fillColor, opacity) { + if (opacity) { + SvgElement_append(this.W/*_el*/, "rect", + SVG_CONSTANTS.U/*WIDTH*/, "100%", + SVG_CONSTANTS.V/*HEIGHT*/, "100%", + "fill", fillColor, + "opacity", opacity); + } +}; + +/** + * Appends a path to the SVG element. + * @param {string} color Fill color on format #xxxxxx. + * @param {string} dataString The SVG path data string. + */ +SvgElement__prototype.S/*appendPath*/ = function appendPath (color, dataString) { + SvgElement_append(this.W/*_el*/, "path", + "fill", color, + "d", dataString); +}; + +/** + * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute. + */ +function updateAll() { + if (documentQuerySelectorAll) { + update(ICON_SELECTOR); + } +} + +/** + * Updates the identicon in the specified `` or `` elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * `` or ``, or a CSS selector to such an element. + * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any + * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function update(el, hashOrValue, config) { + renderDomElement(el, hashOrValue, config, function (el, iconType) { + if (iconType) { + return iconType == ICON_TYPE_SVG ? + new SvgRenderer(new SvgElement(el)) : + new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext("2d")); + } + }); +} + +/** + * Updates the identicon in the specified canvas or svg elements. + * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type + * `` or ``, or a CSS selector to such an element. + * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or + * `data-jdenticon-value` attribute will be evaluated. + * @param {Object|number|undefined} config + * @param {function(Element,number):Renderer} rendererFactory - Factory function for creating an icon renderer. + */ +function renderDomElement(el, hashOrValue, config, rendererFactory) { + if (typeof el === "string") { + if (documentQuerySelectorAll) { + var elements = documentQuerySelectorAll(el); + for (var i = 0; i < elements.length; i++) { + renderDomElement(elements[i], hashOrValue, config, rendererFactory); + } + } + return; + } + + // Hash selection. The result from getValidHash or computeHash is + // accepted as a valid hash. + var hash = + // 1. Explicit valid hash + isValidHash(hashOrValue) || + + // 2. Explicit value (`!= null` catches both null and undefined) + hashOrValue != null && computeHash(hashOrValue) || + + // 3. `data-jdenticon-hash` attribute + isValidHash(el.getAttribute(ATTRIBUTES.t/*HASH*/)) || + + // 4. `data-jdenticon-value` attribute. + // We want to treat an empty attribute as an empty value. + // Some browsers return empty string even if the attribute + // is not specified, so use hasAttribute to determine if + // the attribute is specified. + el.hasAttribute(ATTRIBUTES.o/*VALUE*/) && computeHash(el.getAttribute(ATTRIBUTES.o/*VALUE*/)); + + if (!hash) { + // No hash specified. Don't render an icon. + return; + } + + var renderer = rendererFactory(el, getIdenticonType(el)); + if (renderer) { + // Draw icon + iconGenerator(renderer, hash, config); + } +} + +/** + * Renders an identicon for all matching supported elements. + * + * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. If not + * specified the `data-jdenticon-hash` and `data-jdenticon-value` attributes of each element will be + * evaluated. + * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any global + * configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be + * specified in place of a configuration object. + */ +function jdenticonJqueryPlugin(hashOrValue, config) { + this["each"](function (index, el) { + update(el, hashOrValue, config); + }); + return this; +} + +// This file is compiled to dist/jdenticon.js and dist/jdenticon.min.js + +var jdenticon = updateAll; + +defineConfigProperty(jdenticon); + +// Export public API +jdenticon["configure"] = configure; +jdenticon["drawIcon"] = drawIcon; +jdenticon["toSvg"] = toSvg; +jdenticon["update"] = update; +jdenticon["updateCanvas"] = update; +jdenticon["updateSvg"] = update; + +/** + * Specifies the version of the Jdenticon package in use. + * @type {string} + */ +jdenticon["version"] = "3.1.0"; + +/** + * Specifies which bundle of Jdenticon that is used. + * @type {string} + */ +jdenticon["bundle"] = "browser-umd"; + +// Basic jQuery plugin +var jQuery = GLOBAL["jQuery"]; +if (jQuery) { + jQuery["fn"]["jdenticon"] = jdenticonJqueryPlugin; +} + +/** + * This function is called once upon page load. + */ +function jdenticonStartup() { + var replaceMode = ( + jdenticon[CONFIG_PROPERTIES.n/*MODULE*/] || + GLOBAL[CONFIG_PROPERTIES.G/*GLOBAL*/] || + { } + )["replaceMode"]; + + if (replaceMode != "never") { + updateAll(); + + if (replaceMode == "observe") { + observer(update); + } + } +} + +// Schedule to render all identicons on the page once it has been loaded. +if (typeof setTimeout === "function") { + setTimeout(jdenticonStartup, 0); +} + +return jdenticon; + +}); \ No newline at end of file diff --git a/www/vendor/jdenticon.min.js b/www/vendor/jdenticon.min.js new file mode 100644 index 0000000..36c8750 --- /dev/null +++ b/www/vendor/jdenticon.min.js @@ -0,0 +1,3 @@ +// Jdenticon 3.1.0 | jdenticon.com | MIT licensed | (c) 2014-2020 Daniel Mester Pirttijärvi +!function(t,n){var i=function(t){"use strict";function n(t,n,i){return parseInt(t.substr(n,i),16)}function i(t){return(t|=0)<0?"00":t<16?"0"+t.toString(16):t<256?t.toString(16):"ff"}function e(t,n,e){return i(255*((e=e<0?e+6:e>6?e-6:e)<1?t+(n-t)*e:e<3?n:e<4?t+(n-t)*(4-e):t))}function r(t){if(/^#[0-9a-f]{3,8}$/i.test(t)){var n,i=t.length;if(i<6){var e=t[1],r=t[2],o=t[3],u=t[4]||"";n="#"+e+e+r+r+o+o+u+u}return(7==i||i>8)&&(n=t),n}}function o(t){var i,e=n(t,7,2);isNaN(e)?i=t:i="rgba("+n(t,1,2)+","+n(t,3,2)+","+n(t,5,2)+","+(e/255).toFixed(2)+")";return i}function u(t,n,r){var o;if(0==n){var u=i(255*r);o=u+u+u}else{var f=r<=.5?r*(n+1):r+n-r*n,h=2*r-f;o=e(h,f,6*t+2)+e(h,f,6*t)+e(h,f,6*t-2)}return"#"+o}function f(t,n,i){var e=[.55,.5,.5,.46,.6,.55,.55][6*t+.5|0];return u(t,n,i=i<.5?i*e*2:e+(i-.5)*(1-e)*2)}var h=t,s={G:"jdenticon_config",n:"config"},a={};function c(t){a=t}function v(t){return arguments.length&&(a[s.n]=t),a[s.n]}function l(t,n){var i="object"==typeof t&&t||a[s.n]||h[s.G]||{},e=i.lightness||{},o=i.saturation||{},u="color"in o?o.color:o,f=o.grayscale,c=i.backColor,v=i.padding;function l(t,n){var i=e[t];return i&&i.length>1||(i=n),function(t){return(t=i[0]+t*(i[1]-i[0]))<0?0:t>1?1:t}}function g(t){var n,e=i.hues;return e&&e.length>0&&(n=e[0|.999*t*e.length]),"number"==typeof n?(n/360%1+1)%1:t}return{X:g,p:"number"==typeof u?u:.5,H:"number"==typeof f?f:0,q:l("color",[.4,.8]),I:l("grayscale",[.3,.9]),J:r(c),Y:"number"==typeof t?t:"number"==typeof v?v:n}}var g=1,d=2,p={t:"data-jdenticon-hash",o:"data-jdenticon-value"},y="["+p.t+"],["+p.o+"]",m="undefined"!=typeof document&&document.querySelectorAll.bind(document);function b(t){if(t){var n=t.tagName;if(/^svg$/i.test(n))return g;if(/^canvas$/i.test(n)&&"getContext"in t)return d}}function w(t){"undefined"!=typeof MutationObserver&&new MutationObserver((function(n){for(var i=0;i1?0|h:h>.5?1:h,n.i(s,s,i-h-s,i-h-s)):4==t?(o=0|.15*i,u=0|.5*i,n.h(i-u-o,i-u-o,u)):5==t?((s=4*(h=.1*i))>3&&(s|=0),n.i(0,0,i,i),n.g([s,s,i-h,s,s+(i-s-h)/2,i-h],!0)):6==t?n.g([0,0,i,0,i,.7*i,.4*i,.4*i,.7*i,i,0,i]):7==t?n.j(i/2,i/2,i/2,i/2,3):8==t?(n.i(0,0,i,i/2),n.i(0,i/2,i/2,i/2),n.j(i/2,i/2,i/2,i/2,1)):9==t?(h=.14*i,s=i<4?1:i<6?2:0|.35*i,h=i<8?h:0|h,n.i(0,0,i,i),n.i(s,s,i-s-h,i-s-h,!0)):10==t?(s=3*(h=.12*i),n.i(0,0,i,i),n.h(s,s,i-h-s,!0)):11==t?n.j(i/2,i/2,i/2,i/2,3):12==t?(o=.25*i,n.i(0,0,i,i),n.N(o,o,i-o,i-o,!0)):!e&&(o=.4*i,u=1.2*i,n.h(o,o,u)):(r=.42*i,n.g([0,0,i,0,i,i-2*r,i-r,i,0,i]))}function N(t,n,i){var e;(t%=4)?1==t?n.j(0,i/2,i,i/2,0):2==t?n.N(0,0,i,i):(e=i/6,n.h(e,e,i-2*e)):n.j(0,0,i,i,0)}function T(t,n){return[f(t=n.X(t),n.H,n.I(0)),f(t,n.p,n.q(.5)),f(t,n.H,n.I(1)),f(t,n.p,n.q(1)),f(t,n.p,n.q(0))]}function k(t,i,e){var r=l(e,.08);r.J&&t.m(r.J);var o=t.k,u=.5+o*r.Y|0;o-=2*u;var f=new j(t),h=0|o/4,s=0|u+o/2-2*h,a=0|u+o/2-2*h;function c(e,r,o,u,c){var v=n(i,o,1),l=u?n(i,u,1):0;t.O(g[d[e]]);for(var p=0;p=0)for(var n=0;n=0)return!0}for(var y=0;y<3;y++)v=n(i,8+y,1)%g.length,(p([0,4])||p([2,3]))&&(v=1),d.push(v);c(0,N,2,3,[[1,0],[2,0],[2,3],[1,3],[0,1],[3,1],[3,2],[0,2]]),c(1,N,4,5,[[0,0],[3,0],[3,3],[0,3]]),c(2,M,1,null,[[1,1],[2,1],[2,2],[1,2]]),t.finish()}function I(t){var n,i=40,e=16,r=0,o=0,u=encodeURI(t)+"%80",f=[],h=[],s=1732584193,a=4023233417,c=~s,v=~a,l=3285377520,g=[s,a,c,v,l],d=0,p="";function y(t,n){return t<>>32-n}for(;r>2]=f[o>>2]|("%"==u[r]?parseInt(u.substring(r+1,r+=3),16):u.charCodeAt(r++))<<8*(3-(3&o));for(f[(n=(1+(o+7>>6))*e)-1]=8*o-8;d>3]>>>4*(7-(7&r))&15).toString(16);return p}function O(t){return/^[0-9a-f]{11,}$/i.test(t)&&t}function P(t){return I(null==t?"":""+t)}function F(t,n){var i=t.canvas,e=i.width,r=i.height;t.save(),n||(n=Math.min(e,r),t.translate((e-n)/2|0,(r-n)/2|0)),this.l=t,this.k=n,t.clearRect(0,0,n,n)}C.g=function(t,n){for(var i=this,e=n?-2:2,r=[],o=n?t.length-2:0;o=0;o+=e)r.push(i.A.L(t[o],t[o+1]));this.M.g(r)},C.h=function(t,n,i,e){var r=this.A.L(t,n,i,i);this.M.h(r,i,e)},C.i=function(t,n,i,e,r){this.g([t,n,t+i,n,t+i,n+e,t,n+e],r)},C.j=function(t,n,i,e,r,o){var u=[t+i,n,t+i,n+e,t,n+e,t,n];u.splice((r||0)%4*2,2),this.g(u,o)},C.N=function(t,n,i,e,r){this.g([t+i/2,n,t+i,n+e/2,t+i/2,n+e,t,n+e/2],r)};var R=F.prototype;function q(t,n,i,e){if(!t)throw new Error("No canvas specified.");k(new F(t,i),O(n)||P(n),e)}function B(t){return(10*t+.5|0)/10}function L(){this.B=""}R.m=function(t){var n=this.l,i=this.k;n.fillStyle=o(t),n.fillRect(0,0,i,i)},R.O=function(t){var n=this.l;n.fillStyle=o(t),n.beginPath()},R.P=function(){this.l.fill()},R.g=function(t){var n=this.l;n.moveTo(t[0].x,t[0].y);for(var i=1;i'}var J=H.prototype;function K(t,n,i){var e=new H(n);return k(new U(e),O(t)||P(t),i),e.toString()}function V(t,n){for(var i=[],e=arguments.length-2;e-- >0;)i[e]=arguments[e+2];for(var r=document.createElementNS(G.T,n),o=0;o+1')},J.S=function(t,n){this.F+=''},J.toString=function(){return this.F+""};var Y=W.prototype;function Z(){m&&E(y)}function E(t,n,i){X(t,n,i,(function(t,n){if(n)return n==g?new U(new W(t)):new F(t.getContext("2d"))}))}function X(t,n,i,e){if("string"!=typeof t){var r=O(n)||null!=n&&P(n)||O(t.getAttribute(p.t))||t.hasAttribute(p.o)&&P(t.getAttribute(p.o));if(r){var o=e(t,b(t));o&&k(o,r,i)}}else if(m)for(var u=m(t),f=0;f 6 ? h - 6 : h;\r\n return decToHex(255 * (\r\n h < 1 ? m1 + (m2 - m1) * h :\r\n h < 3 ? m2 :\r\n h < 4 ? m1 + (m2 - m1) * (4 - h) :\r\n m1));\r\n}\r\n\r\n/**\r\n * @param {number} r Red channel [0, 255]\r\n * @param {number} g Green channel [0, 255]\r\n * @param {number} b Blue channel [0, 255]\r\n */\r\nexport function rgb(r, g, b) {\r\n return \"#\" + decToHex(r) + decToHex(g) + decToHex(b);\r\n}\r\n\r\n/**\r\n * @param {string} color Color value to parse. Currently hexadecimal strings on the format #rgb[a] and #rrggbb[aa] are supported.\r\n * @returns {string}\r\n */\r\nexport function parseColor(color) {\r\n if (/^#[0-9a-f]{3,8}$/i.test(color)) {\r\n let result;\r\n const colorLength = color.length;\r\n\r\n if (colorLength < 6) {\r\n const r = color[1],\r\n g = color[2],\r\n b = color[3],\r\n a = color[4] || \"\";\r\n result = \"#\" + r + r + g + g + b + b + a + a;\r\n }\r\n if (colorLength == 7 || colorLength > 8) {\r\n result = color;\r\n }\r\n \r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * Converts a hexadecimal color to a CSS3 compatible color.\r\n * @param {string} hexColor Color on the format \"#RRGGBB\" or \"#RRGGBBAA\"\r\n * @returns {string}\r\n */\r\nexport function toCss3Color(hexColor) {\r\n const a = parseHex(hexColor, 7, 2);\r\n let result;\r\n\r\n if (isNaN(a)) {\r\n result = hexColor;\r\n } else {\r\n const r = parseHex(hexColor, 1, 2),\r\n g = parseHex(hexColor, 3, 2),\r\n b = parseHex(hexColor, 5, 2);\r\n result = \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + (a / 255).toFixed(2) + \")\";\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color.\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function hsl(hue, saturation, lightness) {\r\n // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color\r\n let result;\r\n\r\n if (saturation == 0) {\r\n const partialHex = decToHex(lightness * 255);\r\n result = partialHex + partialHex + partialHex;\r\n }\r\n else {\r\n const m2 = lightness <= 0.5 ? lightness * (saturation + 1) : lightness + saturation - lightness * saturation,\r\n m1 = lightness * 2 - m2;\r\n result =\r\n hueToRgb(m1, m2, hue * 6 + 2) +\r\n hueToRgb(m1, m2, hue * 6) +\r\n hueToRgb(m1, m2, hue * 6 - 2);\r\n }\r\n\r\n return \"#\" + result;\r\n}\r\n\r\n/**\r\n * Converts an HSL color to a hexadecimal RGB color. This function will correct the lightness for the \"dark\" hues\r\n * @param {number} hue Hue in range [0, 1]\r\n * @param {number} saturation Saturation in range [0, 1]\r\n * @param {number} lightness Lightness in range [0, 1]\r\n * @returns {string}\r\n */\r\nexport function correctedHsl(hue, saturation, lightness) {\r\n // The corrector specifies the perceived middle lightness for each hue\r\n const correctors = [ 0.55, 0.5, 0.5, 0.46, 0.6, 0.55, 0.55 ],\r\n corrector = correctors[(hue * 6 + 0.5) | 0];\r\n \r\n // Adjust the input lightness relative to the corrector\r\n lightness = lightness < 0.5 ? lightness * corrector * 2 : corrector + (lightness - 0.5) * (1 - corrector) * 2;\r\n \r\n return hsl(hue, saturation, lightness);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n/* global umdGlobal */\r\n\r\n// In the future we can replace `GLOBAL` with `globalThis`, but for now use the old school global detection for\r\n// backward compatibility.\r\nexport const GLOBAL = umdGlobal;\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { parseColor } from \"../renderer/color\";\r\nimport { GLOBAL } from \"./global\";\r\n\r\n/**\r\n * @typedef {Object} ParsedConfiguration\r\n * @property {number} colorSaturation\r\n * @property {number} grayscaleSaturation\r\n * @property {string} backColor\r\n * @property {number} iconPadding\r\n * @property {function(number):number} hue\r\n * @property {function(number):number} colorLightness\r\n * @property {function(number):number} grayscaleLightness\r\n */\r\n\r\nexport const CONFIG_PROPERTIES = {\r\n GLOBAL: \"jdenticon_config\",\r\n MODULE: \"config\",\r\n};\r\n\r\nvar rootConfigurationHolder = {};\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object. When the property is set a warning is \r\n * printed in the console. To minimize bundle size, this is only used in Node bundles.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigPropertyWithWarn(rootObject) {\r\n Object.defineProperty(rootObject, CONFIG_PROPERTIES.MODULE, {\r\n configurable: true,\r\n get: () => rootConfigurationHolder[CONFIG_PROPERTIES.MODULE],\r\n set: newConfiguration => {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n console.warn(\"jdenticon.config is deprecated. Use jdenticon.configure() instead.\");\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Defines the deprecated `config` property on the root Jdenticon object without printing a warning in the console\r\n * when it is being used.\r\n * @param {!Object} rootObject \r\n */\r\nexport function defineConfigProperty(rootObject) {\r\n rootConfigurationHolder = rootObject;\r\n}\r\n\r\n/**\r\n * Sets a new icon style configuration. The new configuration is not merged with the previous one. * \r\n * @param {Object} newConfiguration - New configuration object.\r\n */\r\nexport function configure(newConfiguration) {\r\n if (arguments.length) {\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] = newConfiguration;\r\n }\r\n return rootConfigurationHolder[CONFIG_PROPERTIES.MODULE];\r\n}\r\n\r\n/**\r\n * Gets the normalized current Jdenticon color configuration. Missing fields have default values.\r\n * @param {Object|number|undefined} paddingOrLocalConfig - Configuration passed to the called API method. A\r\n * local configuration overrides the global configuration in it entirety. This parameter can for backward\r\n * compatibility also contain a padding value. A padding value only overrides the global padding, not the\r\n * entire global configuration.\r\n * @param {number} defaultPadding - Padding used if no padding is specified in neither the configuration nor\r\n * explicitly to the API method.\r\n * @returns {ParsedConfiguration}\r\n */\r\nexport function getConfiguration(paddingOrLocalConfig, defaultPadding) {\r\n const configObject = \r\n typeof paddingOrLocalConfig == \"object\" && paddingOrLocalConfig ||\r\n rootConfigurationHolder[CONFIG_PROPERTIES.MODULE] ||\r\n GLOBAL[CONFIG_PROPERTIES.GLOBAL] ||\r\n { },\r\n\r\n lightnessConfig = configObject[\"lightness\"] || { },\r\n \r\n // In versions < 2.1.0 there was no grayscale saturation -\r\n // saturation was the color saturation.\r\n saturation = configObject[\"saturation\"] || { },\r\n colorSaturation = \"color\" in saturation ? saturation[\"color\"] : saturation,\r\n grayscaleSaturation = saturation[\"grayscale\"],\r\n\r\n backColor = configObject[\"backColor\"],\r\n padding = configObject[\"padding\"];\r\n \r\n /**\r\n * Creates a lightness range.\r\n */\r\n function lightness(configName, defaultRange) {\r\n let range = lightnessConfig[configName];\r\n \r\n // Check if the lightness range is an array-like object. This way we ensure the\r\n // array contain two values at the same time.\r\n if (!(range && range.length > 1)) {\r\n range = defaultRange;\r\n }\r\n\r\n /**\r\n * Gets a lightness relative the specified value in the specified lightness range.\r\n */\r\n return function (value) {\r\n value = range[0] + value * (range[1] - range[0]);\r\n return value < 0 ? 0 : value > 1 ? 1 : value;\r\n };\r\n }\r\n\r\n /**\r\n * Gets a hue allowed by the configured hue restriction,\r\n * provided the originally computed hue.\r\n */\r\n function hueFunction(originalHue) {\r\n const hueConfig = configObject[\"hues\"];\r\n let hue;\r\n \r\n // Check if 'hues' is an array-like object. This way we also ensure that\r\n // the array is not empty, which would mean no hue restriction.\r\n if (hueConfig && hueConfig.length > 0) {\r\n // originalHue is in the range [0, 1]\r\n // Multiply with 0.999 to change the range to [0, 1) and then truncate the index.\r\n hue = hueConfig[0 | (0.999 * originalHue * hueConfig.length)];\r\n }\r\n\r\n return typeof hue == \"number\" ?\r\n \r\n // A hue was specified. We need to convert the hue from\r\n // degrees on any turn - e.g. 746° is a perfectly valid hue -\r\n // to turns in the range [0, 1).\r\n ((((hue / 360) % 1) + 1) % 1) :\r\n\r\n // No hue configured => use original hue\r\n originalHue;\r\n }\r\n \r\n return {\r\n hue: hueFunction,\r\n colorSaturation: typeof colorSaturation == \"number\" ? colorSaturation : 0.5,\r\n grayscaleSaturation: typeof grayscaleSaturation == \"number\" ? grayscaleSaturation : 0,\r\n colorLightness: lightness(\"color\", [0.4, 0.8]),\r\n grayscaleLightness: lightness(\"grayscale\", [0.3, 0.9]),\r\n backColor: parseColor(backColor),\r\n iconPadding: \r\n typeof paddingOrLocalConfig == \"number\" ? paddingOrLocalConfig : \r\n typeof padding == \"number\" ? padding : \r\n defaultPadding\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const ICON_TYPE_SVG = 1;\r\n\r\nexport const ICON_TYPE_CANVAS = 2;\r\n\r\nexport const ATTRIBUTES = {\r\n HASH: \"data-jdenticon-hash\",\r\n VALUE: \"data-jdenticon-value\"\r\n};\r\n\r\nexport const ICON_SELECTOR = \"[\" + ATTRIBUTES.HASH +\"],[\" + ATTRIBUTES.VALUE +\"]\";\r\n\r\nexport const documentQuerySelectorAll = /** @type {!Function} */ (\r\n typeof document !== \"undefined\" && document.querySelectorAll.bind(document));\r\n\r\nexport function getIdenticonType(el) {\r\n if (el) {\r\n const tagName = el[\"tagName\"];\r\n\r\n if (/^svg$/i.test(tagName)) {\r\n return ICON_TYPE_SVG;\r\n }\r\n\r\n if (/^canvas$/i.test(tagName) && \"getContext\" in el) {\r\n return ICON_TYPE_CANVAS;\r\n }\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { ATTRIBUTES, ICON_SELECTOR, getIdenticonType } from \"./dom\";\r\n\r\nexport function observer(updateCallback) {\r\n if (typeof MutationObserver != \"undefined\") {\r\n const mutationObserver = new MutationObserver(function onmutation(mutations) {\r\n for (let mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) {\r\n const mutation = mutations[mutationIndex];\r\n const addedNodes = mutation.addedNodes;\r\n \r\n for (let addedNodeIndex = 0; addedNodes && addedNodeIndex < addedNodes.length; addedNodeIndex++) {\r\n const addedNode = addedNodes[addedNodeIndex];\r\n \r\n // Skip other types of nodes than element nodes, since they might not support\r\n // the querySelectorAll method => runtime error.\r\n if (addedNode.nodeType == Node.ELEMENT_NODE) {\r\n if (getIdenticonType(addedNode)) {\r\n updateCallback(addedNode);\r\n }\r\n else {\r\n const icons = /** @type {Element} */(addedNode).querySelectorAll(ICON_SELECTOR);\r\n for (let iconIndex = 0; iconIndex < icons.length; iconIndex++) {\r\n updateCallback(icons[iconIndex]);\r\n }\r\n }\r\n }\r\n }\r\n \r\n if (mutation.type == \"attributes\" && getIdenticonType(mutation.target)) {\r\n updateCallback(mutation.target);\r\n }\r\n }\r\n });\r\n\r\n mutationObserver.observe(document.body, {\r\n \"childList\": true,\r\n \"attributes\": true,\r\n \"attributeFilter\": [ATTRIBUTES.VALUE, ATTRIBUTES.HASH, \"width\", \"height\"],\r\n \"subtree\": true,\r\n });\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Represents a point.\r\n */\r\nexport class Point {\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n */\r\n constructor(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Point } from \"./point\";\r\n\r\n/**\r\n * Translates and rotates a point before being passed on to the canvas context. This was previously done by the canvas context itself, \r\n * but this caused a rendering issue in Chrome on sizes > 256 where the rotation transformation of inverted paths was not done properly.\r\n */\r\nexport class Transform {\r\n /**\r\n * @param {number} x The x-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the transformed rectangle.\r\n * @param {number} size The size of the transformed rectangle.\r\n * @param {number} rotation Rotation specified as 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad\r\n */\r\n constructor(x, y, size, rotation) {\r\n this._x = x;\r\n this._y = y;\r\n this._size = size;\r\n this._rotation = rotation;\r\n }\r\n\r\n /**\r\n * Transforms the specified point based on the translation and rotation specification for this Transform.\r\n * @param {number} x x-coordinate\r\n * @param {number} y y-coordinate\r\n * @param {number=} w The width of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n * @param {number=} h The height of the transformed rectangle. If greater than 0, this will ensure the returned point is of the upper left corner of the transformed rectangle.\r\n */\r\n transformIconPoint(x, y, w, h) {\r\n const right = this._x + this._size,\r\n bottom = this._y + this._size,\r\n rotation = this._rotation;\r\n return rotation === 1 ? new Point(right - y - (h || 0), this._y + x) :\r\n rotation === 2 ? new Point(right - x - (w || 0), bottom - y - (h || 0)) :\r\n rotation === 3 ? new Point(this._x + y, bottom - x - (w || 0)) :\r\n new Point(this._x + x, this._y + y);\r\n }\r\n}\r\n\r\nexport const NO_TRANSFORM = new Transform(0, 0, 0, 0);\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { NO_TRANSFORM } from \"./transform\";\r\n\r\n/**\r\n * @typedef {import(\"./renderer\").Renderer} Renderer\r\n * @typedef {import(\"./transform\").Transform} Transform\r\n */\r\n\r\n/**\r\n * Provides helper functions for rendering common basic shapes.\r\n */\r\nexport class Graphics {\r\n /**\r\n * @param {Renderer} renderer \r\n */\r\n constructor(renderer) {\r\n /**\r\n * @type {Renderer}\r\n * @private\r\n */\r\n this._renderer = renderer;\r\n\r\n /**\r\n * @type {Transform}\r\n */\r\n this.currentTransform = NO_TRANSFORM;\r\n }\r\n\r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * @param {Array} points The points of the polygon clockwise on the format [ x0, y0, x1, y1, ..., xn, yn ]\r\n * @param {boolean=} invert Specifies if the polygon will be inverted.\r\n */\r\n addPolygon(points, invert) {\r\n const di = invert ? -2 : 2,\r\n transformedPoints = [];\r\n \r\n for (let i = invert ? points.length - 2 : 0; i < points.length && i >= 0; i += di) {\r\n transformedPoints.push(this.currentTransform.transformIconPoint(points[i], points[i + 1]));\r\n }\r\n \r\n this._renderer.addPolygon(transformedPoints);\r\n }\r\n \r\n /**\r\n * Adds a polygon to the underlying renderer.\r\n * Source: http://stackoverflow.com/a/2173084\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the entire ellipse.\r\n * @param {number} size The size of the ellipse.\r\n * @param {boolean=} invert Specifies if the ellipse will be inverted.\r\n */\r\n addCircle(x, y, size, invert) {\r\n const p = this.currentTransform.transformIconPoint(x, y, size, size);\r\n this._renderer.addCircle(p, size, invert);\r\n }\r\n\r\n /**\r\n * Adds a rectangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle.\r\n * @param {number} w The width of the rectangle.\r\n * @param {number} h The height of the rectangle.\r\n * @param {boolean=} invert Specifies if the rectangle will be inverted.\r\n */\r\n addRectangle(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x, y, \r\n x + w, y,\r\n x + w, y + h,\r\n x, y + h\r\n ], invert);\r\n }\r\n\r\n /**\r\n * Adds a right triangle to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the triangle.\r\n * @param {number} w The width of the triangle.\r\n * @param {number} h The height of the triangle.\r\n * @param {number} r The rotation of the triangle (clockwise). 0 = right corner of the triangle in the lower left corner of the bounding rectangle.\r\n * @param {boolean=} invert Specifies if the triangle will be inverted.\r\n */\r\n addTriangle(x, y, w, h, r, invert) {\r\n const points = [\r\n x + w, y, \r\n x + w, y + h, \r\n x, y + h,\r\n x, y\r\n ];\r\n points.splice(((r || 0) % 4) * 2, 2);\r\n this.addPolygon(points, invert);\r\n }\r\n\r\n /**\r\n * Adds a rhombus to the underlying renderer.\r\n * @param {number} x The x-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} y The y-coordinate of the upper left corner of the rectangle holding the rhombus.\r\n * @param {number} w The width of the rhombus.\r\n * @param {number} h The height of the rhombus.\r\n * @param {boolean=} invert Specifies if the rhombus will be inverted.\r\n */\r\n addRhombus(x, y, w, h, invert) {\r\n this.addPolygon([\r\n x + w / 2, y,\r\n x + w, y + h / 2,\r\n x + w / 2, y + h,\r\n x, y + h / 2\r\n ], invert);\r\n }\r\n}","\r\nvar Graphics__prototype = Graphics.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n * @param {number} positionIndex\r\n * @typedef {import('./graphics').Graphics} Graphics\r\n */\r\nexport function centerShape(index, g, cell, positionIndex) {\r\n index = index % 14;\r\n\r\n let k, m, w, h, inner, outer;\r\n\r\n !index ? (\r\n k = cell * 0.42,\r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell - k * 2,\r\n cell - k, cell,\r\n 0, cell\r\n ])) :\r\n\r\n index == 1 ? (\r\n w = 0 | (cell * 0.5), \r\n h = 0 | (cell * 0.8),\r\n\r\n g.addTriangle(cell - w, 0, w, h, 2)) :\r\n\r\n index == 2 ? (\r\n w = 0 | (cell / 3),\r\n g.addRectangle(w, w, cell - w, cell - w)) :\r\n\r\n index == 3 ? (\r\n inner = cell * 0.1,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 6 ? 1 :\r\n cell < 8 ? 2 :\r\n (0 | (cell * 0.25)),\r\n \r\n inner = \r\n inner > 1 ? (0 | inner) : // large icon => truncate decimals\r\n inner > 0.5 ? 1 : // medium size icon => fixed width\r\n inner, // small icon => anti-aliased border\r\n\r\n g.addRectangle(outer, outer, cell - inner - outer, cell - inner - outer)) :\r\n\r\n index == 4 ? (\r\n m = 0 | (cell * 0.15),\r\n w = 0 | (cell * 0.5),\r\n g.addCircle(cell - w - m, cell - w - m, w)) :\r\n\r\n index == 5 ? (\r\n inner = cell * 0.1,\r\n outer = inner * 4,\r\n\r\n // Align edge to nearest pixel in large icons\r\n outer > 3 && (outer = 0 | outer),\r\n \r\n g.addRectangle(0, 0, cell, cell),\r\n g.addPolygon([\r\n outer, outer,\r\n cell - inner, outer,\r\n outer + (cell - outer - inner) / 2, cell - inner\r\n ], true)) :\r\n\r\n index == 6 ? \r\n g.addPolygon([\r\n 0, 0,\r\n cell, 0,\r\n cell, cell * 0.7,\r\n cell * 0.4, cell * 0.4,\r\n cell * 0.7, cell,\r\n 0, cell\r\n ]) :\r\n\r\n index == 7 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 8 ? (\r\n g.addRectangle(0, 0, cell, cell / 2),\r\n g.addRectangle(0, cell / 2, cell / 2, cell / 2),\r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 1)) :\r\n\r\n index == 9 ? (\r\n inner = cell * 0.14,\r\n // Use fixed outer border widths in small icons to ensure the border is drawn\r\n outer = \r\n cell < 4 ? 1 :\r\n cell < 6 ? 2 :\r\n (0 | (cell * 0.35)),\r\n\r\n inner = \r\n cell < 8 ? inner : // small icon => anti-aliased border\r\n (0 | inner), // large icon => truncate decimals\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRectangle(outer, outer, cell - outer - inner, cell - outer - inner, true)) :\r\n\r\n index == 10 ? (\r\n inner = cell * 0.12,\r\n outer = inner * 3,\r\n\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addCircle(outer, outer, cell - inner - outer, true)) :\r\n\r\n index == 11 ? \r\n g.addTriangle(cell / 2, cell / 2, cell / 2, cell / 2, 3) :\r\n\r\n index == 12 ? (\r\n m = cell * 0.25,\r\n g.addRectangle(0, 0, cell, cell),\r\n g.addRhombus(m, m, cell - m, cell - m, true)) :\r\n\r\n // 13\r\n (\r\n !positionIndex && (\r\n m = cell * 0.4, w = cell * 1.2,\r\n g.addCircle(m, m, w)\r\n )\r\n );\r\n}\r\n\r\n/**\r\n * @param {number} index\r\n * @param {Graphics} g\r\n * @param {number} cell\r\n */\r\nexport function outerShape(index, g, cell) {\r\n index = index % 4;\r\n\r\n let m;\r\n\r\n !index ?\r\n g.addTriangle(0, 0, cell, cell, 0) :\r\n \r\n index == 1 ?\r\n g.addTriangle(0, cell / 2, cell, cell / 2, 0) :\r\n\r\n index == 2 ?\r\n g.addRhombus(0, 0, cell, cell) :\r\n\r\n // 3\r\n (\r\n m = cell / 6,\r\n g.addCircle(m, m, cell - 2 * m)\r\n );\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { correctedHsl } from \"./color\";\r\n\r\n/**\r\n * Gets a set of identicon color candidates for a specified hue and config.\r\n * @param {number} hue\r\n * @param {import(\"../common/configuration\").ParsedConfiguration} config\r\n */\r\nexport function colorTheme(hue, config) {\r\n hue = config.hue(hue);\r\n return [\r\n // Dark gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(0)),\r\n // Mid color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0.5)),\r\n // Light gray\r\n correctedHsl(hue, config.grayscaleSaturation, config.grayscaleLightness(1)),\r\n // Light color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(1)),\r\n // Dark color\r\n correctedHsl(hue, config.colorSaturation, config.colorLightness(0))\r\n ];\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { Transform } from \"./transform\";\r\nimport { Graphics } from \"./graphics\";\r\nimport { centerShape, outerShape } from \"./shapes\";\r\nimport { colorTheme } from \"./colorTheme\";\r\nimport { parseHex } from \"../common/parseHex\";\r\nimport { getConfiguration } from \"../common/configuration\";\r\n \r\n/**\r\n * Draws an identicon to a specified renderer.\r\n * @param {import('./renderer').Renderer} renderer\r\n * @param {string} hash\r\n * @param {Object|number=} config\r\n */\r\nexport function iconGenerator(renderer, hash, config) {\r\n const parsedConfig = getConfiguration(config, 0.08);\r\n\r\n // Set background color\r\n if (parsedConfig.backColor) {\r\n renderer.setBackground(parsedConfig.backColor);\r\n }\r\n \r\n // Calculate padding and round to nearest integer\r\n let size = renderer.iconSize;\r\n const padding = (0.5 + size * parsedConfig.iconPadding) | 0;\r\n size -= padding * 2;\r\n \r\n const graphics = new Graphics(renderer);\r\n \r\n // Calculate cell size and ensure it is an integer\r\n const cell = 0 | (size / 4);\r\n \r\n // Since the cell size is integer based, the actual icon will be slightly smaller than specified => center icon\r\n const x = 0 | (padding + size / 2 - cell * 2);\r\n const y = 0 | (padding + size / 2 - cell * 2);\r\n\r\n function renderShape(colorIndex, shapes, index, rotationIndex, positions) {\r\n const shapeIndex = parseHex(hash, index, 1);\r\n let r = rotationIndex ? parseHex(hash, rotationIndex, 1) : 0;\r\n \r\n renderer.beginShape(availableColors[selectedColorIndexes[colorIndex]]);\r\n \r\n for (let i = 0; i < positions.length; i++) {\r\n graphics.currentTransform = new Transform(x + positions[i][0] * cell, y + positions[i][1] * cell, cell, r++ % 4);\r\n shapes(shapeIndex, graphics, cell, i);\r\n }\r\n \r\n renderer.endShape();\r\n }\r\n\r\n // AVAILABLE COLORS\r\n const hue = parseHex(hash, -7) / 0xfffffff,\r\n \r\n // Available colors for this icon\r\n availableColors = colorTheme(hue, parsedConfig),\r\n\r\n // The index of the selected colors\r\n selectedColorIndexes = [];\r\n\r\n let index;\r\n\r\n function isDuplicate(values) {\r\n if (values.indexOf(index) >= 0) {\r\n for (let i = 0; i < values.length; i++) {\r\n if (selectedColorIndexes.indexOf(values[i]) >= 0) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < 3; i++) {\r\n index = parseHex(hash, 8 + i, 1) % availableColors.length;\r\n if (isDuplicate([0, 4]) || // Disallow dark gray and dark color combo\r\n isDuplicate([2, 3])) { // Disallow light gray and light color combo\r\n index = 1;\r\n }\r\n selectedColorIndexes.push(index);\r\n }\r\n\r\n // ACTUAL RENDERING\r\n // Sides\r\n renderShape(0, outerShape, 2, 3, [[1, 0], [2, 0], [2, 3], [1, 3], [0, 1], [3, 1], [3, 2], [0, 2]]);\r\n // Corners\r\n renderShape(1, outerShape, 4, 5, [[0, 0], [3, 0], [3, 3], [0, 3]]);\r\n // Center\r\n renderShape(2, centerShape, 1, null, [[1, 1], [2, 1], [2, 2], [1, 2]]);\r\n \r\n renderer.finish();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Computes a SHA1 hash for any value and returns it as a hexadecimal string.\r\n * \r\n * This function is optimized for minimal code size and rather short messages.\r\n * \r\n * @param {string} message \r\n */\r\nexport function sha1(message) {\r\n const HASH_SIZE_HALF_BYTES = 40;\r\n const BLOCK_SIZE_WORDS = 16;\r\n\r\n // Variables\r\n // `var` is used to be able to minimize the number of `var` keywords.\r\n var i = 0,\r\n f = 0,\r\n \r\n // Use `encodeURI` to UTF8 encode the message without any additional libraries\r\n // We could use `unescape` + `encodeURI` to minimize the code, but that would be slightly risky\r\n // since `unescape` is deprecated.\r\n urlEncodedMessage = encodeURI(message) + \"%80\", // trailing '1' bit padding\r\n \r\n // This can be changed to a preallocated Uint32Array array for greater performance and larger code size\r\n data = [],\r\n dataSize,\r\n \r\n hashBuffer = [],\r\n\r\n a = 0x67452301,\r\n b = 0xefcdab89,\r\n c = ~a,\r\n d = ~b,\r\n e = 0xc3d2e1f0,\r\n hash = [a, b, c, d, e],\r\n\r\n blockStartIndex = 0,\r\n hexHash = \"\";\r\n\r\n /**\r\n * Rotates the value a specified number of bits to the left.\r\n * @param {number} value Value to rotate\r\n * @param {number} shift Bit count to shift.\r\n */\r\n function rotl(value, shift) {\r\n return (value << shift) | (value >>> (32 - shift));\r\n }\r\n\r\n // Message data\r\n for ( ; i < urlEncodedMessage.length; f++) {\r\n data[f >> 2] = data[f >> 2] |\r\n (\r\n (\r\n urlEncodedMessage[i] == \"%\"\r\n // Percent encoded byte\r\n ? parseInt(urlEncodedMessage.substring(i + 1, i += 3), 16)\r\n // Unencoded byte\r\n : urlEncodedMessage.charCodeAt(i++)\r\n )\r\n\r\n // Read bytes in reverse order (big endian words)\r\n << ((3 - (f & 3)) * 8)\r\n );\r\n }\r\n\r\n // f is now the length of the utf8 encoded message\r\n // 7 = 8 bytes (64 bit) for message size, -1 to round down\r\n // >> 6 = integer division with block size\r\n dataSize = (((f + 7) >> 6) + 1) * BLOCK_SIZE_WORDS;\r\n\r\n // Message size in bits.\r\n // SHA1 uses a 64 bit integer to represent the size, but since we only support short messages only the least\r\n // significant 32 bits are set. -8 is for the '1' bit padding byte.\r\n data[dataSize - 1] = f * 8 - 8;\r\n \r\n // Compute hash\r\n for ( ; blockStartIndex < dataSize; blockStartIndex += BLOCK_SIZE_WORDS) {\r\n for (i = 0; i < 80; i++) {\r\n f = rotl(a, 5) + e + (\r\n // Ch\r\n i < 20 ? ((b & c) ^ ((~b) & d)) + 0x5a827999 :\r\n \r\n // Parity\r\n i < 40 ? (b ^ c ^ d) + 0x6ed9eba1 :\r\n \r\n // Maj\r\n i < 60 ? ((b & c) ^ (b & d) ^ (c & d)) + 0x8f1bbcdc :\r\n \r\n // Parity\r\n (b ^ c ^ d) + 0xca62c1d6\r\n ) + ( \r\n hashBuffer[i] = i < BLOCK_SIZE_WORDS\r\n // Bitwise OR is used to coerse `undefined` to 0\r\n ? (data[blockStartIndex + i] | 0)\r\n : rotl(hashBuffer[i - 3] ^ hashBuffer[i - 8] ^ hashBuffer[i - 14] ^ hashBuffer[i - 16], 1)\r\n );\r\n\r\n e = d;\r\n d = c;\r\n c = rotl(b, 30);\r\n b = a;\r\n a = f;\r\n }\r\n\r\n hash[0] = a = ((hash[0] + a) | 0);\r\n hash[1] = b = ((hash[1] + b) | 0);\r\n hash[2] = c = ((hash[2] + c) | 0);\r\n hash[3] = d = ((hash[3] + d) | 0);\r\n hash[4] = e = ((hash[4] + e) | 0);\r\n }\r\n\r\n // Format hex hash\r\n for (i = 0; i < HASH_SIZE_HALF_BYTES; i++) {\r\n hexHash += (\r\n (\r\n // Get word (2^3 half-bytes per word)\r\n hash[i >> 3] >>>\r\n\r\n // Append half-bytes in reverse order\r\n ((7 - (i & 7)) * 4)\r\n ) \r\n // Clamp to half-byte\r\n & 0xf\r\n ).toString(16);\r\n }\r\n\r\n return hexHash;\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { sha1 } from \"./sha1\";\r\n\r\n/**\r\n * Inputs a value that might be a valid hash string for Jdenticon and returns it \r\n * if it is determined valid, otherwise a falsy value is returned.\r\n */\r\nexport function isValidHash(hashCandidate) {\r\n return /^[0-9a-f]{11,}$/i.test(hashCandidate) && hashCandidate;\r\n}\r\n\r\n/**\r\n * Computes a hash for the specified value. Currently SHA1 is used. This function\r\n * always returns a valid hash.\r\n */\r\nexport function computeHash(value) {\r\n return sha1(value == null ? \"\" : \"\" + value);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { toCss3Color } from \"../color\";\r\n\r\n/**\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import('../point').Point} Point\r\n */\r\n\r\n/**\r\n * Renderer redirecting drawing commands to a canvas context.\r\n * @implements {Renderer}\r\n */\r\nexport class CanvasRenderer {\r\n /**\r\n * @param {number=} iconSize\r\n */\r\n constructor(ctx, iconSize) {\r\n const canvas = ctx.canvas; \r\n const width = canvas.width;\r\n const height = canvas.height;\r\n \r\n ctx.save();\r\n \r\n if (!iconSize) {\r\n iconSize = Math.min(width, height);\r\n \r\n ctx.translate(\r\n ((width - iconSize) / 2) | 0,\r\n ((height - iconSize) / 2) | 0);\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n this._ctx = ctx;\r\n this.iconSize = iconSize;\r\n \r\n ctx.clearRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const ctx = this._ctx;\r\n const iconSize = this.iconSize;\r\n\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.fillRect(0, 0, iconSize, iconSize);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} fillColor Fill color on format #rrggbb[aa].\r\n */\r\n beginShape(fillColor) {\r\n const ctx = this._ctx;\r\n ctx.fillStyle = toCss3Color(fillColor);\r\n ctx.beginPath();\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape. This causes the queued paths to be rendered on the canvas.\r\n */\r\n endShape() {\r\n this._ctx.fill();\r\n }\r\n\r\n /**\r\n * Adds a polygon to the rendering queue.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n const ctx = this._ctx;\r\n ctx.moveTo(points[0].x, points[0].y);\r\n for (let i = 1; i < points.length; i++) {\r\n ctx.lineTo(points[i].x, points[i].y);\r\n }\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Adds a circle to the rendering queue.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const ctx = this._ctx,\r\n radius = diameter / 2;\r\n ctx.moveTo(point.x + radius, point.y + radius);\r\n ctx.arc(point.x + radius, point.y + radius, radius, 0, Math.PI * 2, counterClockwise);\r\n ctx.closePath();\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() {\r\n this._ctx.restore();\r\n }\r\n}\r\n","\r\nvar CanvasRenderer__prototype = CanvasRenderer.prototype;","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\n\r\n/**\r\n * Draws an identicon to a context.\r\n * @param {CanvasRenderingContext2D} ctx - Canvas context on which the icon will be drawn at location (0, 0).\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function drawIcon(ctx, hashOrValue, size, config) {\r\n if (!ctx) {\r\n throw new Error(\"No canvas specified.\");\r\n }\r\n \r\n iconGenerator(new CanvasRenderer(ctx, size), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue), \r\n config);\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n/**\r\n * Prepares a measure to be used as a measure in an SVG path, by\r\n * rounding the measure to a single decimal. This reduces the file\r\n * size of the generated SVG with more than 50% in some cases.\r\n */\r\nfunction svgValue(value) {\r\n return ((value * 10 + 0.5) | 0) / 10;\r\n}\r\n\r\n/**\r\n * Represents an SVG path element.\r\n */\r\nexport class SvgPath {\r\n constructor() {\r\n /**\r\n * This property holds the data string (path.d) of the SVG path.\r\n * @type {string}\r\n */\r\n this.dataString = \"\";\r\n }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG path.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n let dataString = \"\";\r\n for (let i = 0; i < points.length; i++) {\r\n dataString += (i ? \"L\" : \"M\") + svgValue(points[i].x) + \" \" + svgValue(points[i].y);\r\n }\r\n this.dataString += dataString + \"Z\";\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG path.\r\n * @param {import('../point').Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n const sweepFlag = counterClockwise ? 0 : 1,\r\n svgRadius = svgValue(diameter / 2),\r\n svgDiameter = svgValue(diameter),\r\n svgArc = \"a\" + svgRadius + \",\" + svgRadius + \" 0 1,\" + sweepFlag + \" \";\r\n \r\n this.dataString += \r\n \"M\" + svgValue(point.x) + \" \" + svgValue(point.y + diameter / 2) +\r\n svgArc + svgDiameter + \",0\" + \r\n svgArc + (-svgDiameter) + \",0\";\r\n }\r\n}\r\n\r\n","\r\nvar SvgPath__prototype = SvgPath.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SvgPath } from \"./svgPath\";\r\nimport { parseHex } from \"../../common/parseHex\";\r\n\r\n/**\r\n * @typedef {import(\"../point\").Point} Point\r\n * @typedef {import(\"../renderer\").Renderer} Renderer\r\n * @typedef {import(\"./svgElement\").SvgElement} SvgElement\r\n * @typedef {import(\"./svgWriter\").SvgWriter} SvgWriter\r\n */\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n * @implements {Renderer}\r\n */\r\nexport class SvgRenderer {\r\n /**\r\n * @param {SvgElement|SvgWriter} target \r\n */\r\n constructor(target) {\r\n /**\r\n * @type {SvgPath}\r\n * @private\r\n */\r\n this._path;\r\n\r\n /**\r\n * @type {Object.}\r\n * @private\r\n */\r\n this._pathsByColor = { };\r\n\r\n /**\r\n * @type {SvgElement|SvgWriter}\r\n * @private\r\n */\r\n this._target = target;\r\n\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = target.iconSize;\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb[aa].\r\n */\r\n setBackground(fillColor) {\r\n const match = /^(#......)(..)?/.exec(fillColor),\r\n opacity = match[2] ? parseHex(match[2], 0) / 255 : 1;\r\n this._target.setBackground(match[1], opacity);\r\n }\r\n\r\n /**\r\n * Marks the beginning of a new shape of the specified color. Should be ended with a call to endShape.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n */\r\n beginShape(color) {\r\n this._path = this._pathsByColor[color] || (this._pathsByColor[color] = new SvgPath());\r\n }\r\n\r\n /**\r\n * Marks the end of the currently drawn shape.\r\n */\r\n endShape() { }\r\n\r\n /**\r\n * Adds a polygon with the current fill color to the SVG.\r\n * @param points An array of Point objects.\r\n */\r\n addPolygon(points) {\r\n this._path.addPolygon(points);\r\n }\r\n\r\n /**\r\n * Adds a circle with the current fill color to the SVG.\r\n * @param {Point} point The upper left corner of the circle bounding box.\r\n * @param {number} diameter The diameter of the circle.\r\n * @param {boolean} counterClockwise True if the circle is drawn counter-clockwise (will result in a hole if rendered on a clockwise path).\r\n */\r\n addCircle(point, diameter, counterClockwise) {\r\n this._path.addCircle(point, diameter, counterClockwise);\r\n }\r\n\r\n /**\r\n * Called when the icon has been completely drawn.\r\n */\r\n finish() { \r\n const pathsByColor = this._pathsByColor;\r\n for (let color in pathsByColor) {\r\n // hasOwnProperty cannot be shadowed in pathsByColor\r\n // eslint-disable-next-line no-prototype-builtins\r\n if (pathsByColor.hasOwnProperty(color)) {\r\n this._target.appendPath(color, pathsByColor[color].dataString);\r\n }\r\n }\r\n }\r\n}\r\n","\r\nvar SvgRenderer__prototype = SvgRenderer.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nexport const SVG_CONSTANTS = {\r\n XMLNS: \"http://www.w3.org/2000/svg\",\r\n WIDTH: \"width\",\r\n HEIGHT: \"height\",\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgWriter {\r\n /**\r\n * @param {number} iconSize - Icon width and height in pixels.\r\n */\r\n constructor(iconSize) {\r\n /**\r\n * @type {number}\r\n */\r\n this.iconSize = iconSize;\r\n\r\n /**\r\n * @type {string}\r\n * @private\r\n */\r\n this._s =\r\n '';\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n this._s += '';\r\n }\r\n }\r\n\r\n /**\r\n * Writes a path to the SVG string.\r\n * @param {string} color Fill color on format #rrggbb.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n this._s += '';\r\n }\r\n\r\n /**\r\n * Gets the rendered image as an SVG string.\r\n */\r\n toString() {\r\n return this._s + \"\";\r\n }\r\n}\r\n","\r\nvar SvgWriter__prototype = SvgWriter.prototype;","import { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgWriter } from \"../renderer/svg/svgWriter\";\r\n\r\n/**\r\n * Draws an identicon as an SVG string.\r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon.\r\n * @param {number} size - Icon size in pixels.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n * @returns {string} SVG string\r\n */\r\nexport function toSvg(hashOrValue, size, config) {\r\n const writer = new SvgWriter(size);\r\n iconGenerator(new SvgRenderer(writer), \r\n isValidHash(hashOrValue) || computeHash(hashOrValue),\r\n config);\r\n return writer.toString();\r\n}\r\n","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { SVG_CONSTANTS } from \"./constants\";\r\n\r\n/**\r\n * Creates a new element and adds it to the specified parent.\r\n * @param {Element} parentNode\r\n * @param {string} name\r\n * @param {...(string|number)} keyValuePairs\r\n */\r\nfunction SvgElement_append(parentNode, name, ...keyValuePairs) {\r\n const el = document.createElementNS(SVG_CONSTANTS.XMLNS, name);\r\n \r\n for (let i = 0; i + 1 < keyValuePairs.length; i += 2) {\r\n el.setAttribute(\r\n /** @type {string} */(keyValuePairs[i]),\r\n /** @type {string} */(keyValuePairs[i + 1]),\r\n );\r\n }\r\n\r\n parentNode.appendChild(el);\r\n}\r\n\r\n\r\n/**\r\n * Renderer producing SVG output.\r\n */\r\nexport class SvgElement {\r\n /**\r\n * @param {Element} element - Target element\r\n */\r\n constructor(element) {\r\n // Don't use the clientWidth and clientHeight properties on SVG elements\r\n // since Firefox won't serve a proper value of these properties on SVG\r\n // elements (https://bugzilla.mozilla.org/show_bug.cgi?id=874811)\r\n // Instead use 100px as a hardcoded size (the svg viewBox will rescale \r\n // the icon to the correct dimensions)\r\n const iconSize = this.iconSize = Math.min(\r\n (Number(element.getAttribute(SVG_CONSTANTS.WIDTH)) || 100),\r\n (Number(element.getAttribute(SVG_CONSTANTS.HEIGHT)) || 100)\r\n );\r\n \r\n /**\r\n * @type {Element}\r\n * @private\r\n */\r\n this._el = element;\r\n \r\n // Clear current SVG child elements\r\n while (element.firstChild) {\r\n element.removeChild(element.firstChild);\r\n }\r\n \r\n // Set viewBox attribute to ensure the svg scales nicely.\r\n element.setAttribute(\"viewBox\", \"0 0 \" + iconSize + \" \" + iconSize);\r\n element.setAttribute(\"preserveAspectRatio\", \"xMidYMid meet\");\r\n }\r\n\r\n /**\r\n * Fills the background with the specified color.\r\n * @param {string} fillColor Fill color on the format #rrggbb.\r\n * @param {number} opacity Opacity in the range [0.0, 1.0].\r\n */\r\n setBackground(fillColor, opacity) {\r\n if (opacity) {\r\n SvgElement_append(this._el, \"rect\",\r\n SVG_CONSTANTS.WIDTH, \"100%\",\r\n SVG_CONSTANTS.HEIGHT, \"100%\",\r\n \"fill\", fillColor,\r\n \"opacity\", opacity);\r\n }\r\n }\r\n\r\n /**\r\n * Appends a path to the SVG element.\r\n * @param {string} color Fill color on format #xxxxxx.\r\n * @param {string} dataString The SVG path data string.\r\n */\r\n appendPath(color, dataString) {\r\n SvgElement_append(this._el, \"path\",\r\n \"fill\", color,\r\n \"d\", dataString);\r\n }\r\n}\r\n","\r\nvar SvgElement__prototype = SvgElement.prototype;","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\nimport { iconGenerator } from \"../renderer/iconGenerator\";\r\nimport { isValidHash, computeHash } from \"../common/hashUtils\";\r\nimport { ATTRIBUTES, ICON_SELECTOR, documentQuerySelectorAll } from \"../common/dom\";\r\nimport { SvgRenderer } from \"../renderer/svg/svgRenderer\";\r\nimport { SvgElement } from \"../renderer/svg/svgElement\";\r\nimport { CanvasRenderer } from \"../renderer/canvas/canvasRenderer\";\r\nimport { ICON_TYPE_CANVAS, ICON_TYPE_SVG, getIdenticonType } from \"../common/dom\";\r\n\r\n\r\n/**\r\n * Updates all canvas elements with the `data-jdenticon-hash` or `data-jdenticon-value` attribute.\r\n */\r\nexport function updateAll() {\r\n if (documentQuerySelectorAll) {\r\n update(ICON_SELECTOR);\r\n }\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` or `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * `` or ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function update(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType) {\r\n return iconType == ICON_TYPE_SVG ? \r\n new SvgRenderer(new SvgElement(el)) : \r\n new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext(\"2d\"));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function updateCanvas(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType == ICON_TYPE_CANVAS) {\r\n return new CanvasRenderer(/** @type {HTMLCanvasElement} */(el).getContext(\"2d\"));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified `` elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * ``, or a CSS selector to such an element.\r\n * @param {*=} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any\r\n * global configuration in its entirety. For backward compability a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function updateSvg(el, hashOrValue, config) {\r\n renderDomElement(el, hashOrValue, config, function (el, iconType) {\r\n if (iconType == ICON_TYPE_SVG) {\r\n return new SvgRenderer(new SvgElement(el));\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Updates the identicon in the specified canvas or svg elements.\r\n * @param {(string|Element)} el - Specifies the container in which the icon is rendered as a DOM element of the type\r\n * `` or ``, or a CSS selector to such an element.\r\n * @param {*} hashOrValue - Optional hash or value to be rendered. If not specified, the `data-jdenticon-hash` or\r\n * `data-jdenticon-value` attribute will be evaluated.\r\n * @param {Object|number|undefined} config\r\n * @param {function(Element,number):import(\"../renderer/renderer\").Renderer} rendererFactory - Factory function for creating an icon renderer.\r\n */\r\nfunction renderDomElement(el, hashOrValue, config, rendererFactory) {\r\n if (typeof el === \"string\") {\r\n if (documentQuerySelectorAll) {\r\n const elements = documentQuerySelectorAll(el);\r\n for (let i = 0; i < elements.length; i++) {\r\n renderDomElement(elements[i], hashOrValue, config, rendererFactory);\r\n }\r\n }\r\n return;\r\n }\r\n \r\n // Hash selection. The result from getValidHash or computeHash is \r\n // accepted as a valid hash.\r\n const hash = \r\n // 1. Explicit valid hash\r\n isValidHash(hashOrValue) ||\r\n \r\n // 2. Explicit value (`!= null` catches both null and undefined)\r\n hashOrValue != null && computeHash(hashOrValue) ||\r\n \r\n // 3. `data-jdenticon-hash` attribute\r\n isValidHash(el.getAttribute(ATTRIBUTES.HASH)) ||\r\n \r\n // 4. `data-jdenticon-value` attribute. \r\n // We want to treat an empty attribute as an empty value. \r\n // Some browsers return empty string even if the attribute \r\n // is not specified, so use hasAttribute to determine if \r\n // the attribute is specified.\r\n el.hasAttribute(ATTRIBUTES.VALUE) && computeHash(el.getAttribute(ATTRIBUTES.VALUE));\r\n \r\n if (!hash) {\r\n // No hash specified. Don't render an icon.\r\n return;\r\n }\r\n \r\n const renderer = rendererFactory(el, getIdenticonType(el));\r\n if (renderer) {\r\n // Draw icon\r\n iconGenerator(renderer, hash, config);\r\n }\r\n}\r\n","import { update } from \"./update\";\r\n\r\n/**\r\n * Renders an identicon for all matching supported elements.\r\n * \r\n * @param {*} hashOrValue - A hexadecimal hash string or any value that will be hashed by Jdenticon. If not \r\n * specified the `data-jdenticon-hash` and `data-jdenticon-value` attributes of each element will be\r\n * evaluated.\r\n * @param {Object|number=} config - Optional configuration. If specified, this configuration object overrides any global\r\n * configuration in its entirety. For backward compatibility a padding value in the range [0.0, 0.5) can be\r\n * specified in place of a configuration object.\r\n */\r\nexport function jdenticonJqueryPlugin(hashOrValue, config) {\r\n this[\"each\"](function (index, el) {\r\n update(el, hashOrValue, config);\r\n });\r\n return this;\r\n}","/**\r\n * Jdenticon\r\n * https://github.com/dmester/jdenticon\r\n * Copyright © Daniel Mester Pirttijärvi\r\n */\r\n\r\n// This file is compiled to dist/jdenticon.js and dist/jdenticon.min.js\r\n\r\nimport { CONFIG_PROPERTIES, defineConfigProperty } from \"./common/configuration\";\r\nimport { observer } from \"./common/observer\";\r\nimport { configure } from \"./apis/configure\";\r\nimport { drawIcon } from \"./apis/drawIcon\";\r\nimport { toSvg } from \"./apis/toSvg\";\r\nimport { update, updateAll } from \"./apis/update\";\r\nimport { jdenticonJqueryPlugin } from \"./apis/jquery\";\r\nimport { GLOBAL } from \"./common/global\";\r\n\r\nconst jdenticon = updateAll;\r\n\r\ndefineConfigProperty(jdenticon);\r\n\r\n// Export public API\r\njdenticon[\"configure\"] = configure;\r\njdenticon[\"drawIcon\"] = drawIcon;\r\njdenticon[\"toSvg\"] = toSvg;\r\njdenticon[\"update\"] = update;\r\njdenticon[\"updateCanvas\"] = update;\r\njdenticon[\"updateSvg\"] = update;\r\n\r\n/**\r\n * Specifies the version of the Jdenticon package in use.\r\n * @type {string}\r\n */\r\njdenticon[\"version\"] = \"#version#\";\r\n\r\n/**\r\n * Specifies which bundle of Jdenticon that is used.\r\n * @type {string}\r\n */\r\njdenticon[\"bundle\"] = \"browser-umd\";\r\n\r\n// Basic jQuery plugin\r\nconst jQuery = GLOBAL[\"jQuery\"];\r\nif (jQuery) {\r\n jQuery[\"fn\"][\"jdenticon\"] = jdenticonJqueryPlugin;\r\n}\r\n\r\n/**\r\n * This function is called once upon page load.\r\n */\r\nfunction jdenticonStartup() {\r\n const replaceMode = (\r\n jdenticon[CONFIG_PROPERTIES.MODULE] ||\r\n GLOBAL[CONFIG_PROPERTIES.GLOBAL] ||\r\n { }\r\n )[\"replaceMode\"];\r\n \r\n if (replaceMode != \"never\") {\r\n updateAll();\r\n \r\n if (replaceMode == \"observe\") {\r\n observer(update);\r\n }\r\n }\r\n}\r\n\r\n// Schedule to render all identicons on the page once it has been loaded.\r\nif (typeof setTimeout === \"function\") {\r\n setTimeout(jdenticonStartup, 0);\r\n}\r\n\r\nmodule.exports = jdenticon;\r\n"]} \ No newline at end of file