trigonometry-equations
Version:
Trigonometry rules to solve equations for angles and sides
242 lines (205 loc) • 25.9 kB
JavaScript
;
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