code:
import { createPopper, popperGenerator, detectOverflow } from "./createPopper";
export * from "./types";
export { createPopper, popperGenerator, detectOverflow };


code:
import { popperGenerator, detectOverflow } from "./createPopper";
export * from "./types";
declare const defaultModifiers: (import("./modifiers/popperOffsets").PopperOffsetsModifier | import("./modifiers/eventListeners").EventListenersModifier | import("./modifiers/computeStyles").ComputeStylesModifier | import("./modifiers/applyStyles").ApplyStylesModifier)[];
declare const createPopper: <TModifier extends Partial<import("./types").Modifier<any, any>>>(reference: Element | import("./types").VirtualElement, popper: HTMLElement, options?: Partial<import("./types").OptionsGeneric<TModifier>>) => import("./types").Instance;
export { createPopper, popperGenerator, defaultModifiers, detectOverflow };

license: mit


code:
import { popperGenerator, detectOverflow } from "./createPopper";
export * from "./types";
declare const defaultModifiers: (import("./modifiers/popperOffsets").PopperOffsetsModifier | import("./modifiers/flip").FlipModifier | import("./modifiers/hide").HideModifier | import("./modifiers/offset").OffsetModifier | import("./modifiers/eventListeners").EventListenersModifier | import("./modifiers/computeStyles").ComputeStylesModifier | import("./modifiers/arrow").ArrowModifier | import("./modifiers/preventOverflow").PreventOverflowModifier | import("./modifiers/applyStyles").ApplyStylesModifier)[];
declare const createPopper: <TModifier extends Partial<import("./types").Modifier<any, any>>>(reference: Element | import("./types").VirtualElement, popper: HTMLElement, options?: Partial<import("./types").OptionsGeneric<TModifier>>) => import("./types").Instance;
export { createPopper, popperGenerator, defaultModifiers, detectOverflow };
export { createPopper as createPopperLite } from "./popper-lite";
export * from "./modifiers";


code:
import type { Placement, ModifierPhases } from "./enums";
import type { PopperOffsetsModifier } from "./modifiers/popperOffsets";
import type { FlipModifier } from "./modifiers/flip";
import type { HideModifier } from "./modifiers/hide";
import type { OffsetModifier } from "./modifiers/offset";
import type { EventListenersModifier } from "./modifiers/eventListeners";
import type { ComputeStylesModifier } from "./modifiers/computeStyles";
import type { ArrowModifier } from "./modifiers/arrow";
import type { PreventOverflowModifier } from "./modifiers/preventOverflow";
import type { ApplyStylesModifier } from "./modifiers/applyStyles";
export declare type Obj = {
    [key: string]: any;
};
export declare type VisualViewport = EventTarget & {
    width: number;
    height: number;
    offsetLeft: number;
    offsetTop: number;
    scale: number;
};
export declare type Window = {
    innerHeight: number;
    offsetHeight: number;
    innerWidth: number;
    offsetWidth: number;
    pageXOffset: number;
    pageYOffset: number;
    getComputedStyle: typeof getComputedStyle;
    addEventListener(type: any, listener: any, optionsOrUseCapture?: any): void;
    removeEventListener(type: any, listener: any, optionsOrUseCapture?: any): void;
    Element: Element;
    HTMLElement: HTMLElement;
    Node: Node;
    toString(): "[object Window]";
    devicePixelRatio: number;
    visualViewport?: VisualViewport;
    ShadowRoot: ShadowRoot;
};
export declare type Rect = {
    width: number;
    height: number;
    x: number;
    y: number;
};
export declare type Offsets = {
    y: number;
    x: number;
};
export declare type PositioningStrategy = "absolute" | "fixed";
export declare type StateRects = {
    reference: Rect;
    popper: Rect;
};
export declare type StateOffsets = {
    popper: Offsets;
    arrow?: Offsets;
};
declare type OffsetData = {
    [key in Placement]?: Offsets;
};
export declare type State = {
    elements: {
        reference: Element | VirtualElement;
        popper: HTMLElement;
        arrow?: HTMLElement;
    };
    options: OptionsGeneric<any>;
    placement: Placement;
    strategy: PositioningStrategy;
    orderedModifiers: Array<Modifier<any, any>>;
    rects: StateRects;
    scrollParents: {
        reference: Array<Element | Window | VisualViewport>;
        popper: Array<Element | Window | VisualViewport>;
    };
    styles: {
        [key: string]: Partial<CSSStyleDeclaration>;
    };
    attributes: {
        [key: string]: {
            [key: string]: string | boolean;
        };
    };
    modifiersData: {
        arrow?: {
            x?: number;
            y?: number;
            centerOffset: number;
        };
        hide?: {
            isReferenceHidden: boolean;
            hasPopperEscaped: boolean;
            referenceClippingOffsets: SideObject;
            popperEscapeOffsets: SideObject;
        };
        offset?: OffsetData;
        preventOverflow?: Offsets;
        popperOffsets?: Offsets;
        [key: string]: any;
    };
    reset: boolean;
};
declare type SetAction<S> = S | ((prev: S) => S);
export declare type Instance = {
    state: State;
    destroy: () => void;
    forceUpdate: () => void;
    update: () => Promise<Partial<State>>;
    setOptions: (setOptionsAction: SetAction<Partial<OptionsGeneric<any>>>) => Promise<Partial<State>>;
};
export declare type ModifierArguments<Options extends Obj> = {
    state: State;
    instance: Instance;
    options: Partial<Options>;
    name: string;
};
export declare type Modifier<Name, Options extends Obj> = {
    name: Name;
    enabled: boolean;
    phase: ModifierPhases;
    requires?: Array<string>;
    requiresIfExists?: Array<string>;
    fn: (arg0: ModifierArguments<Options>) => State | void;
    effect?: (arg0: ModifierArguments<Options>) => (() => void) | void;
    options?: Partial<Options>;
    data?: Obj;
};
export declare type StrictModifiers = Partial<OffsetModifier> | Partial<ApplyStylesModifier> | Partial<ArrowModifier> | Partial<HideModifier> | Partial<ComputeStylesModifier> | Partial<EventListenersModifier> | Partial<FlipModifier> | Partial<PreventOverflowModifier> | Partial<PopperOffsetsModifier>;
export declare type EventListeners = {
    scroll: boolean;
    resize: boolean;
};
export declare type Options = {
    placement: Placement;
    modifiers: Array<Partial<Modifier<any, any>>>;
    strategy: PositioningStrategy;
    onFirstUpdate?: (arg0: Partial<State>) => void;
};
export declare type OptionsGeneric<TModifier> = {
    placement: Placement;
    modifiers: Array<TModifier>;
    strategy: PositioningStrategy;
    onFirstUpdate?: (arg0: Partial<State>) => void;
};
export declare type UpdateCallback = (arg0: State) => void;
export declare type ClientRectObject = {
    x: number;
    y: number;
    top: number;
    left: number;
    right: number;
    bottom: number;
    width: number;
    height: number;
};
export declare type SideObject = {
    top: number;
    left: number;
    right: number;
    bottom: number;
};
export declare type Padding = number | Partial<SideObject>;
export declare type VirtualElement = {
    getBoundingClientRect: () => ClientRect | DOMRect;
    contextElement?: Element;
};
export {};


code:
import type { State, Padding } from "../types";
import type { Placement, ComputedPlacement, Boundary, RootBoundary } from "../enums";
declare type Options = {
    placement: Placement;
    padding: Padding;
    boundary: Boundary;
    rootBoundary: RootBoundary;
    flipVariations: boolean;
    allowedAutoPlacements?: Array<Placement>;
};
export default function computeAutoPlacement(state: Partial<State>, options?: Options): Array<ComputedPlacement>;
export {};


code:
import type { Rect, PositioningStrategy, Offsets, ClientRectObject } from "../types";
import { Placement } from "../enums";
export default function computeOffsets({ reference, element, placement }: {
    reference: Rect | ClientRectObject;
    element: Rect | ClientRectObject;
    strategy: PositioningStrategy;
    placement?: Placement;
}): Offsets;


code: export default function debounce<T>(fn: (...args: Array<any>) => any): () => Promise<T>;


code:
import type { State, SideObject, Padding } from "../types";
import type { Placement, Boundary, RootBoundary, Context } from "../enums";
export declare type Options = {
    placement: Placement;
    boundary: Boundary;
    rootBoundary: RootBoundary;
    elementContext: Context;
    altBoundary: boolean;
    padding: Padding;
};
export default function detectOverflow(state: State, options?: Partial<Options>): SideObject;


code:
export default function expandToHashMap<T extends number | string | boolean, K extends string>(value: T, keys: Array<K>): {
    [key: string]: T;
};


code: export default function format(str: string, ...args: Array<string>): string;


code: export default function getAltAxis(axis: "x" | "y"): "x" | "y";


code: export default function getAltLen(len: "width" | "height"): "width" | "height";


code:
import { BasePlacement, Placement, auto } from "../enums";
export default function getBasePlacement(placement: Placement | typeof auto): BasePlacement;


code:
import type { SideObject } from "../types";
export default function getFreshSideObject(): SideObject;


code:
import type { Placement } from "../enums";
export default function getMainAxisFromPlacement(placement: Placement): "x" | "y";


code:
import type { Placement } from "../enums";
export default function getOppositePlacement(placement: Placement): Placement;


code:
import type { Placement } from "../enums";
export default function getOppositeVariationPlacement(placement: Placement): Placement;


code:
import { Variation, Placement } from "../enums";
export default function getVariation(placement: Placement): Variation | null | undefined;


code:
export declare const max: (...values: number[]) => number;
export declare const min: (...values: number[]) => number;
export declare const round: (x: number) => number;


code:
import type { Modifier } from "../types";
export default function mergeByName(modifiers: Array<Partial<Modifier<any, any>>>): Array<Partial<Modifier<any, any>>>;


code:
import type { SideObject } from "../types";
export default function mergePaddingObject(paddingObject: Partial<SideObject>): SideObject;


code:
import type { Modifier } from "../types";
export default function orderModifiers(modifiers: Array<Modifier<any, any>>): Array<Modifier<any, any>>;


code:
import type { Rect, ClientRectObject } from "../types";
export default function rectToClientRect(rect: Rect): ClientRectObject;


code: export default function uniqueBy<T>(arr: Array<T>, fn: (arg0: T) => any): Array<T>;


code: export default function validateModifiers(modifiers: Array<any>): void;


code:
export declare function within(min: number, value: number, max: number): number;
export declare function withinMaxClamp(min: number, value: number, max: number): number;


code:
# @sideway/address

#### Validate email address and domain.

**address** is part of the **joi** ecosystem.

### Visit the [joi.dev](https://joi.dev) Developer Portal for tutorials, documentation, and support

## Useful resources

