@lacussoft/cnpj-gen
Version:
Utility to generate CNPJ (Brazilian Business Tax ID)
971 lines (944 loc) • 244 kB
JavaScript
/**
* Lacus Solutions :: cnpj-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.cnpjGen = 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;
if (type === 'numeric') {
charactersRange = NUMERIC_CHARACTERS;
}
else if (type === 'alphabetic') {
charactersRange = ALPHABETIC_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 :: cnpj-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 `cnpj-dv` type-related errors.
*
* This abstract class extends the native `TypeError` and serves as the base for
* all type validation errors in the `CnpjCheckDigits`. It ensures proper
* prototype chain setup and automatically sets the error name from the
* constructor.
*/
var CnpjCheckDigitsTypeError = /** @class */ (function (_super) {
__extends(CnpjCheckDigitsTypeError, _super);
function CnpjCheckDigitsTypeError(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 CnpjCheckDigitsTypeError;
}(TypeError));
/**
* Error raised when the input provided to `CnpjCheckDigits` is not of the
* expected type (`{@link CnpjInput}`). The error message includes both the
* actual type of the input and the expected type.
*/
var CnpjCheckDigitsInputTypeError = /** @class */ (function (_super) {
__extends(CnpjCheckDigitsInputTypeError, _super);
function CnpjCheckDigitsInputTypeError(actualInput, expectedType) {
var actualInputType = describeType(actualInput);
return _super.call(this, actualInput, actualInputType, expectedType, "CNPJ input must be of type ".concat(expectedType, ". Got ").concat(actualInputType, ".")) || this;
}
return CnpjCheckDigitsInputTypeError;
}(CnpjCheckDigitsTypeError));
/**
* Base exception for all `cnpj-dv` rules-related errors.
*
* This abstract class extends the native `Error` and serves as the base for all
* non-type-related errors in the `CnpjCheckDigits`. 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 CnpjCheckDigitsException = /** @class */ (function (_super) {
__extends(CnpjCheckDigitsException, _super);
function CnpjCheckDigitsException(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 CnpjCheckDigitsException;
}(Error));
/**
* Error raised when the input `{@link CnpjInput}` (after optional processing)
* does not have the required length to calculate the check digits. A valid CNPJ
* input must contain between 12 and 14 alphanumeric characters. The error
* message distinguishes between the original input and the evaluated one (which
* strips punctuation characters).
*/
var CnpjCheckDigitsInputLengthException = /** @class */ (function (_super) {
__extends(CnpjCheckDigitsInputLengthException, _super);
function CnpjCheckDigitsInputLengthException(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, "CNPJ 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 CnpjCheckDigitsInputLengthException;
}(CnpjCheckDigitsException));
/**
* Exception raised when the CNPJ 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 CnpjCheckDigitsInputInvalidException = /** @class */ (function (_super) {
__extends(CnpjCheckDigitsInputInvalidException, _super);
function CnpjCheckDigitsInputInvalidException(actualInput, reason) {
var _this = this;
var fmtActualInput = typeof actualInput === 'string' ? "\"".concat(actualInput, "\"") : JSON.stringify(actualInput);
_this = _super.call(this, "CNPJ input ".concat(fmtActualInput, " is invalid. ").concat(reason)) || this;
_this.actualInput = actualInput;
_this.reason = reason;
return _this;
}
return CnpjCheckDigitsInputInvalidException;
}(CnpjCheckDigitsException));
/**
* Minimum number of characters required for the CNPJ check digits calculation.
*/
var CNPJ_MIN_LENGTH = 12;
/**
* Maximum number of characters accepted as input for the CNPJ check digits
* calculation.
*/
var CNPJ_MAX_LENGTH = 14;
var CNPJ_BASE_ID_LENGTH$1 = 8;
var CNPJ_BASE_ID_LAST_INDEX$1 = CNPJ_BASE_ID_LENGTH$1 - 1;
var CNPJ_INVALID_BASE_ID = '0'.repeat(CNPJ_BASE_ID_LENGTH$1);
var CNPJ_BRANCH_ID_LENGTH$1 = 4;
var CNPJ_BRANCH_ID_LAST_INDEX$1 = CNPJ_BASE_ID_LAST_INDEX$1 + CNPJ_BRANCH_ID_LENGTH$1;
var CNPJ_INVALID_BRANCH_ID = '0'.repeat(CNPJ_BRANCH_ID_LENGTH$1);
var DELTA_FACTOR = '0'.charCodeAt(0);
/**
* Calculates and exposes CNPJ check digits from a valid base input. Validates
* length, base ID, branch ID and rejects repeated-character sequences.
*/
var CnpjCheckDigits = /** @class */ (function () {
/**
* Creates a calculator for the given CNPJ base (12 to 14 characters).
*
* @throws {CnpjCheckDigitsInputTypeError} When input is not a string or
* string[].
* @throws {CnpjCheckDigitsInputLengthException} When character count is not
* between 12 and 14.
* @throws {CnpjCheckDigitsInputInvalidException} When base ID is all zero
* (`00.000.000`), branch ID is all zero (`0000`) or all digits are the same
* (repeated digits, e.g. `77.777.777/7777-...`).
*/
function CnpjCheckDigits(cnpjInput) {
this._cachedFirstDigit = undefined;
this._cachedSecondDigit = undefined;
var parsedInput;
if (typeof cnpjInput === 'string') {
parsedInput = this._handleStringInput(cnpjInput);
}
else if (Array.isArray(cnpjInput)) {
parsedInput = this._handleArrayInput(cnpjInput);
}
else {
throw new CnpjCheckDigitsInputTypeError(cnpjInput, 'string or string[]');
}
this._validateLength(parsedInput, cnpjInput);
this._validateBaseId(parsedInput, cnpjInput);
this._validateBranchId(parsedInput, cnpjInput);
this._validateNonRepeatedDigits(parsedInput, cnpjInput);
this._cnpjChars = parsedInput.slice(0, CNPJ_MIN_LENGTH);
}
Object.defineProperty(CnpjCheckDigits.prototype, "first", {
/**
* First check digit (13th character of the full CNPJ).
*/
get: function () {
if (this._cachedFirstDigit === undefined) {
var baseCharsSequence = __spreadArray([], this._cnpjChars, true);
this._cachedFirstDigit = this._calculate(baseCharsSequence);
}
return this._cachedFirstDigit.toString();
},
enumerable: false,
configurable: true
});
Object.defineProperty(CnpjCheckDigits.prototype, "second", {
/**
* Second check digit (14th character of the full CNPJ).
*/
get: function () {
if (this._cachedSecondDigit === undefined) {
var baseCharsSequence = __spreadArray(__spreadArray([], this._cnpjChars, true), [this.first], false);
this._cachedSecondDigit = this._calculate(baseCharsSequence);
}
return this._cachedSecondDigit.toString();
},
enumerable: false,
configurable: true
});
Object.defineProperty(CnpjCheckDigits.prototype, "both", {
/**
* Both check digits concatenated (13th and 14th characters).
*/
get: function () {
return this.first + this.second;
},
enumerable: false,
configurable: true
});
Object.defineProperty(CnpjCheckDigits.prototype, "cnpj", {
/**
* Full 14-character CNPJ (base 12 characters concatenated with the 2 check
* digits).
*/
get: function () {
return __spreadArray(__spreadArray([], this._cnpjChars, true), [this.both], false).join('');
},
enumerable: false,
configurable: true
});
/**
* Parses a string into an array of alphanumeric characters.
*/
CnpjCheckDigits.prototype._handleStringInput = function (cnpjString) {
var alphanumericOnly = cnpjString.replace(/[^0-9A-Z]/gi, '');
var alphanumericUpper = alphanumericOnly.toUpperCase();
var alphanumericArray = alphanumericUpper.split('');
return alphanumericArray;
};
/**
* Normalizes array input to a string array and delegates to string parsing.
*/
CnpjCheckDigits.prototype._handleArrayInput = function (cnpjArray) {
if (cnpjArray.length === 0) {
return [];
}
var isStringArray = cnpjArray.every(function (item) { return typeof item === 'string'; });
if (!isStringArray) {
throw new CnpjCheckDigitsInputTypeError(cnpjArray, 'string or string[]');
}
return this._handleStringInput(cnpjArray.join(''));
};
/**
* Ensures character count is between {@link CNPJ_MIN_LENGTH} and
* {@link CNPJ_MAX_LENGTH}.
*/
CnpjCheckDigits.prototype._validateLength = function (cnpjChars, originalInput) {
var charsCount = cnpjChars.length;
if (charsCount < CNPJ_MIN_LENGTH || charsCount > CNPJ_MAX_LENGTH) {
throw new CnpjCheckDigitsInputLengthException(originalInput, cnpjChars.join(''), CNPJ_MIN_LENGTH, CNPJ_MAX_LENGTH);
}
};
/**
* Rejects base ID (first 8 digits) when it is all zeros.
*/
CnpjCheckDigits.prototype._validateBaseId = function (cnpjIntArray, originalInput) {
var cnpjBaseIdArray = cnpjIntArray.slice(0, CNPJ_BASE_ID_LAST_INDEX$1 + 1);
var cnpjBaseIdString = cnpjBaseIdArray.join('');
if (cnpjBaseIdString === CNPJ_INVALID_BASE_ID) {
throw new CnpjCheckDigitsInputInvalidException(originalInput, "Base ID \"".concat(CNPJ_INVALID_BASE_ID, "\" is not eligible."));
}
};
/**
* Rejects branch ID (digits 9–12) when it is all zeros.
*/
CnpjCheckDigits.prototype._validateBranchId = function (cnpjIntArray, originalInput) {
var cnpjBranchIdArray = cnpjIntArray.slice(CNPJ_BASE_ID_LENGTH$1, CNPJ_BRANCH_ID_LAST_INDEX$1 + 1);
var cnpjBranchIdString = cnpjBranchIdArray.join('');
if (cnpjBranchIdString === CNPJ_INVALID_BRANCH_ID) {
throw new CnpjCheckDigitsInputInvalidException(originalInput, "Branch ID \"".concat(CNPJ_INVALID_BRANCH_ID, "\" is not eligible."));
}
};
/**
* Rejects inputs where all first 12 characters are the same.
*/
CnpjCheckDigits.prototype._validateNonRepeatedDigits = function (cnpjIntArray, originalInput) {
var _a;
var eligibleCnpjIntArray = cnpjIntArray.slice(0, CNPJ_MIN_LENGTH);
var uniqueCharacters = new Set(eligibleCnpjIntArray);
if (uniqueCharacters.size === 1 && /^\d$/.test((_a = eligibleCnpjIntArray[0]) !== null && _a !== void 0 ? _a : '')) {
throw new CnpjCheckDigitsInputInvalidException(originalInput, 'Repeated digits are not considered valid.');
}
};
/**
* Computes a single check digit using the standard CNPJ modulo-11 algorithm.
*/
CnpjCheckDigits.prototype._calculate = function (cnpjSequence) {
var factor = 2;
var sumResult = 0;
for (var i = cnpjSequence.length - 1; i >= 0; i--) {
var charCode = cnpjSequence[i].charCodeAt(0);
var charValue = charCode - DELTA_FACTOR;
sumResult += charValue * factor;
factor = factor === 9 ? 2 : factor + 1;
}
var remainder = sumResult % 11;
return remainder < 2 ? 0 : 11 - remainder;
};
return CnpjCheckDigits;
}());
Object.freeze(CnpjCheckDigits);
/**
* Base error class for all `cnpj-gen` type-related errors.
*
* This abstract class extends the native `TypeError` and serves as the base for
* all type validation errors in the CNPJ generator. It ensures proper prototype
* chain setup and automatically sets the error name from the constructor.
*/
var CnpjGeneratorTypeError = /** @class */function (_super) {
__extends$1(CnpjGeneratorTypeError, _super);
function CnpjGeneratorTypeError(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 CnpjGeneratorTypeError;
}(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 CnpjGeneratorOptionsTypeError = /** @class */function (_super) {
__extends$1(CnpjGeneratorOptionsTypeError, _super);
function CnpjGeneratorOptionsTypeError(optionName, actualInput, expectedType) {
var _this = this;
var actualInputType = describeType(actualInput);
_this = _super.call(this, actualInput, actualInputType, expectedType, "CNPJ generator option \"".concat(optionName, "\" must be of type ").concat(expectedType, ". Got ").concat(actualInputType, ".")) || this;
_this.optionName = optionName;
return _this;
}
return CnpjGeneratorOptionsTypeError;
}(CnpjGeneratorTypeError);
/**
* Base exception for all `cnpj-gen` rules-related errors.
*
* This abstract class extends the native `Error` and serves as the base for all
* non-type-related errors in the `CnpjGenerator` 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 CnpjGeneratorException = /** @class */function (_super) {
__extends$1(CnpjGeneratorException, _super);
function CnpjGeneratorException(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 CnpjGeneratorException;
}(Error);
/**
* Exception raised when the CNPJ 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 CnpjGeneratorOptionPrefixInvalidException = /** @class */function (_super) {
__extends$1(CnpjGeneratorOptionPrefixInvalidException, _super);
function CnpjGeneratorOptionPrefixInvalidException(actualInput, reason) {
var _this = _super.call(this, "CNPJ generator option \"prefix\" with value \"".concat(actualInput, "\" is invalid. ").concat(reason)) || this;
_this.actualInput = actualInput;
_this.reason = reason;
return _this;
}
return CnpjGeneratorOptionPrefixInvalidException;
}(CnpjGeneratorException);
/**
* Exception raised when the CNPJ option `type` is given a value that is not one
* of the allowed values. The option must be one of the enumerated values of
* {@link CnpjType}. This is a business logic exception and it is highly
* recommended that users of the library catch it and handle it appropriately.
*/
var CnpjGeneratorOptionTypeInvalidException = /** @class */function (_super) {
__extends$1(CnpjGeneratorOptionTypeInvalidException, _super);
function CnpjGeneratorOptionTypeInvalidException(actualInput, expectedValues) {
var _this = _super.call(this, "CNPJ generator option \"type\" accepts only the following values: \"".concat(expectedValues.join('", "'), "\". Got \"").concat(actualInput, "\".")) || this;
_this.actualInput = actualInput;
_this.expectedValues = expectedValues;
return _this;
}
return CnpjGeneratorOptionTypeInvalidException;
}(CnpjGeneratorException);
/**
* The standard length of a CNPJ (Cadastro Nacional da Pessoa Jurídica)
* identifier (14 alphanumeric characters).
*/
var CNPJ_LENGTH = 14;
/**
* Maximum length of the prefix (base ID and branch ID) of a CNPJ.
*/
var CNPJ_PREFIX_MAX_LENGTH = CNPJ_LENGTH - 2;
var CNPJ_BASE_ID_LENGTH = 8;
var CNPJ_BASE_ID_LAST_INDEX = CNPJ_BASE_ID_LENGTH - 1;
var ZEROED_CNPJ_BASE_ID = '0'.repeat(CNPJ_BASE_ID_LENGTH);
var CNPJ_BRANCH_ID_LENGTH = 4;
var CNPJ_BRANCH_ID_LAST_INDEX = CNPJ_BASE_ID_LAST_INDEX + CNPJ_BRANCH_ID_LENGTH;
var ZEROED_CNPJ_BRANCH_ID = '0'.repeat(CNPJ_BRANCH_ID_LENGTH);
var CNPJ_TYPE_OPTIONS = ['alphabetic', 'alphanumeric', 'numeric'];
/**
* Class to store the options for the CNPJ generator. This class provides a
* centralized way to configure how CNPJ characters are generated, including
* partial start string, formatting, and the type of characters to be generated
* (numeric, alphabetic, or alphanumeric).
*/
var CnpjGeneratorOptions = /** @class */function () {
/**
* Creates a new instance of `CnpjGeneratorOptions`.
*
* Options can be provided in multiple ways:
*
* 1. As a single options object or another `CnpjGeneratorOptions` 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 {CnpjGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains invalid combination of characters.
* @throws {CnpjGeneratorOptionTypeInvalidException} If the `type` option is
* not one of the allowed values.
*/
function CnpjGeneratorOptions(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;
this.type = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.type;
for (var _a = 0, overrides_1 = overrides; _a < overrides_1.length; _a++) {
var override = overrides_1[_a];
this.set(override);
}
}
Object.defineProperty(CnpjGeneratorOptions.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(CnpjGeneratorOptions.prototype, "format", {
/**
* Gets whether the generated CNPJ string will have the standard formatting
* (`00.000.000/0000-00`).
*/
get: function get() {
return this._options.format;
},
/**
* Sets whether the generated CNPJ string will have the standard formatting
* (`00.000.000/0000-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 : CnpjGeneratorOptions.DEFAULT_FORMAT;
actualFormat = Boolean(actualFormat);
this._options.format = actualFormat;
},
enumerable: false,
configurable: true
});
Object.defineProperty(CnpjGeneratorOptions.prototype, "prefix", {
/**
* Gets the string used as the initial string of the generated CNPJ.
*
* Note: If the evaluated prefix (after stripping non-alphanumeric characters)
* is longer than 12 characters, the extra characters are ignored, because a
* CNPJ has 12 base characters followed by 2 calculated check digits.
*/
get: function get() {
return this._options.prefix;
},
/**
* Sets the string used as the initial string of the generated CNPJ. Only
* alphanumeric characters are kept and the rest is stripped. If provided,
* only the missing characters are generated randomly. For example, if the
* prefix `AAABBB` (6 characters) is given, only the next 8 characters are
* randomly generated and concatenated to the prefix.
*
* Note: If the evaluated prefix (after stripping non-alphanumeric characters)
* is longer than 12 characters, the extra characters are ignored, because a
* CNPJ has 12 base characters followed by 2 calculated check digits.
*
* @throws {CnpjGeneratorOptionsTypeError} If the value is not a string.
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains invalid combination of characters or is too long.
*/
set: function set(value) {
var actualPrefix = value !== null && value !== void 0 ? value : CnpjGeneratorOptions.DEFAULT_PREFIX;
if (typeof actualPrefix !== 'string') {
throw new CnpjGeneratorOptionsTypeError('prefix', actualPrefix, 'string');
}
actualPrefix = actualPrefix.replace(/[^0-9A-Z]/gi, '');
actualPrefix = actualPrefix.toUpperCase();
actualPrefix = actualPrefix.slice(0, CNPJ_PREFIX_MAX_LENGTH);
this._validatePrefixBaseId(actualPrefix);
this._validatePrefixBranchId(actualPrefix);
this._validatePrefixNonRepeatedDigits(actualPrefix);
this._options.prefix = actualPrefix;
},
enumerable: false,
configurable: true
});
Object.defineProperty(CnpjGeneratorOptions.prototype, "type", {
/**
* Gets the type of characters to generate for the CNPJ.
*/
get: function get() {
return this._options.type;
},
/**
* Sets the type of characters to generate for the CNPJ.
*
* The options are:
*
* - `alphabetic`: Generates a sequence of alphabetic characters (`A-Z`).
* - `alphanumeric`: Generates a sequence of alphanumeric characters (`0-9A-Z`).
* - `numeric`: Generates a sequence of numbers-only characters (`0-9`).
*
* @throws {CnpjGeneratorOptionsTypeError} If the value is not a string.
* @throws {CnpjGeneratorOptionTypeInvalidException} If the value is not a
* valid type.
*/
set: function set(value) {
var actualType = value !== null && value !== void 0 ? value : CnpjGeneratorOptions.DEFAULT_TYPE;
if (typeof actualType !== 'string') {
throw new CnpjGeneratorOptionsTypeError('type', actualType, 'string');
}
if (!CNPJ_TYPE_OPTIONS.includes(actualType)) {
throw new CnpjGeneratorOptionTypeInvalidException(actualType, CNPJ_TYPE_OPTIONS);
}
this._options.type = actualType;
},
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 `CnpjGeneratorOptions` instance.
*
* @throws {CnpjGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains invalid combination of characters or is too long.
* @throws {CnpjGeneratorOptionTypeInvalidException} If the `type` option is
* not one of the allowed values.
*/
CnpjGeneratorOptions.prototype.set = function (options) {
var _a, _b, _c;
this.format = (_a = options.format) !== null && _a !== void 0 ? _a : this.format;
this.prefix = (_b = options.prefix) !== null && _b !== void 0 ? _b : this.prefix;
this.type = (_c = options.type) !== null && _c !== void 0 ? _c : this.type;
return this;
};
/**
* Throws if the prefix's first 8 characters (base ID) are all zeros.
*
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the prefix's first 8
* characters are all zeros.
*/
CnpjGeneratorOptions.prototype._validatePrefixBaseId = function (partialCnpj) {
if (partialCnpj.length < CNPJ_BASE_ID_LENGTH) {
return;
}
var cnpjBaseIdString = partialCnpj.slice(0, CNPJ_BASE_ID_LAST_INDEX + 1);
if (cnpjBaseIdString === ZEROED_CNPJ_BASE_ID) {
throw new CnpjGeneratorOptionPrefixInvalidException(partialCnpj, "Zeroed base ID is not eligible.");
}
};
/**
* Throws if the prefix's characters at positions 9–12 (branch ID) are all
* zeros.
*
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the prefix's
* characters at positions 9–12 are all zeros.
*/
CnpjGeneratorOptions.prototype._validatePrefixBranchId = function (partialCnpj) {
if (partialCnpj.length < CNPJ_BASE_ID_LENGTH + CNPJ_BRANCH_ID_LENGTH) {
return;
}
var cnpjBranchIdString = partialCnpj.slice(CNPJ_BASE_ID_LENGTH, CNPJ_BRANCH_ID_LAST_INDEX + 1);
if (cnpjBranchIdString === ZEROED_CNPJ_BRANCH_ID) {
throw new CnpjGeneratorOptionPrefixInvalidException(partialCnpj, "Zeroed branch ID is not eligible.");
}
};
/**
* Throws if the prefix has 12 characters and they are all the same digit.
*
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the prefix has 12
* characters that are all the same digit.
*/
CnpjGeneratorOptions.prototype._validatePrefixNonRepeatedDigits = function (cnpjPrefix) {
var _a;
if (cnpjPrefix.length < CNPJ_PREFIX_MAX_LENGTH) {
return;
}
var eligibleCnpjPrefix = cnpjPrefix.slice(0, CNPJ_PREFIX_MAX_LENGTH);
var uniqueCharacters = new Set(eligibleCnpjPrefix);
if (uniqueCharacters.size === 1 && /^\d$/.test((_a = eligibleCnpjPrefix[0]) !== null && _a !== void 0 ? _a : '')) {
throw new CnpjGeneratorOptionPrefixInvalidException(cnpjPrefix, 'Repeated digits are not considered valid.');
}
};
/**
* Default value for the `format` option. When `true`, the generated CNPJ
* string will have the standard formatting (`00.000.000/0000-00`).
*/
CnpjGeneratorOptions.DEFAULT_FORMAT = false;
/**
* Default string used as the initial string of the generated CNPJ.
*/
CnpjGeneratorOptions.DEFAULT_PREFIX = '';
/**
* Default type of characters to generate for the CNPJ.
*/
CnpjGeneratorOptions.DEFAULT_TYPE = 'alphanumeric';
return CnpjGeneratorOptions;
}();
Object.freeze(CnpjGeneratorOptions);
/**
* @typedef {import('./exceptions').CnpjGeneratorOptionsTypeError} CnpjGeneratorOptionsTypeError
*
*
* @typedef {import('./exceptions').CnpjGeneratorOptionPrefixInvalidException} CnpjGeneratorOptionPrefixInvalidException
*
*
* @typedef {import('./exceptions').CnpjGeneratorOptionTypeInvalidException} CnpjGeneratorOptionTypeInvalidException
*/
var CNPJ_DOT_KEY = '.';
var CNPJ_SLASH_KEY = '/';
var CNPJ_DASH_KEY = '-';
/**
* Generator for CNPJ (Cadastro Nacional da Pessoa Jurídica) identifiers. Builds
* valid 14-character CNPJ values by combining an optional prefix with a
* randomly generated sequence and computed check digits. Options control
* prefix, character type (numeric, alphabetic, or alphanumeric), and whether
* the result is formatted (`00.000.000/0000-00`).
*/
var CnpjGenerator = /** @class */function () {
/**
* Creates a new `CnpjGenerator` with optional default options.
*
* Default options apply to every call to `generate` unless overridden by the
* per-call `options` argument. Options control prefix, character type, and
* whether the generated CNPJ is formatted.
*
* When `defaultOptions` is a `CnpjGeneratorOptions` 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 `CnpjGeneratorOptions` instance is created from it.
*
* @throws {CnpjGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of characters.
* @throws {CnpjGeneratorOptionTypeInvalidException} If the `type` option is
* not one of the allowed values.
*/
function CnpjGenerator(defaultOptions) {
this._options = defaultOptions instanceof CnpjGeneratorOptions ? defaultOptions : new CnpjGeneratorOptions(defaultOptions);
}
Object.defineProperty(CnpjGenerator.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 `CnpjGeneratorOptions`) affects future `generate` calls that
* do not pass `options`.
*/
get: function get() {
return this._options;
},
enumerable: false,
configurable: true
});
/**
* Generates a valid CNPJ value.
*
* Builds a 14-character CNPJ from the configured prefix (if any), a random
* sequence of the configured character type, and two computed check digits.
* If formatting is enabled, the result is returned as `00.000.000/0000-00`.
*
* Per-call `options` are merged over the instance default options for this
* call only; the instance defaults are unchanged.
*
* @throws {CnpjGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of characters.
* @throws {CnpjGeneratorOptionTypeInvalidException} If the `type` option is
* not one of the allowed values.
*/
CnpjGenerator.prototype.generate = function (options) {
var actualOptions = options ? new CnpjGeneratorOptions(this._options, options) : this._options;
var charactersToGenerate = CNPJ_PREFIX_MAX_LENGTH - actualOptions.prefix.length;
var generatedCharacters = generateRandomSequence(charactersToGenerate, actualOptions.type);
var generatedCnpj = actualOptions.prefix + generatedCharacters;
try {
var cnpjCheckDigits = new CnpjCheckDigits(generatedCnpj);
generatedCnpj = cnpjCheckDigits.cnpj;
} catch (error) {
if (error instanceof CnpjCheckDigitsException) {
return this.generate(options);
}
throw error;
}
if (actualOptions.format) {
generatedCnpj = generatedCnpj.slice(0, 2) + CNPJ_DOT_KEY + generatedCnpj.slice(2, 5) + CNPJ_DOT_KEY + generatedCnpj.slice(5, 8) + CNPJ_SLASH_KEY + generatedCnpj.slice(8, 12) + CNPJ_DASH_KEY + generatedCnpj.slice(12, 14);
}
return generatedCnpj;
};
return CnpjGenerator;
}();
Object.freeze(CnpjGenerator);
/**
* Helper function to simplify the usage of the {@link CnpjGenerator} class.
*
* If no options are provided, it generates a 14-character unformatted
* alphanumeric CNPJ (e.g., `AB123CDE000155`). using default settings. If
* options are provided, they control prefix, type, and whether the result is
* formatted.
*
* @throws {CnpjGeneratorOptionsTypeError} If any option has an invalid type.
* @throws {CnpjGeneratorOptionPrefixInvalidException} If the `prefix` option
* contains an invalid combination of characters.
* @throws {CnpjGeneratorOptionTypeInvalidException} If the `type` option is not
* one of the allowed values.
* @see CnpjGenerator for detailed option descriptions.
*/
function cnpjGen$1(options) {
return new CnpjGenerator(options).generate();
}
var all = /*#__PURE__*/Object.freeze({
__proto__: null,
CNPJ_LENGTH: CNPJ_LENGTH,
CNPJ_PREFIX_MAX_LENGTH: CNPJ_PREFIX_MAX_LENGTH,
CnpjGenerator: CnpjGenerator,
CnpjGeneratorException: CnpjGeneratorException,
CnpjGeneratorOptionPrefixInvalidException: CnpjGeneratorOptionPrefixInvalidException,
CnpjGeneratorOptionTypeInvalidException: CnpjGeneratorOptionTypeInvalidException,
CnpjGeneratorOptions: CnpjGeneratorOptions,
CnpjGeneratorOptionsTypeError: CnpjGeneratorOptionsTypeError,
CnpjGeneratorTypeError: CnpjGeneratorTypeError,
cnpjGen: cnpjGen$1,
default: cnpjGen$1
});
var baseCnpjGen = cnpjGen$1,
rest = __rest(all, ["default", "cnpjGen"]);
var cnpjGen = function cnpjGen() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return baseCnpjGen.apply(void 0, args);
};
var index_cjs = Object.assign(cnpjGen, rest);
return index_cjs;
}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY25wai1nZW4uanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8uYnVuL0Byb2xsdXArcGx1Z2luLXR5cGVzY3JpcHRAMTIuMy4wK2Q2NDk2Nzk4ZDE4YTkwODkvbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIi4uLy4uL3V0aWxzL2Rpc3QvaW5kZXgubWpzIiwiLi4vLi4vY25wai1kdi9kaXN0L2luZGV4Lm1qcyIsIi4uL3NyYy9leGNlcHRpb25zLnRzIiwiLi4vc3JjL2NucGotZ2VuZXJhdG9yLW9wdGlvbnMudHMiLCIuLi9zcmMvY25wai1nZW5lcmF0b3IudHMiLCIuLi9zcmMvY25wai1nZW4udHMiLCIuLi9zcmMvaW5kZXguY2pzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wsIEl0ZXJhdG9yICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lk