UNPKG

trigonometry-equations

Version:

Trigonometry rules to solve equations for angles and sides

242 lines (205 loc) 25.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports.cosineRule = cosineRule; exports.sineRule = sineRule; exports.angleRule = angleRule; exports.ambiguousCaseRule = ambiguousCaseRule; var _degreesRadians = require('degrees-radians'); var _degreesRadians2 = _interopRequireDefault(_degreesRadians); var _radiansDegrees = require('radians-degrees'); var _radiansDegrees2 = _interopRequireDefault(_radiansDegrees); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * Uses the law of cosines to solve a partially complete triangle * @param {object} angles - angle indices and numerical values * @param {object} sides - side indices and numerical values * @param {object} findAngle - angle to calculate when there are three sides * @return {object} error key with the issue description as the value * @return {object} input with additional key-values pairs of solutions */ function cosineRule() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$angles = _ref.angles, angles = _ref$angles === undefined ? {} : _ref$angles, _ref$sides = _ref.sides, sides = _ref$sides === undefined ? {} : _ref$sides, error = _ref.error; var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, findAngle = _ref2.findAngle; if (error) { return { error: error }; } if (Object.keys(sides).length < 2) { return { error: 'cosineRule expects at least 2 sides' }; } var doubleSides = function doubleSides(keys) { return keys.reduce(function (sum, key) { return sum * sides[key]; }, 1) * 2; }; var squareSides = function squareSides(keys) { return keys.reduce(function (sum, key) { return sum + Math.pow(sides[key], 2); }, 0); }; var result = void 0; var segment = void 0; var segmentName = void 0; var segmentNumber = void 0; if (Object.keys(sides).length === 3) { var firstAngle = [0, 1, 2].findIndex(function (e) { return !(e in angles); }); var angle = findAngle || firstAngle; var twoSides = [0, 1, 2].filter(function (e) { return e !== Number(angle); }); var lastSide = Math.pow(sides[angle], 2); var firstSides = squareSides(twoSides); result = (0, _radiansDegrees2.default)(Math.acos((firstSides - lastSide) / doubleSides(twoSides))); segment = angles; segmentName = 'angles'; segmentNumber = Number(angle); } else if (Object.keys(sides).length === 2 && Object.keys(angles).length === 1) { var angleNumber = Object.keys(angles); var knownAngle = angles[angleNumber]; var knownSides = Object.keys(sides); var partialResult = doubleSides(knownSides) * Math.cos((0, _degreesRadians2.default)(knownAngle)); result = Math.sqrt(squareSides(knownSides) - partialResult); segment = sides; segmentName = 'sides'; segmentNumber = angleNumber; } else { return { error: 'cosineRule expected 3 sides or 2 sides and 1 angle' }; } var resultPair = _defineProperty({}, segmentNumber, result); var solvedSegment = _defineProperty({}, segmentName, _extends({}, segment, resultPair)); return _extends({ angles: angles, sides: sides }, solvedSegment); } /** * Uses the law of sines to solve a partially complete triangle * @param {object} angles - angle indices and numerical values * @param {object} sides - side indices and numerical values * @return {object} error key with the issue description as the value * @return {object} input with additional key-values pairs of solutions */ function sineRule() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref3$angles = _ref3.angles, angles = _ref3$angles === undefined ? {} : _ref3$angles, _ref3$sides = _ref3.sides, sides = _ref3$sides === undefined ? {} : _ref3$sides, error = _ref3.error; if (error) { return { error: error }; } var match = function match(e) { return e in angles && e in sides; }; var partialMatch = function partialMatch(e) { return (e in angles || e in sides) && !match(e); }; var firstNonPair = [0, 1, 2].find(partialMatch); var firstPair = [0, 1, 2].find(match); if (firstNonPair === undefined) { return { error: 'sineRule expected an unpaired angle or side' }; } var knownAngle = angles[firstPair]; var knownSide = sides[firstPair]; var unPairedAngle = angles[firstNonPair]; var unPairedSide = sides[firstNonPair]; var result = void 0; var segment = void 0; var segmentName = void 0; if (unPairedAngle) { result = knownSide * Math.sin((0, _degreesRadians2.default)(unPairedAngle)) / Math.sin((0, _degreesRadians2.default)(knownAngle)); segment = sides; segmentName = 'sides'; } else if (knownAngle !== undefined) { result = (0, _radiansDegrees2.default)(Math.asin(Math.sin((0, _degreesRadians2.default)(knownAngle)) / knownSide * unPairedSide)); segment = angles; segmentName = 'angles'; } else { return { error: 'sineRule expected an unpaired angle or side' }; } var resultPair = _defineProperty({}, firstNonPair, result); var solvedSegment = _defineProperty({}, segmentName, _extends({}, segment, resultPair)); return _extends({ angles: angles, sides: sides }, solvedSegment); } /** * Uses the angle sum invariant to solve for the last angle in a triangle * @param {object} angles - angle indices and numerical values * @param {object} sides - side indices and numerical values * @return {object} error key with the issue description as the value * @return {object} input with additional key-values pairs of solutions */ function angleRule() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref4$angles = _ref4.angles, angles = _ref4$angles === undefined ? {} : _ref4$angles, _ref4$sides = _ref4.sides, sides = _ref4$sides === undefined ? {} : _ref4$sides, error = _ref4.error; if (error) { return { error: error }; } if (Object.keys(angles).length !== 2) { return { error: 'angleRule expects 2 angles' }; } var knownAngles = Object.keys(angles).map(function (e) { return Number(e); }); var unknownAngle = [0, 1, 2].filter(function (e) { return !knownAngles.includes(e); }); var unknownValue = 180 - knownAngles.reduce(function (sum, key) { return sum + angles[key]; }, 0); var lastAngle = _defineProperty({}, unknownAngle, unknownValue); var allAngles = { angles: _extends({}, angles, lastAngle) }; return _extends({ sides: sides }, allAngles); } /** * Verifies and solves an alternate solution to the given triangle * @param {object} angles - angle indices and numerical values * @param {object} sides - side indices and numerical values * @return {object} error key with the issue description as the value * @return {object} input with additional key-values pairs of solutions */ function ambiguousCaseRule() { var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref5$angles = _ref5.angles, angles = _ref5$angles === undefined ? {} : _ref5$angles, _ref5$sides = _ref5.sides, sides = _ref5$sides === undefined ? {} : _ref5$sides, error = _ref5.error; if (error) { return { error: error }; } if (Object.keys(angles).length !== 1 || Object.keys(sides).length !== 2) { return { error: 'ambiguousCaseRule expects 1 angle and 2 sides' }; } var angleKey = Object.keys(angles).join(); var paired = angleKey in sides; var findAngle = paired ? sineRule({ angles: angles, sides: sides }) : { angles: angles, sides: sides }; var solvedAngle = Object.keys(findAngle.angles).find(function (e) { return !(e in angles); }); var otherAngle = 180 - findAngle.angles[solvedAngle]; var acuteAngle = angles[angleKey] < 90; var otherSide = Object.keys(sides).find(function (e) { return e !== angleKey; }); var smallSide = sides[angleKey] < sides[otherSide]; var validAngle = otherAngle < 180; if (!acuteAngle || !paired || !smallSide || !validAngle) return {}; var alternateAngles = _extends({}, angles, _defineProperty({}, solvedAngle, otherAngle)); var alternate = _extends({ angles: alternateAngles }, { sides: sides }); var ambiguous = sineRule(angleRule(alternate)); return { ambiguous: ambiguous }; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJjb3NpbmVSdWxlIiwic2luZVJ1bGUiLCJhbmdsZVJ1bGUiLCJhbWJpZ3VvdXNDYXNlUnVsZSIsImFuZ2xlcyIsInNpZGVzIiwiZXJyb3IiLCJmaW5kQW5nbGUiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiZG91YmxlU2lkZXMiLCJyZWR1Y2UiLCJzdW0iLCJrZXkiLCJzcXVhcmVTaWRlcyIsInJlc3VsdCIsInNlZ21lbnQiLCJzZWdtZW50TmFtZSIsInNlZ21lbnROdW1iZXIiLCJmaXJzdEFuZ2xlIiwiZmluZEluZGV4IiwiZSIsImFuZ2xlIiwidHdvU2lkZXMiLCJmaWx0ZXIiLCJOdW1iZXIiLCJsYXN0U2lkZSIsImZpcnN0U2lkZXMiLCJNYXRoIiwiYWNvcyIsImFuZ2xlTnVtYmVyIiwia25vd25BbmdsZSIsImtub3duU2lkZXMiLCJwYXJ0aWFsUmVzdWx0IiwiY29zIiwic3FydCIsInJlc3VsdFBhaXIiLCJzb2x2ZWRTZWdtZW50IiwibWF0Y2giLCJwYXJ0aWFsTWF0Y2giLCJmaXJzdE5vblBhaXIiLCJmaW5kIiwiZmlyc3RQYWlyIiwidW5kZWZpbmVkIiwia25vd25TaWRlIiwidW5QYWlyZWRBbmdsZSIsInVuUGFpcmVkU2lkZSIsInNpbiIsImFzaW4iLCJrbm93bkFuZ2xlcyIsIm1hcCIsInVua25vd25BbmdsZSIsImluY2x1ZGVzIiwidW5rbm93blZhbHVlIiwibGFzdEFuZ2xlIiwiYWxsQW5nbGVzIiwiYW5nbGVLZXkiLCJqb2luIiwicGFpcmVkIiwic29sdmVkQW5nbGUiLCJvdGhlckFuZ2xlIiwiYWN1dGVBbmdsZSIsIm90aGVyU2lkZSIsInNtYWxsU2lkZSIsInZhbGlkQW5nbGUiLCJhbHRlcm5hdGVBbmdsZXMiLCJhbHRlcm5hdGUiLCJhbWJpZ3VvdXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O1FBV2dCQSxVLEdBQUFBLFU7UUFvREFDLFEsR0FBQUEsUTtRQStDQUMsUyxHQUFBQSxTO1FB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QUF1QjlELE1BQXZCLHNCQUFxQ3dELFdBQXJDLEVBQW1EQyxVQUFuRCxFQUFOO0FBQ0EsTUFBTU0scUJBQWlCLEVBQUUvRCxRQUFROEQsZUFBVixFQUFqQixFQUFpRCxFQUFFN0QsWUFBRixFQUFqRCxDQUFOO0FBQ0EsTUFBTStELFlBQVluRSxTQUFTQyxVQUFVaUUsU0FBVixDQUFULENBQWxCOztBQUVBLFNBQU8sRUFBRUMsb0JBQUYsRUFBUDtBQUNEIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJhZGlhbnMgZnJvbSAnZGVncmVlcy1yYWRpYW5zJ1xuaW1wb3J0IGRlZ3JlZXMgZnJvbSAncmFkaWFucy1kZWdyZWVzJ1xuXG4vKipcbiogVXNlcyB0aGUgbGF3IG9mIGNvc2luZXMgdG8gc29sdmUgYSBwYXJ0aWFsbHkgY29tcGxldGUgdHJpYW5nbGVcbiogQHBhcmFtIHtvYmplY3R9IGFuZ2xlcyAtIGFuZ2xlIGluZGljZXMgYW5kIG51bWVyaWNhbCB2YWx1ZXNcbiogQHBhcmFtIHtvYmplY3R9IHNpZGVzIC0gc2lkZSBpbmRpY2VzIGFuZCBudW1lcmljYWwgdmFsdWVzXG4qIEBwYXJhbSB7b2JqZWN0fSBmaW5kQW5nbGUgLSBhbmdsZSB0byBjYWxjdWxhdGUgd2hlbiB0aGVyZSBhcmUgdGhyZWUgc2lkZXNcbiogQHJldHVybiB7b2JqZWN0fSBlcnJvciBrZXkgd2l0aCB0aGUgaXNzdWUgZGVzY3JpcHRpb24gYXMgdGhlIHZhbHVlXG4qIEByZXR1cm4ge29iamVjdH0gaW5wdXQgd2l0aCBhZGRpdGlvbmFsIGtleS12YWx1ZXMgcGFpcnMgb2Ygc29sdXRpb25zXG4qL1xuZXhwb3J0IGZ1bmN0aW9uIGNvc2luZVJ1bGUgKHsgYW5nbGVzID0ge30sIHNpZGVzID0ge30sIGVycm9yIH0gPSB7fSwgeyBmaW5kQW5nbGUgfSA9IHt9KSB7XG4gIGlmIChlcnJvcikge1xuICAgIHJldHVybiB7IGVycm9yIH1cbiAgfVxuXG4gIGlmIChPYmplY3Qua2V5cyhzaWRlcykubGVuZ3RoIDwgMikge1xuICAgIHJldHVybiB7IGVycm9yOiAnY29zaW5lUnVsZSBleHBlY3RzIGF0IGxlYXN0IDIgc2lkZXMnIH1cbiAgfVxuXG4gIGNvbnN0IGRvdWJsZVNpZGVzID0ga2V5cyA9PiBrZXlzLnJlZHVjZSgoc3VtLCBrZXkpID0+IHN1bSAqIHNpZGVzW2tleV0sIDEpICogMlxuICBjb25zdCBzcXVhcmVTaWRlcyA9IGtleXMgPT4ga2V5cy5yZWR1Y2UoKHN1bSwga2V5KSA9PiBzdW0gKyBzaWRlc1trZXldICoqIDIsIDApXG4gIGxldCByZXN1bHRcbiAgbGV0IHNlZ21lbnRcbiAgbGV0IHNlZ21lbnROYW1lXG4gIGxldCBzZWdtZW50TnVtYmVyXG5cbiAgaWYgKE9iamVjdC5rZXlzKHNpZGVzKS5sZW5ndGggPT09IDMpIHtcbiAgICBjb25zdCBmaXJzdEFuZ2xlID0gWzAsIDEsIDJdLmZpbmRJbmRleChlID0+ICEoZSBpbiBhbmdsZXMpKVxuICAgIGNvbnN0IGFuZ2xlID0gZmluZEFuZ2xlIHx8IGZpcnN0QW5nbGVcbiAgICBjb25zdCB0d29TaWRlcyA9IFswLCAxLCAyXS5maWx0ZXIoZSA9PiBlICE9PSBOdW1iZXIoYW5nbGUpKVxuICAgIGNvbnN0IGxhc3RTaWRlID0gc2lkZXNbYW5nbGVdICoqIDJcbiAgICBjb25zdCBmaXJzdFNpZGVzID0gc3F1YXJlU2lkZXModHdvU2lkZXMpXG4gICAgcmVzdWx0ID0gZGVncmVlcyhNYXRoLmFjb3MoKGZpcnN0U2lkZXMgLSBsYXN0U2lkZSkgLyBkb3VibGVTaWRlcyh0d29TaWRlcykpKVxuICAgIHNlZ21lbnQgPSBhbmdsZXNcbiAgICBzZWdtZW50TmFtZSA9ICdhbmdsZXMnXG4gICAgc2VnbWVudE51bWJlciA9IE51bWJlcihhbmdsZSlcbiAgfSBlbHNlIGlmIChPYmplY3Qua2V5cyhzaWRlcykubGVuZ3RoID09PSAyICYmIE9iamVjdC5rZXlzKGFuZ2xlcykubGVuZ3RoID09PSAxKSB7XG4gICAgY29uc3QgYW5nbGVOdW1iZXIgPSBPYmplY3Qua2V5cyhhbmdsZXMpXG4gICAgY29uc3Qga25vd25BbmdsZSA9IGFuZ2xlc1thbmdsZU51bWJlcl1cbiAgICBjb25zdCBrbm93blNpZGVzID0gT2JqZWN0LmtleXMoc2lkZXMpXG4gICAgY29uc3QgcGFydGlhbFJlc3VsdCA9IGRvdWJsZVNpZGVzKGtub3duU2lkZXMpICogTWF0aC5jb3MocmFkaWFucyhrbm93bkFuZ2xlKSlcbiAgICByZXN1bHQgPSBNYXRoLnNxcnQoc3F1YXJlU2lkZXMoa25vd25TaWRlcykgLSBwYXJ0aWFsUmVzdWx0KVxuICAgIHNlZ21lbnQgPSBzaWRlc1xuICAgIHNlZ21lbnROYW1lID0gJ3NpZGVzJ1xuICAgIHNlZ21lbnROdW1iZXIgPSBhbmdsZU51bWJlclxuICB9IGVsc2Uge1xuICAgIHJldHVybiB7IGVycm9yOiAnY29zaW5lUnVsZSBleHBlY3RlZCAzIHNpZGVzIG9yIDIgc2lkZXMgYW5kIDEgYW5nbGUnIH1cbiAgfVxuXG4gIGNvbnN0IHJlc3VsdFBhaXIgPSB7IFtzZWdtZW50TnVtYmVyXTogcmVzdWx0IH1cbiAgY29uc3Qgc29sdmVkU2VnbWVudCA9IHsgW3NlZ21lbnROYW1lXTogeyAuLi5zZWdtZW50LCAuLi5yZXN1bHRQYWlyIH0gfVxuXG4gIHJldHVybiB7IC4uLnsgYW5nbGVzLCBzaWRlcyB9LCAuLi5zb2x2ZWRTZWdtZW50IH1cbn1cblxuLyoqXG4qIFVzZXMgdGhlIGxhdyBvZiBzaW5lcyB0byBzb2x2ZSBhIHBhcnRpYWxseSBjb21wbGV0ZSB0cmlhbmdsZVxuKiBAcGFyYW0ge29iamVjdH0gYW5nbGVzIC0gYW5nbGUgaW5kaWNlcyBhbmQgbnVtZXJpY2FsIHZhbHVlc1xuKiBAcGFyYW0ge29iamVjdH0gc2lkZXMgLSBzaWRlIGluZGljZXMgYW5kIG51bWVyaWNhbCB2YWx1ZXNcbiogQHJldHVybiB7b2JqZWN0fSBlcnJvciBrZXkgd2l0aCB0aGUgaXNzdWUgZGVzY3JpcHRpb24gYXMgdGhlIHZhbHVlXG4qIEByZXR1cm4ge29iamVjdH0gaW5wdXQgd2l0aCBhZGRpdGlvbmFsIGtleS12YWx1ZXMgcGFpcnMgb2Ygc29sdXRpb25zXG4qL1xuZXhwb3J0IGZ1bmN0aW9uIHNpbmVSdWxlICh7IGFuZ2xlcyA9IHt9LCBzaWRlcyA9IHt9LCBlcnJvciB9ID0ge30pIHtcbiAgaWYgKGVycm9yKSB7XG4gICAgcmV0dXJuIHsgZXJyb3IgfVxuICB9XG5cbiAgY29uc3QgbWF0Y2ggPSBlID0+IGUgaW4gYW5nbGVzICYmIGUgaW4gc2lkZXNcbiAgY29uc3QgcGFydGlhbE1hdGNoID0gZSA9PiAoZSBpbiBhbmdsZXMgfHwgZSBpbiBzaWRlcykgJiYgIW1hdGNoKGUpXG4gIGNvbnN0IGZpcnN0Tm9uUGFpciA9IFswLCAxLCAyXS5maW5kKHBhcnRpYWxNYXRjaClcbiAgY29uc3QgZmlyc3RQYWlyID0gWzAsIDEsIDJdLmZpbmQobWF0Y2gpXG5cbiAgaWYgKGZpcnN0Tm9uUGFpciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHsgZXJyb3I6ICdzaW5lUnVsZSBleHBlY3RlZCBhbiB1bnBhaXJlZCBhbmdsZSBvciBzaWRlJyB9XG4gIH1cblxuICBjb25zdCBrbm93bkFuZ2xlID0gYW5nbGVzW2ZpcnN0UGFpcl1cbiAgY29uc3Qga25vd25TaWRlID0gc2lkZXNbZmlyc3RQYWlyXVxuICBjb25zdCB1blBhaXJlZEFuZ2xlID0gYW5nbGVzW2ZpcnN0Tm9uUGFpcl1cbiAgY29uc3QgdW5QYWlyZWRTaWRlID0gc2lkZXNbZmlyc3ROb25QYWlyXVxuICBsZXQgcmVzdWx0XG4gIGxldCBzZWdtZW50XG4gIGxldCBzZWdtZW50TmFtZVxuXG4gIGlmICh1blBhaXJlZEFuZ2xlKSB7XG4gICAgcmVzdWx0ID0ga25vd25TaWRlICogTWF0aC5zaW4ocmFkaWFucyh1blBhaXJlZEFuZ2xlKSkgLyBNYXRoLnNpbihyYWRpYW5zKGtub3duQW5nbGUpKVxuICAgIHNlZ21lbnQgPSBzaWRlc1xuICAgIHNlZ21lbnROYW1lID0gJ3NpZGVzJ1xuICB9IGVsc2UgaWYgKGtub3duQW5nbGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHJlc3VsdCA9IGRlZ3JlZXMoTWF0aC5hc2luKE1hdGguc2luKHJhZGlhbnMoa25vd25BbmdsZSkpIC8ga25vd25TaWRlICogdW5QYWlyZWRTaWRlKSlcbiAgICBzZWdtZW50ID0gYW5nbGVzXG4gICAgc2VnbWVudE5hbWUgPSAnYW5nbGVzJ1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB7IGVycm9yOiAnc2luZVJ1bGUgZXhwZWN0ZWQgYW4gdW5wYWlyZWQgYW5nbGUgb3Igc2lkZScgfVxuICB9XG5cbiAgY29uc3QgcmVzdWx0UGFpciA9IHsgW2ZpcnN0Tm9uUGFpcl06IHJlc3VsdCB9XG4gIGNvbnN0IHNvbHZlZFNlZ21lbnQgPSB7IFtzZWdtZW50TmFtZV06IHsgLi4uc2VnbWVudCwgLi4ucmVzdWx0UGFpciB9IH1cblxuICByZXR1cm4geyAuLi57IGFuZ2xlcywgc2lkZXMgfSwgLi4uc29sdmVkU2VnbWVudCB9XG59XG5cbi8qKlxuKiBVc2VzIHRoZSBhbmdsZSBzdW0gaW52YXJpYW50IHRvIHNvbHZlIGZvciB0aGUgbGFzdCBhbmdsZSBpbiBhIHRyaWFuZ2xlXG4qIEBwYXJhbSB7b2JqZWN0fSBhbmdsZXMgLSBhbmdsZSBpbmRpY2VzIGFuZCBudW1lcmljYWwgdmFsdWVzXG4qIEBwYXJhbSB7b2JqZWN0fSBzaWRlcyAtIHNpZGUgaW5kaWNlcyBhbmQgbnVtZXJpY2FsIHZhbHVlc1xuKiBAcmV0dXJuIHtvYmplY3R9IGVycm9yIGtleSB3aXRoIHRoZSBpc3N1ZSBkZXNjcmlwdGlvbiBhcyB0aGUgdmFsdWVcbiogQHJldHVybiB7b2JqZWN0fSBpbnB1dCB3aXRoIGFkZGl0aW9uYWwga2V5LXZhbHVlcyBwYWlycyBvZiBzb2x1dGlvbnNcbiovXG5leHBvcnQgZnVuY3Rpb24gYW5nbGVSdWxlICh7IGFuZ2xlcyA9IHt9LCBzaWRlcyA9IHt9LCBlcnJvciB9ID0ge30pIHtcbiAgaWYgKGVycm9yKSB7XG4gICAgcmV0dXJuIHsgZXJyb3IgfVxuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKGFuZ2xlcykubGVuZ3RoICE9PSAyKSB7XG4gICAgcmV0dXJuIHsgZXJyb3I6ICdhbmdsZVJ1bGUgZXhwZWN0cyAyIGFuZ2xlcycgfVxuICB9XG5cbiAgY29uc3Qga25vd25BbmdsZXMgPSBPYmplY3Qua2V5cyhhbmdsZXMpLm1hcChlID0+IE51bWJlcihlKSlcbiAgY29uc3QgdW5rbm93bkFuZ2xlID0gWzAsIDEsIDJdLmZpbHRlcihlID0+ICFrbm93bkFuZ2xlcy5pbmNsdWRlcyhlKSlcbiAgY29uc3QgdW5rbm93blZhbHVlID0gMTgwIC0ga25vd25BbmdsZXMucmVkdWNlKChzdW0sIGtleSkgPT4gc3VtICsgYW5nbGVzW2tleV0sIDApXG4gIGNvbnN0IGxhc3RBbmdsZSA9IHsgW3Vua25vd25BbmdsZV06IHVua25vd25WYWx1ZSB9XG4gIGNvbnN0IGFsbEFuZ2xlcyA9IHsgYW5nbGVzOiB7IC4uLmFuZ2xlcywgLi4ubGFzdEFuZ2xlIH0gfVxuXG4gIHJldHVybiB7IC4uLnsgc2lkZXMgfSwgLi4uYWxsQW5nbGVzIH1cbn1cblxuLyoqXG4qIFZlcmlmaWVzIGFuZCBzb2x2ZXMgYW4gYWx0ZXJuYXRlIHNvbHV0aW9uIHRvIHRoZSBnaXZlbiB0cmlhbmdsZVxuKiBAcGFyYW0ge29iamVjdH0gYW5nbGVzIC0gYW5nbGUgaW5kaWNlcyBhbmQgbnVtZXJpY2FsIHZhbHVlc1xuKiBAcGFyYW0ge29iamVjdH0gc2lkZXMgLSBzaWRlIGluZGljZXMgYW5kIG51bWVyaWNhbCB2YWx1ZXNcbiogQHJldHVybiB7b2JqZWN0fSBlcnJvciBrZXkgd2l0aCB0aGUgaXNzdWUgZGVzY3JpcHRpb24gYXMgdGhlIHZhbHVlXG4qIEByZXR1cm4ge29iamVjdH0gaW5wdXQgd2l0aCBhZGRpdGlvbmFsIGtleS12YWx1ZXMgcGFpcnMgb2Ygc29sdXRpb25zXG4qL1xuZXhwb3J0IGZ1bmN0aW9uIGFtYmlndW91c0Nhc2VSdWxlICh7IGFuZ2xlcyA9IHt9LCBzaWRlcyA9IHt9LCBlcnJvciB9ID0ge30pIHtcbiAgaWYgKGVycm9yKSB7XG4gICAgcmV0dXJuIHsgZXJyb3IgfVxuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKGFuZ2xlcykubGVuZ3RoICE9PSAxIHx8IE9iamVjdC5rZXlzKHNpZGVzKS5sZW5ndGggIT09IDIpIHtcbiAgICByZXR1cm4geyBlcnJvcjogJ2FtYmlndW91c0Nhc2VSdWxlIGV4cGVjdHMgMSBhbmdsZSBhbmQgMiBzaWRlcycgfVxuICB9XG5cbiAgY29uc3QgYW5nbGVLZXkgPSBPYmplY3Qua2V5cyhhbmdsZXMpLmpvaW4oKVxuICBjb25zdCBwYWlyZWQgPSBhbmdsZUtleSBpbiBzaWRlc1xuICBjb25zdCBmaW5kQW5nbGUgPSBwYWlyZWQgPyBzaW5lUnVsZSh7IGFuZ2xlcywgc2lkZXMgfSkgOiB7IGFuZ2xlcywgc2lkZXMgfVxuICBjb25zdCBzb2x2ZWRBbmdsZSA9IE9iamVjdC5rZXlzKGZpbmRBbmdsZS5hbmdsZXMpLmZpbmQoZSA9PiAhKGUgaW4gYW5nbGVzKSlcbiAgY29uc3Qgb3RoZXJBbmdsZSA9IDE4MCAtIGZpbmRBbmdsZS5hbmdsZXNbc29sdmVkQW5nbGVdXG4gIGNvbnN0IGFjdXRlQW5nbGUgPSBhbmdsZXNbYW5nbGVLZXldIDwgOTBcbiAgY29uc3Qgb3RoZXJTaWRlID0gT2JqZWN0LmtleXMoc2lkZXMpLmZpbmQoZSA9PiBlICE9PSBhbmdsZUtleSlcbiAgY29uc3Qgc21hbGxTaWRlID0gc2lkZXNbYW5nbGVLZXldIDwgc2lkZXNbb3RoZXJTaWRlXVxuICBjb25zdCB2YWxpZEFuZ2xlID0gb3RoZXJBbmdsZSA8IDE4MFxuXG4gIGlmICghYWN1dGVBbmdsZSB8fCAhcGFpcmVkIHx8ICFzbWFsbFNpZGUgfHwgIXZhbGlkQW5nbGUpIHJldHVybiB7fVxuXG4gIGNvbnN0IGFsdGVybmF0ZUFuZ2xlcyA9IHsgLi4uYW5nbGVzLCAuLi57IFtzb2x2ZWRBbmdsZV06IG90aGVyQW5nbGUgfSB9XG4gIGNvbnN0IGFsdGVybmF0ZSA9IHsgLi4ueyBhbmdsZXM6IGFsdGVybmF0ZUFuZ2xlcyB9LCAuLi57IHNpZGVzIH0gfVxuICBjb25zdCBhbWJpZ3VvdXMgPSBzaW5lUnVsZShhbmdsZVJ1bGUoYWx0ZXJuYXRlKSlcblxuICByZXR1cm4geyBhbWJpZ3VvdXMgfVxufVxuIl19