- [Documentation and API](https://joi.dev/module/address/)
- [Versions status](https://joi.dev/resources/status/#address)
- [Changelog](https://joi.dev/module/address/changelog/)
- [Project policies](https://joi.dev/policies/)


code:
'use strict';

// Adapted from:
// Copyright (c) 2017-2019 Justin Ridgewell, MIT Licensed, https://github.com/jridgewell/safe-decode-string-component
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>, MIT Licensed, http://bjoern.hoehrmann.de/utf-8/decoder/dfa/

const internals = {};

exports.decode = function (string) {

    let percentPos = string.indexOf('%');
    if (percentPos === -1) {
        return string;
    }

    let decoded = '';
    let last = 0;
    let codepoint = 0;
    let startOfOctets = percentPos;
    let state = internals.utf8.accept;

    while (percentPos > -1 &&
        percentPos < string.length) {

        const high = internals.resolveHex(string[percentPos + 1], 4);
        const low = internals.resolveHex(string[percentPos + 2], 0);
        const byte = high | low;
        const type = internals.utf8.data[byte];
        state = internals.utf8.data[256 + state + type];
        codepoint = (codepoint << 6) | (byte & internals.utf8.data[364 + type]);

        if (state === internals.utf8.accept) {
            decoded += string.slice(last, startOfOctets);
            decoded += codepoint <= 0xFFFF
                ? String.fromCharCode(codepoint)
                : String.fromCharCode(0xD7C0 + (codepoint >> 10), 0xDC00 + (codepoint & 0x3FF));

            codepoint = 0;
            last = percentPos + 3;
            percentPos = string.indexOf('%', last);
            startOfOctets = percentPos;
            continue;
        }

        if (state === internals.utf8.reject) {
            return null;
        }

        percentPos += 3;

        if (percentPos >= string.length ||
            string[percentPos] !== '%') {

            return null;
        }
    }

    return decoded + string.slice(last);
};

internals.resolveHex = function (char, shift) {

    const i = internals.hex[char];
    return i === undefined ? 255 : i << shift;
};

internals.hex = {
    '0': 0, '1': 1, '2': 2, '3': 3, '4': 4,
    '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
    'a': 10, 'A': 10, 'b': 11, 'B': 11, 'c': 12,
    'C': 12, 'd': 13, 'D': 13, 'e': 14, 'E': 14,
    'f': 15, 'F': 15
};

internals.utf8 = {
    accept: 12,
    reject: 0,
    data: [

        // Maps bytes to character to a transition

        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
        6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 7,
        10, 9, 9, 9, 11, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,

        // Maps a state to a new state when adding a transition

        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        12, 0, 0, 0, 0, 24, 36, 48, 60, 72, 84, 96,
        0, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

        // Maps the current transition to a mask that needs to apply to the byte

        0x7F, 0x3F, 0x3F, 0x3F, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07
    ]
};


code:
'use strict';

const Url = require('url');

const Errors = require('./errors');

const internals = {
    minDomainSegments: 2,
    nonAsciiRx: /[^\x00-\x7f]/,
    domainControlRx: /[\x00-\x20@\:\/\\#!\$&\'\(\)\*\+,;=\?]/,                          // Control + space + separators
    tldSegmentRx: /^[a-zA-Z](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/,
    domainSegmentRx: /^[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/,
    URL: Url.URL || URL                                                                 // $lab:coverage:ignore$
};

exports.analyze = function (domain, options = {}) {

    if (!domain) {                                                                      // Catch null / undefined
        return Errors.code('DOMAIN_NON_EMPTY_STRING');
    }

    if (typeof domain !== 'string') {
        throw new Error('Invalid input: domain must be a string');
    }

    if (domain.length > 256) {
        return Errors.code('DOMAIN_TOO_LONG');
    }

    const ascii = !internals.nonAsciiRx.test(domain);
    if (!ascii) {
        if (options.allowUnicode === false) {                                           // Defaults to true
            return Errors.code('DOMAIN_INVALID_UNICODE_CHARS');
        }

        domain = domain.normalize('NFC');
    }

    if (internals.domainControlRx.test(domain)) {
        return Errors.code('DOMAIN_INVALID_CHARS');
    }

    domain = internals.punycode(domain);

    // https://tools.ietf.org/html/rfc1035 section 2.3.1

    if (options.allowFullyQualified &&
        domain[domain.length - 1] === '.') {

        domain = domain.slice(0, -1);
    }

    const minDomainSegments = options.minDomainSegments || internals.minDomainSegments;

    const segments = domain.split('.');
    if (segments.length < minDomainSegments) {
        return Errors.code('DOMAIN_SEGMENTS_COUNT');
    }

    if (options.maxDomainSegments) {
        if (segments.length > options.maxDomainSegments) {
            return Errors.code('DOMAIN_SEGMENTS_COUNT_MAX');
        }
    }

    const tlds = options.tlds;
    if (tlds) {
        const tld = segments[segments.length - 1].toLowerCase();
        if (tlds.deny && tlds.deny.has(tld) ||
            tlds.allow && !tlds.allow.has(tld)) {

            return Errors.code('DOMAIN_FORBIDDEN_TLDS');
        }
    }

    for (let i = 0; i < segments.length; ++i) {
        const segment = segments[i];

        if (!segment.length) {
            return Errors.code('DOMAIN_EMPTY_SEGMENT');
        }

        if (segment.length > 63) {
            return Errors.code('DOMAIN_LONG_SEGMENT');
        }

        if (i < segments.length - 1) {
            if (!internals.domainSegmentRx.test(segment)) {
                return Errors.code('DOMAIN_INVALID_CHARS');
            }
        }
        else {
            if (!internals.tldSegmentRx.test(segment)) {
                return Errors.code('DOMAIN_INVALID_TLDS_CHARS');
            }
        }
    }

    return null;
};

exports.isValid = function (domain, options) {

    return !exports.analyze(domain, options);
};

internals.punycode = function (domain) {

    if (domain.includes('%')) {
        domain = domain.replace(/%/g, '%25');
    }

    try {
        return new internals.URL(`http://${domain}`).host;
    }
    catch (err) {
        return domain;
    }
};


code:
'use strict';

const Util = require('util');

const Domain = require('./domain');
const Errors = require('./errors');

const internals = {
    nonAsciiRx: /[^\x00-\x7f]/,
    encoder: new (Util.TextEncoder || TextEncoder)()                                            // $lab:coverage:ignore$
};

exports.analyze = function (email, options) {

    return internals.email(email, options);
};

exports.isValid = function (email, options) {

    return !internals.email(email, options);
};

internals.email = function (email, options = {}) {

    if (typeof email !== 'string') {
        throw new Error('Invalid input: email must be a string');
    }

    if (!email) {
        return Errors.code('EMPTY_STRING');
    }

    // Unicode

    const ascii = !internals.nonAsciiRx.test(email);
    if (!ascii) {
        if (options.allowUnicode === false) {                                                   // Defaults to true
            return Errors.code('FORBIDDEN_UNICODE');
        }

        email = email.normalize('NFC');
    }

    // Basic structure

    const parts = email.split('@');
    if (parts.length !== 2) {
        return parts.length > 2 ? Errors.code('MULTIPLE_AT_CHAR') : Errors.code('MISSING_AT_CHAR');
    }

    const [local, domain] = parts;

    if (!local) {
        return Errors.code('EMPTY_LOCAL');
    }

    if (!options.ignoreLength) {
        if (email.length > 254) {                                           // http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3
            return Errors.code('ADDRESS_TOO_LONG');
        }

        if (internals.encoder.encode(local).length > 64) {                  // http://tools.ietf.org/html/rfc5321#section-4.5.3.1.1
            return Errors.code('LOCAL_TOO_LONG');
        }
    }

    // Validate parts

    return internals.local(local, ascii) || Domain.analyze(domain, options);
};

internals.local = function (local, ascii) {

    const segments = local.split('.');
    for (const segment of segments) {
        if (!segment.length) {
            return Errors.code('EMPTY_LOCAL_SEGMENT');
        }

        if (ascii) {
            if (!internals.atextRx.test(segment)) {
                return Errors.code('INVALID_LOCAL_CHARS');
            }

            continue;
        }

        for (const char of segment) {
            if (internals.atextRx.test(char)) {
                continue;
            }

            const binary = internals.binary(char);
            if (!internals.atomRx.test(binary)) {
                return Errors.code('INVALID_LOCAL_CHARS');
            }
        }
    }
};

internals.binary = function (char) {

    return Array.from(internals.encoder.encode(char)).map((v) => String.fromCharCode(v)).join('');
};

/*
    From RFC 5321:

        Mailbox         =   Local-part "@" ( Domain / address-literal )

        Local-part      =   Dot-string / Quoted-string
        Dot-string      =   Atom *("."  Atom)
        Atom            =   1*atext
        atext           =   ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"

        Domain          =   sub-domain *("." sub-domain)
        sub-domain      =   Let-dig [Ldh-str]
        Let-dig         =   ALPHA / DIGIT
        Ldh-str         =   *( ALPHA / DIGIT / "-" ) Let-dig

        ALPHA           =   %x41-5A / %x61-7A        ; a-z, A-Z
        DIGIT           =   %x30-39                  ; 0-9

    From RFC 6531:

        sub-domain      =/  U-label
        atext           =/  UTF8-non-ascii

        UTF8-non-ascii  =   UTF8-2 / UTF8-3 / UTF8-4

        UTF8-2          =   %xC2-DF UTF8-tail
        UTF8-3          =   %xE0 %xA0-BF UTF8-tail /
                            %xE1-EC 2( UTF8-tail ) /
                            %xED %x80-9F UTF8-tail /
                            %xEE-EF 2( UTF8-tail )
        UTF8-4          =   %xF0 %x90-BF 2( UTF8-tail ) /
                            %xF1-F3 3( UTF8-tail ) /
                            %xF4 %x80-8F 2( UTF8-tail )

        UTF8-tail       =   %x80-BF

    Note: The following are not supported:

        RFC 5321: address-literal, Quoted-string
        RFC 5322: obs-*, CFWS
*/

internals.atextRx = /^[\w!#\$%&'\*\+\-/=\?\^`\{\|\}~]+$/;               // _ included in \w

internals.atomRx = new RegExp([

    //  %xC2-DF UTF8-tail
    '(?:[\\xc2-\\xdf][\\x80-\\xbf])',

    //  %xE0 %xA0-BF UTF8-tail              %xE1-EC 2( UTF8-tail )            %xED %x80-9F UTF8-tail              %xEE-EF 2( UTF8-tail )
    '(?:\\xe0[\\xa0-\\xbf][\\x80-\\xbf])|(?:[\\xe1-\\xec][\\x80-\\xbf]{2})|(?:\\xed[\\x80-\\x9f][\\x80-\\xbf])|(?:[\\xee-\\xef][\\x80-\\xbf]{2})',

    //  %xF0 %x90-BF 2( UTF8-tail )            %xF1-F3 3( UTF8-tail )            %xF4 %x80-8F 2( UTF8-tail )
    '(?:\\xf0[\\x90-\\xbf][\\x80-\\xbf]{2})|(?:[\\xf1-\\xf3][\\x80-\\xbf]{3})|(?:\\xf4[\\x80-\\x8f][\\x80-\\xbf]{2})'

].join('|'));


code:
'use strict';

exports.codes = {
    EMPTY_STRING: 'Address must be a non-empty string',
    FORBIDDEN_UNICODE: 'Address contains forbidden Unicode characters',
    MULTIPLE_AT_CHAR: 'Address cannot contain more than one @ character',
    MISSING_AT_CHAR: 'Address must contain one @ character',
    EMPTY_LOCAL: 'Address local part cannot be empty',
    ADDRESS_TOO_LONG: 'Address too long',
    LOCAL_TOO_LONG: 'Address local part too long',
    EMPTY_LOCAL_SEGMENT: 'Address local part contains empty dot-separated segment',
    INVALID_LOCAL_CHARS: 'Address local part contains invalid character',
    DOMAIN_NON_EMPTY_STRING: 'Domain must be a non-empty string',
    DOMAIN_TOO_LONG: 'Domain too long',
    DOMAIN_INVALID_UNICODE_CHARS: 'Domain contains forbidden Unicode characters',
    DOMAIN_INVALID_CHARS: 'Domain contains invalid character',
    DOMAIN_INVALID_TLDS_CHARS: 'Domain contains invalid tld character',
    DOMAIN_SEGMENTS_COUNT: 'Domain lacks the minimum required number of segments',
    DOMAIN_SEGMENTS_COUNT_MAX: 'Domain contains too many segments',
    DOMAIN_FORBIDDEN_TLDS: 'Domain uses forbidden TLD',
    DOMAIN_EMPTY_SEGMENT: 'Domain contains empty dot-separated segment',
    DOMAIN_LONG_SEGMENT: 'Domain contains dot-separated segment that is too long'
};

exports.code = function (code) {

    return { code, error: exports.codes[code] };
};


code:
/// <reference types="node" />

import * as Hoek from '@hapi/hoek';

export namespace domain {

    /**
     * Analyzes a string to verify it is a valid domain name.
     *
     * @param domain - the domain name to validate.
     * @param options - optional settings.
     *
     * @return - undefined when valid, otherwise an object with single error key with a string message value.
     */
    function analyze(domain: string, options?: Options): Analysis | null;

    /**
     * Analyzes a string to verify it is a valid domain name.
     *
     * @param domain - the domain name to validate.
     * @param options - optional settings.
     *
     * @return - true when valid, otherwise false.
     */
    function isValid(domain: string, options?: Options): boolean;

    interface Options {

        /**
         * Determines whether Unicode characters are allowed.
         *
         * @default true
         */
        readonly allowUnicode?: boolean;

        /**
         * The minimum number of domain segments (e.g. `x.y.z` has 3 segments) required.
         *
         * @default 2
         */
        readonly minDomainSegments?: number;

        /**
         * Top-level-domain options
         *
         * @default true
         */
        readonly tlds?: Tlds.Allow | Tlds.Deny | boolean;
    }

    namespace Tlds {

        interface Allow {

            readonly allow: Set<string> | true;
        }

        interface Deny {

            readonly deny: Set<string>;
        }
    }
}

export namespace email {

    /**
     * Analyzes a string to verify it is a valid email address.
     *
     * @param email - the email address to validate.
     * @param options - optional settings.
     *
     * @return - undefined when valid, otherwise an object with single error key with a string message value.
     */
    function analyze(email: string, options?: Options): Analysis | null;

    /**
     * Analyzes a string to verify it is a valid email address.
     *
     * @param email - the email address to validate.
     * @param options - optional settings.
     *
     * @return - true when valid, otherwise false.
     */
    function isValid(email: string, options?: Options): boolean;

    interface Options extends domain.Options {

        /**
         * Determines whether to ignore the standards maximum email length limit.
         *
         * @default false
         */
        readonly ignoreLength?: boolean;
    }
}

export interface Analysis {

    /**
     * The reason validation failed.
     */
    error: string;

    /**
     * The error code.
     */
    code: string;
}

export const errors: Record<string, string>;

export namespace ip {

    /**
     * Generates a regular expression used to validate IP addresses.
     *
     * @param options - optional settings.
     *
     * @returns an object with the regular expression and meta data.
     */
    function regex(options?: Options): Expression;

    interface Options {

        /**
         * The required CIDR mode.
         *
         * @default 'optional'
         */
        readonly cidr?: Cidr;

        /**
         * The allowed versions.
         *
         * @default ['ipv4', 'ipv6', 'ipvfuture']
         */
        readonly version?: Version | Version[];
    }

    type Cidr = 'optional' | 'required' | 'forbidden';
    type Version = 'ipv4' | 'ipv6' | 'ipvfuture';

    interface Expression {

        /**
         * The CIDR mode.
         */
        cidr: Cidr;

        /**
         * The raw regular expression string.
         */
        raw: string;

        /**
         * The regular expression.
         */
        regex: RegExp;

        /**
         * The array of versions allowed.
         */
        versions: Version[];
    }
}

export namespace uri {

    /**
     * Faster version of decodeURIComponent() that does not throw.
     *
     * @param string - the URL string to decode.
     *
     * @returns the decoded string or null if invalid.
     */
    function decode(string: string): string | null;

    /**
     * Generates a regular expression used to validate URI addresses.
     *
     * @param options - optional settings.
     *
     * @returns an object with the regular expression and meta data.
     */
    function regex(options?: Options): Expression;

    type Options = Hoek.ts.XOR<Options.Options, Options.Relative>;

    namespace Options {

        interface Query {

            /**
             * Allow the use of [] in query parameters.
             *
             * @default false
             */
            readonly allowQuerySquareBrackets?: boolean;
        }

        interface Relative extends Query {

            /**
             * Requires the URI to be relative.
             *
             * @default false
             */
            readonly relativeOnly?: boolean;
        }

        interface Options extends Query {

            /**
             * Allow relative URIs.
             *
             * @default false
             */
            readonly allowRelative?: boolean;

            /**
             * Capture domain segment ($1).
             *
             * @default false
             */
            readonly domain?: boolean;

            /**
             * The allowed URI schemes.
             */
            readonly scheme?: Scheme | Scheme[];
        }

        type Scheme = string | RegExp;
    }

    interface Expression {

        /**
         * The raw regular expression string.
         */
        raw: string;

        /**
         * The regular expression.
         */
        regex: RegExp;
    }
}


code:
'use strict';

const Decode = require('./decode');
const Domain = require('./domain');
const Email = require('./email');
const Errors = require('./errors');
const Ip = require('./ip');
const Tlds = require('./tlds');
const Uri = require('./uri');

const internals = {
    defaultTlds: { allow: Tlds, deny: null }
};

module.exports = {
    errors: Errors.codes,

    domain: {
        analyze(domain, options) {

            options = internals.options(options);
            return Domain.analyze(domain, options);
        },

        isValid(domain, options) {

            options = internals.options(options);
            return Domain.isValid(domain, options);
        }
    },
    email: {
        analyze(email, options) {

            options = internals.options(options);
            return Email.analyze(email, options);
        },

        isValid(email, options) {

            options = internals.options(options);
            return Email.isValid(email, options);
        }
    },
    ip: {
        regex: Ip.regex
    },
    uri: {
        decode: Decode.decode,
        regex: Uri.regex
    }
};

internals.options = function (options) {

    if (!options) {
        return { tlds: internals.defaultTlds };
    }

    if (options.tlds === false) {                // Defaults to true
        return options;
    }

    if (!options.tlds ||
        options.tlds === true) {

        return Object.assign({}, options, { tlds: internals.defaultTlds });
    }

    if (typeof options.tlds !== 'object') {
        throw new Error('Invalid options: tlds must be a boolean or an object');
    }

    if (options.tlds.deny) {
        if (options.tlds.deny instanceof Set === false) {
            throw new Error('Invalid options: tlds.deny must be a Set object');
        }

        if (options.tlds.allow) {
            throw new Error('Invalid options: cannot specify both tlds.allow and tlds.deny lists');
        }

        return options;
    }

    if (options.tlds.allow === true) {
        return Object.assign({}, options, { tlds: internals.defaultTlds });
    }

    if (options.tlds.allow instanceof Set === false) {
        throw new Error('Invalid options: tlds.allow must be a Set object or true');
    }

    return options;
};


code:
'use strict';

const Assert = require('@hapi/hoek/lib/assert');

const Uri = require('./uri');

const internals = {};

exports.regex = function (options = {}) {

    // CIDR

    Assert(options.cidr === undefined || typeof options.cidr === 'string', 'options.cidr must be a string');
    const cidr = options.cidr ? options.cidr.toLowerCase() : 'optional';
    Assert(['required', 'optional', 'forbidden'].includes(cidr), 'options.cidr must be one of required, optional, forbidden');

    // Versions

    Assert(options.version === undefined || typeof options.version === 'string' || Array.isArray(options.version), 'options.version must be a string or an array of string');
    let versions = options.version || ['ipv4', 'ipv6', 'ipvfuture'];
    if (!Array.isArray(versions)) {
        versions = [versions];
    }

    Assert(versions.length >= 1, 'options.version must have at least 1 version specified');

    for (let i = 0; i < versions.length; ++i) {
        Assert(typeof versions[i] === 'string', 'options.version must only contain strings');
        versions[i] = versions[i].toLowerCase();
        Assert(['ipv4', 'ipv6', 'ipvfuture'].includes(versions[i]), 'options.version contains unknown version ' + versions[i] + ' - must be one of ipv4, ipv6, ipvfuture');
    }

    versions = Array.from(new Set(versions));

    // Regex

    const parts = versions.map((version) => {

        // Forbidden

        if (cidr === 'forbidden') {
            return Uri.ip[version];
        }

        // Required

        const cidrpart = `\\/${version === 'ipv4' ? Uri.ip.v4Cidr : Uri.ip.v6Cidr}`;

        if (cidr === 'required') {
            return `${Uri.ip[version]}${cidrpart}`;
        }

        // Optional

        return `${Uri.ip[version]}(?:${cidrpart})?`;
    });

    const raw = `(?:${parts.join('|')})`;
    const regex = new RegExp(`^${raw}$`);
    return { cidr, versions, regex, raw };
};


code:
'use strict';

const internals = {};

// http://data.iana.org/TLD/tlds-alpha-by-domain.txt
// # Version 2024012900, Last Updated Mon Jan 29 07:07:01 2024 UTC

internals.tlds = [
    'AAA',
    'AARP',
    'ABB',
    'ABBOTT',
    'ABBVIE',
    'ABC',
    'ABLE',
    'ABOGADO',
    'ABUDHABI',
    'AC',
    'ACADEMY',
    'ACCENTURE',
    'ACCOUNTANT',
    'ACCOUNTANTS',
    'ACO',
    'ACTOR',
    'AD',
    'ADS',
    'ADULT',
    'AE',
    'AEG',
    'AERO',
    'AETNA',
    'AF',
    'AFL',
    'AFRICA',
    'AG',
    'AGAKHAN',
    'AGENCY',
    'AI',
    'AIG',
    'AIRBUS',
    'AIRFORCE',
    'AIRTEL',
    'AKDN',
    'AL',
    'ALIBABA',
    'ALIPAY',
    'ALLFINANZ',
    'ALLSTATE',
    'ALLY',
    'ALSACE',
    'ALSTOM',
    'AM',
    'AMAZON',
    'AMERICANEXPRESS',
    'AMERICANFAMILY',
    'AMEX',
    'AMFAM',
    'AMICA',
    'AMSTERDAM',
    'ANALYTICS',
    'ANDROID',
    'ANQUAN',
    'ANZ',
    'AO',
    'AOL',
    'APARTMENTS',
    'APP',
    'APPLE',
    'AQ',
    'AQUARELLE',
    'AR',
    'ARAB',
    'ARAMCO',
    'ARCHI',
    'ARMY',
    'ARPA',
    'ART',
    'ARTE',
    'AS',
    'ASDA',
    'ASIA',
    'ASSOCIATES',
    'AT',
    'ATHLETA',
    'ATTORNEY',
    'AU',
    'AUCTION',
    'AUDI',
    'AUDIBLE',
    'AUDIO',
    'AUSPOST',
    'AUTHOR',
    'AUTO',
    'AUTOS',
    'AVIANCA',
    'AW',
    'AWS',
    'AX',
    'AXA',
    'AZ',
    'AZURE',
    'BA',
    'BABY',
    'BAIDU',
    'BANAMEX',
    'BAND',
    'BANK',
    'BAR',
    'BARCELONA',
    'BARCLAYCARD',
    'BARCLAYS',
    'BAREFOOT',
    'BARGAINS',
    'BASEBALL',
    'BASKETBALL',
    'BAUHAUS',
    'BAYERN',
    'BB',
    'BBC',
    'BBT',
    'BBVA',
    'BCG',
    'BCN',
    'BD',
    'BE',
    'BEATS',
    'BEAUTY',
    'BEER',
    'BENTLEY',
    'BERLIN',
    'BEST',
    'BESTBUY',
    'BET',
    'BF',
    'BG',
    'BH',
    'BHARTI',
    'BI',
    'BIBLE',
    'BID',
    'BIKE',
    'BING',
    'BINGO',
    'BIO',
    'BIZ',
    'BJ',
    'BLACK',
    'BLACKFRIDAY',
    'BLOCKBUSTER',
    'BLOG',
    'BLOOMBERG',
    'BLUE',
    'BM',
    'BMS',
    'BMW',
    'BN',
    'BNPPARIBAS',
    'BO',
    'BOATS',
    'BOEHRINGER',
    'BOFA',
    'BOM',
    'BOND',
    'BOO',
    'BOOK',
    'BOOKING',
    'BOSCH',
    'BOSTIK',
    'BOSTON',
    'BOT',
    'BOUTIQUE',
    'BOX',
    'BR',
    'BRADESCO',
    'BRIDGESTONE',
    'BROADWAY',
    'BROKER',
    'BROTHER',
    'BRUSSELS',
    'BS',
    'BT',
    'BUILD',
    'BUILDERS',
    'BUSINESS',
    'BUY',
    'BUZZ',
    'BV',
    'BW',
    'BY',
    'BZ',
    'BZH',
    'CA',
    'CAB',
    'CAFE',
    'CAL',
    'CALL',
    'CALVINKLEIN',
    'CAM',
    'CAMERA',
    'CAMP',
    'CANON',
    'CAPETOWN',
    'CAPITAL',
    'CAPITALONE',
    'CAR',
    'CARAVAN',
    'CARDS',
    'CARE',
    'CAREER',
    'CAREERS',
    'CARS',
    'CASA',
    'CASE',
    'CASH',
    'CASINO',
    'CAT',
    'CATERING',
    'CATHOLIC',
    'CBA',
    'CBN',
    'CBRE',
    'CC',
    'CD',
    'CENTER',
    'CEO',
    'CERN',
    'CF',
    'CFA',
    'CFD',
    'CG',
    'CH',
    'CHANEL',
    'CHANNEL',
    'CHARITY',
    'CHASE',
    'CHAT',
    'CHEAP',
    'CHINTAI',
    'CHRISTMAS',
    'CHROME',
    'CHURCH',
    'CI',
    'CIPRIANI',
    'CIRCLE',
    'CISCO',
    'CITADEL',
    'CITI',
    'CITIC',
    'CITY',
    'CK',
    'CL',
    'CLAIMS',
    'CLEANING',
    'CLICK',
    'CLINIC',
    'CLINIQUE',
    'CLOTHING',
    'CLOUD',
    'CLUB',
    'CLUBMED',
    'CM',
    'CN',
    'CO',
    'COACH',
    'CODES',
    'COFFEE',
    'COLLEGE',
    'COLOGNE',
    'COM',
    'COMCAST',
    'COMMBANK',
    'COMMUNITY',
    'COMPANY',
    'COMPARE',
    'COMPUTER',
    'COMSEC',
    'CONDOS',
    'CONSTRUCTION',
    'CONSULTING',
    'CONTACT',
    'CONTRACTORS',
    'COOKING',
    'COOL',
    'COOP',
    'CORSICA',
    'COUNTRY',
    'COUPON',
    'COUPONS',
    'COURSES',
    'CPA',
    'CR',
    'CREDIT',
    'CREDITCARD',
    'CREDITUNION',
    'CRICKET',
    'CROWN',
    'CRS',
    'CRUISE',
    'CRUISES',
    'CU',
    'CUISINELLA',
    'CV',
    'CW',
    'CX',
    'CY',
    'CYMRU',
    'CYOU',
    'CZ',
    'DABUR',
    'DAD',
    'DANCE',
    'DATA',
    'DATE',
    'DATING',
    'DATSUN',
    'DAY',
    'DCLK',
    'DDS',
    'DE',
    'DEAL',
    'DEALER',
    'DEALS',
    'DEGREE',
    'DELIVERY',
    'DELL',
    'DELOITTE',
    'DELTA',
    'DEMOCRAT',
    'DENTAL',
    'DENTIST',
    'DESI',
    'DESIGN',
    'DEV',
    'DHL',
    'DIAMONDS',
    'DIET',
    'DIGITAL',
    'DIRECT',
    'DIRECTORY',
    'DISCOUNT',
    'DISCOVER',
    'DISH',
    'DIY',
    'DJ',
    'DK',
    'DM',
    'DNP',
    'DO',
    'DOCS',
    'DOCTOR',
    'DOG',
    'DOMAINS',
    'DOT',
    'DOWNLOAD',
    'DRIVE',
    'DTV',
    'DUBAI',
    'DUNLOP',
    'DUPONT',
    'DURBAN',
    'DVAG',
    'DVR',
    'DZ',
    'EARTH',
    'EAT',
    'EC',
    'ECO',
    'EDEKA',
    'EDU',
    'EDUCATION',
    'EE',
    'EG',
    'EMAIL',
    'EMERCK',
    'ENERGY',
    'ENGINEER',
    'ENGINEERING',
    'ENTERPRISES',
    'EPSON',
    'EQUIPMENT',
    'ER',
    'ERICSSON',
    'ERNI',
    'ES',
    'ESQ',
    'ESTATE',
    'ET',
    'EU',
    'EUROVISION',
    'EUS',
    'EVENTS',
    'EXCHANGE',
    'EXPERT',
    'EXPOSED',
    'EXPRESS',
    'EXTRASPACE',
    'FAGE',
    'FAIL',
    'FAIRWINDS',
    'FAITH',
    'FAMILY',
    'FAN',
    'FANS',
    'FARM',
    'FARMERS',
    'FASHION',
    'FAST',
    'FEDEX',
    'FEEDBACK',
    'FERRARI',
    'FERRERO',
    'FI',
    'FIDELITY',
    'FIDO',
    'FILM',
    'FINAL',
    'FINANCE',
    'FINANCIAL',
    'FIRE',
    'FIRESTONE',
    'FIRMDALE',
    'FISH',
    'FISHING',
    'FIT',
    'FITNESS',
    'FJ',
    'FK',
    'FLICKR',
    'FLIGHTS',
    'FLIR',
    'FLORIST',
    'FLOWERS',
    'FLY',
    'FM',
    'FO',
    'FOO',
    'FOOD',
    'FOOTBALL',
    'FORD',
    'FOREX',
    'FORSALE',
    'FORUM',
    'FOUNDATION',
    'FOX',
    'FR',
    'FREE',
    'FRESENIUS',
    'FRL',
    'FROGANS',
    'FRONTIER',
    'FTR',
    'FUJITSU',
    'FUN',
    'FUND',
    'FURNITURE',
    'FUTBOL',
    'FYI',
    'GA',
    'GAL',
    'GALLERY',
    'GALLO',
    'GALLUP',
    'GAME',
    'GAMES',
    'GAP',
    'GARDEN',
    'GAY',
    'GB',
    'GBIZ',
    'GD',
    'GDN',
    'GE',
    'GEA',
    'GENT',
    'GENTING',
    'GEORGE',
    'GF',
    'GG',
    'GGEE',
    'GH',
    'GI',
    'GIFT',
    'GIFTS',
    'GIVES',
    'GIVING',
    'GL',
    'GLASS',
    'GLE',
    'GLOBAL',
    'GLOBO',
    'GM',
    'GMAIL',
    'GMBH',
    'GMO',
    'GMX',
    'GN',
    'GODADDY',
    'GOLD',
    'GOLDPOINT',
    'GOLF',
    'GOO',
    'GOODYEAR',
    'GOOG',
    'GOOGLE',
    'GOP',
    'GOT',
    'GOV',
    'GP',
    'GQ',
    'GR',
    'GRAINGER',
    'GRAPHICS',
    'GRATIS',
    'GREEN',
    'GRIPE',
    'GROCERY',
    'GROUP',
    'GS',
    'GT',
    'GU',
    'GUARDIAN',
    'GUCCI',
    'GUGE',
    'GUIDE',
    'GUITARS',
    'GURU',
    'GW',
    'GY',
    'HAIR',
    'HAMBURG',
    'HANGOUT',
    'HAUS',
    'HBO',
    'HDFC',
    'HDFCBANK',
    'HEALTH',
    'HEALTHCARE',
    'HELP',
    'HELSINKI',
    'HERE',
    'HERMES',
    'HIPHOP',
    'HISAMITSU',
    'HITACHI',
    'HIV',
    'HK',
    'HKT',
    'HM',
    'HN',
    'HOCKEY',
    'HOLDINGS',
    'HOLIDAY',
    'HOMEDEPOT',
    'HOMEGOODS',
    'HOMES',
    'HOMESENSE',
    'HONDA',
    'HORSE',
    'HOSPITAL',
    'HOST',
    'HOSTING',
    'HOT',
    'HOTELS',
    'HOTMAIL',
    'HOUSE',
    'HOW',
    'HR',
    'HSBC',
    'HT',
    'HU',
    'HUGHES',
    'HYATT',
    'HYUNDAI',
    'IBM',
    'ICBC',
    'ICE',
    'ICU',
    'ID',
    'IE',
    'IEEE',
    'IFM',
    'IKANO',
    'IL',
    'IM',
    'IMAMAT',
    'IMDB',
    'IMMO',
    'IMMOBILIEN',
    'IN',
    'INC',
    'INDUSTRIES',
    'INFINITI',
    'INFO',
    'ING',
    'INK',
    'INSTITUTE',
    'INSURANCE',
    'INSURE',
    'INT',
    'INTERNATIONAL',
    'INTUIT',
    'INVESTMENTS',
    'IO',
    'IPIRANGA',
    'IQ',
    'IR',
    'IRISH',
    'IS',
    'ISMAILI',
    'IST',
    'ISTANBUL',
    'IT',
    'ITAU',
    'ITV',
    'JAGUAR',
    'JAVA',
    'JCB',
    'JE',
    'JEEP',
    'JETZT',
    'JEWELRY',
    'JIO',
    'JLL',
    'JM',
    'JMP',
    'JNJ',
    'JO',
    'JOBS',
    'JOBURG',
    'JOT',
    'JOY',
    'JP',
    'JPMORGAN',
    'JPRS',
    'JUEGOS',
    'JUNIPER',
    'KAUFEN',
    'KDDI',
    'KE',
    'KERRYHOTELS',
    'KERRYLOGISTICS',
    'KERRYPROPERTIES',
    'KFH',
    'KG',
    'KH',
    'KI',
    'KIA',
    'KIDS',
    'KIM',
    'KINDLE',
    'KITCHEN',
    'KIWI',
    'KM',
    'KN',
    'KOELN',
    'KOMATSU',
    'KOSHER',
    'KP',
    'KPMG',
    'KPN',
    'KR',
    'KRD',
    'KRED',
    'KUOKGROUP',
    'KW',
    'KY',
    'KYOTO',
    'KZ',
    'LA',
    'LACAIXA',
    'LAMBORGHINI',
    'LAMER',
    'LANCASTER',
    'LAND',
    'LANDROVER',
    'LANXESS',
    'LASALLE',
    'LAT',
    'LATINO',
    'LATROBE',
    'LAW',
    'LAWYER',
    'LB',
    'LC',
    'LDS',
    'LEASE',
    'LECLERC',
    'LEFRAK',
    'LEGAL',
    'LEGO',
    'LEXUS',
    'LGBT',
    'LI',
    'LIDL',
    'LIFE',
    'LIFEINSURANCE',
    'LIFESTYLE',
    'LIGHTING',
    'LIKE',
    'LILLY',
    'LIMITED',
    'LIMO',
    'LINCOLN',
    'LINK',
    'LIPSY',
    'LIVE',
    'LIVING',
    'LK',
    'LLC',
    'LLP',
    'LOAN',
    'LOANS',
    'LOCKER',
    'LOCUS',
    'LOL',
    'LONDON',
    'LOTTE',
    'LOTTO',
    'LOVE',
    'LPL',
    'LPLFINANCIAL',
    'LR',
    'LS',
    'LT',
    'LTD',
    'LTDA',
    'LU',
    'LUNDBECK',
    'LUXE',
    'LUXURY',
    'LV',
    'LY',
    'MA',
    'MADRID',
    'MAIF',
    'MAISON',
    'MAKEUP',
    'MAN',
    'MANAGEMENT',
    'MANGO',
    'MAP',
    'MARKET',
    'MARKETING',
    'MARKETS',
    'MARRIOTT',
    'MARSHALLS',
    'MATTEL',
    'MBA',
    'MC',
    'MCKINSEY',
    'MD',
    'ME',
    'MED',
    'MEDIA',
    'MEET',
    'MELBOURNE',
    'MEME',
    'MEMORIAL',
    'MEN',
    'MENU',
    'MERCKMSD',
    'MG',
    'MH',
    'MIAMI',
    'MICROSOFT',
    'MIL',
    'MINI',
    'MINT',
    'MIT',
    'MITSUBISHI',
    'MK',
    'ML',
    'MLB',
    'MLS',
    'MM',
    'MMA',
    'MN',
    'MO',
    'MOBI',
    'MOBILE',
    'MODA',
    'MOE',
    'MOI',
    'MOM',
    'MONASH',
    'MONEY',
    'MONSTER',
    'MORMON',
    'MORTGAGE',
    'MOSCOW',
    'MOTO',
    'MOTORCYCLES',
    'MOV',
    'MOVIE',
    'MP',
    'MQ',
    'MR',
    'MS',
    'MSD',
    'MT',
    'MTN',
    'MTR',
    'MU',
    'MUSEUM',
    'MUSIC',
    'MV',
    'MW',
    'MX',
    'MY',
    'MZ',
    'NA',
    'NAB',
    'NAGOYA',
    'NAME',
    'NATURA',
    'NAVY',
    'NBA',
    'NC',
    'NE',
    'NEC',
    'NET',
    'NETBANK',
    'NETFLIX',
    'NETWORK',
    'NEUSTAR',
    'NEW',
    'NEWS',
    'NEXT',
    'NEXTDIRECT',
    'NEXUS',
    'NF',
    'NFL',
    'NG',
    'NGO',
    'NHK',
    'NI',
    'NICO',
    'NIKE',
    'NIKON',
    'NINJA',
    'NISSAN',
    'NISSAY',
    'NL',
    'NO',
    'NOKIA',
    'NORTON',
    'NOW',
    'NOWRUZ',
    'NOWTV',
    'NP',
    'NR',
    'NRA',
    'NRW',
    'NTT',
    'NU',
    'NYC',
    'NZ',
    'OBI',
    'OBSERVER',
    'OFFICE',
    'OKINAWA',
    'OLAYAN',
    'OLAYANGROUP',
    'OLLO',
    'OM',
    'OMEGA',
    'ONE',
    'ONG',
    'ONL',
    'ONLINE',
    'OOO',
    'OPEN',
    'ORACLE',
    'ORANGE',
    'ORG',
    'ORGANIC',
    'ORIGINS',
    'OSAKA',
    'OTSUKA',
    'OTT',
    'OVH',
    'PA',
    'PAGE',
    'PANASONIC',
    'PARIS',
    'PARS',
    'PARTNERS',
    'PARTS',
    'PARTY',
    'PAY',
    'PCCW',
    'PE',
    'PET',
    'PF',
    'PFIZER',
    'PG',
    'PH',
    'PHARMACY',
    'PHD',
    'PHILIPS',
    'PHONE',
    'PHOTO',
    'PHOTOGRAPHY',
    'PHOTOS',
    'PHYSIO',
    'PICS',
    'PICTET',
    'PICTURES',
    'PID',
    'PIN',
    'PING',
    'PINK',
    'PIONEER',
    'PIZZA',
    'PK',
    'PL',
    'PLACE',
    'PLAY',
    'PLAYSTATION',
    'PLUMBING',
    'PLUS',
    'PM',
    'PN',
    'PNC',
    'POHL',
    'POKER',
    'POLITIE',
    'PORN',
    'POST',
    'PR',
    'PRAMERICA',
    'PRAXI',
    'PRESS',
    'PRIME',
    'PRO',
    'PROD',
    'PRODUCTIONS',
    'PROF',
    'PROGRESSIVE',
    'PROMO',
    'PROPERTIES',
    'PROPERTY',
    'PROTECTION',
    'PRU',
    'PRUDENTIAL',
    'PS',
    'PT',
    'PUB',
    'PW',
    'PWC',
    'PY',
    'QA',
    'QPON',
    'QUEBEC',
    'QUEST',
    'RACING',
    'RADIO',
    'RE',
    'READ',
    'REALESTATE',
    'REALTOR',
    'REALTY',
    'RECIPES',
    'RED',
    'REDSTONE',
    'REDUMBRELLA',
    'REHAB',
    'REISE',
    'REISEN',
    'REIT',
    'RELIANCE',
    'REN',
    'RENT',
    'RENTALS',
    'REPAIR',
    'REPORT',
    'REPUBLICAN',
    'REST',
    'RESTAURANT',
    'REVIEW',
    'REVIEWS',
    'REXROTH',
    'RICH',
    'RICHARDLI',
    'RICOH',
    'RIL',
    'RIO',
    'RIP',
    'RO',
    'ROCKS',
    'RODEO',
    'ROGERS',
    'ROOM',
    'RS',
    'RSVP',
    'RU',
    'RUGBY',
    'RUHR',
    'RUN',
    'RW',
    'RWE',
    'RYUKYU',
    'SA',
    'SAARLAND',
    'SAFE',
    'SAFETY',
    'SAKURA',
    'SALE',
    'SALON',
    'SAMSCLUB',
    'SAMSUNG',
    'SANDVIK',
    'SANDVIKCOROMANT',
    'SANOFI',
    'SAP',
    'SARL',
    'SAS',
    'SAVE',
    'SAXO',
    'SB',
    'SBI',
    'SBS',
    'SC',
    'SCB',
    'SCHAEFFLER',
    'SCHMIDT',
    'SCHOLARSHIPS',
    'SCHOOL',
    'SCHULE',
    'SCHWARZ',
    'SCIENCE',
    'SCOT',
    'SD',
    'SE',
    'SEARCH',
    'SEAT',
    'SECURE',
    'SECURITY',
    'SEEK',
    'SELECT',
    'SENER',
    'SERVICES',
    'SEVEN',
    'SEW',
    'SEX',
    'SEXY',
    'SFR',
    'SG',
    'SH',
    'SHANGRILA',
    'SHARP',
    'SHAW',
    'SHELL',
    'SHIA',
    'SHIKSHA',
    'SHOES',
    'SHOP',
    'SHOPPING',
    'SHOUJI',
    'SHOW',
    'SI',
    'SILK',
    'SINA',
    'SINGLES',
    'SITE',
    'SJ',
    'SK',
    'SKI',
    'SKIN',
    'SKY',
    'SKYPE',
    'SL',
    'SLING',
    'SM',
    'SMART',
    'SMILE',
    'SN',
    'SNCF',
    'SO',
    'SOCCER',
    'SOCIAL',
    'SOFTBANK',
    'SOFTWARE',
    'SOHU',
    'SOLAR',
    'SOLUTIONS',
    'SONG',
    'SONY',
    'SOY',
    'SPA',
    'SPACE',
    'SPORT',
    'SPOT',
    'SR',
    'SRL',
    'SS',
    'ST',
    'STADA',
    'STAPLES',
    'STAR',
    'STATEBANK',
    'STATEFARM',
    'STC',
    'STCGROUP',
    'STOCKHOLM',
    'STORAGE',
    'STORE',
    'STREAM',
    'STUDIO',
    'STUDY',
    'STYLE',
    'SU',
    'SUCKS',
    'SUPPLIES',
    'SUPPLY',
    'SUPPORT',
    'SURF',
    'SURGERY',
    'SUZUKI',
    'SV',
    'SWATCH',
    'SWISS',
    'SX',
    'SY',
    'SYDNEY',
    'SYSTEMS',
    'SZ',
    'TAB',
    'TAIPEI',
    'TALK',
    'TAOBAO',
    'TARGET',
    'TATAMOTORS',
    'TATAR',
    'TATTOO',
    'TAX',
    'TAXI',
    'TC',
    'TCI',
    'TD',
    'TDK',
    'TEAM',
    'TECH',
    'TECHNOLOGY',
    'TEL',
    'TEMASEK',
    'TENNIS',
    'TEVA',
    'TF',
    'TG',
    'TH',
    'THD',
    'THEATER',
    'THEATRE',
    'TIAA',
    'TICKETS',
    'TIENDA',
    'TIPS',
    'TIRES',
    'TIROL',
    'TJ',
    'TJMAXX',
    'TJX',
    'TK',
    'TKMAXX',
    'TL',
    'TM',
    'TMALL',
    'TN',
    'TO',
    'TODAY',
    'TOKYO',
    'TOOLS',
    'TOP',
    'TORAY',
    'TOSHIBA',
    'TOTAL',
    'TOURS',
    'TOWN',
    'TOYOTA',
    'TOYS',
    'TR',
    'TRADE',
    'TRADING',
    'TRAINING',
    'TRAVEL',
    'TRAVELERS',
    'TRAVELERSINSURANCE',
    'TRUST',
    'TRV',
    'TT',
    'TUBE',
    'TUI',
    'TUNES',
    'TUSHU',
    'TV',
    'TVS',
    'TW',
    'TZ',
    'UA',
    'UBANK',
    'UBS',
    'UG',
    'UK',
    'UNICOM',
    'UNIVERSITY',
    'UNO',
    'UOL',
    'UPS',
    'US',
    'UY',
    'UZ',
    'VA',
    'VACATIONS',
    'VANA',
    'VANGUARD',
    'VC',
    'VE',
    'VEGAS',
    'VENTURES',
    'VERISIGN',
    'VERSICHERUNG',
    'VET',
    'VG',
    'VI',
    'VIAJES',
    'VIDEO',
    'VIG',
    'VIKING',
    'VILLAS',
    'VIN',
    'VIP',
    'VIRGIN',
    'VISA',
    'VISION',
    'VIVA',
    'VIVO',
    'VLAANDEREN',
    'VN',
    'VODKA',
    'VOLVO',
    'VOTE',
    'VOTING',
    'VOTO',
    'VOYAGE',
    'VU',
    'WALES',
    'WALMART',
    'WALTER',
    'WANG',
    'WANGGOU',
    'WATCH',
    'WATCHES',
    'WEATHER',
    'WEATHERCHANNEL',
    'WEBCAM',
    'WEBER',
    'WEBSITE',
    'WED',
    'WEDDING',
    'WEIBO',
    'WEIR',
    'WF',
    'WHOSWHO',
    'WIEN',
    'WIKI',
    'WILLIAMHILL',
    'WIN',
    'WINDOWS',
    'WINE',
    'WINNERS',
    'WME',
    'WOLTERSKLUWER',
    'WOODSIDE',
    'WORK',
    'WORKS',
    'WORLD',
    'WOW',
    'WS',
    'WTC',
    'WTF',
    'XBOX',
    'XEROX',
    'XFINITY',
    'XIHUAN',
    'XIN',
    'XN--11B4C3D',
    'XN--1CK2E1B',
    'XN--1QQW23A',
    'XN--2SCRJ9C',
    'XN--30RR7Y',
    'XN--3BST00M',
    'XN--3DS443G',
    'XN--3E0B707E',
    'XN--3HCRJ9C',
    'XN--3PXU8K',
    'XN--42C2D9A',
    'XN--45BR5CYL',
    'XN--45BRJ9C',
    'XN--45Q11C',
    'XN--4DBRK0CE',
    'XN--4GBRIM',
    'XN--54B7FTA0CC',
    'XN--55QW42G',
    'XN--55QX5D',
    'XN--5SU34J936BGSG',
    'XN--5TZM5G',
    'XN--6FRZ82G',
    'XN--6QQ986B3XL',
    'XN--80ADXHKS',
    'XN--80AO21A',
    'XN--80AQECDR1A',
    'XN--80ASEHDB',
    'XN--80ASWG',
    'XN--8Y0A063A',
    'XN--90A3AC',
    'XN--90AE',
    'XN--90AIS',
    'XN--9DBQ2A',
    'XN--9ET52U',
    'XN--9KRT00A',
    'XN--B4W605FERD',
    'XN--BCK1B9A5DRE4C',
    'XN--C1AVG',
    'XN--C2BR7G',
    'XN--CCK2B3B',
    'XN--CCKWCXETD',
    'XN--CG4BKI',
    'XN--CLCHC0EA0B2G2A9GCD',
    'XN--CZR694B',
    'XN--CZRS0T',
    'XN--CZRU2D',
    'XN--D1ACJ3B',
    'XN--D1ALF',
    'XN--E1A4C',
    'XN--ECKVDTC9D',
    'XN--EFVY88H',
    'XN--FCT429K',
    'XN--FHBEI',
    'XN--FIQ228C5HS',
    'XN--FIQ64B',
    'XN--FIQS8S',
    'XN--FIQZ9S',
    'XN--FJQ720A',
    'XN--FLW351E',
    'XN--FPCRJ9C3D',
    'XN--FZC2C9E2C',
    'XN--FZYS8D69UVGM',
    'XN--G2XX48C',
    'XN--GCKR3F0F',
    'XN--GECRJ9C',
    'XN--GK3AT1E',
    'XN--H2BREG3EVE',
    'XN--H2BRJ9C',
    'XN--H2BRJ9C8C',
    'XN--HXT814E',
    'XN--I1B6B1A6A2E',
    'XN--IMR513N',
    'XN--IO0A7I',
    'XN--J1AEF',
    'XN--J1AMH',
    'XN--J6W193G',
    'XN--JLQ480N2RG',
    'XN--JVR189M',
    'XN--KCRX77D1X4A',
    'XN--KPRW13D',
    'XN--KPRY57D',
    'XN--KPUT3I',
    'XN--L1ACC',
    'XN--LGBBAT1AD8J',
    'XN--MGB9AWBF',
    'XN--MGBA3A3EJT',
    'XN--MGBA3A4F16A',
    'XN--MGBA7C0BBN0A',
    'XN--MGBAAM7A8H',
    'XN--MGBAB2BD',
    'XN--MGBAH1A3HJKRD',
    'XN--MGBAI9AZGQP6J',
    'XN--MGBAYH7GPA',
    'XN--MGBBH1A',
    'XN--MGBBH1A71E',
    'XN--MGBC0A9AZCG',
    'XN--MGBCA7DZDO',
    'XN--MGBCPQ6GPA1A',
    'XN--MGBERP4A5D4AR',
    'XN--MGBGU82A',
    'XN--MGBI4ECEXP',
    'XN--MGBPL2FH',
    'XN--MGBT3DHD',
    'XN--MGBTX2B',
    'XN--MGBX4CD0AB',
    'XN--MIX891F',
    'XN--MK1BU44C',
    'XN--MXTQ1M',
    'XN--NGBC5AZD',
    'XN--NGBE9E0A',
    'XN--NGBRX',
    'XN--NODE',
    'XN--NQV7F',
    'XN--NQV7FS00EMA',
    'XN--NYQY26A',
    'XN--O3CW4H',
    'XN--OGBPF8FL',
    'XN--OTU796D',
    'XN--P1ACF',
    'XN--P1AI',
    'XN--PGBS0DH',
    'XN--PSSY2U',
    'XN--Q7CE6A',
    'XN--Q9JYB4C',
    'XN--QCKA1PMC',
    'XN--QXA6A',
    'XN--QXAM',
    'XN--RHQV96G',
    'XN--ROVU88B',
    'XN--RVC1E0AM3E',
    'XN--S9BRJ9C',
    'XN--SES554G',
    'XN--T60B56A',
    'XN--TCKWE',
    'XN--TIQ49XQYJ',
    'XN--UNUP4Y',
    'XN--VERMGENSBERATER-CTB',
    'XN--VERMGENSBERATUNG-PWB',
    'XN--VHQUV',
    'XN--VUQ861B',
    'XN--W4R85EL8FHU5DNRA',
    'XN--W4RS40L',
    'XN--WGBH1C',
    'XN--WGBL6A',
    'XN--XHQ521B',
    'XN--XKC2AL3HYE2A',
    'XN--XKC2DL3A5EE0H',
    'XN--Y9A3AQ',
    'XN--YFRO4I67O',
    'XN--YGBI2AMMX',
    'XN--ZFR164B',
    'XXX',
    'XYZ',
    'YACHTS',
    'YAHOO',
    'YAMAXUN',
    'YANDEX',
    'YE',
    'YODOBASHI',
    'YOGA',
    'YOKOHAMA',
    'YOU',
    'YOUTUBE',
    'YT',
    'YUN',
    'ZA',
    'ZAPPOS',
    'ZARA',
    'ZERO',
    'ZIP',
    'ZM',
    'ZONE',
    'ZUERICH',
    'ZW'
];

// Keep as upper-case to make updating from source easier

module.exports = new Set(internals.tlds.map((tld) => tld.toLowerCase()));


code:
'use strict';

const Assert = require('@hapi/hoek/lib/assert');
const EscapeRegex = require('@hapi/hoek/lib/escapeRegex');

const internals = {};

internals.generate = function () {

    const rfc3986 = {};

    const hexDigit = '\\dA-Fa-f';                                               // HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
    const hexDigitOnly = '[' + hexDigit + ']';

    const unreserved = '\\w-\\.~';                                              // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
    const subDelims = '!\\$&\'\\(\\)\\*\\+,;=';                                 // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
    const pctEncoded = '%' + hexDigit;                                          // pct-encoded = "%" HEXDIG HEXDIG
    const pchar = unreserved + pctEncoded + subDelims + ':@';                   // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
    const pcharOnly = '[' + pchar + ']';
    const decOctect = '(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])';     // dec-octet = DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35  ; 0-9 / 10-99 / 100-199 / 200-249 / 250-255

    rfc3986.ipv4address = '(?:' + decOctect + '\\.){3}' + decOctect;            // IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

    /*
        h16 = 1*4HEXDIG ; 16 bits of address represented in hexadecimal
        ls32 = ( h16 ":" h16 ) / IPv4address ; least-significant 32 bits of address
        IPv6address =                            6( h16 ":" ) ls32
                    /                       "::" 5( h16 ":" ) ls32
                    / [               h16 ] "::" 4( h16 ":" ) ls32
                    / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
                    / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
                    / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
                    / [ *4( h16 ":" ) h16 ] "::"              ls32
                    / [ *5( h16 ":" ) h16 ] "::"              h16
                    / [ *6( h16 ":" ) h16 ] "::"
    */

    const h16 = hexDigitOnly + '{1,4}';
    const ls32 = '(?:' + h16 + ':' + h16 + '|' + rfc3986.ipv4address + ')';
    const IPv6SixHex = '(?:' + h16 + ':){6}' + ls32;
    const IPv6FiveHex = '::(?:' + h16 + ':){5}' + ls32;
    const IPv6FourHex = '(?:' + h16 + ')?::(?:' + h16 + ':){4}' + ls32;
    const IPv6ThreeHex = '(?:(?:' + h16 + ':){0,1}' + h16 + ')?::(?:' + h16 + ':){3}' + ls32;
    const IPv6TwoHex = '(?:(?:' + h16 + ':){0,2}' + h16 + ')?::(?:' + h16 + ':){2}' + ls32;
    const IPv6OneHex = '(?:(?:' + h16 + ':){0,3}' + h16 + ')?::' + h16 + ':' + ls32;
    const IPv6NoneHex = '(?:(?:' + h16 + ':){0,4}' + h16 + ')?::' + ls32;
    const IPv6NoneHex2 = '(?:(?:' + h16 + ':){0,5}' + h16 + ')?::' + h16;
    const IPv6NoneHex3 = '(?:(?:' + h16 + ':){0,6}' + h16 + ')?::';

    rfc3986.ipv4Cidr = '(?:\\d|[1-2]\\d|3[0-2])';                                           // IPv4 cidr = DIGIT / %x31-32 DIGIT / "3" %x30-32  ; 0-9 / 10-29 / 30-32
    rfc3986.ipv6Cidr = '(?:0{0,2}\\d|0?[1-9]\\d|1[01]\\d|12[0-8])';                         // IPv6 cidr = DIGIT / %x31-39 DIGIT / "1" %x0-1 DIGIT / "12" %x0-8;   0-9 / 10-99 / 100-119 / 120-128
    rfc3986.ipv6address = '(?:' + IPv6SixHex + '|' + IPv6FiveHex + '|' + IPv6FourHex + '|' + IPv6ThreeHex + '|' + IPv6TwoHex + '|' + IPv6OneHex + '|' + IPv6NoneHex + '|' + IPv6NoneHex2 + '|' + IPv6NoneHex3 + ')';
    rfc3986.ipvFuture = 'v' + hexDigitOnly + '+\\.[' + unreserved + subDelims + ':]+';      // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

    rfc3986.scheme = '[a-zA-Z][a-zA-Z\\d+-\\.]*';                                           // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
    rfc3986.schemeRegex = new RegExp(rfc3986.scheme);

    const userinfo = '[' + unreserved + pctEncoded + subDelims + ':]*';                     // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
    const IPLiteral = '\\[(?:' + rfc3986.ipv6address + '|' + rfc3986.ipvFuture + ')\\]';    // IP-literal = "[" ( IPv6address / IPvFuture  ) "]"
    const regName = '[' + unreserved + pctEncoded + subDelims + ']{1,255}';                 // reg-name = *( unreserved / pct-encoded / sub-delims )
    const host = '(?:' + IPLiteral + '|' + rfc3986.ipv4address + '|' + regName + ')';       // host = IP-literal / IPv4address / reg-name
    const port = '\\d*';                                                                    // port = *DIGIT
    const authority = '(?:' + userinfo + '@)?' + host + '(?::' + port + ')?';               // authority   = [ userinfo "@" ] host [ ":" port ]
    const authorityCapture = '(?:' + userinfo + '@)?(' + host + ')(?::' + port + ')?';

    /*
        segment       = *pchar
        segment-nz    = 1*pchar
        path          = path-abempty    ; begins with "/" '|' is empty
                    / path-absolute   ; begins with "/" but not "//"
                    / path-noscheme   ; begins with a non-colon segment
                    / path-rootless   ; begins with a segment
                    / path-empty      ; zero characters
        path-abempty  = *( "/" segment )
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
        path-rootless = segment-nz *( "/" segment )
    */

    const segment = pcharOnly + '*';
    const segmentNz = pcharOnly + '+';
    const segmentNzNc = '[' + unreserved + pctEncoded + subDelims + '@' + ']+';
    const pathEmpty = '';
    const pathAbEmpty = '(?:\\/' + segment + ')*';
    const pathAbsolute = '\\/(?:' + segmentNz + pathAbEmpty + ')?';
    const pathRootless = segmentNz + pathAbEmpty;
    const pathNoScheme = segmentNzNc + pathAbEmpty;
    const pathAbNoAuthority = '(?:\\/\\/\\/' + segment + pathAbEmpty + ')';     // Used by file:///

    // hier-part = "//" authority path

    rfc3986.hierPart = '(?:' + '(?:\\/\\/' + authority + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathRootless + '|' + pathAbNoAuthority + ')';
    rfc3986.hierPartCapture = '(?:' + '(?:\\/\\/' + authorityCapture + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathRootless + ')';

    // relative-part = "//" authority path-abempty / path-absolute / path-noscheme / path-empty

    rfc3986.relativeRef = '(?:' + '(?:\\/\\/' + authority + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathNoScheme + '|' + pathEmpty + ')';
    rfc3986.relativeRefCapture = '(?:' + '(?:\\/\\/' + authorityCapture + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathNoScheme + '|' + pathEmpty + ')';

    // query = *( pchar / "/" / "?" )
    // query = *( pchar / "[" / "]" / "/" / "?" )

    rfc3986.query = '[' + pchar + '\\/\\?]*(?=#|$)';                            //Finish matching either at the fragment part '|' end of the line.
    rfc3986.queryWithSquareBrackets = '[' + pchar + '\\[\\]\\/\\?]*(?=#|$)';

    // fragment = *( pchar / "/" / "?" )

    rfc3986.fragment = '[' + pchar + '\\/\\?]*';

    return rfc3986;
};

internals.rfc3986 = internals.generate();

exports.ip = {
    v4Cidr: internals.rfc3986.ipv4Cidr,
    v6Cidr: internals.rfc3986.ipv6Cidr,
    ipv4: internals.rfc3986.ipv4address,
    ipv6: internals.rfc3986.ipv6address,
    ipvfuture: internals.rfc3986.ipvFuture
};

internals.createRegex = function (options) {

    const rfc = internals.rfc3986;

    // Construct expression

    const query = options.allowQuerySquareBrackets ? rfc.queryWithSquareBrackets : rfc.query;
    const suffix = '(?:\\?' + query + ')?' + '(?:#' + rfc.fragment + ')?';

    // relative-ref = relative-part [ "?" query ] [ "#" fragment ]

    const relative = options.domain ? rfc.relativeRefCapture : rfc.relativeRef;

    if (options.relativeOnly) {
        return internals.wrap(relative + suffix);
    }

    // Custom schemes

    let customScheme = '';
    if (options.scheme) {
        Assert(options.scheme instanceof RegExp || typeof options.scheme === 'string' || Array.isArray(options.scheme), 'scheme must be a RegExp, String, or Array');

        const schemes = [].concat(options.scheme);
        Assert(schemes.length >= 1, 'scheme must have at least 1 scheme specified');

        // Flatten the array into a string to be used to match the schemes

        const selections = [];
        for (let i = 0; i < schemes.length; ++i) {
            const scheme = schemes[i];
            Assert(scheme instanceof RegExp || typeof scheme === 'string', 'scheme at position ' + i + ' must be a RegExp or String');

            if (scheme instanceof RegExp) {
                selections.push(scheme.source.toString());
            }
            else {
                Assert(rfc.schemeRegex.test(scheme), 'scheme at position ' + i + ' must be a valid scheme');
                selections.push(EscapeRegex(scheme));
            }
        }

        customScheme = selections.join('|');
    }

    // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

    const scheme = customScheme ? '(?:' + customScheme + ')' : rfc.scheme;
    const absolute = '(?:' + scheme + ':' + (options.domain ? rfc.hierPartCapture : rfc.hierPart) + ')';
    const prefix = options.allowRelative ? '(?:' + absolute + '|' + relative + ')' : absolute;
    return internals.wrap(prefix + suffix, customScheme);
};

internals.wrap = function (raw, scheme) {

    raw = `(?=.)(?!https?\:/(?:$|[^/]))(?!https?\:///)(?!https?\:[^/])${raw}`;     // Require at least one character and explicitly forbid 'http:/' or HTTP with empty domain

    return {
        raw,
        regex: new RegExp(`^${raw}$`),
        scheme
    };
};

internals.uriRegex = internals.createRegex({});

exports.regex = function (options = {}) {

    if (options.scheme ||
        options.allowRelative ||
        options.relativeOnly ||
        options.allowQuerySquareBrackets ||
        options.domain) {

        return internals.createRegex(options);
    }

    return internals.uriRegex;
};


@sideway/address

description: Email address and domain validation

keywords: email domain address validation

test: lab -a @hapi/code -t 100 -L -Y

test-cov-html: lab -a @hapi/code -t 100 -L -r html -o coverage.html


code:
# @sideway/formula

#### Math and string formula parser.

**formula** is part of the **joi** ecosystem.

### Visit the [joi.dev](https://joi.dev) Developer Portal for tutorials, documentation, and support

## Useful resources

- [Documentation and API](https://joi.dev/module/formula/)
- [Version status](https://joi.dev/resources/status/#formula) (builds, dependencies, node versions, licenses, eol)
- [Changelog](https://joi.dev/module/formula/changelog/)
- [Project policies](https://joi.dev/policies/)

## Acknowledgements

Inspired by [**fparse**](https://github.com/bylexus/fparse), copyright 2012-2018 Alexander Schenkel <alex@alexi.ch>


code:
/**
 * Formula parser
 */
export class Parser<T extends (string | number)> {

    /**
     * Create a new formula parser.
     *
     * @param formula - the formula string to parse.
     * @param options - optional settings.
     */
    constructor(formula: string, options?: Options);

    /**
     * Evaluate the formula.
     *
     * @param context - optional object with runtime formula context used to resolve variables.
     *
     * @returns the string or number outcome of the resolved formula.
     */
    evaluate(context?: any): T;
}

export interface Options {

    /**
     * A hash of key - value pairs used to convert constants to values.
     */
    readonly constants?: Record<string, any>;

    /**
     * A regular expression used to validate token variables.
     */
    readonly tokenRx?: RegExp;

    /**
     * A variable resolver factory function.
     */
    readonly reference?: Options.Reference;

    /**
     * A hash of key-value pairs used to resolve formula functions.
     */
    readonly functions?: Record<string, Function>;
}

export namespace Options {

    type Reference = (name: string) => (context: any) => any;
}


code:
'use strict';

const internals = {
    operators: ['!', '^', '*', '/', '%', '+', '-', '<', '<=', '>', '>=', '==', '!=', '&&', '||', '??'],
    operatorCharacters: ['!', '^', '*', '/', '%', '+', '-', '<', '=', '>', '&', '|', '?'],
    operatorsOrder: [['^'], ['*', '/', '%'], ['+', '-'], ['<', '<=', '>', '>='], ['==', '!='], ['&&'], ['||', '??']],
    operatorsPrefix: ['!', 'n'],

    literals: {
        '"': '"',
        '`': '`',
        '\'': '\'',
        '[': ']'
    },

    numberRx: /^(?:[0-9]*(\.[0-9]*)?){1}$/,
    tokenRx: /^[\w\$\#\.\@\:\{\}]+$/,

    symbol: Symbol('formula'),
    settings: Symbol('settings')
};

exports.Parser = class {

    constructor(string, options = {}) {

        if (!options[internals.settings] &&
            options.constants) {

            for (const constant in options.constants) {
                const value = options.constants[constant];
                if (value !== null &&
                    !['boolean', 'number', 'string'].includes(typeof value)) {

                    throw new Error(`Formula constant ${constant} contains invalid ${typeof value} value type`);
                }
            }
        }

        this.settings = options[internals.settings] ? options : Object.assign({ [internals.settings]: true, constants: {}, functions: {} }, options);
        this.single = null;

        this._parts = null;
        this._parse(string);
    }

    _parse(string) {

        let parts = [];
        let current = '';
        let parenthesis = 0;
        let literal = false;

        const flush = (inner) => {

            if (parenthesis) {
                throw new Error('Formula missing closing parenthesis');
            }

            const last = parts.length ? parts[parts.length - 1] : null;

            if (!literal &&
                !current &&
                !inner) {

                return;
            }

            if (last &&
                last.type === 'reference' &&
                inner === ')') {                                                                // Function

                last.type = 'function';
                last.value = this._subFormula(current, last.value);
                current = '';
                return;
            }

            if (inner === ')') {                                                                // Segment
                const sub = new exports.Parser(current, this.settings);
                parts.push({ type: 'segment', value: sub });
            }
            else if (literal) {
                if (literal === ']') {                                                          // Reference
                    parts.push({ type: 'reference', value: current });
                    current = '';
                    return;
                }

                parts.push({ type: 'literal', value: current });                                // Literal
            }
            else if (internals.operatorCharacters.includes(current)) {                          // Operator
                if (last &&
                    last.type === 'operator' &&
                    internals.operators.includes(last.value + current)) {                       // 2 characters operator

                    last.value += current;
                }
                else {
                    parts.push({ type: 'operator', value: current });
                }
            }
            else if (current.match(internals.numberRx)) {                                       // Number
                parts.push({ type: 'constant', value: parseFloat(current) });
            }
            else if (this.settings.constants[current] !== undefined) {                          // Constant
                parts.push({ type: 'constant', value: this.settings.constants[current] });
            }
            else {                                                                              // Reference
                if (!current.match(internals.tokenRx)) {
                    throw new Error(`Formula contains invalid token: ${current}`);
                }

                parts.push({ type: 'reference', value: current });
            }

            current = '';
        };

        for (const c of string) {
            if (literal) {
                if (c === literal) {
                    flush();
                    literal = false;
                }
                else {
                    current += c;
                }
            }
            else if (parenthesis) {
                if (c === '(') {
                    current += c;
                    ++parenthesis;
                }
                else if (c === ')') {
                    --parenthesis;
                    if (!parenthesis) {
                        flush(c);
                    }
                    else {
                        current += c;
                    }
                }
                else {
                    current += c;
                }
            }
            else if (c in internals.literals) {
                literal = internals.literals[c];
            }
            else if (c === '(') {
                flush();
                ++parenthesis;
            }
            else if (internals.operatorCharacters.includes(c)) {
                flush();
                current = c;
                flush();
            }
            else if (c !== ' ') {
                current += c;
            }
            else {
                flush();
            }
        }

        flush();

        // Replace prefix - to internal negative operator

        parts = parts.map((part, i) => {

            if (part.type !== 'operator' ||
                part.value !== '-' ||
                i && parts[i - 1].type !== 'operator') {

                return part;
            }

            return { type: 'operator', value: 'n' };
        });

        // Validate tokens order

        let operator = false;
        for (const part of parts) {
            if (part.type === 'operator') {
                if (internals.operatorsPrefix.includes(part.value)) {
                    continue;
                }

                if (!operator) {
                    throw new Error('Formula contains an operator in invalid position');
                }

                if (!internals.operators.includes(part.value)) {
                    throw new Error(`Formula contains an unknown operator ${part.value}`);
                }
            }
            else if (operator) {
                throw new Error('Formula missing expected operator');
            }

            operator = !operator;
        }

        if (!operator) {
            throw new Error('Formula contains invalid trailing operator');
        }

        // Identify single part

        if (parts.length === 1 &&
            ['reference', 'literal', 'constant'].includes(parts[0].type)) {

            this.single = { type: parts[0].type === 'reference' ? 'reference' : 'value', value: parts[0].value };
        }

        // Process parts

        this._parts = parts.map((part) => {

            // Operators

            if (part.type === 'operator') {
                return internals.operatorsPrefix.includes(part.value) ? part : part.value;
            }

            // Literals, constants, segments

            if (part.type !== 'reference') {
                return part.value;
            }

            // References

            if (this.settings.tokenRx &&
                !this.settings.tokenRx.test(part.value)) {

                throw new Error(`Formula contains invalid reference ${part.value}`);
            }

            if (this.settings.reference) {
                return this.settings.reference(part.value);
            }

            return internals.reference(part.value);
        });
    }

    _subFormula(string, name) {

        const method = this.settings.functions[name];
        if (typeof method !== 'function') {
            throw new Error(`Formula contains unknown function ${name}`);
        }

        let args = [];
        if (string) {
            let current = '';
            let parenthesis = 0;
            let literal = false;

            const flush = () => {

                if (!current) {
                    throw new Error(`Formula contains function ${name} with invalid arguments ${string}`);
                }

                args.push(current);
                current = '';
            };

            for (let i = 0; i < string.length; ++i) {
                const c = string[i];
                if (literal) {
                    current += c;
                    if (c === literal) {
                        literal = false;
                    }
                }
                else if (c in internals.literals &&
                    !parenthesis) {

                    current += c;
                    literal = internals.literals[c];
                }
                else if (c === ',' &&
                    !parenthesis) {

                    flush();
                }
                else {
                    current += c;
                    if (c === '(') {
                        ++parenthesis;
                    }
                    else if (c === ')') {
                        --parenthesis;
                    }
                }
            }

            flush();
        }

        args = args.map((arg) => new exports.Parser(arg, this.settings));

        return function (context) {

            const innerValues = [];
            for (const arg of args) {
                innerValues.push(arg.evaluate(context));
            }

            return method.call(context, ...innerValues);
        };
    }

    evaluate(context) {

        const parts = this._parts.slice();

        // Prefix operators

        for (let i = parts.length - 2; i >= 0; --i) {
            const part = parts[i];
            if (part &&
                part.type === 'operator') {

                const current = parts[i + 1];
                parts.splice(i + 1, 1);
                const value = internals.evaluate(current, context);
                parts[i] = internals.single(part.value, value);
            }
        }

        // Left-right operators

        internals.operatorsOrder.forEach((set) => {

            for (let i = 1; i < parts.length - 1;) {
                if (set.includes(parts[i])) {
                    const operator = parts[i];
                    const left = internals.evaluate(parts[i - 1], context);
                    const right = internals.evaluate(parts[i + 1], context);

                    parts.splice(i, 2);
                    const result = internals.calculate(operator, left, right);
                    parts[i - 1] = result === 0 ? 0 : result;                               // Convert -0
                }
                else {
                    i += 2;
                }
            }
        });

        return internals.evaluate(parts[0], context);
    }
};

exports.Parser.prototype[internals.symbol] = true;

internals.reference = function (name) {

    return function (context) {

        return context && context[name] !== undefined ? context[name] : null;
    };
};

internals.evaluate = function (part, context) {

    if (part === null) {
        return null;
    }

    if (typeof part === 'function') {
        return part(context);
    }

    if (part[internals.symbol]) {
        return part.evaluate(context);
    }

    return part;
};

internals.single = function (operator, value) {

    if (operator === '!') {
        return value ? false : true;
    }

    // operator === 'n'

    const negative = -value;
    if (negative === 0) {       // Override -0
        return 0;
    }

    return negative;
};

internals.calculate = function (operator, left, right) {

    if (operator === '??') {
        return internals.exists(left) ? left : right;
    }

    if (typeof left === 'string' ||
        typeof right === 'string') {

        if (operator === '+') {
            left = internals.exists(left) ? left : '';
            right = internals.exists(right) ? right : '';
            return left + right;
        }
    }
    else {
        switch (operator) {
            case '^': return Math.pow(left, right);
            case '*': return left * right;
            case '/': return left / right;
            case '%': return left % right;
            case '+': return left + right;
            case '-': return left - right;
        }
    }

    switch (operator) {
        case '<': return left < right;
        case '<=': return left <= right;
        case '>': return left > right;
        case '>=': return left >= right;
        case '==': return left === right;
        case '!=': return left !== right;
        case '&&': return left && right;
        case '||': return left || right;
    }

    return null;
};

internals.exists = function (value) {

    return value !== null && value !== undefined;
};


@sideway/formula

description: Math and string formula parser.

keywords: formula parser math string


code:
# @sideway/pinpoint

#### Return the filename and line number of the calling function.

**pinpoint** is part of the **joi** ecosystem.

### Visit the [joi.dev](https://joi.dev) Developer Portal for tutorials, documentation, and support

## Useful resources

- [Documentation and API](https://joi.dev/module/pinpoint/)
- [Version status](https://joi.dev/resources/status/#pinpoint) (builds, dependencies, node versions, licenses, eol)
- [Changelog](https://joi.dev/module/pinpoint/changelog/)
- [Project policies](https://joi.dev/policies/)


code:
/**
Returns the filename and line number of the caller in the call stack

@param depth - The distance from the location function in the call stack. Defaults to 1 (caller).

@return an object with the filename and line number.
*/
export function location(depth?: number): location.Location;

declare namespace location {

    interface Location {

        /**
        The fully qualified filename.
        */
        readonly filename: string;

        /**
        The file line number.
        */
        readonly line: number;
    }
}


code:
'use strict';

const internals = {};

exports.location = function (depth = 0) {

    const orig = Error.prepareStackTrace;
    Error.prepareStackTrace = (ignore, stack) => stack;

    const capture = {};
    Error.captureStackTrace(capture, this);
    const line = capture.stack[depth + 1];

    Error.prepareStackTrace = orig;

    return {
        filename: line.getFileName(),
        line: line.getLineNumber()
    };
};


@sideway/pinpoint

description: Return the filename and line number of the calling function


code:
# Friendly-errors-webpack-plugin

[![npm](https://img.shields.io/npm/v/@soda/friendly-errors-webpack-plugin.svg)](https://www.npmjs.com/package/@soda/friendly-errors-webpack-plugin)
[![Build Status](https://travis-ci.org/sodatea/friendly-errors-webpack-plugin.svg?branch=master)](https://travis-ci.org/sodatea/friendly-errors-webpack-plugin)
[![Build status](https://ci.appveyor.com/api/projects/status/bbrt7hmp6lav3erh/branch/master?svg=true)](https://ci.appveyor.com/project/sodatea/friendly-errors-webpack-plugin/branch/master)

Friendly-errors-webpack-plugin recognizes certain classes of webpack
errors and cleans, aggregates and prioritizes them to provide a better
Developer Experience.

It is easy to add types of errors so if you would like to see more
errors get handled, please open a [PR](https://help.github.com/articles/creating-a-pull-request/)!

## Getting started

### Installation

```bash
npm install @soda/friendly-errors-webpack-plugin --save-dev
```

### Basic usage

Simply add `FriendlyErrorsWebpackPlugin` to the plugin section in your Webpack config.

```javascript
var FriendlyErrorsWebpackPlugin = require('@soda/friendly-errors-webpack-plugin');

var webpackConfig = {
  // ...
  plugins: [
    new FriendlyErrorsWebpackPlugin(),
  ],
  // ...
}
```

### Turn off errors

You need to turn off all error logging by setting your webpack config quiet option to true.

```javascript
app.use(require('webpack-dev-middleware')(compiler, {
  // ...
  logLevel: 'silent',
  // ...
}));
```

If you use the webpack-dev-server, there is a setting in webpack's ```devServer``` options:

```javascript
// webpack config root
{
  // ...
  devServer: {
    // ...
    quiet: true,
    // ...
  },
  // ...
}
```

If you use webpack-hot-middleware, that is done by setting the log option to `false`. You can do something sort of like this, depending upon your setup:

```javascript
app.use(require('webpack-hot-middleware')(compiler, {
  log: false
}));
```

_Thanks to [webpack-dashboard](https://github.com/FormidableLabs/webpack-dashboard) for this piece of info._

## Demo

### Build success

![success](http://i.imgur.com/MkUEhYz.gif)

### eslint-loader errors

![lint](http://i.imgur.com/xYRkldr.gif)

### babel-loader syntax errors

![babel](http://i.imgur.com/W59z8WF.gif)

### Module not found

![babel](http://i.imgur.com/OivW4As.gif)

## Options

You can pass options to the plugin:

```js
new FriendlyErrorsPlugin({
  compilationSuccessInfo: {
    messages: ['You application is running here http://localhost:3000'],
    notes: ['Some additional notes to be displayed upon successful compilation']
  },
  onErrors: function (severity, errors) {
    // You can listen to errors transformed and prioritized by the plugin
    // severity can be 'error' or 'warning'
  },
  // should the console be cleared between each compilation?
  // default is true
  clearConsole: true,

  // add formatters and transformers (see below)
  additionalFormatters: [],
  additionalTransformers: []
})
```

## Adding desktop notifications

The plugin has no native support for desktop notifications but it is easy
to add them thanks to [node-notifier](https://www.npmjs.com/package/node-notifier) for instance.

```js
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
var notifier = require('node-notifier');
var ICON = path.join(__dirname, 'icon.png');

new FriendlyErrorsPlugin({
    onErrors: (severity, errors) => {
      if (severity !== 'error') {
        return;
      }
      const error = errors[0];
      notifier.notify({
        title: "Webpack error",
        message: severity + ': ' + error.name,
        subtitle: error.file || '',
        icon: ICON
      });
    }
  })
```

## API

### Transformers and formatters

Webpack's errors processing, is done in four phases:

1. Extract relevant info from webpack errors. This is done by the plugin [here](https://github.com/sodatea/friendly-errors-webpack-plugin/blob/master/src/core/extractWebpackError.js)
2. Apply transformers to all errors to identify and annotate well know errors and give them a priority
3. Get only top priority error or top priority warnings if no errors are thrown
4. Apply formatters to all annotated errors

You can add transformers and formatters. Please see [transformErrors](https://github.com/sodatea/friendly-errors-webpack-plugin/blob/master/src/core/transformErrors.js),
and [formatErrors](https://github.com/sodatea/friendly-errors-webpack-plugin/blob/master/src/core/formatErrors.js)
in the source code and take a look a the [default transformers](https://github.com/sodatea/friendly-errors-webpack-plugin/tree/master/src/transformers)
and the [default formatters](https://github.com/sodatea/friendly-errors-webpack-plugin/tree/master/src/formatters).

## TODO

- [x] Make it compatible with node 4


code:
const FriendlyErrorsWebpackPlugin = require('./src/friendly-errors-plugin');

module.exports = FriendlyErrorsWebpackPlugin;
module.exports.default = FriendlyErrorsWebpackPlugin;


code:
declare type CSSColor =
	| 'aliceblue'
	| 'antiquewhite'
	| 'aqua'
	| 'aquamarine'
	| 'azure'
	| 'beige'
	| 'bisque'
	| 'black'
	| 'blanchedalmond'
	| 'blue'
	| 'blueviolet'
	| 'brown'
	| 'burlywood'
	| 'cadetblue'
	| 'chartreuse'
	| 'chocolate'
	| 'coral'
	| 'cornflowerblue'
	| 'cornsilk'
	| 'crimson'
	| 'cyan'
	| 'darkblue'
	| 'darkcyan'
	| 'darkgoldenrod'
	| 'darkgray'
	| 'darkgreen'
	| 'darkgrey'
	| 'darkkhaki'
	| 'darkmagenta'
	| 'darkolivegreen'
	| 'darkorange'
	| 'darkorchid'
	| 'darkred'
	| 'darksalmon'
	| 'darkseagreen'
	| 'darkslateblue'
	| 'darkslategray'
	| 'darkslategrey'
	| 'darkturquoise'
	| 'darkviolet'
	| 'deeppink'
	| 'deepskyblue'
	| 'dimgray'
	| 'dimgrey'
	| 'dodgerblue'
	| 'firebrick'
	| 'floralwhite'
	| 'forestgreen'
	| 'fuchsia'
	| 'gainsboro'
	| 'ghostwhite'
	| 'gold'
	| 'goldenrod'
	| 'gray'
	| 'green'
	| 'greenyellow'
	| 'grey'
	| 'honeydew'
	| 'hotpink'
	| 'indianred'
	| 'indigo'
	| 'ivory'
	| 'khaki'
	| 'lavender'
	| 'lavenderblush'
	| 'lawngreen'
	| 'lemonchiffon'
	| 'lightblue'
	| 'lightcoral'
	| 'lightcyan'
	| 'lightgoldenrodyellow'
	| 'lightgray'
	| 'lightgreen'
	| 'lightgrey'
	| 'lightpink'
	| 'lightsalmon'
	| 'lightseagreen'
	| 'lightskyblue'
	| 'lightslategray'
	| 'lightslategrey'
	| 'lightsteelblue'
	| 'lightyellow'
	| 'lime'
	| 'limegreen'
	| 'linen'
	| 'magenta'
	| 'maroon'
	| 'mediumaquamarine'
	| 'mediumblue'
	| 'mediumorchid'
	| 'mediumpurple'
	| 'mediumseagreen'
	| 'mediumslateblue'
	| 'mediumspringgreen'
	| 'mediumturquoise'
	| 'mediumvioletred'
	| 'midnightblue'
	| 'mintcream'
	| 'mistyrose'
	| 'moccasin'
	| 'navajowhite'
	| 'navy'
	| 'oldlace'
	| 'olive'
	| 'olivedrab'
	| 'orange'
	| 'orangered'
	| 'orchid'
	| 'palegoldenrod'
	| 'palegreen'
	| 'paleturquoise'
	| 'palevioletred'
	| 'papayawhip'
	| 'peachpuff'
	| 'peru'
	| 'pink'
	| 'plum'
	| 'powderblue'
	| 'purple'
	| 'rebeccapurple'
	| 'red'
	| 'rosybrown'
	| 'royalblue'
	| 'saddlebrown'
	| 'salmon'
	| 'sandybrown'
	| 'seagreen'
	| 'seashell'
	| 'sienna'
	| 'silver'
	| 'skyblue'
	| 'slateblue'
	| 'slategray'
	| 'slategrey'
	| 'snow'
	| 'springgreen'
	| 'steelblue'
	| 'tan'
	| 'teal'
	| 'thistle'
	| 'tomato'
	| 'turquoise'
	| 'violet'
	| 'wheat'
	| 'white'
	| 'whitesmoke'
	| 'yellow'
	| 'yellowgreen';

declare namespace ansiStyles {
	interface ColorConvert {
		/**
		The RGB color space.

		@param red - (`0`-`255`)
		@param green - (`0`-`255`)
		@param blue - (`0`-`255`)
		*/
		rgb(red: number, green: number, blue: number): string;

		/**
		The RGB HEX color space.

		@param hex - A hexadecimal string containing RGB data.
		*/
		hex(hex: string): string;

		/**
		@param keyword - A CSS color name.
		*/
		keyword(keyword: CSSColor): string;

		/**
		The HSL color space.

		@param hue - (`0`-`360`)
		@param saturation - (`0`-`100`)
		@param lightness - (`0`-`100`)
		*/
		hsl(hue: number, saturation: number, lightness: number): string;

		/**
		The HSV color space.

		@param hue - (`0`-`360`)
		@param saturation - (`0`-`100`)
		@param value - (`0`-`100`)
		*/
		hsv(hue: number, saturation: number, value: number): string;

		/**
		The HSV color space.

		@param hue - (`0`-`360`)
		@param whiteness - (`0`-`100`)
		@param blackness - (`0`-`100`)
		*/
		hwb(hue: number, whiteness: number, blackness: number): string;

		/**
		Use a [4-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4-bit) to set text color.
		*/
		ansi(ansi: number): string;

		/**
		Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color.
		*/
		ansi256(ansi: number): string;
	}

	interface CSPair {
		/**
		The ANSI terminal control sequence for starting this style.
		*/
		readonly open: string;

		/**
		The ANSI terminal control sequence for ending this style.
		*/
		readonly close: string;
	}

	interface ColorBase {
		readonly ansi: ColorConvert;
		readonly ansi256: ColorConvert;
		readonly ansi16m: ColorConvert;

		/**
		The ANSI terminal control sequence for ending this color.
		*/
		readonly close: string;
	}

	interface Modifier {
		/**
		Resets the current color chain.
		*/
		readonly reset: CSPair;

		/**
		Make text bold.
		*/
		readonly bold: CSPair;

		/**
		Emitting only a small amount of light.
		*/
		readonly dim: CSPair;

		/**
		Make text italic. (Not widely supported)
		*/
		readonly italic: CSPair;

		/**
		Make text underline. (Not widely supported)
		*/
		readonly underline: CSPair;

		/**
		Inverse background and foreground colors.
		*/
		readonly inverse: CSPair;

		/**
		Prints the text, but makes it invisible.
		*/
		readonly hidden: CSPair;

		/**
		Puts a horizontal line through the center of the text. (Not widely supported)
		*/
		readonly strikethrough: CSPair;
	}

	interface ForegroundColor {
		readonly black: CSPair;
		readonly red: CSPair;
		readonly green: CSPair;
		readonly yellow: CSPair;
		readonly blue: CSPair;
		readonly cyan: CSPair;
		readonly magenta: CSPair;
		readonly white: CSPair;

		/**
		Alias for `blackBright`.
		*/
		readonly gray: CSPair;

		/**
		Alias for `blackBright`.
		*/
		readonly grey: CSPair;

		readonly blackBright: CSPair;
		readonly redBright: CSPair;
		readonly greenBright: CSPair;
		readonly yellowBright: CSPair;
		readonly blueBright: CSPair;
		readonly cyanBright: CSPair;
		readonly magentaBright: CSPair;
		readonly whiteBright: CSPair;
	}

	interface BackgroundColor {
		readonly bgBlack: CSPair;
		readonly bgRed: CSPair;
		readonly bgGreen: CSPair;
		readonly bgYellow: CSPair;
		readonly bgBlue: CSPair;
		readonly bgCyan: CSPair;
		readonly bgMagenta: CSPair;
		readonly bgWhite: CSPair;

		/**
		Alias for `bgBlackBright`.
		*/
		readonly bgGray: CSPair;

		/**
		Alias for `bgBlackBright`.
		*/
		readonly bgGrey: CSPair;

		readonly bgBlackBright: CSPair;
		readonly bgRedBright: CSPair;
		readonly bgGreenBright: CSPair;
		readonly bgYellowBright: CSPair;
		readonly bgBlueBright: CSPair;
		readonly bgCyanBright: CSPair;
		readonly bgMagentaBright: CSPair;
		readonly bgWhiteBright: CSPair;
	}
}

declare const ansiStyles: {
	readonly modifier: ansiStyles.Modifier;
	readonly color: ansiStyles.ForegroundColor & ansiStyles.ColorBase;
	readonly bgColor: ansiStyles.BackgroundColor & ansiStyles.ColorBase;
	readonly codes: ReadonlyMap<number, number>;
} & ansiStyles.BackgroundColor & ansiStyles.ForegroundColor & ansiStyles.Modifier;

export = ansiStyles;


code:
'use strict';

const wrapAnsi16 = (fn, offset) => (...args) => {
	const code = fn(...args);
	return `\u001B[${code + offset}m`;
};

const wrapAnsi256 = (fn, offset) => (...args) => {
	const code = fn(...args);
	return `\u001B[${38 + offset};5;${code}m`;
};

const wrapAnsi16m = (fn, offset) => (...args) => {
	const rgb = fn(...args);
	return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
};

const ansi2ansi = n => n;
const rgb2rgb = (r, g, b) => [r, g, b];

const setLazyProperty = (object, property, get) => {
	Object.defineProperty(object, property, {
		get: () => {
			const value = get();

			Object.defineProperty(object, property, {
				value,
				enumerable: true,
				configurable: true
			});

			return value;
		},
		enumerable: true,
		configurable: true
	});
};

/** @type {typeof import('color-convert')} */
let colorConvert;
const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => {
	if (colorConvert === undefined) {
		colorConvert = require('color-convert');
	}

	const offset = isBackground ? 10 : 0;
	const styles = {};

	for (const [sourceSpace, suite] of Object.entries(colorConvert)) {
		const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace;
		if (sourceSpace === targetSpace) {
			styles[name] = wrap(identity, offset);
		} else if (typeof suite === 'object') {
			styles[name] = wrap(suite[targetSpace], offset);
		}
	}

	return styles;
};

function assembleStyles() {
	const codes = new Map();
	const styles = {
		modifier: {
			reset: [0, 0],
			// 21 isn't widely supported and 22 does the same thing
			bold: [1, 22],
			dim: [2, 22],
			italic: [3, 23],
			underline: [4, 24],
			inverse: [7, 27],
			hidden: [8, 28],
			strikethrough: [9, 29]
		},
		color: {
			black: [30, 39],
			red: [31, 39],
			green: [32, 39],
			yellow: [33, 39],
			blue: [34, 39],
			magenta: [35, 39],
			cyan: [36, 39],
			white: [37, 39],

			// Bright color
			blackBright: [90, 39],
			redBright: [91, 39],
			greenBright: [92, 39],
			yellowBright: [93, 39],
			blueBright: [94, 39],
			magentaBright: [95, 39],
			cyanBright: [96, 39],
			whiteBright: [97, 39]
		},
		bgColor: {
			bgBlack: [40, 49],
			bgRed: [41, 49],
			bgGreen: [42, 49],
			bgYellow: [43, 49],
			bgBlue: [44, 49],
			bgMagenta: [45, 49],
			bgCyan: [46, 49],
			bgWhite: [47, 49],

			// Bright color
			bgBlackBright: [100, 49],
			bgRedBright: [101, 49],
			bgGreenBright: [102, 49],
			bgYellowBright: [103, 49],
			bgBlueBright: [104, 49],
			bgMagentaBright: [105, 49],
			bgCyanBright: [106, 49],
			bgWhiteBright: [107, 49]
		}
	};

	// Alias bright black as gray (and grey)
	styles.color.gray = styles.color.blackBright;
	styles.bgColor.bgGray = styles.bgColor.bgBlackBright;
	styles.color.grey = styles.color.blackBright;
	styles.bgColor.bgGrey = styles.bgColor.bgBlackBright;

	for (const [groupName, group] of Object.entries(styles)) {
		for (const [styleName, style] of Object.entries(group)) {
			styles[styleName] = {
				open: `\u001B[${style[0]}m`,
				close: `\u001B[${style[1]}m`
			};

			group[styleName] = styles[styleName];

			codes.set(style[0], style[1]);
		}

		Object.defineProperty(styles, groupName, {
			value: group,
			enumerable: false
		});
	}

	Object.defineProperty(styles, 'codes', {
		value: codes,
		enumerable: false
	});

	styles.color.close = '\u001B[39m';
	styles.bgColor.close = '\u001B[49m';

	setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false));
	setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false));
	setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false));
	setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true));
	setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true));
	setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true));

	return styles;
}

// Make the export immutable
Object.defineProperty(module, 'exports', {
	enumerable: true,
	get: assembleStyles
});


ansi-styles

description: ANSI escape codes for styling strings in the terminal

license: MIT

repository: chalk/ansi-styles

test: xo && ava && tsd

screenshot: svg-term --command='node screenshot' --out=screenshot.svg --padding=3 --width=55 --height=3 --at=1000 --no-cursor

keywords: ansi styles color colour colors terminal console cli string tty escape formatting rgb 256 shell xterm log logging command-line text