UNPKG

dnd-travel-calculator

Version:
146 lines (124 loc) 16.4 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.TravelCalculator = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ module.exports = require("./travel-calculator"); },{"./travel-calculator":2}],2:[function(require,module,exports){ var config = (function (props) { var self = {}; var _getByPropPath = function (o, s) { // http://stackoverflow.com/a/6491621 s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties s = s.replace(/^\./, ''); // strip a leading dot var a = s.split('.'); for (var i = 0, n = a.length; i < n; ++i) { var k = a[i]; if (k in o) { o = o[k]; } else { return; } } return o; }; self.get = function (a) { return _getByPropPath(props, a); }; return self; })({"Client":{"5e":{"land":{"fast":{"milesPerDay":30,"hoursPerDay":8},"normal":{"milesPerDay":24,"hoursPerDay":8},"slow":{"milesPerDay":18,"hoursPerDay":8}},"sea":{"galley":{"milesPerDay":96,"hoursPerDay":24},"keelboat":{"milesPerDay":72,"hoursPerDay":24},"longship":{"milesPerDay":120,"hoursPerDay":24},"rowboat":{"milesPerDay":24,"hoursPerDay":8},"sailingShip":{"milesPerDay":120,"hoursPerDay":24},"warship":{"milesPerDay":96,"hoursPerDay":24}}}}});; var TravelCalculator = (function () { /** * @param normalTerrainMiles [int] The total miles in normal terrain * @param difficultTerrainMiles [int] The total miles in difficult terrain * @param travelPace [string] The travel pace used (normal|slow|fast) * @return [map] An associative array that represents a time object: { days: <int>, hours: <int>, minutes: <int>} */ var calculateTravelTimeByLand = function(normalTerrainMiles, difficultTerrainMiles, travelPace) { //0. Check the pace if (!(travelPace == 'fast' || travelPace == 'slow' || travelPace == 'normal')) { travelPace = "normal"; } //1. Independently get the travel times for normal and diff terrains var normalResult = calculate(normalTerrainMiles, false, "land", travelPace); var difficultResult = calculate(difficultTerrainMiles, true, "land", travelPace); //2. Add the results together var mergedResult = { days : normalResult.days + difficultResult.days, hours : normalResult.hours + difficultResult.hours, minutes : normalResult.minutes + difficultResult.minutes }; //3. Make human readable upConvertTime(mergedResult, "land", travelPace); return mergedResult; }; var calculateTravelTimeBySea = function(totalMiles, boatType) { //0. Check the boat type //1. Get the travel time var result = calculate(totalMiles, false, "sea", boatType); //2. Upconvert upConvertTime(result, "sea", boatType); return result; }; /** * @param totalMiles [int] The total miles to travel * @param isDifficult [boolean] Whether the travel is over difficult terrain * @param travelType [String] Possible values: "land", "sea" * @para travelPace [string] Possible values: (fast|normal|slow|galley|keelboat|longship|rowboat|sailingShip|warship) */ var calculate = function(totalMiles, isDifficult, travelType, travelPace) { var configPrefix = "Client.5e." + travelType + "." + travelPace; var time = { days: 0, hours: 0, minutes: 0 }; if (!isInt(totalMiles) || totalMiles <= 0) { return time; } var milesPerDay = config.get(configPrefix + ".milesPerDay"); if (isDifficult) { milesPerDay /= 2; } var maxHoursTraveledPerDay = config.get(configPrefix + ".hoursPerDay"); var milesPerHour = milesPerDay / maxHoursTraveledPerDay; var minsPerMile = 60 / milesPerHour; var remainingMiles = totalMiles % milesPerDay; //Get the total days the trip takes (rounded down) time.days = Math.floor(totalMiles / milesPerDay); //Get the remaining miles needed to complete the journey on the last day time.hours = Math.floor(remainingMiles / milesPerHour); time.minutes = (remainingMiles % milesPerHour) * minsPerMile; return time; }; /** * Upconverts time from something like * days: 1, hours: 7, minutes: 60 * to * days: 2, hours: 0, minutes: 0 */ var upConvertTime = function(time, travelType, travelPace) { //1. Upconvert minutes to hours by mod-ing the value by 60 since there are 60 minutes in an hour var modMinutes = time.minutes % 60; //Then, add the quotient back to the hours since that represents //how many hours were made from the minutes time.hours += Math.floor(time.minutes / 60); time.minutes = modMinutes; //2. Upconvert hours to days by mod-ing the total hours by the hours traveled in a day var maxHoursTraveledPerDay = config.get("Client.5e." + travelType + "." + travelPace + ".hoursPerDay"); var modHours = time.hours % maxHoursTraveledPerDay; //Then, add the quotient back to the days since that represents //how many days were made from the hours time.days += Math.floor(time.hours / maxHoursTraveledPerDay); time.hours = modHours; //3. The days should be a merged result of extra day made from hours/minutes }; var isInt = function(value) { return !isNaN(value) && parseInt(Number(value)) == value && !isNaN(parseInt(value, 10)); }; return { calculateTravelTimeByLand : calculateTravelTimeByLand, calculateTravelTimeBySea : calculateTravelTimeBySea }; })(); module.exports = TravelCalculator; },{}]},{},[1])(1) }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvaW5kZXguanMiLCJzcmMvdHJhdmVsLWNhbGN1bGF0b3IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL3RyYXZlbC1jYWxjdWxhdG9yXCIpOyIsInZhciBjb25maWcgPSAoZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9nZXRCeVByb3BQYXRoID0gZnVuY3Rpb24gKG8sIHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS82NDkxNjIxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHMucmVwbGFjZSgvXFxbKFxcdyspXFxdL2csICcuJDEnKTsgLy8gY29udmVydCBpbmRleGVzIHRvIHByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcy5yZXBsYWNlKC9eXFwuLywgJycpOyAgICAgICAgICAgLy8gc3RyaXAgYSBsZWFkaW5nIGRvdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhID0gcy5zcGxpdCgnLicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBuID0gYS5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGsgPSBhW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoayBpbiBvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvID0gb1trXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbztcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZ2V0ID0gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2dldEJ5UHJvcFBhdGgocHJvcHMsIGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgICAgICAgICAgICAgICAgIH0pKHtcIkNsaWVudFwiOntcIjVlXCI6e1wibGFuZFwiOntcImZhc3RcIjp7XCJtaWxlc1BlckRheVwiOjMwLFwiaG91cnNQZXJEYXlcIjo4fSxcIm5vcm1hbFwiOntcIm1pbGVzUGVyRGF5XCI6MjQsXCJob3Vyc1BlckRheVwiOjh9LFwic2xvd1wiOntcIm1pbGVzUGVyRGF5XCI6MTgsXCJob3Vyc1BlckRheVwiOjh9fSxcInNlYVwiOntcImdhbGxleVwiOntcIm1pbGVzUGVyRGF5XCI6OTYsXCJob3Vyc1BlckRheVwiOjI0fSxcImtlZWxib2F0XCI6e1wibWlsZXNQZXJEYXlcIjo3MixcImhvdXJzUGVyRGF5XCI6MjR9LFwibG9uZ3NoaXBcIjp7XCJtaWxlc1BlckRheVwiOjEyMCxcImhvdXJzUGVyRGF5XCI6MjR9LFwicm93Ym9hdFwiOntcIm1pbGVzUGVyRGF5XCI6MjQsXCJob3Vyc1BlckRheVwiOjh9LFwic2FpbGluZ1NoaXBcIjp7XCJtaWxlc1BlckRheVwiOjEyMCxcImhvdXJzUGVyRGF5XCI6MjR9LFwid2Fyc2hpcFwiOntcIm1pbGVzUGVyRGF5XCI6OTYsXCJob3Vyc1BlckRheVwiOjI0fX19fX0pOztcblxudmFyIFRyYXZlbENhbGN1bGF0b3IgPSAoZnVuY3Rpb24gKCkge1xuXHQvKipcblx0KiBAcGFyYW0gbm9ybWFsVGVycmFpbk1pbGVzIFtpbnRdIFRoZSB0b3RhbCBtaWxlcyBpbiBub3JtYWwgdGVycmFpblxuXHQqIEBwYXJhbSBkaWZmaWN1bHRUZXJyYWluTWlsZXMgW2ludF0gVGhlIHRvdGFsIG1pbGVzIGluIGRpZmZpY3VsdCB0ZXJyYWluXG5cdCogQHBhcmFtIHRyYXZlbFBhY2UgW3N0cmluZ10gVGhlIHRyYXZlbCBwYWNlIHVzZWQgKG5vcm1hbHxzbG93fGZhc3QpXG5cdCogQHJldHVybiBbbWFwXSBBbiBhc3NvY2lhdGl2ZSBhcnJheSB0aGF0IHJlcHJlc2VudHMgYSB0aW1lIG9iamVjdDpcblx0eyBkYXlzOiA8aW50PiwgaG91cnM6IDxpbnQ+LCBtaW51dGVzOiA8aW50Pn1cblx0Ki9cblx0dmFyIGNhbGN1bGF0ZVRyYXZlbFRpbWVCeUxhbmQgPSBmdW5jdGlvbihub3JtYWxUZXJyYWluTWlsZXMsIGRpZmZpY3VsdFRlcnJhaW5NaWxlcywgdHJhdmVsUGFjZSkge1xuXHRcdC8vMC4gQ2hlY2sgdGhlIHBhY2Vcblx0XHRpZiAoISh0cmF2ZWxQYWNlID09ICdmYXN0JyB8fCB0cmF2ZWxQYWNlID09ICdzbG93JyB8fCB0cmF2ZWxQYWNlID09ICdub3JtYWwnKSkge1xuXHRcdFx0dHJhdmVsUGFjZSA9IFwibm9ybWFsXCI7XG5cdFx0fVxuXG5cdFx0Ly8xLiBJbmRlcGVuZGVudGx5IGdldCB0aGUgdHJhdmVsIHRpbWVzIGZvciBub3JtYWwgYW5kIGRpZmYgdGVycmFpbnNcblx0XHR2YXIgbm9ybWFsUmVzdWx0ID0gY2FsY3VsYXRlKG5vcm1hbFRlcnJhaW5NaWxlcywgZmFsc2UsIFwibGFuZFwiLCB0cmF2ZWxQYWNlKTtcblx0XHR2YXIgZGlmZmljdWx0UmVzdWx0ID0gY2FsY3VsYXRlKGRpZmZpY3VsdFRlcnJhaW5NaWxlcywgdHJ1ZSwgXCJsYW5kXCIsIHRyYXZlbFBhY2UpO1xuXHRcdFxuXHRcdC8vMi4gQWRkIHRoZSByZXN1bHRzIHRvZ2V0aGVyXG5cdFx0dmFyIG1lcmdlZFJlc3VsdCA9IHtcblx0XHRcdGRheXMgOiBub3JtYWxSZXN1bHQuZGF5cyArIGRpZmZpY3VsdFJlc3VsdC5kYXlzLFxuXHRcdFx0aG91cnMgOiBub3JtYWxSZXN1bHQuaG91cnMgKyBkaWZmaWN1bHRSZXN1bHQuaG91cnMsXG5cdFx0XHRtaW51dGVzIDogbm9ybWFsUmVzdWx0Lm1pbnV0ZXMgKyBkaWZmaWN1bHRSZXN1bHQubWludXRlc1xuXHRcdH07XG5cblx0XHQvLzMuIE1ha2UgaHVtYW4gcmVhZGFibGVcblx0XHR1cENvbnZlcnRUaW1lKG1lcmdlZFJlc3VsdCwgXCJsYW5kXCIsIHRyYXZlbFBhY2UpOyBcblx0XHRyZXR1cm4gbWVyZ2VkUmVzdWx0O1xuXHR9O1xuXG5cdHZhciBjYWxjdWxhdGVUcmF2ZWxUaW1lQnlTZWEgPSBmdW5jdGlvbih0b3RhbE1pbGVzLCBib2F0VHlwZSkge1xuXHRcdC8vMC4gQ2hlY2sgdGhlIGJvYXQgdHlwZVxuXG5cdFx0Ly8xLiBHZXQgdGhlIHRyYXZlbCB0aW1lXG5cdFx0dmFyIHJlc3VsdCA9IGNhbGN1bGF0ZSh0b3RhbE1pbGVzLCBmYWxzZSwgXCJzZWFcIiwgYm9hdFR5cGUpO1xuXG5cdFx0Ly8yLiBVcGNvbnZlcnRcblx0XHR1cENvbnZlcnRUaW1lKHJlc3VsdCwgXCJzZWFcIiwgYm9hdFR5cGUpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH07XG5cblx0LyoqXG5cdCogQHBhcmFtIHRvdGFsTWlsZXMgW2ludF0gVGhlIHRvdGFsIG1pbGVzIHRvIHRyYXZlbFxuXHQqIEBwYXJhbSBpc0RpZmZpY3VsdCBbYm9vbGVhbl0gV2hldGhlciB0aGUgdHJhdmVsIGlzIG92ZXIgZGlmZmljdWx0IHRlcnJhaW5cblx0KiBAcGFyYW0gdHJhdmVsVHlwZSBbU3RyaW5nXSBQb3NzaWJsZSB2YWx1ZXM6IFwibGFuZFwiLCBcInNlYVwiXG5cdCogQHBhcmEgdHJhdmVsUGFjZSBbc3RyaW5nXSBQb3NzaWJsZSB2YWx1ZXM6IChmYXN0fG5vcm1hbHxzbG93fGdhbGxleXxrZWVsYm9hdHxsb25nc2hpcHxyb3dib2F0fHNhaWxpbmdTaGlwfHdhcnNoaXApXG5cdCovXG5cdHZhciBjYWxjdWxhdGUgPSBmdW5jdGlvbih0b3RhbE1pbGVzLCBpc0RpZmZpY3VsdCwgdHJhdmVsVHlwZSwgdHJhdmVsUGFjZSkge1xuXHRcdHZhciBjb25maWdQcmVmaXggPSBcIkNsaWVudC41ZS5cIiArIHRyYXZlbFR5cGUgKyBcIi5cIiArIHRyYXZlbFBhY2U7XG5cdFx0dmFyIHRpbWUgPSB7XG5cdFx0XHRkYXlzOiAwLFxuXHRcdFx0aG91cnM6IDAsXG5cdFx0XHRtaW51dGVzOiAwXG5cdFx0fTtcblxuXHRcdGlmICghaXNJbnQodG90YWxNaWxlcykgfHwgdG90YWxNaWxlcyA8PSAwKSB7XG5cdFx0XHRyZXR1cm4gdGltZTtcblx0XHR9XG5cblx0XHR2YXIgbWlsZXNQZXJEYXkgPSBjb25maWcuZ2V0KGNvbmZpZ1ByZWZpeCArIFwiLm1pbGVzUGVyRGF5XCIpO1xuXHRcdGlmIChpc0RpZmZpY3VsdCkge1xuXHRcdFx0bWlsZXNQZXJEYXkgLz0gMjtcblx0XHR9XG5cdFx0dmFyIG1heEhvdXJzVHJhdmVsZWRQZXJEYXkgPSBjb25maWcuZ2V0KGNvbmZpZ1ByZWZpeCArIFwiLmhvdXJzUGVyRGF5XCIpO1xuXHRcdHZhciBtaWxlc1BlckhvdXIgPSBtaWxlc1BlckRheSAvIG1heEhvdXJzVHJhdmVsZWRQZXJEYXk7XG5cdFx0dmFyIG1pbnNQZXJNaWxlID0gNjAgLyBtaWxlc1BlckhvdXI7XG5cdFx0dmFyIHJlbWFpbmluZ01pbGVzID0gdG90YWxNaWxlcyAlIG1pbGVzUGVyRGF5OyBcblxuXHRcdC8vR2V0IHRoZSB0b3RhbCBkYXlzIHRoZSB0cmlwIHRha2VzIChyb3VuZGVkIGRvd24pXG5cdFx0dGltZS5kYXlzID0gTWF0aC5mbG9vcih0b3RhbE1pbGVzIC8gbWlsZXNQZXJEYXkpO1xuXHRcdC8vR2V0IHRoZSByZW1haW5pbmcgbWlsZXMgbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBqb3VybmV5IG9uIHRoZSBsYXN0IGRheVxuXHRcdHRpbWUuaG91cnMgPSBNYXRoLmZsb29yKHJlbWFpbmluZ01pbGVzIC8gbWlsZXNQZXJIb3VyKTtcblx0XHR0aW1lLm1pbnV0ZXMgPSAocmVtYWluaW5nTWlsZXMgJSBtaWxlc1BlckhvdXIpICogbWluc1Blck1pbGU7XG5cdFx0cmV0dXJuIHRpbWU7XG5cdH07XG5cblx0LyoqXG5cdCogVXBjb252ZXJ0cyB0aW1lIGZyb20gc29tZXRoaW5nIGxpa2UgXG5cdCogZGF5czogMSwgaG91cnM6IDcsIG1pbnV0ZXM6IDYwXG5cdCogdG9cblx0KiBkYXlzOiAyLCBob3VyczogMCwgbWludXRlczogMFxuXHQqLyBcblx0dmFyIHVwQ29udmVydFRpbWUgPSBmdW5jdGlvbih0aW1lLCB0cmF2ZWxUeXBlLCB0cmF2ZWxQYWNlKSB7XG5cdFx0Ly8xLiBVcGNvbnZlcnQgbWludXRlcyB0byBob3VycyBieSBtb2QtaW5nIHRoZSB2YWx1ZSBieSA2MCBzaW5jZSB0aGVyZSBhcmUgNjAgbWludXRlcyBpbiBhbiBob3VyXG5cdFx0dmFyIG1vZE1pbnV0ZXMgPSB0aW1lLm1pbnV0ZXMgJSA2MDtcblx0XHQvL1RoZW4sIGFkZCB0aGUgcXVvdGllbnQgYmFjayB0byB0aGUgaG91cnMgc2luY2UgdGhhdCByZXByZXNlbnRzIFxuXHRcdC8vaG93IG1hbnkgaG91cnMgd2VyZSBtYWRlIGZyb20gdGhlIG1pbnV0ZXNcblx0XHR0aW1lLmhvdXJzICs9IE1hdGguZmxvb3IodGltZS5taW51dGVzIC8gNjApO1xuXHRcdHRpbWUubWludXRlcyA9IG1vZE1pbnV0ZXM7XG5cblx0XHQvLzIuIFVwY29udmVydCBob3VycyB0byBkYXlzIGJ5IG1vZC1pbmcgdGhlIHRvdGFsIGhvdXJzIGJ5IHRoZSBob3VycyB0cmF2ZWxlZCBpbiBhIGRheVxuXHRcdHZhciBtYXhIb3Vyc1RyYXZlbGVkUGVyRGF5ID0gY29uZmlnLmdldChcIkNsaWVudC41ZS5cIiArIHRyYXZlbFR5cGUgKyBcIi5cIiArIHRyYXZlbFBhY2UgKyBcIi5ob3Vyc1BlckRheVwiKTtcblx0XHR2YXIgbW9kSG91cnMgPSB0aW1lLmhvdXJzICUgbWF4SG91cnNUcmF2ZWxlZFBlckRheTtcblx0XHQvL1RoZW4sIGFkZCB0aGUgcXVvdGllbnQgYmFjayB0byB0aGUgZGF5cyBzaW5jZSB0aGF0IHJlcHJlc2VudHNcblx0XHQvL2hvdyBtYW55IGRheXMgd2VyZSBtYWRlIGZyb20gdGhlIGhvdXJzXG5cdFx0dGltZS5kYXlzICs9IE1hdGguZmxvb3IodGltZS5ob3VycyAvIG1heEhvdXJzVHJhdmVsZWRQZXJEYXkpO1xuXHRcdHRpbWUuaG91cnMgPSBtb2RIb3VycztcblxuXHRcdC8vMy4gVGhlIGRheXMgc2hvdWxkIGJlIGEgbWVyZ2VkIHJlc3VsdCBvZiBleHRyYSBkYXkgbWFkZSBmcm9tIGhvdXJzL21pbnV0ZXNcblx0fTtcblxuXHR2YXIgaXNJbnQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBcdFx0cmV0dXJuICFpc05hTih2YWx1ZSkgJiYgcGFyc2VJbnQoTnVtYmVyKHZhbHVlKSkgPT0gdmFsdWUgJiYgIWlzTmFOKHBhcnNlSW50KHZhbHVlLCAxMCkpO1xuXHR9O1xuICBcblx0cmV0dXJuIHtcbiAgXHRcdGNhbGN1bGF0ZVRyYXZlbFRpbWVCeUxhbmQgOiBjYWxjdWxhdGVUcmF2ZWxUaW1lQnlMYW5kLFxuICBcdFx0Y2FsY3VsYXRlVHJhdmVsVGltZUJ5U2VhIDogY2FsY3VsYXRlVHJhdmVsVGltZUJ5U2VhXG5cdH07XG5cbn0pKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhdmVsQ2FsY3VsYXRvcjsiXX0=