@lacussoft/cpf-gen
Version:
Utility to generate CPF (Brazilian Individual's Taxpayer ID)
838 lines (811 loc) • 215 kB
JavaScript
/**
* Lacus Solutions :: cpf-gen v3.0.0
*
* @author Julio L. Muller.
* @license MIT - 2021-2026
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.cpfGen = factory());
})(this, (function () { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var _extendStatics = function extendStatics(d, b) {
_extendStatics = Object.setPrototypeOf || {
__proto__: []
} instanceof Array && function (d, b) {
d.__proto__ = b;
} || function (d, b) {
for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
};
return _extendStatics(d, b);
};
function __extends$1(d, b) {
if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
_extendStatics(d, b);
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var _assign = function __assign() {
_assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return _assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* Lacus Solutions :: utils v1.0.0
*
* @author Julio L. Muller.
* @license MIT - 2026
*/
/**
* Describes the type of a value for error messages.
*
* @example
* describeType(null); // 'null'
* describeType(undefined); // 'undefined'
* describeType('hello'); // 'string'
* describeType(true); // 'boolean'
* describeType(42); // 'integer number'
* describeType(3.14); // 'float number'
* describeType(NaN); // 'NaN'
* describeType(Infinity); // 'Infinity'
* describeType([]); // 'Array (empty)'
* describeType([1, 2, 3]); // 'number[]'
* describeType([1, 'a', 2]); // '(number | string)[]'
* describeType({}); // 'object'
*/
function describeType(value) {
if (!Array.isArray(value)) {
if (typeof value === 'number') {
if (isNaN(value)) {
return 'NaN';
}
if (!isFinite(value)) {
return 'Infinity';
}
if (Number.isInteger(value)) {
return 'integer number';
}
return 'float number';
}
if (value === null) {
return 'null';
}
return typeof value;
}
if (value.length === 0) {
return 'Array (empty)';
}
var uniqueTypesSet = new Set(value.map(function (item) { return typeof item; }));
var uniqueTypes = Array.from(uniqueTypesSet);
if (uniqueTypes.length === 1) {
return "".concat(uniqueTypes[0], "[]");
}
return "(".concat(uniqueTypes.join(' | '), ")[]");
}
var NUMERIC_CHARACTERS = '0123456789';
var ALPHABETIC_CHARACTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var ALPHANUMERIC_CHARACTERS = NUMERIC_CHARACTERS + ALPHABETIC_CHARACTERS;
/**
* Generates a random character sequence of the given length and type (numeric,
* alphabetic, or alphanumeric).
*
* @example
* generateRandomSequence(10, 'numeric'); // e.g. '9956000611'
* generateRandomSequence(6, 'alphabetic'); // e.g. 'AXQMZB'
* generateRandomSequence(8, 'alphanumeric'); // e.g. '8ZFB2K09'
*/
function generateRandomSequence(size, type) {
var charactersSequence = [];
var charactersRange = ALPHANUMERIC_CHARACTERS;
{
charactersRange = NUMERIC_CHARACTERS;
}
while (charactersSequence.length < size) {
var random = Math.random();
var randomFloat = random * charactersRange.length;
var randomInteger = Math.floor(randomFloat);
var randomCharacter = charactersRange[randomInteger];
charactersSequence.push(randomCharacter);
}
return charactersSequence.join('');
}
/**
* Lacus Solutions :: cpf-dv v1.0.0
*
* @author Julio L. Muller.
* @license MIT - 2026
*/
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* Base error for all `cpf-dv` type-related errors.
*
* This abstract class extends the native `TypeError` and serves as the base for
* all type validation errors in the `CpfCheckDigits`. It ensures proper
* prototype chain setup and automatically sets the error name from the
* constructor.
*/
var CpfCheckDigitsTypeError = /** @class */ (function (_super) {
__extends(CpfCheckDigitsTypeError, _super);
function CpfCheckDigitsTypeError(actualInput, actualType, expectedType, message) {
var _newTarget = this.constructor;
var _this = _super.call(this, message) || this;
Object.setPrototypeOf(_this, _newTarget.prototype);
_this.name = _this.constructor.name;
_this.actualInput = actualInput;
_this.actualType = actualType;
_this.expectedType = expectedType;
return _this;
}
return CpfCheckDigitsTypeError;
}(TypeError));
/**
* Error raised when the input provided to `CpfCheckDigits` is not of the
* expected type ({@link CpfInput}). The error message includes both the actual
* type of the input and the expected type.
*/
var CpfCheckDigitsInputTypeError = /** @class */ (function (_super) {
__extends(CpfCheckDigitsInputTypeError, _super);
function CpfCheckDigitsInputTypeError(actualInput, expectedType) {
var actualInputType = describeType(actualInput);
return _super.call(this, actualInput, actualInputType, expectedType, "CPF input must be of type ".concat(expectedType, ". Got ").concat(actualInputType, ".")) || this;
}
return CpfCheckDigitsInputTypeError;
}(CpfCheckDigitsTypeError));
/**
* Base exception for all `cpf-dv` rules-related errors.
*
* This abstract class extends the native `Error` and serves as the base for all
* non-type-related errors in the `CpfCheckDigits`. It is suitable for
* validation errors, range errors, and other business logic exceptions that are
* not strictly type-related. It ensures proper prototype chain setup and
* automatically sets the error name from the constructor.
*/
var CpfCheckDigitsException = /** @class */ (function (_super) {
__extends(CpfCheckDigitsException, _super);
function CpfCheckDigitsException(message) {
var _newTarget = this.constructor;
var _this = _super.call(this, message) || this;
Object.setPrototypeOf(_this, _newTarget.prototype);
_this.name = _this.constructor.name;
return _this;
}
return CpfCheckDigitsException;
}(Error));
/**
* Error raised when the input `{@link CpfInput}` (after optional processing)
* does not have the required length to calculate the check digits. A valid CPF
* input must contain between 9 and 11 numeric characters. The error message
* distinguishes between the original input and the evaluated one (which strips
* punctuation characters).
*/
var CpfCheckDigitsInputLengthException = /** @class */ (function (_super) {
__extends(CpfCheckDigitsInputLengthException, _super);
function CpfCheckDigitsInputLengthException(actualInput, evaluatedInput, minExpectedLength, maxExpectedLength) {
var _this = this;
var fmtActualInput = typeof actualInput === 'string' ? "\"".concat(actualInput, "\"") : JSON.stringify(actualInput);
var fmtEvaluatedInput = actualInput === evaluatedInput
? "".concat(evaluatedInput.length)
: "".concat(evaluatedInput.length, " in \"").concat(evaluatedInput, "\"");
_this = _super.call(this, "CPF input ".concat(fmtActualInput, " does not contain ").concat(minExpectedLength, " to ").concat(maxExpectedLength, " digits. Got ").concat(fmtEvaluatedInput, ".")) || this;
_this.actualInput = actualInput;
_this.evaluatedInput = evaluatedInput;
_this.minExpectedLength = minExpectedLength;
_this.maxExpectedLength = maxExpectedLength;
return _this;
}
return CpfCheckDigitsInputLengthException;
}(CpfCheckDigitsException));
/**
* Exception raised when the CPF input contains invalid character sequences,
* like all digits are repeated. This is a business logic exception and it is
* highly recommended that users of the library catch it and handle it
* appropriately.
*/
var CpfCheckDigitsInputInvalidException = /** @class */ (function (_super) {
__extends(CpfCheckDigitsInputInvalidException, _super);
function CpfCheckDigitsInputInvalidException(actualInput, reason) {
var _this = this;
var fmtActualInput = typeof actualInput === 'string' ? "\"".concat(actualInput, "\"") : JSON.stringify(actualInput);
_this = _super.call(this, "CPF input ".concat(fmtActualInput, " is invalid. ").concat(reason)) || this;
_this.actualInput = actualInput;
_this.reason = reason;
return _this;
}
return CpfCheckDigitsInputInvalidException;
}(CpfCheckDigitsException));
/**
* Minimum number of digits required for the CPF check digits calculation.
*/
var CPF_MIN_LENGTH = 9;
/**
* Maximum number of digits accepted as input for the CPF check digits
* calculation.
*/
var CPF_MAX_LENGTH = 11;
/**
* Calculates and exposes CPF check digits from a valid base input. Validates
* length and rejects repeated-digit sequences.
*/
var CpfCheckDigits = /** @class */ (function () {
/**
* Creates a calculator for the given CPF base (9 to 11 digits).
*
* @throws {CpfCheckDigitsInputTypeError} When input is not a string or
* string[].
* @throws {CpfCheckDigitsInputLengthException} When digit count is not
* between 9 and 11.
* @throws {CpfCheckDigitsInputInvalidException} When all digits are the same
* (repeated digits, e.g. `777.777.777-...`).
*/
function CpfCheckDigits(cpfInput) {
this._cachedFirstDigit = undefined;
this._cachedSecondDigit = undefined;
var parsedInput;
if (typeof cpfInput === 'string') {
parsedInput = this._handleStringInput(cpfInput);
}
else if (Array.isArray(cpfInput)) {
parsedInput = this._handleArrayInput(cpfInput);
}
else {
throw new CpfCheckDigitsInputTypeError(cpfInput, 'string or string[]');
}
this._validateLength(parsedInput, cpfInput);
this._validateNonRepeatedDigits(parsedInput, cpfInput);
this._cpfDigits = parsedInput.slice(0, CPF_MIN_LENGTH);
}
Object.defineProperty(CpfCheckDigits.prototype, "first", {
/**
* First check digit (10th digit of the full CPF).
*/
get: function () {
if (this._cachedFirstDigit === undefined) {
var baseDigitsSequence = __spreadArray([], this._cpfDigits, true);
this._cachedFirstDigit = this._calculate(baseDigitsSequence);
}
return this._cachedFirstDigit.toString();
},
enumerable: false,
configurable: true
});
Object.defineProperty(CpfCheckDigits.prototype, "second", {
/**
* Second check digit (11th digit of the full CPF).
*/
get: function () {
if (this._cachedSecondDigit === undefined) {
var baseDigitsSequence = __spreadArray(__spreadArray([], this._cpfDigits, true), [Number(this.first)], false);
this._cachedSecondDigit = this._calculate(baseDigitsSequence);
}
return this._cachedSecondDigit.toString();
},
enumerable: false,
configurable: true
});
Object.defineProperty(CpfCheckDigits.prototype, "both", {
/**
* Both check digits concatenated (10th and 11th digits).
*/
get: function () {
return this.first + this.second;
},
enumerable: false,
configurable: true
});
Object.defineProperty(CpfCheckDigits.prototype, "cpf", {
/**
* Full 11-digit CPF (base 9 digits concatenated with the 2 check digits).
*/
get: function () {
return __spreadArray(__spreadArray([], this._cpfDigits, true), [this.both], false).join('');
},
enumerable: false,
configurable: true
});
/**
* Parses a string into an array of numbers.
*/
CpfCheckDigits.prototype._handleStringInput = function (cpfString) {
var stringDigitsOnly = cpfString.replace(/\D/g, '');
var stringDigitsArray = stringDigitsOnly.split('');
var numberDigitsArray = stringDigitsArray.map(Number);
return numberDigitsArray;
};
/**
* Normalizes array input to a string array and delegates to number parsing.
*/
CpfCheckDigits.prototype._handleArrayInput = function (cpfArray) {
if (cpfArray.length === 0) {
return [];
}
var isStringArray = cpfArray.every(function (item) { return typeof item === 'string'; });
if (!isStringArray) {
throw new CpfCheckDigitsInputTypeError(cpfArray, 'string or string[]');
}
return this._handleStringInput(cpfArray.join(''));
};
/**
* Ensures digit count is between {@link CPF_MIN_LENGTH} and
* {@link CPF_MAX_LENGTH}.
*/
CpfCheckDigits.prototype._validateLength = function (cpfIntArray, originalInput) {
var digitsCount = cpfIntArray.length;
if (digitsCount < CPF_MIN_LENGTH || digitsCount > CPF_MAX_LENGTH) {
throw new CpfCheckDigitsInputLengthException(originalInput, cpfIntArray.join(''), CPF_MIN_LENGTH, CPF_MAX_LENGTH);
}
};
/**
* Rejects inputs where all first 9 digits are the same.
*/
CpfCheckDigits.prototype._validateNonRepeatedDigits = function (cpfIntArray, originalInput) {
var eligibleCpfIntArray = cpfIntArray.slice(0, CPF_MIN_LENGTH);
var uniqueDigits = new Set(eligibleCpfIntArray);
if (uniqueDigits.size === 1) {
throw new CpfCheckDigitsInputInvalidException(originalInput, 'Repeated digits are not considered valid.');
}
};
/**
* Computes a single check digit using the standard CPF modulo-11 algorithm.
*/
CpfCheckDigits.prototype._calculate = function (cpfSequence) {
var factor = cpfSequence.length + 1;
var sumResult = 0;
for (var _i = 0, cpfSequence_1 = cpfSequence; _i < cpfSequence_1.length; _i++) {
var num = cpfSequence_1[_i];
sumResult += num * factor;
factor -= 1;
}
var remainder = 11 - (sumResult % 11);
return remainder > 9 ? 0 : remainder;
};
return CpfCheckDigits;
}());
Object.freeze(CpfCheckDigits);
/**
* Base error class for all `cpf-gen` type-related errors.
*
* This abstract class extends the native `TypeError` and serves as the base for
* all type validation errors in the CPF generator. It ensures proper prototype
* chain setup and automatically sets the error name from the constructor.
*/
var CpfGeneratorTypeError = /** @class */function (_super) {
__extends$1(CpfGeneratorTypeError, _super);
function CpfGeneratorTypeError(actualInput, actualType, expectedType, message) {
var _newTarget = this.constructor;
var _this = _super.call(this, message) || this;
Object.setPrototypeOf(_this, _newTarget.prototype);
_this.name = _this.constructor.name;
_this.actualInput = actualInput;
_this.actualType = actualType;
_this.expectedType = expectedType;
return _this;
}
return CpfGeneratorTypeError;
}(TypeError);
/**
* Error raised when a specific option in the generator configuration has an
* invalid type. The error message includes the option name, the actual input
* type and the expected type.
*/
var CpfGeneratorOptionsTypeError = /** @class */function (_super) {
__extends$1(CpfGeneratorOptionsTypeError, _super);
function CpfGeneratorOptionsTypeError(optionName, actualInput, expectedType) {
var _this = this;
var actualInputType = describeType(actualInput);
_this = _super.call(this, actualInput, actualInputType, expectedType, "CPF generator option \"".concat(optionName, "\" must be of type ").concat(expectedType, ". Got ").concat(actualInputType, ".")) || this;
_this.optionName = optionName;
return _this;
}
return CpfGeneratorOptionsTypeError;
}(CpfGeneratorTypeError);
/**
* Base exception for all `cpf-gen` rules-related errors.
*
* This abstract class extends the native `Error` and serves as the base for all
* non-type-related errors in the `CpfGenerator` and its dependencies. It is
* suitable for validation errors, range errors, and other business logic
* exceptions that are not strictly type-related. It ensures proper prototype
* chain setup and automatically sets the error name from the constructor.
*/
var CpfGeneratorException = /** @class */function (_super) {
__extends$1(CpfGeneratorException, _super);
function CpfGeneratorException(message) {
var _newTarget = this.constructor;
var _this = _super.call(this, message) || this;
Object.setPrototypeOf(_this, _newTarget.prototype);
_this.name = _this.constructor.name;
return _this;
}
return CpfGeneratorException;
}(Error);
/**
* Exception raised when the CPF option `prefix` is invalid. This is a business
* logic exception and it is highly recommended that users of the library catch
* it and handle it appropriately.
*/
var CpfGeneratorOptionPrefixInvalidException = /** @class */function (_super) {
__extends$1(CpfGeneratorOptionPrefixInvalidException, _super);
function CpfGeneratorOptionPrefixInvalidException(actualInput, reason) {
var _this = _super.call(this, "CPF generator option \"prefix\" with value \"".concat(actualInput, "\" is invalid. ").concat(reason)) || this;
_this.actualInput = actualInput;
_this.reason = reason;
return _this;
}
return CpfGeneratorOptionPrefixInvalidException;
}(CpfGeneratorException);
/**
* The standard length of a CPF (Cadastro de Pessoa Física) identifier (11
* digits).
*/
var CPF_LENGTH = 11;
/**
* Maximum length of the prefix of a CPF.
*/
var CPF_PREFIX_MAX_LENGTH = CPF_LENGTH - 2;
var CPF_BASE_ID_LENGTH = 9;
var CPF_BASE_ID_LAST_INDEX = CPF_BASE_ID_LENGTH - 1;
var CPF_INVALID_BASE_ID = '0'.repeat(CPF_BASE_ID_LENGTH);
/**
* Class to store the options for the CPF generator. This class provides a
* centralized way to configure how CPF digits are generated, including partial
* start string and formatting.
*/
var CpfGeneratorOptions = /** @class */function () {
/**
* Creates a new instance of `CpfGeneratorOptions`.
*
* Options can be provided in multiple ways:
*
* 1. As a single options object or another `CpfGeneratorOptions` instance.
* 2. As multiple override objects that are merged in order (later overrides take
* precedence)
*
* All options are optional and will default to their predefined values if not
* provided.
*
* @throws {CpfGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of digits.
*/
function CpfGeneratorOptions(defaultOptions) {
var overrides = [];
for (var _i = 1; _i < arguments.length; _i++) {
overrides[_i - 1] = arguments[_i];
}
this._options = {};
this.format = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.format;
this.prefix = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.prefix;
for (var _a = 0, overrides_1 = overrides; _a < overrides_1.length; _a++) {
var override = overrides_1[_a];
this.set(override);
}
}
Object.defineProperty(CpfGeneratorOptions.prototype, "all", {
/**
* Returns a shallow copy of all current options, frozen to prevent
* modification. This is useful for creating immutable snapshots of the
* current configuration.
*/
get: function get() {
var options = _assign({}, this._options);
return Object.freeze(options);
},
enumerable: false,
configurable: true
});
Object.defineProperty(CpfGeneratorOptions.prototype, "format", {
/**
* Gets whether the generated CPF string will have the standard formatting
* (`000.000.000-00`).
*/
get: function get() {
return this._options.format;
},
/**
* Sets whether the generated CPF string will have the standard formatting
* (`000.000.000-00`). The value is converted to a boolean using `Boolean()`,
* so truthy/falsy values are handled appropriately.
*/
set: function set(value) {
var actualFormat = value !== null && value !== void 0 ? value : CpfGeneratorOptions.DEFAULT_FORMAT;
actualFormat = Boolean(actualFormat);
this._options.format = actualFormat;
},
enumerable: false,
configurable: true
});
Object.defineProperty(CpfGeneratorOptions.prototype, "prefix", {
/**
* Gets the string used as the initial string of the generated CPF.
*
* Note: If the evaluated prefix (after stripping non-digit characters) is
* longer than 9 digits, the extra digits are ignored, because a CPF has 9
* base digits followed by 2 calculated check digits.
*/
get: function get() {
return this._options.prefix;
},
/**
* Sets the string used as the initial string of the generated CPF. Only
* digits are kept and the rest is stripped. If provided, only the missing
* digits are generated randomly. For example, if the prefix `123456` (6
* digits) is given, only the next 3 digits are randomly generated and
* concatenated to the prefix.
*
* Note: If the evaluated prefix (after stripping non-digit characters) is
* longer than 9 digits, the extra digits are ignored, because a CPF has 9
* base digits followed by 2 calculated check digits.
*
* @throws {CpfGeneratorOptionsTypeError} If the value is not a string.
* @throws {CpfGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of digits or is too long.
*/
set: function set(value) {
var actualPrefix = value !== null && value !== void 0 ? value : CpfGeneratorOptions.DEFAULT_PREFIX;
if (typeof actualPrefix !== 'string') {
throw new CpfGeneratorOptionsTypeError('prefix', actualPrefix, 'string');
}
actualPrefix = actualPrefix.replace(/\D/g, '');
actualPrefix = actualPrefix.slice(0, CPF_PREFIX_MAX_LENGTH);
this._validatePrefixBaseId(actualPrefix);
this._validatePrefixNonRepeatedDigits(actualPrefix);
this._options.prefix = actualPrefix;
},
enumerable: false,
configurable: true
});
/**
* Sets multiple options at once. This method allows you to update multiple
* options in a single call. Only the provided options are updated; options
* not included in the object retain their current values. You can pass either
* a partial options object or another `CpfGeneratorOptions` instance.
*
* @throws {CpfGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CpfGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of digits or is too long.
*/
CpfGeneratorOptions.prototype.set = function (options) {
var _a, _b;
this.format = (_a = options.format) !== null && _a !== void 0 ? _a : this.format;
this.prefix = (_b = options.prefix) !== null && _b !== void 0 ? _b : this.prefix;
return this;
};
/**
* Throws if the prefix's digits are all zeros.
*
* @throws {CpfGeneratorOptionPrefixInvalidException} If the prefix's first 8
* digits are all zeros.
*/
CpfGeneratorOptions.prototype._validatePrefixBaseId = function (partialCpf) {
if (partialCpf.length < CPF_BASE_ID_LENGTH) {
return;
}
var cpfBaseIdString = partialCpf.slice(0, CPF_BASE_ID_LAST_INDEX + 1);
if (cpfBaseIdString === CPF_INVALID_BASE_ID) {
throw new CpfGeneratorOptionPrefixInvalidException(partialCpf, "Zeroed base ID is not eligible.");
}
};
/**
* Throws if the prefix has 9 digits and they are all the same number.
*
* @throws {CpfGeneratorOptionPrefixInvalidException} If the prefix has 12
* digits that are all the same digit.
*/
CpfGeneratorOptions.prototype._validatePrefixNonRepeatedDigits = function (cpfPrefix) {
if (cpfPrefix.length < CPF_PREFIX_MAX_LENGTH) {
return;
}
var eligibleCpfPrefix = cpfPrefix.slice(0, CPF_PREFIX_MAX_LENGTH);
var uniqueDigits = new Set(eligibleCpfPrefix);
if (uniqueDigits.size === 1) {
throw new CpfGeneratorOptionPrefixInvalidException(cpfPrefix, 'Repeated digits are not considered valid.');
}
};
/**
* Default value for the `format` option. When `true`, the generated CPF
* string will have the standard formatting (`000.000.000-00`).
*/
CpfGeneratorOptions.DEFAULT_FORMAT = false;
/**
* Default string used as the initial string of the generated CPF.
*/
CpfGeneratorOptions.DEFAULT_PREFIX = '';
return CpfGeneratorOptions;
}();
Object.freeze(CpfGeneratorOptions);
/**
* @typedef {import('./exceptions').CpfGeneratorOptionsTypeError} CpfGeneratorOptionsTypeError
*
*
* @typedef {import('./exceptions').CpfGeneratorOptionPrefixInvalidException} CpfGeneratorOptionPrefixInvalidException
*/
var CPF_DOT_KEY = '.';
var CPF_DASH_KEY = '-';
/**
* Generator for CPF (Cadastro de Pessoa Física) identifiers. Builds valid
* 11-digit CPF values by combining an optional prefix with a randomly generated
* sequence and computed check digits. Options control prefix and whether the
* result is formatted (`000.000.000-00`).
*/
var CpfGenerator = /** @class */function () {
/**
* Creates a new `CpfGenerator` with optional default options.
*
* Default options apply to every call to `generate` unless overridden by the
* per-call `options` argument. Options control prefix and whether the
* generated CPF is formatted.
*
* When `defaultOptions` is a `CpfGeneratorOptions` instance, that instance is
* used directly (no copy is created). Mutating it later (e.g. via the
* `options` getter or the original reference) affects future `generate` calls
* that do not pass per-call options. When a plain object or nothing is
* passed, a new `CpfGeneratorOptions` instance is created from it.
*
* @throws {CpfGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CpfGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of digits.
*/
function CpfGenerator(defaultOptions) {
this._options = defaultOptions instanceof CpfGeneratorOptions ? defaultOptions : new CpfGeneratorOptions(defaultOptions);
}
Object.defineProperty(CpfGenerator.prototype, "options", {
/**
* Returns the default options used by this generator when per-call options
* are not provided.
*
* The returned object is the same instance used internally; mutating it (e.g.
* via setters on `CpfGeneratorOptions`) affects future `generate` calls that
* do not pass `options`.
*/
get: function get() {
return this._options;
},
enumerable: false,
configurable: true
});
/**
* Generates a valid CPF value.
*
* Builds a 9-digit CPF from the configured prefix (if any), a random sequence
* of digits, and two computed check digits. If formatting is enabled, the
* result is returned as `000.000.000-00`.
*
* Per-call `options` are merged over the instance default options for this
* call only; the instance defaults are unchanged.
*
* @throws {CpfGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CpfGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of digits.
*/
CpfGenerator.prototype.generate = function (options) {
var actualOptions = options ? new CpfGeneratorOptions(this._options, options) : this._options;
var digitsToGenerate = CPF_PREFIX_MAX_LENGTH - actualOptions.prefix.length;
var generatedDigits = generateRandomSequence(digitsToGenerate);
var generatedCpf = actualOptions.prefix + generatedDigits;
try {
var cpfCheckDigits = new CpfCheckDigits(generatedCpf);
generatedCpf = cpfCheckDigits.cpf;
} catch (error) {
if (error instanceof CpfCheckDigitsException) {
return this.generate(options);
}
throw error;
}
if (actualOptions.format) {
generatedCpf = generatedCpf.slice(0, 3) + CPF_DOT_KEY + generatedCpf.slice(3, 6) + CPF_DOT_KEY + generatedCpf.slice(6, 9) + CPF_DASH_KEY + generatedCpf.slice(9, 11);
}
return generatedCpf;
};
return CpfGenerator;
}();
Object.freeze(CpfGenerator);
/**
* Helper function to simplify the usage of the {@link CpfGenerator} class.
*
* If no options are provided, it generates an 11-digit unformatted numeric CPF
* (e.g., `12345678901`) using default settings. If options are provided, they
* control prefix and whether the result is formatted.
*
* @throws {CpfGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CpfGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of digits.
* @see CpfGenerator for detailed option descriptions.
*/
function cpfGen$1(options) {
return new CpfGenerator(options).generate();
}
var all = /*#__PURE__*/Object.freeze({
__proto__: null,
CPF_LENGTH: CPF_LENGTH,
CPF_PREFIX_MAX_LENGTH: CPF_PREFIX_MAX_LENGTH,
CpfGenerator: CpfGenerator,
CpfGeneratorException: CpfGeneratorException,
CpfGeneratorOptionPrefixInvalidException: CpfGeneratorOptionPrefixInvalidException,
CpfGeneratorOptions: CpfGeneratorOptions,
CpfGeneratorOptionsTypeError: CpfGeneratorOptionsTypeError,
CpfGeneratorTypeError: CpfGeneratorTypeError,
cpfGen: cpfGen$1,
default: cpfGen$1
});
var baseCpfGen = cpfGen$1,
rest = __rest(all, ["default", "cpfGen"]);
var cpfGen = function cpfGen() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return baseCpfGen.apply(void 0, args);
};
var index_cjs = Object.assign(cpfGen, rest);
return index_cjs;
}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3BmLWdlbi5qcyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbm9kZV9tb2R1bGVzLy5idW4vQHJvbGx1cCtwbHVnaW4tdHlwZXNjcmlwdEAxMi4zLjArZDY0OTY3OThkMThhOTA4OS9ub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzIiwiLi4vLi4vdXRpbHMvZGlzdC9pbmRleC5tanMiLCIuLi8uLi9jcGYtZHYvZGlzdC9pbmRleC5tanMiLCIuLi9zcmMvZXhjZXB0aW9ucy50cyIsIi4uL3NyYy9jcGYtZ2VuZXJhdG9yLW9wdGlvbnMudHMiLCIuLi9zcmMvY3BmLWdlbmVyYXRvci50cyIsIi4uL3NyYy9jcGYtZ2VuLnRzIiwiLi4vc3JjL2luZGV4LmNqcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UsIFN1cHByZXNzZWRFcnJvciwgU3ltYm9sLCBJdGVyYXRvciAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19lc0RlY29yYXRlKGN0b3IsIGRlc2NyaXB0b3JJbiwgZGVjb3JhdG9ycywgY29udGV4dEluLCBpbml0aWFsaXplcnMsIGV4dHJhSW5pdGlhbGl6ZXJzKSB7XHJcbiAgICBmdW5jdGlvbiBhY2NlcHQoZikgeyBpZiAoZiAhPT0gdm9pZCAwICYmIHR5cGVvZiBmICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGdW5jdGlvbiBleHBlY3RlZFwiKTsgcmV0dXJuIGY7IH1cclxuICAgIHZhciBraW5kID0gY29udGV4dEluLmtpbmQsIGtleSA9IGtpbmQgPT09IFwiZ2V0dGVyXCIgPyBcImdldFwiIDoga2luZCA9PT0gXCJzZXR0ZXJcIiA/IFwic2V0XCIgOiBcInZhbHVlXCI7XHJcbiAgICB2YXIgdGFyZ2V0ID0gIWRlc2NyaXB0b3JJbiAmJiBjdG9yID8gY29udGV4dEluW1wic3RhdGljXCJdID8gY3RvciA6IGN0b3IucHJvdG90eXBlIDogbnVsbDtcclxuICAgIHZhciBkZXNjcmlwdG9yID0gZGVzY3JpcHRvckluIHx8ICh0YXJnZXQgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgY29udGV4dEluLm5hbWUpIDoge30pO1xyXG4gICAgdmFyIF8sIGRvbmUgPSBmYWxzZTtcclxuICAgIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIGNvbnRleHQgPSB7fTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbikgY29udGV4dFtwXSA9IHAgPT09IFwiYWNjZXNzXCIgPyB7fSA6IGNvbnRleHRJbltwXTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbi5hY2Nlc3MpIGNvbnRleHQuYWNjZXNzW3BdID0gY29udGV4dEluLmFjY2Vzc1twXTtcclxuICAgICAgICBjb250ZXh0LmFkZEluaXRpYWxpemVyID0gZnVuY3Rpb24gKGYpIHsgaWYgKGRvbmUpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgYWRkIGluaXRpYWxpemVycyBhZnRlciBkZWNvcmF0aW9uIGhhcyBjb21wbGV0ZWRcIik7IGV4dHJhSW5pdGlhbGl6ZXJzLnB1c2goYWNjZXB0KGYgfHwgbnVsbCkpOyB9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSAoMCwgZGVjb3JhdG9yc1tpXSkoa2luZCA9PT0gXCJhY2Nlc3NvclwiID8geyBnZXQ6IGRlc2NyaXB0b3IuZ2V0LCBzZXQ6IGRlc2NyaXB0b3Iuc2V0IH0gOiBkZXNjcmlwdG9yW2tleV0sIGNvbnRleHQpO1xyXG4gICAgICAgIGlmIChraW5kID09PSBcImFjY2Vzc29yXCIpIHtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCB0eXBlb2YgcmVzdWx0ICE9PSBcIm9iamVjdFwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkXCIpO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuZ2V0KSkgZGVzY3JpcHRvci5nZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuc2V0KSkgZGVzY3JpcHRvci5zZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuaW5pdCkpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChfID0gYWNjZXB0KHJlc3VsdCkpIHtcclxuICAgICAgICAgICAgaWYgKGtpbmQgPT09IFwiZmllbGRcIikgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XHJcbiAgICAgICAgICAgIGVsc2UgZGVzY3JpcHRvcltrZXldID0gXztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGFyZ2V0KSBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSwgZGVzY3JpcHRvcik7XHJcbiAgICBkb25lID0gdHJ1ZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3J1bkluaXRpYWxpemVycyh0aGlzQXJnLCBpbml0aWFsaXplcnMsIHZhbHVlKSB7XHJcbiAgICB2YXIgdXNlVmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMjtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5pdGlhbGl6ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdmFsdWUgPSB1c2VWYWx1ZSA/IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcsIHZhbHVlKSA6IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVzZVZhbHVlID8gdmFsdWUgOiB2b2lkIDA7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wcm9wS2V5KHgpIHtcclxuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzeW1ib2xcIiA/IHggOiBcIlwiLmNvbmNhdCh4KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NldEZ1bmN0aW9uTmFtZShmLCBuYW1lLCBwcmVmaXgpIHtcclxuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gXCJzeW1ib2xcIikgbmFtZSA9IG5hbWUuZGVzY3JpcHRpb24gPyBcIltcIi5jb25jYXQobmFtZS5kZXNjcmlwdGlvbiwgXCJdXCIpIDogXCJcIjtcclxuICAgIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoZiwgXCJuYW1lXCIsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogcHJlZml4ID8gXCJcIi5jb25jYXQocHJlZml4LCBcIiBcIiwgbmFtZSkgOiBuYW1lIH0pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZyA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gSXRlcmF0b3IgOiBPYmplY3QpLnByb3RvdHlwZSk7XHJcbiAgICByZXR1cm4gZy5uZXh0ID0gdmVyYigwKSwgZ1tcInRocm93XCJdID0gdmVyYigxKSwgZ1tcInJldHVyblwiXSA9IHZlcmIoMiksIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoZyAmJiAoZyA9IDAsIG9wWzBdICYmIChfID0gMCkpLCBfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcclxuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XHJcbiAgICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gX