w-gis 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/interp2.wk.umd.js +12 -12
- package/dist/w-gis.umd.js +5 -5
- package/dist/w-gis.umd.js.map +1 -1
- package/docs/-_class.mjs.html +1 -1
- package/docs/CholeskyDecomposition.html +1 -1
- package/docs/ConstantPrior.html +1 -1
- package/docs/Exponential.html +1 -1
- package/docs/ExtendableMatrix.html +1 -1
- package/docs/ExtendableVector.html +1 -1
- package/docs/GaussianProcess.html +1 -1
- package/docs/GaussianProcessBuilder.html +1 -1
- package/docs/HyperTan.html +1 -1
- package/docs/KernelProd.html +1 -1
- package/docs/KernelSum.html +1 -1
- package/docs/Linear.html +1 -1
- package/docs/LinearPrior.html +1 -1
- package/docs/Matern1.html +1 -1
- package/docs/Matern2.html +1 -1
- package/docs/Multiquadric.html +1 -1
- package/docs/MultivariateNormal.html +1 -1
- package/docs/Polynomial.html +1 -1
- package/docs/RationalQuadratic.html +1 -1
- package/docs/SquaredExp.html +1 -1
- package/docs/ZeroPrior.html +1 -1
- package/docs/aggregatePoints.mjs.html +1 -1
- package/docs/bufferMultiPolygon.mjs.html +1 -1
- package/docs/buildFindPointInGeojson.mjs.html +1 -1
- package/docs/buildFindPointInKpBoxPolygons.mjs.html +1 -1
- package/docs/buildFindPointInKpPolygons.mjs.html +1 -1
- package/docs/buildFindPointInTiff.mjs.html +1 -1
- package/docs/calcContours.mjs.html +1 -1
- package/docs/calcDelaunay.mjs.html +1 -1
- package/docs/calcVoronoi.mjs.html +1 -1
- package/docs/clipMultiPolygon.mjs.html +1 -1
- package/docs/clipPolygon.mjs.html +1 -1
- package/docs/convertCoordinate.mjs.html +1 -1
- package/docs/distilMultiPolygon.mjs.html +1 -1
- package/docs/examples/ex-convertCoordinate.html +1 -1
- package/docs/examples/ex-getCenterOfMassMultiPolygon.html +1 -1
- package/docs/examples/ex-getCentroidMultiPolygon.html +1 -1
- package/docs/findPointInKpBoxPolygons.mjs.html +1 -1
- package/docs/findPointInKpFeature.mjs.html +1 -1
- package/docs/findPointInKpPolygons.mjs.html +1 -1
- package/docs/fixCloseMultiPolygon.mjs.html +1 -1
- package/docs/fixClosePolygon.mjs.html +1 -1
- package/docs/fixGeometryMultiPolygon.mjs.html +1 -1
- package/docs/flattenMultiPolygon.mjs.html +1 -1
- package/docs/getAreaMultiPolygon.mjs.html +1 -1
- package/docs/getAreaMultiPolygonSm.mjs.html +1 -1
- package/docs/getAreaPolygon.mjs.html +1 -1
- package/docs/getAreaRingString.mjs.html +1 -1
- package/docs/getBox.mjs.html +1 -1
- package/docs/getBoxFromGeojson.mjs.html +1 -1
- package/docs/getBoxPolygon.mjs.html +1 -1
- package/docs/getCenterOfMassMultiPolygon.mjs.html +1 -1
- package/docs/getCentroidMultiPolygon.mjs.html +1 -1
- package/docs/getKpFeatureFromGeojson.mjs.html +1 -1
- package/docs/getPointDepth.mjs.html +1 -1
- package/docs/global.html +1 -1
- package/docs/importTurf.mjs.html +1 -1
- package/docs/index.html +1 -1
- package/docs/interp1.mjs.html +1 -1
- package/docs/interp2.mjs.html +1 -1
- package/docs/interp2Grid.mjs.html +1 -1
- package/docs/interp2Kriging.mjs.html +1 -1
- package/docs/interp2NaturalNeighbor.mjs.html +1 -1
- package/docs/interp2Normalize.mjs.html +1 -1
- package/docs/interp2Raster.mjs.html +1 -1
- package/docs/interp3.mjs.html +1 -1
- package/docs/intersectMultiPolygon.mjs.html +1 -1
- package/docs/intersectPolygon.mjs.html +1 -1
- package/docs/invCoordMultiPolygon.mjs.html +1 -1
- package/docs/invCoordMultiPolygonOrMultiPolyline.mjs.html +1 -1
- package/docs/invCoordMultiPolyline.mjs.html +1 -1
- package/docs/invCoordPolygon.mjs.html +1 -1
- package/docs/invCoordPolygonOrPolyline.mjs.html +1 -1
- package/docs/invCoordPolyline.mjs.html +1 -1
- package/docs/isPointInPolygons.mjs.html +1 -1
- package/docs/kriging-friedrich_algebra.mjs.html +1 -1
- package/docs/kriging-friedrich_conversion.mjs.html +1 -1
- package/docs/kriging-friedrich_gaussian_process.mjs.html +1 -1
- package/docs/kriging-friedrich_kernels.mjs.html +1 -1
- package/docs/kriging-friedrich_multivariate_normal.mjs.html +1 -1
- package/docs/kriging-friedrich_optimizer.mjs.html +1 -1
- package/docs/kriging-friedrich_priors.mjs.html +1 -1
- package/docs/kriging-friedrich_test.mjs.html +1 -1
- package/docs/normalizeArray.mjs.html +1 -1
- package/docs/ptXYtoObj.mjs.html +1 -1
- package/docs/ptsXYZVtoArr.mjs.html +1 -1
- package/docs/ptsXYZtoArr.mjs.html +1 -1
- package/docs/ptsXYtoArr.mjs.html +1 -1
- package/docs/ptsXtoArr.mjs.html +1 -1
- package/docs/simplifyMultiPolygon.mjs.html +1 -1
- package/docs/splineMultiPolygon.mjs.html +1 -1
- package/docs/splitAndProcGeoJSON.mjs.html +1 -1
- package/docs/toMultiPoint.mjs.html +1 -1
- package/docs/toMultiPolygon.mjs.html +1 -1
- package/docs/toPolygon.mjs.html +1 -1
- package/docs/unionMultiPolygon.mjs.html +1 -1
- package/docs/unionPolygon.mjs.html +1 -1
- package/docs/w-gis.html +1 -1
- package/package.json +2 -2
package/dist/interp2.wk.umd.js
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
8
8
|
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
get exports(){ return
|
|
12
|
-
set exports(v){
|
|
9
|
+
var tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlINwExports = {};
|
|
10
|
+
var tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlINw = {
|
|
11
|
+
get exports(){ return tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlINwExports; },
|
|
12
|
+
set exports(v){ tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlINwExports = v; },
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
(function(module,exports){(function(global,factory){module.exports=factory(require$$0);})(commonjsGlobal,function(worker_threads){var eventemitter3Exports={};var eventemitter3={get exports(){return eventemitter3Exports;},set exports(v){eventemitter3Exports=v;}};(function(module){var has=Object.prototype.hasOwnProperty,prefix='~';/**
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
return Buffer.from(b64,'base64').toString('utf8');//Nodejs端使用Buffer解碼
|
|
137
137
|
}//codeShow
|
|
138
138
|
//codeB64, 此處需提供worker執行程式碼, 因有特殊符號轉譯困難, 故需先轉base64再使用
|
|
139
|
-
let codeB64=`CgogICAgICAgIC8vaW1wb3J0IHsgcGFyZW50UG9ydCB9IGZyb20gJ3dvcmtlcl90aHJlYWRzJwogICAgICAgIGxldCB7IHBhcmVudFBvcnQgfSA9IHJlcXVpcmUoJ3dvcmtlcl90aHJlYWRzJykgLy/lm6BwYWNrYWdlLmpzb27kuI3ntaZ0eXBlPW1vZHVsZeaVheeEoeazleaUr+aPtGVzNiBpbXBvcnQsIOW+l+S9v+eUqHJlcXVpcmUKICAgICAgICAvL+iLpeimgeaWvG5vZGVqcyB3b3JrZXLlhafkvb/nlKjnhKHms5XovYnora/nmoTljp/nlJ/lpZfku7bkvovlpoJmcywg6YG/5YWN5L2/55So6aCC5bGkaW1wb3J05Yqg6LyJ5L2/55SoLCDlm6DnhKHms5XovYnora/mnIPnm7TmjqXkv53nlZkKICAgICAgICAvL+S4puWboGltcG9ydOS9jeaWvHdvcmtlcuWkluWxpOmZkOWumueCunJlcXVpcmXljYAocGFja2FnZS5qc29u5LiN57WmdHlwZT1tb2R1bGUpLCDmlYXlh7rnj77pjK/oqqTnhKHms5XovYnora8KICAgICAgICAKCid1c2Ugc3RyaWN0JzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0FycmF5KFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzQXJyYXkoJ2FiYycpOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzQXJyYXkoXy5ub29wKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTsKdmFyIGlzQXJyYXkkMSA9IGlzQXJyYXk7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqLwp2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7CnZhciBmcmVlR2xvYmFsJDEgPSBmcmVlR2xvYmFsOwoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi8KdmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7CgovKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi8KdmFyIHJvb3QgPSBmcmVlR2xvYmFsJDEgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTsKdmFyIHJvb3QkMSA9IHJvb3Q7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIFN5bWJvbCA9IHJvb3QkMS5TeW1ib2w7CnZhciBTeW1ib2wkMSA9IFN5bWJvbDsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJGIgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQ4ID0gb2JqZWN0UHJvdG8kYi5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBVc2VkIHRvIHJlc29sdmUgdGhlCiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKQogKiBvZiB2YWx1ZXMuCiAqLwp2YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmckMSA9IG9iamVjdFByb3RvJGIudG9TdHJpbmc7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHN5bVRvU3RyaW5nVGFnJDEgPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnRvU3RyaW5nVGFnIDogdW5kZWZpbmVkOwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUdldFRhZ2Agd2hpY2ggaWdub3JlcyBgU3ltYm9sLnRvU3RyaW5nVGFnYCB2YWx1ZXMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByYXcgYHRvU3RyaW5nVGFnYC4KICovCmZ1bmN0aW9uIGdldFJhd1RhZyh2YWx1ZSkgewogIHZhciBpc093biA9IGhhc093blByb3BlcnR5JDguY2FsbCh2YWx1ZSwgc3ltVG9TdHJpbmdUYWckMSksCiAgICB0YWcgPSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXTsKICB0cnkgewogICAgdmFsdWVbc3ltVG9TdHJpbmdUYWckMV0gPSB1bmRlZmluZWQ7CiAgICB2YXIgdW5tYXNrZWQgPSB0cnVlOwogIH0gY2F0Y2ggKGUpIHt9CiAgdmFyIHJlc3VsdCA9IG5hdGl2ZU9iamVjdFRvU3RyaW5nJDEuY2FsbCh2YWx1ZSk7CiAgaWYgKHVubWFza2VkKSB7CiAgICBpZiAoaXNPd24pIHsKICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWckMV0gPSB0YWc7CiAgICB9IGVsc2UgewogICAgICBkZWxldGUgdmFsdWVbc3ltVG9TdHJpbmdUYWckMV07CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJGEgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqCiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUKICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpCiAqIG9mIHZhbHVlcy4KICovCnZhciBuYXRpdmVPYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvJGEudG9TdHJpbmc7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyB1c2luZyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuCiAqLwpmdW5jdGlvbiBvYmplY3RUb1N0cmluZyh2YWx1ZSkgewogIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgbnVsbFRhZyA9ICdbb2JqZWN0IE51bGxdJywKICB1bmRlZmluZWRUYWcgPSAnW29iamVjdCBVbmRlZmluZWRdJzsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnRvU3RyaW5nVGFnIDogdW5kZWZpbmVkOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRUYWdgIHdpdGhvdXQgZmFsbGJhY2tzIGZvciBidWdneSBlbnZpcm9ubWVudHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLgogKi8KZnVuY3Rpb24gYmFzZUdldFRhZyh2YWx1ZSkgewogIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZFRhZyA6IG51bGxUYWc7CiAgfQogIHJldHVybiBzeW1Ub1N0cmluZ1RhZyAmJiBzeW1Ub1N0cmluZ1RhZyBpbiBPYmplY3QodmFsdWUpID8gZ2V0UmF3VGFnKHZhbHVlKSA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYAogKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mICJvYmplY3QiLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc09iamVjdExpa2Uoe30pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdExpa2UoXy5ub29wKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5pc09iamVjdExpa2UobnVsbCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHsKICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIHN5bWJvbFRhZyQxID0gJ1tvYmplY3QgU3ltYm9sXSc7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTeW1ib2xgIHByaW1pdGl2ZSBvciBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHN5bWJvbCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7CiAqIC8vID0+IHRydWUKICoKICogXy5pc1N5bWJvbCgnYWJjJyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHwgaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBzeW1ib2xUYWckMTsKfQoKLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqLwp2YXIgcmVJc0RlZXBQcm9wID0gL1wufFxbKD86W15bXF1dKnwoWyInXSkoPzooPyFcMSlbXlxcXXxcXC4pKj9cMSlcXS8sCiAgcmVJc1BsYWluUHJvcCA9IC9eXHcqJC87CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc0tleSh2YWx1ZSwgb2JqZWN0KSB7CiAgaWYgKGlzQXJyYXkkMSh2YWx1ZSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgaWYgKHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnc3ltYm9sJyB8fCB0eXBlID09ICdib29sZWFuJyB8fCB2YWx1ZSA9PSBudWxsIHx8IGlzU3ltYm9sKHZhbHVlKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpIHx8ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSkgfHwgb2JqZWN0ICE9IG51bGwgJiYgdmFsdWUgaW4gT2JqZWN0KG9iamVjdCk7Cn0KCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUKICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKQogKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc09iamVjdCh7fSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdChbMSwgMiwgM10pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNPYmplY3QoXy5ub29wKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzT2JqZWN0KG51bGwpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHsKICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJywKICBmdW5jVGFnJDEgPSAnW29iamVjdCBGdW5jdGlvbl0nLAogIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsCiAgcHJveHlUYWcgPSAnW29iamVjdCBQcm94eV0nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0Z1bmN0aW9uKF8pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7CiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yCiAgLy8gaW4gU2FmYXJpIDkgd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXlzIGFuZCBvdGhlciBjb25zdHJ1Y3RvcnMuCiAgdmFyIHRhZyA9IGJhc2VHZXRUYWcodmFsdWUpOwogIHJldHVybiB0YWcgPT0gZnVuY1RhZyQxIHx8IHRhZyA9PSBnZW5UYWcgfHwgdGFnID09IGFzeW5jVGFnIHx8IHRhZyA9PSBwcm94eVRhZzsKfQoKLyoqIFVzZWQgdG8gZGV0ZWN0IG92ZXJyZWFjaGluZyBjb3JlLWpzIHNoaW1zLiAqLwp2YXIgY29yZUpzRGF0YSA9IHJvb3QkMVsnX19jb3JlLWpzX3NoYXJlZF9fJ107CnZhciBjb3JlSnNEYXRhJDEgPSBjb3JlSnNEYXRhOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi8KdmFyIG1hc2tTcmNLZXkgPSBmdW5jdGlvbiAoKSB7CiAgdmFyIHVpZCA9IC9bXi5dKyQvLmV4ZWMoY29yZUpzRGF0YSQxICYmIGNvcmVKc0RhdGEkMS5rZXlzICYmIGNvcmVKc0RhdGEkMS5rZXlzLklFX1BST1RPIHx8ICcnKTsKICByZXR1cm4gdWlkID8gJ1N5bWJvbChzcmMpXzEuJyArIHVpZCA6ICcnOwp9KCk7CgovKioKICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgaXRzIHNvdXJjZSBtYXNrZWQuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGZ1bmNgIGlzIG1hc2tlZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNNYXNrZWQoZnVuYykgewogIHJldHVybiAhIW1hc2tTcmNLZXkgJiYgbWFza1NyY0tleSBpbiBmdW5jOwp9CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBmdW5jUHJvdG8kMSA9IEZ1bmN0aW9uLnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi8KdmFyIGZ1bmNUb1N0cmluZyQxID0gZnVuY1Byb3RvJDEudG9TdHJpbmc7CgovKioKICogQ29udmVydHMgYGZ1bmNgIHRvIGl0cyBzb3VyY2UgY29kZS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY29udmVydC4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc291cmNlIGNvZGUuCiAqLwpmdW5jdGlvbiB0b1NvdXJjZShmdW5jKSB7CiAgaWYgKGZ1bmMgIT0gbnVsbCkgewogICAgdHJ5IHsKICAgICAgcmV0dXJuIGZ1bmNUb1N0cmluZyQxLmNhbGwoZnVuYyk7CiAgICB9IGNhdGNoIChlKSB7fQogICAgdHJ5IHsKICAgICAgcmV0dXJuIGZ1bmMgKyAnJzsKICAgIH0gY2F0Y2ggKGUpIHt9CiAgfQogIHJldHVybiAnJzsKfQoKLyoqCiAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAKICogW3N5bnRheCBjaGFyYWN0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wYXR0ZXJucykuCiAqLwp2YXIgcmVSZWdFeHBDaGFyID0gL1tcXF4kLiorPygpW1xde318XS9nOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkpLiAqLwp2YXIgcmVJc0hvc3RDdG9yID0gL15cW29iamVjdCAuKz9Db25zdHJ1Y3RvclxdJC87CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBmdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGUsCiAgb2JqZWN0UHJvdG8kOSA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovCnZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDcgPSBvYmplY3RQcm90byQ5Lmhhc093blByb3BlcnR5OwoKLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi8KdmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICsgZnVuY1RvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkkNykucmVwbGFjZShyZVJlZ0V4cENoYXIsICdcXCQmJykucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXCgpfCBmb3IgLis/KD89XFxcXSkvZywgJyQxLio/JykgKyAnJCcpOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmF0aXZlYCB3aXRob3V0IGJhZCBzaGltIGNoZWNrcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzTmF0aXZlKHZhbHVlKSB7CiAgaWYgKCFpc09iamVjdCh2YWx1ZSkgfHwgaXNNYXNrZWQodmFsdWUpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHZhciBwYXR0ZXJuID0gaXNGdW5jdGlvbih2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yOwogIHJldHVybiBwYXR0ZXJuLnRlc3QodG9Tb3VyY2UodmFsdWUpKTsKfQoKLyoqCiAqIEdldHMgdGhlIHZhbHVlIGF0IGBrZXlgIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS4KICovCmZ1bmN0aW9uIGdldFZhbHVlKG9iamVjdCwga2V5KSB7CiAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07Cn0KCi8qKgogKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZnVuY3Rpb24gaWYgaXQncyBuYXRpdmUsIGVsc2UgYHVuZGVmaW5lZGAuCiAqLwpmdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHsKICB2YXIgdmFsdWUgPSBnZXRWYWx1ZShvYmplY3QsIGtleSk7CiAgcmV0dXJuIGJhc2VJc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDsKfQoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpOwp2YXIgbmF0aXZlQ3JlYXRlJDEgPSBuYXRpdmVDcmVhdGU7CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgaGFzaC4KICoKICogQHByaXZhdGUKICogQG5hbWUgY2xlYXIKICogQG1lbWJlck9mIEhhc2gKICovCmZ1bmN0aW9uIGhhc2hDbGVhcigpIHsKICB0aGlzLl9fZGF0YV9fID0gbmF0aXZlQ3JlYXRlJDEgPyBuYXRpdmVDcmVhdGUkMShudWxsKSA6IHt9OwogIHRoaXMuc2l6ZSA9IDA7Cn0KCi8qKgogKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZGVsZXRlCiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoIFRoZSBoYXNoIHRvIG1vZGlmeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGhhc2hEZWxldGUoa2V5KSB7CiAgdmFyIHJlc3VsdCA9IHRoaXMuaGFzKGtleSkgJiYgZGVsZXRlIHRoaXMuX19kYXRhX19ba2V5XTsKICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqLwp2YXIgSEFTSF9VTkRFRklORUQkMiA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJzsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDggPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQ2ID0gb2JqZWN0UHJvdG8kOC5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBHZXRzIHRoZSBoYXNoIHZhbHVlIGZvciBga2V5YC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZ2V0CiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuCiAqLwpmdW5jdGlvbiBoYXNoR2V0KGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXzsKICBpZiAobmF0aXZlQ3JlYXRlJDEpIHsKICAgIHZhciByZXN1bHQgPSBkYXRhW2tleV07CiAgICByZXR1cm4gcmVzdWx0ID09PSBIQVNIX1VOREVGSU5FRCQyID8gdW5kZWZpbmVkIDogcmVzdWx0OwogIH0KICByZXR1cm4gaGFzT3duUHJvcGVydHkkNi5jYWxsKGRhdGEsIGtleSkgPyBkYXRhW2tleV0gOiB1bmRlZmluZWQ7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDcgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQ1ID0gb2JqZWN0UHJvdG8kNy5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBDaGVja3MgaWYgYSBoYXNoIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGhhcwogKiBAbWVtYmVyT2YgSGFzaAogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187CiAgcmV0dXJuIG5hdGl2ZUNyZWF0ZSQxID8gZGF0YVtrZXldICE9PSB1bmRlZmluZWQgOiBoYXNPd25Qcm9wZXJ0eSQ1LmNhbGwoZGF0YSwga2V5KTsKfQoKLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqLwp2YXIgSEFTSF9VTkRFRklORUQkMSA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJzsKCi8qKgogKiBTZXRzIHRoZSBoYXNoIGBrZXlgIHRvIGB2YWx1ZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIHNldAogKiBAbWVtYmVyT2YgSGFzaAogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBoYXNoIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gaGFzaFNldChrZXksIHZhbHVlKSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fOwogIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7CiAgZGF0YVtrZXldID0gbmF0aXZlQ3JlYXRlJDEgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCA/IEhBU0hfVU5ERUZJTkVEJDEgOiB2YWx1ZTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYSBoYXNoIG9iamVjdC4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gSGFzaChlbnRyaWVzKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CiAgdGhpcy5jbGVhcigpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTsKICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7CiAgfQp9CgovLyBBZGQgbWV0aG9kcyB0byBgSGFzaGAuCkhhc2gucHJvdG90eXBlLmNsZWFyID0gaGFzaENsZWFyOwpIYXNoLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBoYXNoRGVsZXRlOwpIYXNoLnByb3RvdHlwZS5nZXQgPSBoYXNoR2V0OwpIYXNoLnByb3RvdHlwZS5oYXMgPSBoYXNoSGFzOwpIYXNoLnByb3RvdHlwZS5zZXQgPSBoYXNoU2V0OwoKLyoqCiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIGxpc3QgY2FjaGUuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGNsZWFyCiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICovCmZ1bmN0aW9uIGxpc3RDYWNoZUNsZWFyKCkgewogIHRoaXMuX19kYXRhX18gPSBbXTsKICB0aGlzLnNpemUgPSAwOwp9CgovKioKICogUGVyZm9ybXMgYQogKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKQogKiBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXF1aXZhbGVudC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07CiAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07CiAqCiAqIF8uZXEob2JqZWN0LCBvYmplY3QpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uZXEob2JqZWN0LCBvdGhlcik7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uZXEoJ2EnLCAnYScpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uZXEoTmFOLCBOYU4pOwogKiAvLyA9PiB0cnVlCiAqLwpmdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHsKICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8IHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7Cn0KCi8qKgogKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgYGtleWAgaXMgZm91bmQgaW4gYGFycmF5YCBvZiBrZXktdmFsdWUgcGFpcnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LgogKiBAcGFyYW0geyp9IGtleSBUaGUga2V5IHRvIHNlYXJjaCBmb3IuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuCiAqLwpmdW5jdGlvbiBhc3NvY0luZGV4T2YoYXJyYXksIGtleSkgewogIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKGxlbmd0aC0tKSB7CiAgICBpZiAoZXEoYXJyYXlbbGVuZ3RoXVswXSwga2V5KSkgewogICAgICByZXR1cm4gbGVuZ3RoOwogICAgfQogIH0KICByZXR1cm4gLTE7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlOwoKLyoqCiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlRGVsZXRlKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7CiAgaWYgKGluZGV4IDwgMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxOwogIGlmIChpbmRleCA9PSBsYXN0SW5kZXgpIHsKICAgIGRhdGEucG9wKCk7CiAgfSBlbHNlIHsKICAgIHNwbGljZS5jYWxsKGRhdGEsIGluZGV4LCAxKTsKICB9CiAgLS10aGlzLnNpemU7CiAgcmV0dXJuIHRydWU7Cn0KCi8qKgogKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZ2V0CiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS4KICovCmZ1bmN0aW9uIGxpc3RDYWNoZUdldChrZXkpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sCiAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpOwogIHJldHVybiBpbmRleCA8IDAgPyB1bmRlZmluZWQgOiBkYXRhW2luZGV4XVsxXTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGxpc3RDYWNoZUhhcyhrZXkpIHsKICByZXR1cm4gYXNzb2NJbmRleE9mKHRoaXMuX19kYXRhX18sIGtleSkgPiAtMTsKfQoKLyoqCiAqIFNldHMgdGhlIGxpc3QgY2FjaGUgYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbGlzdCBjYWNoZSBpbnN0YW5jZS4KICovCmZ1bmN0aW9uIGxpc3RDYWNoZVNldChrZXksIHZhbHVlKSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLAogICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTsKICBpZiAoaW5kZXggPCAwKSB7CiAgICArK3RoaXMuc2l6ZTsKICAgIGRhdGEucHVzaChba2V5LCB2YWx1ZV0pOwogIH0gZWxzZSB7CiAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlOwogIH0KICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gbGlzdCBjYWNoZSBvYmplY3QuCiAqCiAqIEBwcml2YXRlCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS4KICovCmZ1bmN0aW9uIExpc3RDYWNoZShlbnRyaWVzKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CiAgdGhpcy5jbGVhcigpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTsKICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7CiAgfQp9CgovLyBBZGQgbWV0aG9kcyB0byBgTGlzdENhY2hlYC4KTGlzdENhY2hlLnByb3RvdHlwZS5jbGVhciA9IGxpc3RDYWNoZUNsZWFyOwpMaXN0Q2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IGxpc3RDYWNoZURlbGV0ZTsKTGlzdENhY2hlLnByb3RvdHlwZS5nZXQgPSBsaXN0Q2FjaGVHZXQ7Ckxpc3RDYWNoZS5wcm90b3R5cGUuaGFzID0gbGlzdENhY2hlSGFzOwpMaXN0Q2FjaGUucHJvdG90eXBlLnNldCA9IGxpc3RDYWNoZVNldDsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi8KdmFyIE1hcCA9IGdldE5hdGl2ZShyb290JDEsICdNYXAnKTsKdmFyIE1hcCQxID0gTWFwOwoKLyoqCiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC4KICoKICogQHByaXZhdGUKICogQG5hbWUgY2xlYXIKICogQG1lbWJlck9mIE1hcENhY2hlCiAqLwpmdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkgewogIHRoaXMuc2l6ZSA9IDA7CiAgdGhpcy5fX2RhdGFfXyA9IHsKICAgICdoYXNoJzogbmV3IEhhc2goKSwKICAgICdtYXAnOiBuZXcgKE1hcCQxIHx8IExpc3RDYWNoZSkoKSwKICAgICdzdHJpbmcnOiBuZXcgSGFzaCgpCiAgfTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciB1c2UgYXMgdW5pcXVlIG9iamVjdCBrZXkuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7CiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgcmV0dXJuIHR5cGUgPT0gJ3N0cmluZycgfHwgdHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nID8gdmFsdWUgIT09ICdfX3Byb3RvX18nIDogdmFsdWUgPT09IG51bGw7Cn0KCi8qKgogKiBHZXRzIHRoZSBkYXRhIGZvciBgbWFwYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIHF1ZXJ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSByZWZlcmVuY2Uga2V5LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWFwIGRhdGEuCiAqLwpmdW5jdGlvbiBnZXRNYXBEYXRhKG1hcCwga2V5KSB7CiAgdmFyIGRhdGEgPSBtYXAuX19kYXRhX187CiAgcmV0dXJuIGlzS2V5YWJsZShrZXkpID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddIDogZGF0YS5tYXA7Cn0KCi8qKgogKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgbWFwLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIE1hcENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZURlbGV0ZShrZXkpIHsKICB2YXIgcmVzdWx0ID0gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpWydkZWxldGUnXShrZXkpOwogIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogR2V0cyB0aGUgbWFwIHZhbHVlIGZvciBga2V5YC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZ2V0CiAqIEBtZW1iZXJPZiBNYXBDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLgogKi8KZnVuY3Rpb24gbWFwQ2FjaGVHZXQoa2V5KSB7CiAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5nZXQoa2V5KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIG1hcCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBoYXMKICogQG1lbWJlck9mIE1hcENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHsKICByZXR1cm4gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLmhhcyhrZXkpOwp9CgovKioKICogU2V0cyB0aGUgbWFwIGBrZXlgIHRvIGB2YWx1ZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIHNldAogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbWFwIGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gbWFwQ2FjaGVTZXQoa2V5LCB2YWx1ZSkgewogIHZhciBkYXRhID0gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLAogICAgc2l6ZSA9IGRhdGEuc2l6ZTsKICBkYXRhLnNldChrZXksIHZhbHVlKTsKICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYSBtYXAgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gTWFwQ2FjaGUoZW50cmllcykgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoOwogIHRoaXMuY2xlYXIoKTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07CiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pOwogIH0KfQoKLy8gQWRkIG1ldGhvZHMgdG8gYE1hcENhY2hlYC4KTWFwQ2FjaGUucHJvdG90eXBlLmNsZWFyID0gbWFwQ2FjaGVDbGVhcjsKTWFwQ2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IG1hcENhY2hlRGVsZXRlOwpNYXBDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbWFwQ2FjaGVHZXQ7Ck1hcENhY2hlLnByb3RvdHlwZS5oYXMgPSBtYXBDYWNoZUhhczsKTWFwQ2FjaGUucHJvdG90eXBlLnNldCA9IG1hcENhY2hlU2V0OwoKLyoqIEVycm9yIG1lc3NhZ2UgY29uc3RhbnRzLiAqLwp2YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nOwoKLyoqCiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IG1lbW9pemVzIHRoZSByZXN1bHQgb2YgYGZ1bmNgLiBJZiBgcmVzb2x2ZXJgIGlzCiAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGUKICogYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBtZW1vaXplZCBmdW5jdGlvbi4gQnkgZGVmYXVsdCwgdGhlIGZpcnN0IGFyZ3VtZW50CiAqIHByb3ZpZGVkIHRvIHRoZSBtZW1vaXplZCBmdW5jdGlvbiBpcyB1c2VkIGFzIHRoZSBtYXAgY2FjaGUga2V5LiBUaGUgYGZ1bmNgCiAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLgogKgogKiAqKk5vdGU6KiogVGhlIGNhY2hlIGlzIGV4cG9zZWQgYXMgdGhlIGBjYWNoZWAgcHJvcGVydHkgb24gdGhlIG1lbW9pemVkCiAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYAogKiBjb25zdHJ1Y3RvciB3aXRoIG9uZSB3aG9zZSBpbnN0YW5jZXMgaW1wbGVtZW50IHRoZQogKiBbYE1hcGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXByb3BlcnRpZXMtb2YtdGhlLW1hcC1wcm90b3R5cGUtb2JqZWN0KQogKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IEZ1bmN0aW9uCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC4KICogQHBhcmFtIHtGdW5jdGlvbn0gW3Jlc29sdmVyXSBUaGUgZnVuY3Rpb24gdG8gcmVzb2x2ZSB0aGUgY2FjaGUga2V5LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIgfTsKICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9OwogKgogKiB2YXIgdmFsdWVzID0gXy5tZW1vaXplKF8udmFsdWVzKTsKICogdmFsdWVzKG9iamVjdCk7CiAqIC8vID0+IFsxLCAyXQogKgogKiB2YWx1ZXMob3RoZXIpOwogKiAvLyA9PiBbMywgNF0KICoKICogb2JqZWN0LmEgPSAyOwogKiB2YWx1ZXMob2JqZWN0KTsKICogLy8gPT4gWzEsIDJdCiAqCiAqIC8vIE1vZGlmeSB0aGUgcmVzdWx0IGNhY2hlLgogKiB2YWx1ZXMuY2FjaGUuc2V0KG9iamVjdCwgWydhJywgJ2InXSk7CiAqIHZhbHVlcyhvYmplY3QpOwogKiAvLyA9PiBbJ2EnLCAnYiddCiAqCiAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuCiAqIF8ubWVtb2l6ZS5DYWNoZSA9IFdlYWtNYXA7CiAqLwpmdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7CiAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicgfHwgcmVzb2x2ZXIgIT0gbnVsbCAmJiB0eXBlb2YgcmVzb2x2ZXIgIT0gJ2Z1bmN0aW9uJykgewogICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpOwogIH0KICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbiAoKSB7CiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cywKICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sCiAgICAgIGNhY2hlID0gbWVtb2l6ZWQuY2FjaGU7CiAgICBpZiAoY2FjaGUuaGFzKGtleSkpIHsKICAgICAgcmV0dXJuIGNhY2hlLmdldChrZXkpOwogICAgfQogICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7CiAgICBtZW1vaXplZC5jYWNoZSA9IGNhY2hlLnNldChrZXksIHJlc3VsdCkgfHwgY2FjaGU7CiAgICByZXR1cm4gcmVzdWx0OwogIH07CiAgbWVtb2l6ZWQuY2FjaGUgPSBuZXcgKG1lbW9pemUuQ2FjaGUgfHwgTWFwQ2FjaGUpKCk7CiAgcmV0dXJuIG1lbW9pemVkOwp9CgovLyBFeHBvc2UgYE1hcENhY2hlYC4KbWVtb2l6ZS5DYWNoZSA9IE1hcENhY2hlOwoKLyoqIFVzZWQgYXMgdGhlIG1heGltdW0gbWVtb2l6ZSBjYWNoZSBzaXplLiAqLwp2YXIgTUFYX01FTU9JWkVfU0laRSA9IDUwMDsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWVtb2l6ZWAgd2hpY2ggY2xlYXJzIHRoZSBtZW1vaXplZCBmdW5jdGlvbidzCiAqIGNhY2hlIHdoZW4gaXQgZXhjZWVkcyBgTUFYX01FTU9JWkVfU0laRWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBtZW1vaXplQ2FwcGVkKGZ1bmMpIHsKICB2YXIgcmVzdWx0ID0gbWVtb2l6ZShmdW5jLCBmdW5jdGlvbiAoa2V5KSB7CiAgICBpZiAoY2FjaGUuc2l6ZSA9PT0gTUFYX01FTU9JWkVfU0laRSkgewogICAgICBjYWNoZS5jbGVhcigpOwogICAgfQogICAgcmV0dXJuIGtleTsKICB9KTsKICB2YXIgY2FjaGUgPSByZXN1bHQuY2FjaGU7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqLwp2YXIgcmVQcm9wTmFtZSA9IC9bXi5bXF1dK3xcWyg/OigtP1xkKyg/OlwuXGQrKT8pfChbIiddKSgoPzooPyFcMilbXlxcXXxcXC4pKj8pXDIpXF18KD89KD86XC58XFtcXSkoPzpcLnxcW1xdfCQpKS9nOwoKLyoqIFVzZWQgdG8gbWF0Y2ggYmFja3NsYXNoZXMgaW4gcHJvcGVydHkgcGF0aHMuICovCnZhciByZUVzY2FwZUNoYXIgPSAvXFwoXFwpPy9nOwoKLyoqCiAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcHJvcGVydHkgcGF0aCBhcnJheS4KICovCnZhciBzdHJpbmdUb1BhdGggPSBtZW1vaXplQ2FwcGVkKGZ1bmN0aW9uIChzdHJpbmcpIHsKICB2YXIgcmVzdWx0ID0gW107CiAgaWYgKHN0cmluZy5jaGFyQ29kZUF0KDApID09PSA0NiAvKiAuICovKSB7CiAgICByZXN1bHQucHVzaCgnJyk7CiAgfQogIHN0cmluZy5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7CiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN1YlN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2gpOwogIH0pOwogIHJldHVybiByZXN1bHQ7Cn0pOwp2YXIgc3RyaW5nVG9QYXRoJDEgPSBzdHJpbmdUb1BhdGg7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlCiAqIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LgogKi8KZnVuY3Rpb24gYXJyYXlNYXAoYXJyYXksIGl0ZXJhdGVlKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCwKICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSk7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgSU5GSU5JVFkkMiA9IDEgLyAwOwoKLyoqIFVzZWQgdG8gY29udmVydCBzeW1ib2xzIHRvIHByaW1pdGl2ZXMgYW5kIHN0cmluZ3MuICovCnZhciBzeW1ib2xQcm90byQxID0gU3ltYm9sJDEgPyBTeW1ib2wkMS5wcm90b3R5cGUgOiB1bmRlZmluZWQsCiAgc3ltYm9sVG9TdHJpbmcgPSBzeW1ib2xQcm90byQxID8gc3ltYm9sUHJvdG8kMS50b1N0cmluZyA6IHVuZGVmaW5lZDsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b1N0cmluZ2Agd2hpY2ggZG9lc24ndCBjb252ZXJ0IG51bGxpc2gKICogdmFsdWVzIHRvIGVtcHR5IHN0cmluZ3MuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy4KICovCmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkgewogIC8vIEV4aXQgZWFybHkgZm9yIHN0cmluZ3MgdG8gYXZvaWQgYSBwZXJmb3JtYW5jZSBoaXQgaW4gc29tZSBlbnZpcm9ubWVudHMuCiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICBpZiAoaXNBcnJheSQxKHZhbHVlKSkgewogICAgLy8gUmVjdXJzaXZlbHkgY29udmVydCB2YWx1ZXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS4KICAgIHJldHVybiBhcnJheU1hcCh2YWx1ZSwgYmFzZVRvU3RyaW5nKSArICcnOwogIH0KICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7CiAgICByZXR1cm4gc3ltYm9sVG9TdHJpbmcgPyBzeW1ib2xUb1N0cmluZy5jYWxsKHZhbHVlKSA6ICcnOwogIH0KICB2YXIgcmVzdWx0ID0gdmFsdWUgKyAnJzsKICByZXR1cm4gcmVzdWx0ID09ICcwJyAmJiAxIC8gdmFsdWUgPT0gLUlORklOSVRZJDIgPyAnLTAnIDogcmVzdWx0Owp9CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZy4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkIGZvciBgbnVsbGAKICogYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuCiAqIEBleGFtcGxlCiAqCiAqIF8udG9TdHJpbmcobnVsbCk7CiAqIC8vID0+ICcnCiAqCiAqIF8udG9TdHJpbmcoLTApOwogKiAvLyA9PiAnLTAnCiAqCiAqIF8udG9TdHJpbmcoWzEsIDIsIDNdKTsKICogLy8gPT4gJzEsMiwzJwogKi8KZnVuY3Rpb24gdG9TdHJpbmcodmFsdWUpIHsKICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogYmFzZVRvU3RyaW5nKHZhbHVlKTsKfQoKLyoqCiAqIENhc3RzIGB2YWx1ZWAgdG8gYSBwYXRoIGFycmF5IGlmIGl0J3Mgbm90IG9uZS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC4KICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjYXN0IHByb3BlcnR5IHBhdGggYXJyYXkuCiAqLwpmdW5jdGlvbiBjYXN0UGF0aCh2YWx1ZSwgb2JqZWN0KSB7CiAgaWYgKGlzQXJyYXkkMSh2YWx1ZSkpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CiAgcmV0dXJuIGlzS2V5KHZhbHVlLCBvYmplY3QpID8gW3ZhbHVlXSA6IHN0cmluZ1RvUGF0aCQxKHRvU3RyaW5nKHZhbHVlKSk7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgSU5GSU5JVFkkMSA9IDEgLyAwOwoKLyoqCiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzdHJpbmcga2V5IGlmIGl0J3Mgbm90IGEgc3RyaW5nIG9yIHN5bWJvbC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC4KICogQHJldHVybnMge3N0cmluZ3xzeW1ib2x9IFJldHVybnMgdGhlIGtleS4KICovCmZ1bmN0aW9uIHRvS2V5KHZhbHVlKSB7CiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCBpc1N5bWJvbCh2YWx1ZSkpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CiAgdmFyIHJlc3VsdCA9IHZhbHVlICsgJyc7CiAgcmV0dXJuIHJlc3VsdCA9PSAnMCcgJiYgMSAvIHZhbHVlID09IC1JTkZJTklUWSQxID8gJy0wJyA6IHJlc3VsdDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWZhdWx0IHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuCiAqLwpmdW5jdGlvbiBiYXNlR2V0KG9iamVjdCwgcGF0aCkgewogIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpOwogIHZhciBpbmRleCA9IDAsCiAgICBsZW5ndGggPSBwYXRoLmxlbmd0aDsKICB3aGlsZSAob2JqZWN0ICE9IG51bGwgJiYgaW5kZXggPCBsZW5ndGgpIHsKICAgIG9iamVjdCA9IG9iamVjdFt0b0tleShwYXRoW2luZGV4KytdKV07CiAgfQogIHJldHVybiBpbmRleCAmJiBpbmRleCA9PSBsZW5ndGggPyBvYmplY3QgOiB1bmRlZmluZWQ7Cn0KCi8qKgogKiBHZXRzIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuIElmIHRoZSByZXNvbHZlZCB2YWx1ZSBpcwogKiBgdW5kZWZpbmVkYCwgdGhlIGBkZWZhdWx0VmFsdWVgIGlzIHJldHVybmVkIGluIGl0cyBwbGFjZS4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMy43LjAKICogQGNhdGVnb3J5IE9iamVjdAogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfV0gfTsKICoKICogXy5nZXQob2JqZWN0LCAnYVswXS5iLmMnKTsKICogLy8gPT4gMwogKgogKiBfLmdldChvYmplY3QsIFsnYScsICcwJywgJ2InLCAnYyddKTsKICogLy8gPT4gMwogKgogKiBfLmdldChvYmplY3QsICdhLmIuYycsICdkZWZhdWx0Jyk7CiAqIC8vID0+ICdkZWZhdWx0JwogKi8KZnVuY3Rpb24gZ2V0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7CiAgdmFyIHJlc3VsdCA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogYmFzZUdldChvYmplY3QsIHBhdGgpOwogIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWx1ZSA6IHJlc3VsdDsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgYm9vbFRhZyQyID0gJ1tvYmplY3QgQm9vbGVhbl0nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBib29sZWFuIHByaW1pdGl2ZSBvciBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJvb2xlYW4sIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0Jvb2xlYW4oZmFsc2UpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNCb29sZWFuKG51bGwpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNCb29sZWFuKHZhbHVlKSB7CiAgcmV0dXJuIHZhbHVlID09PSB0cnVlIHx8IHZhbHVlID09PSBmYWxzZSB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGJvb2xUYWckMjsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrpib29sZWFuDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNib2wudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzYm9sKGZhbHNlKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNib2wodikgewogIHJldHVybiBpc0Jvb2xlYW4odik7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65a2X5LiyDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNzdHIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyKDApKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc3N0cignMCcpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyKCcnKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNzdHIodikgewogIGxldCBjID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpOwogIHJldHVybiBjID09PSAnW29iamVjdCBTdHJpbmddJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrmnInmlYjlrZfkuLINCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2VzdHIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXN0cignMS4yNScpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXN0cigxMjUpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VzdHIoJycpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKi8KZnVuY3Rpb24gaXNlc3RyKHYpIHsKICAvL2NoZWNrCiAgaWYgKGlzc3RyKHYpKSB7CiAgICBpZiAodiAhPT0gJycpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IKICogaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC4KICovCmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkgewogICAgICBicmVhazsKICAgIH0KICB9CiAgcmV0dXJuIGFycmF5Owp9CgovKioKICogQ3JlYXRlcyBhIGJhc2UgZnVuY3Rpb24gZm9yIG1ldGhvZHMgbGlrZSBgXy5mb3JJbmAgYW5kIGBfLmZvck93bmAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gY3JlYXRlQmFzZUZvcihmcm9tUmlnaHQpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwgaXRlcmF0ZWUsIGtleXNGdW5jKSB7CiAgICB2YXIgaW5kZXggPSAtMSwKICAgICAgaXRlcmFibGUgPSBPYmplY3Qob2JqZWN0KSwKICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLAogICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7CiAgICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgICAgdmFyIGtleSA9IHByb3BzW2Zyb21SaWdodCA/IGxlbmd0aCA6ICsraW5kZXhdOwogICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBvYmplY3Q7CiAgfTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlcyBvdmVyIGBvYmplY3RgCiAqIHByb3BlcnRpZXMgcmV0dXJuZWQgYnkgYGtleXNGdW5jYCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIHByb3BlcnR5LgogKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuCiAqLwp2YXIgYmFzZUZvciA9IGNyZWF0ZUJhc2VGb3IoKTsKdmFyIGJhc2VGb3IkMSA9IGJhc2VGb3I7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udGltZXNgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcwogKiBvciBtYXggYXJyYXkgbGVuZ3RoIGNoZWNrcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byBpbnZva2UgYGl0ZXJhdGVlYC4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLgogKi8KZnVuY3Rpb24gYmFzZVRpbWVzKG4sIGl0ZXJhdGVlKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSBBcnJheShuKTsKICB3aGlsZSAoKytpbmRleCA8IG4pIHsKICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShpbmRleCk7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGFyZ3NUYWckMiA9ICdbb2JqZWN0IEFyZ3VtZW50c10nOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzQXJndW1lbnRzYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCwKICovCmZ1bmN0aW9uIGJhc2VJc0FyZ3VtZW50cyh2YWx1ZSkgewogIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGFyZ3NUYWckMjsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNiA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDQgPSBvYmplY3RQcm90byQ2Lmhhc093blByb3BlcnR5OwoKLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovCnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSQxID0gb2JqZWN0UHJvdG8kNi5wcm9wZXJ0eUlzRW51bWVyYWJsZTsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LAogKiAgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc0FyZ3VtZW50cyA9IGJhc2VJc0FyZ3VtZW50cyhmdW5jdGlvbiAoKSB7CiAgcmV0dXJuIGFyZ3VtZW50czsKfSgpKSA/IGJhc2VJc0FyZ3VtZW50cyA6IGZ1bmN0aW9uICh2YWx1ZSkgewogIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGhhc093blByb3BlcnR5JDQuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmICFwcm9wZXJ0eUlzRW51bWVyYWJsZSQxLmNhbGwodmFsdWUsICdjYWxsZWUnKTsKfTsKdmFyIGlzQXJndW1lbnRzJDEgPSBpc0FyZ3VtZW50czsKCi8qKgogKiBUaGlzIG1ldGhvZCByZXR1cm5zIGBmYWxzZWAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMTMuMAogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLnRpbWVzKDIsIF8uc3R1YkZhbHNlKTsKICogLy8gPT4gW2ZhbHNlLCBmYWxzZV0KICovCmZ1bmN0aW9uIHN0dWJGYWxzZSgpIHsKICByZXR1cm4gZmFsc2U7Cn0KCi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovCnZhciBmcmVlRXhwb3J0cyQxID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzOwoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqLwp2YXIgZnJlZU1vZHVsZSQxID0gZnJlZUV4cG9ydHMkMSAmJiB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTsKCi8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovCnZhciBtb2R1bGVFeHBvcnRzJDEgPSBmcmVlTW9kdWxlJDEgJiYgZnJlZU1vZHVsZSQxLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzJDE7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIEJ1ZmZlciA9IG1vZHVsZUV4cG9ydHMkMSA/IHJvb3QkMS5CdWZmZXIgOiB1bmRlZmluZWQ7CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovCnZhciBuYXRpdmVJc0J1ZmZlciA9IEJ1ZmZlciA/IEJ1ZmZlci5pc0J1ZmZlciA6IHVuZGVmaW5lZDsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGJ1ZmZlci4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4zLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNCdWZmZXIobmV3IEJ1ZmZlcigyKSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0J1ZmZlcihuZXcgVWludDhBcnJheSgyKSk7CiAqIC8vID0+IGZhbHNlCiAqLwp2YXIgaXNCdWZmZXIgPSBuYXRpdmVJc0J1ZmZlciB8fCBzdHViRmFsc2U7CnZhciBpc0J1ZmZlciQxID0gaXNCdWZmZXI7CgovKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi8KdmFyIE1BWF9TQUZFX0lOVEVHRVIkMSA9IDkwMDcxOTkyNTQ3NDA5OTE7CgovKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovCnZhciByZUlzVWludCA9IC9eKD86MHxbMS05XVxkKikkLzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgaW5kZXgsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkgewogIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlOwogIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiQxIDogbGVuZ3RoOwogIHJldHVybiAhIWxlbmd0aCAmJiAodHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlICE9ICdzeW1ib2wnICYmIHJlSXNVaW50LnRlc3QodmFsdWUpKSAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoOwp9CgovKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi8KdmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguCiAqCiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uCiAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzTGVuZ3RoKDMpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNMZW5ndGgoSW5maW5pdHkpOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzTGVuZ3RoKCczJyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8PSBNQVhfU0FGRV9JTlRFR0VSOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBhcmdzVGFnJDEgPSAnW29iamVjdCBBcmd1bWVudHNdJywKICBhcnJheVRhZyQxID0gJ1tvYmplY3QgQXJyYXldJywKICBib29sVGFnJDEgPSAnW29iamVjdCBCb29sZWFuXScsCiAgZGF0ZVRhZyQxID0gJ1tvYmplY3QgRGF0ZV0nLAogIGVycm9yVGFnJDEgPSAnW29iamVjdCBFcnJvcl0nLAogIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLAogIG1hcFRhZyQzID0gJ1tvYmplY3QgTWFwXScsCiAgbnVtYmVyVGFnJDIgPSAnW29iamVjdCBOdW1iZXJdJywKICBvYmplY3RUYWckMiA9ICdbb2JqZWN0IE9iamVjdF0nLAogIHJlZ2V4cFRhZyQxID0gJ1tvYmplY3QgUmVnRXhwXScsCiAgc2V0VGFnJDMgPSAnW29iamVjdCBTZXRdJywKICBzdHJpbmdUYWckMiA9ICdbb2JqZWN0IFN0cmluZ10nLAogIHdlYWtNYXBUYWckMSA9ICdbb2JqZWN0IFdlYWtNYXBdJzsKdmFyIGFycmF5QnVmZmVyVGFnJDEgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLAogIGRhdGFWaWV3VGFnJDIgPSAnW29iamVjdCBEYXRhVmlld10nLAogIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJywKICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsCiAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLAogIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLAogIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLAogIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLAogIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsCiAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJywKICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nOwoKLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqLwp2YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTsKdHlwZWRBcnJheVRhZ3NbZmxvYXQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1tmbG9hdDY0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQxNlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTsKdHlwZWRBcnJheVRhZ3NbYXJnc1RhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW2FycmF5VGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tib29sVGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWckMl0gPSB0eXBlZEFycmF5VGFnc1tkYXRlVGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tmdW5jVGFnXSA9IHR5cGVkQXJyYXlUYWdzW21hcFRhZyQzXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW29iamVjdFRhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW3NldFRhZyQzXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW3dlYWtNYXBUYWckMV0gPSBmYWxzZTsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkgewogIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bmFyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBzdG9yaW5nIG1ldGFkYXRhLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gYmFzZVVuYXJ5KGZ1bmMpIHsKICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICByZXR1cm4gZnVuYyh2YWx1ZSk7CiAgfTsKfQoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi8KdmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzOwoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqLwp2YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlOwoKLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi8KdmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHByb2Nlc3NgIGZyb20gTm9kZS5qcy4gKi8KdmFyIGZyZWVQcm9jZXNzID0gbW9kdWxlRXhwb3J0cyAmJiBmcmVlR2xvYmFsJDEucHJvY2VzczsKCi8qKiBVc2VkIHRvIGFjY2VzcyBmYXN0ZXIgTm9kZS5qcyBoZWxwZXJzLiAqLwp2YXIgbm9kZVV0aWwgPSBmdW5jdGlvbiAoKSB7CiAgdHJ5IHsKICAgIC8vIFVzZSBgdXRpbC50eXBlc2AgZm9yIE5vZGUuanMgMTArLgogICAgdmFyIHR5cGVzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlKCd1dGlsJykudHlwZXM7CiAgICBpZiAodHlwZXMpIHsKICAgICAgcmV0dXJuIHR5cGVzOwogICAgfQoKICAgIC8vIExlZ2FjeSBgcHJvY2Vzcy5iaW5kaW5nKCd1dGlsJylgIGZvciBOb2RlLmpzIDwgMTAuCiAgICByZXR1cm4gZnJlZVByb2Nlc3MgJiYgZnJlZVByb2Nlc3MuYmluZGluZyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nKCd1dGlsJyk7CiAgfSBjYXRjaCAoZSkge30KfSgpOwp2YXIgbm9kZVV0aWwkMSA9IG5vZGVVdGlsOwoKLyogTm9kZS5qcyBoZWxwZXIgcmVmZXJlbmNlcy4gKi8KdmFyIG5vZGVJc1R5cGVkQXJyYXkgPSBub2RlVXRpbCQxICYmIG5vZGVVdGlsJDEuaXNUeXBlZEFycmF5OwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSB0eXBlZCBhcnJheS4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMy4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc1R5cGVkQXJyYXkobmV3IFVpbnQ4QXJyYXkpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNUeXBlZEFycmF5KFtdKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc1R5cGVkQXJyYXkgPSBub2RlSXNUeXBlZEFycmF5ID8gYmFzZVVuYXJ5KG5vZGVJc1R5cGVkQXJyYXkpIDogYmFzZUlzVHlwZWRBcnJheTsKdmFyIGlzVHlwZWRBcnJheSQxID0gaXNUeXBlZEFycmF5OwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNSA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDMgPSBvYmplY3RQcm90byQ1Lmhhc093blByb3BlcnR5OwoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5oZXJpdGVkIFNwZWNpZnkgcmV0dXJuaW5nIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lcy4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy4KICovCmZ1bmN0aW9uIGFycmF5TGlrZUtleXModmFsdWUsIGluaGVyaXRlZCkgewogIHZhciBpc0FyciA9IGlzQXJyYXkkMSh2YWx1ZSksCiAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyQxKHZhbHVlKSwKICAgIGlzQnVmZiA9ICFpc0FyciAmJiAhaXNBcmcgJiYgaXNCdWZmZXIkMSh2YWx1ZSksCiAgICBpc1R5cGUgPSAhaXNBcnIgJiYgIWlzQXJnICYmICFpc0J1ZmYgJiYgaXNUeXBlZEFycmF5JDEodmFsdWUpLAogICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLAogICAgcmVzdWx0ID0gc2tpcEluZGV4ZXMgPyBiYXNlVGltZXModmFsdWUubGVuZ3RoLCBTdHJpbmcpIDogW10sCiAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoOwogIGZvciAodmFyIGtleSBpbiB2YWx1ZSkgewogICAgaWYgKChpbmhlcml0ZWQgfHwgaGFzT3duUHJvcGVydHkkMy5jYWxsKHZhbHVlLCBrZXkpKSAmJiAhKHNraXBJbmRleGVzICYmICgKICAgIC8vIFNhZmFyaSA5IGhhcyBlbnVtZXJhYmxlIGBhcmd1bWVudHMubGVuZ3RoYCBpbiBzdHJpY3QgbW9kZS4KICAgIGtleSA9PSAnbGVuZ3RoJyB8fAogICAgLy8gTm9kZS5qcyAwLjEwIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIGJ1ZmZlcnMuCiAgICBpc0J1ZmYgJiYgKGtleSA9PSAnb2Zmc2V0JyB8fCBrZXkgPT0gJ3BhcmVudCcpIHx8CiAgICAvLyBQaGFudG9tSlMgMiBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiB0eXBlZCBhcnJheXMuCiAgICBpc1R5cGUgJiYgKGtleSA9PSAnYnVmZmVyJyB8fCBrZXkgPT0gJ2J5dGVMZW5ndGgnIHx8IGtleSA9PSAnYnl0ZU9mZnNldCcpIHx8CiAgICAvLyBTa2lwIGluZGV4IHByb3BlcnRpZXMuCiAgICBpc0luZGV4KGtleSwgbGVuZ3RoKSkpKSB7CiAgICAgIHJlc3VsdC5wdXNoKGtleSk7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDQgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxpa2VseSBhIHByb3RvdHlwZSBvYmplY3QuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNQcm90b3R5cGUodmFsdWUpIHsKICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLAogICAgcHJvdG8gPSB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlIHx8IG9iamVjdFByb3RvJDQ7CiAgcmV0dXJuIHZhbHVlID09PSBwcm90bzsKfQoKLyoqCiAqIENyZWF0ZXMgYSB1bmFyeSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50IHRyYW5zZm9ybWVkLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIGFyZ3VtZW50IHRyYW5zZm9ybS4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkgewogIHJldHVybiBmdW5jdGlvbiAoYXJnKSB7CiAgICByZXR1cm4gZnVuYyh0cmFuc2Zvcm0oYXJnKSk7CiAgfTsKfQoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqLwp2YXIgbmF0aXZlS2V5cyA9IG92ZXJBcmcoT2JqZWN0LmtleXMsIE9iamVjdCk7CnZhciBuYXRpdmVLZXlzJDEgPSBuYXRpdmVLZXlzOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kMyA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDIgPSBvYmplY3RQcm90byQzLmhhc093blByb3BlcnR5OwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmtleXNgIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLgogKi8KZnVuY3Rpb24gYmFzZUtleXMob2JqZWN0KSB7CiAgaWYgKCFpc1Byb3RvdHlwZShvYmplY3QpKSB7CiAgICByZXR1cm4gbmF0aXZlS2V5cyQxKG9iamVjdCk7CiAgfQogIHZhciByZXN1bHQgPSBbXTsKICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHsKICAgIGlmIChoYXNPd25Qcm9wZXJ0eSQyLmNhbGwob2JqZWN0LCBrZXkpICYmIGtleSAhPSAnY29uc3RydWN0b3InKSB7CiAgICAgIHJlc3VsdC5wdXNoKGtleSk7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgYXJyYXktbGlrZSBpZiBpdCdzCiAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3IKICogZXF1YWwgdG8gYDBgIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYE51bWJlci5NQVhfU0FGRV9JTlRFR0VSYC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0FycmF5TGlrZShbMSwgMiwgM10pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNBcnJheUxpa2UoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5TGlrZSgnYWJjJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5TGlrZShfLm5vb3ApOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHsKICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLgogKgogKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZQogKiBbRVMgc3BlY10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LmtleXMpCiAqIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIEBzdGF0aWMKICogQHNpbmNlIDAuMS4wCiAqIEBtZW1iZXJPZiBfCiAqIEBjYXRlZ29yeSBPYmplY3QKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLgogKiBAZXhhbXBsZQogKgogKiBmdW5jdGlvbiBGb28oKSB7CiAqICAgdGhpcy5hID0gMTsKICogICB0aGlzLmIgPSAyOwogKiB9CiAqCiAqIEZvby5wcm90b3R5cGUuYyA9IDM7CiAqCiAqIF8ua2V5cyhuZXcgRm9vKTsKICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKQogKgogKiBfLmtleXMoJ2hpJyk7CiAqIC8vID0+IFsnMCcsICcxJ10KICovCmZ1bmN0aW9uIGtleXMob2JqZWN0KSB7CiAgcmV0dXJuIGlzQXJyYXlMaWtlKG9iamVjdCkgPyBhcnJheUxpa2VLZXlzKG9iamVjdCkgOiBiYXNlS2V5cyhvYmplY3QpOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuCiAqLwpmdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHsKICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3IkMShvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTsKfQoKLyoqCiAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gY3JlYXRlQmFzZUVhY2goZWFjaEZ1bmMsIGZyb21SaWdodCkgewogIHJldHVybiBmdW5jdGlvbiAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHsKICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHsKICAgICAgcmV0dXJuIGNvbGxlY3Rpb247CiAgICB9CiAgICBpZiAoIWlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7CiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7CiAgICB9CiAgICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGgsCiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTEsCiAgICAgIGl0ZXJhYmxlID0gT2JqZWN0KGNvbGxlY3Rpb24pOwogICAgd2hpbGUgKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSB7CiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBjb2xsZWN0aW9uOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuCiAqLwp2YXIgYmFzZUVhY2ggPSBjcmVhdGVCYXNlRWFjaChiYXNlRm9yT3duKTsKdmFyIGJhc2VFYWNoJDEgPSBiYXNlRWFjaDsKCi8qKgogKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBpdCByZWNlaXZlcy4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IFV0aWwKICogQHBhcmFtIHsqfSB2YWx1ZSBBbnkgdmFsdWUuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9OwogKgogKiBjb25zb2xlLmxvZyhfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdCk7CiAqIC8vID0+IHRydWUKICovCmZ1bmN0aW9uIGlkZW50aXR5JDEodmFsdWUpIHsKICByZXR1cm4gdmFsdWU7Cn0KCi8qKgogKiBDYXN0cyBgdmFsdWVgIHRvIGBpZGVudGl0eWAgaWYgaXQncyBub3QgYSBmdW5jdGlvbi4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGNhc3QgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBjYXN0RnVuY3Rpb24odmFsdWUpIHsKICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IGlkZW50aXR5JDE7Cn0KCi8qKgogKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIGVsZW1lbnQuCiAqIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuCiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC4KICoKICogKipOb3RlOioqIEFzIHdpdGggb3RoZXIgIkNvbGxlY3Rpb25zIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSAibGVuZ3RoIgogKiBwcm9wZXJ0eSBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgdXNlIGBfLmZvckluYAogKiBvciBgXy5mb3JPd25gIGZvciBvYmplY3QgaXRlcmF0aW9uLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAYWxpYXMgZWFjaAogKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbgogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC4KICogQHNlZSBfLmZvckVhY2hSaWdodAogKiBAZXhhbXBsZQogKgogKiBfLmZvckVhY2goWzEsIDJdLCBmdW5jdGlvbih2YWx1ZSkgewogKiAgIGNvbnNvbGUubG9nKHZhbHVlKTsKICogfSk7CiAqIC8vID0+IExvZ3MgYDFgIHRoZW4gYDJgLgogKgogKiBfLmZvckVhY2goeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7CiAqICAgY29uc29sZS5sb2coa2V5KTsKICogfSk7CiAqIC8vID0+IExvZ3MgJ2EnIHRoZW4gJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLgogKi8KZnVuY3Rpb24gZm9yRWFjaChjb2xsZWN0aW9uLCBpdGVyYXRlZSkgewogIHZhciBmdW5jID0gaXNBcnJheSQxKGNvbGxlY3Rpb24pID8gYXJyYXlFYWNoIDogYmFzZUVhY2gkMTsKICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBjYXN0RnVuY3Rpb24oaXRlcmF0ZWUpKTsKfQoKLyoqCiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIHN0YWNrLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBjbGVhcgogKiBAbWVtYmVyT2YgU3RhY2sKICovCmZ1bmN0aW9uIHN0YWNrQ2xlYXIoKSB7CiAgdGhpcy5fX2RhdGFfXyA9IG5ldyBMaXN0Q2FjaGUoKTsKICB0aGlzLnNpemUgPSAwOwp9CgovKioKICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIHN0YWNrLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIFN0YWNrCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBzdGFja0RlbGV0ZShrZXkpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sCiAgICByZXN1bHQgPSBkYXRhWydkZWxldGUnXShrZXkpOwogIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogR2V0cyB0aGUgc3RhY2sgdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIFN0YWNrCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuCiAqLwpmdW5jdGlvbiBzdGFja0dldChrZXkpIHsKICByZXR1cm4gdGhpcy5fX2RhdGFfXy5nZXQoa2V5KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIHN0YWNrIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGhhcwogKiBAbWVtYmVyT2YgU3RhY2sKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIHN0YWNrSGFzKGtleSkgewogIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyhrZXkpOwp9CgovKiogVXNlZCBhcyB0aGUgc2l6ZSB0byBlbmFibGUgbGFyZ2UgYXJyYXkgb3B0aW1pemF0aW9ucy4gKi8KdmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7CgovKioKICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBTdGFjawogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBzdGFjayBjYWNoZSBpbnN0YW5jZS4KICovCmZ1bmN0aW9uIHN0YWNrU2V0KGtleSwgdmFsdWUpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187CiAgaWYgKGRhdGEgaW5zdGFuY2VvZiBMaXN0Q2FjaGUpIHsKICAgIHZhciBwYWlycyA9IGRhdGEuX19kYXRhX187CiAgICBpZiAoIU1hcCQxIHx8IHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSB7CiAgICAgIHBhaXJzLnB1c2goW2tleSwgdmFsdWVdKTsKICAgICAgdGhpcy5zaXplID0gKytkYXRhLnNpemU7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGUocGFpcnMpOwogIH0KICBkYXRhLnNldChrZXksIHZhbHVlKTsKICB0aGlzLnNpemUgPSBkYXRhLnNpemU7CiAgcmV0dXJuIHRoaXM7Cn0KCi8qKgogKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gU3RhY2soZW50cmllcykgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyA9IG5ldyBMaXN0Q2FjaGUoZW50cmllcyk7CiAgdGhpcy5zaXplID0gZGF0YS5zaXplOwp9CgovLyBBZGQgbWV0aG9kcyB0byBgU3RhY2tgLgpTdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyOwpTdGFjay5wcm90b3R5cGVbJ2RlbGV0ZSddID0gc3RhY2tEZWxldGU7ClN0YWNrLnByb3RvdHlwZS5nZXQgPSBzdGFja0dldDsKU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzOwpTdGFjay5wcm90b3R5cGUuc2V0ID0gc3RhY2tTZXQ7CgovKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovCnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJzsKCi8qKgogKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGFycmF5IGNhY2hlLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBhZGQKICogQG1lbWJlck9mIFNldENhY2hlCiAqIEBhbGlhcyBwdXNoCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNhY2hlLgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjYWNoZSBpbnN0YW5jZS4KICovCmZ1bmN0aW9uIHNldENhY2hlQWRkKHZhbHVlKSB7CiAgdGhpcy5fX2RhdGFfXy5zZXQodmFsdWUsIEhBU0hfVU5ERUZJTkVEKTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGluIHRoZSBhcnJheSBjYWNoZS4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBTZXRDYWNoZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gc2V0Q2FjaGVIYXModmFsdWUpIHsKICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXModmFsdWUpOwp9CgovKioKICoKICogQ3JlYXRlcyBhbiBhcnJheSBjYWNoZSBvYmplY3QgdG8gc3RvcmUgdW5pcXVlIHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBTZXRDYWNoZSh2YWx1ZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IHZhbHVlcyA9PSBudWxsID8gMCA6IHZhbHVlcy5sZW5ndGg7CiAgdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZSgpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB0aGlzLmFkZCh2YWx1ZXNbaW5kZXhdKTsKICB9Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBTZXRDYWNoZWAuClNldENhY2hlLnByb3RvdHlwZS5hZGQgPSBTZXRDYWNoZS5wcm90b3R5cGUucHVzaCA9IHNldENhY2hlQWRkOwpTZXRDYWNoZS5wcm90b3R5cGUuaGFzID0gc2V0Q2FjaGVIYXM7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNvbWVgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZQogKiBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssCiAqICBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBhcnJheVNvbWUoYXJyYXksIHByZWRpY2F0ZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBjYWNoZUhhcyhjYWNoZSwga2V5KSB7CiAgcmV0dXJuIGNhY2hlLmhhcyhrZXkpOwp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDUgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMyA9IDI7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBhcnJheXMgd2l0aCBzdXBwb3J0IGZvcgogKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYXJlLgogKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgYXJyYXlgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBlcXVhbEFycmF5cyhhcnJheSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHsKICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHJDUsCiAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsCiAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7CiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc1BhcnRpYWwgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICAvLyBDaGVjayB0aGF0IGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLgogIHZhciBhcnJTdGFja2VkID0gc3RhY2suZ2V0KGFycmF5KTsKICB2YXIgb3RoU3RhY2tlZCA9IHN0YWNrLmdldChvdGhlcik7CiAgaWYgKGFyclN0YWNrZWQgJiYgb3RoU3RhY2tlZCkgewogICAgcmV0dXJuIGFyclN0YWNrZWQgPT0gb3RoZXIgJiYgb3RoU3RhY2tlZCA9PSBhcnJheTsKICB9CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSB0cnVlLAogICAgc2VlbiA9IGJpdG1hc2sgJiBDT01QQVJFX1VOT1JERVJFRF9GTEFHJDMgPyBuZXcgU2V0Q2FjaGUoKSA6IHVuZGVmaW5lZDsKICBzdGFjay5zZXQoYXJyYXksIG90aGVyKTsKICBzdGFjay5zZXQob3RoZXIsIGFycmF5KTsKCiAgLy8gSWdub3JlIG5vbi1pbmRleCBwcm9wZXJ0aWVzLgogIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7CiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sCiAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdOwogICAgaWYgKGN1c3RvbWl6ZXIpIHsKICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsID8gY3VzdG9taXplcihvdGhWYWx1ZSwgYXJyVmFsdWUsIGluZGV4LCBvdGhlciwgYXJyYXksIHN0YWNrKSA6IGN1c3RvbWl6ZXIoYXJyVmFsdWUsIG90aFZhbHVlLCBpbmRleCwgYXJyYXksIG90aGVyLCBzdGFjayk7CiAgICB9CiAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkgewogICAgICBpZiAoY29tcGFyZWQpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgYnJlYWs7CiAgICB9CiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLgogICAgaWYgKHNlZW4pIHsKICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uIChvdGhWYWx1ZSwgb3RoSW5kZXgpIHsKICAgICAgICBpZiAoIWNhY2hlSGFzKHNlZW4sIG90aEluZGV4KSAmJiAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHsKICAgICAgICAgIHJldHVybiBzZWVuLnB1c2gob3RoSW5kZXgpOwogICAgICAgIH0KICAgICAgfSkpIHsKICAgICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfSBlbHNlIGlmICghKGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykpKSB7CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICB9CiAgc3RhY2tbJ2RlbGV0ZSddKGFycmF5KTsKICBzdGFja1snZGVsZXRlJ10ob3RoZXIpOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgVWludDhBcnJheSA9IHJvb3QkMS5VaW50OEFycmF5Owp2YXIgVWludDhBcnJheSQxID0gVWludDhBcnJheTsKCi8qKgogKiBDb252ZXJ0cyBgbWFwYCB0byBpdHMga2V5LXZhbHVlIHBhaXJzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gbWFwIFRoZSBtYXAgdG8gY29udmVydC4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuCiAqLwpmdW5jdGlvbiBtYXBUb0FycmF5KG1hcCkgewogIHZhciBpbmRleCA9IC0xLAogICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpOwogIG1hcC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7CiAgICByZXN1bHRbKytpbmRleF0gPSBba2V5LCB2YWx1ZV07CiAgfSk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENvbnZlcnRzIGBzZXRgIHRvIGFuIGFycmF5IG9mIGl0cyB2YWx1ZXMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBzZXQgVGhlIHNldCB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlcy4KICovCmZ1bmN0aW9uIHNldFRvQXJyYXkoc2V0KSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7CiAgc2V0LmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7CiAgICByZXN1bHRbKytpbmRleF0gPSB2YWx1ZTsKICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDQgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMiA9IDI7CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLAogIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsCiAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLAogIG1hcFRhZyQyID0gJ1tvYmplY3QgTWFwXScsCiAgbnVtYmVyVGFnJDEgPSAnW29iamVjdCBOdW1iZXJdJywKICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJywKICBzZXRUYWckMiA9ICdbb2JqZWN0IFNldF0nLAogIHN0cmluZ1RhZyQxID0gJ1tvYmplY3QgU3RyaW5nXScsCiAgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7CnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsCiAgZGF0YVZpZXdUYWckMSA9ICdbb2JqZWN0IERhdGFWaWV3XSc7CgovKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi8KdmFyIHN5bWJvbFByb3RvID0gU3ltYm9sJDEgPyBTeW1ib2wkMS5wcm90b3R5cGUgOiB1bmRlZmluZWQsCiAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZDsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGNvbXBhcmluZyBvYmplY3RzIG9mCiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuCiAqCiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY29tcGFyaW5nIHZhbHVlcyB3aXRoIHRhZ3Mgb2YKICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3RzIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy4KICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykgewogIHN3aXRjaCAodGFnKSB7CiAgICBjYXNlIGRhdGFWaWV3VGFnJDE6CiAgICAgIGlmIChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoIHx8IG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgb2JqZWN0ID0gb2JqZWN0LmJ1ZmZlcjsKICAgICAgb3RoZXIgPSBvdGhlci5idWZmZXI7CiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOgogICAgICBpZiAob2JqZWN0LmJ5dGVMZW5ndGggIT0gb3RoZXIuYnl0ZUxlbmd0aCB8fCAhZXF1YWxGdW5jKG5ldyBVaW50OEFycmF5JDEob2JqZWN0KSwgbmV3IFVpbnQ4QXJyYXkkMShvdGhlcikpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogICAgY2FzZSBib29sVGFnOgogICAgY2FzZSBkYXRlVGFnOgogICAgY2FzZSBudW1iZXJUYWckMToKICAgICAgLy8gQ29lcmNlIGJvb2xlYW5zIHRvIGAxYCBvciBgMGAgYW5kIGRhdGVzIHRvIG1pbGxpc2Vjb25kcy4KICAgICAgLy8gSW52YWxpZCBkYXRlcyBhcmUgY29lcmNlZCB0byBgTmFOYC4KICAgICAgcmV0dXJuIGVxKCtvYmplY3QsICtvdGhlcik7CiAgICBjYXNlIGVycm9yVGFnOgogICAgICByZXR1cm4gb2JqZWN0Lm5hbWUgPT0gb3RoZXIubmFtZSAmJiBvYmplY3QubWVzc2FnZSA9PSBvdGhlci5tZXNzYWdlOwogICAgY2FzZSByZWdleHBUYWc6CiAgICBjYXNlIHN0cmluZ1RhZyQxOgogICAgICAvLyBDb2VyY2UgcmVnZXhlcyB0byBzdHJpbmdzIGFuZCB0cmVhdCBzdHJpbmdzLCBwcmltaXRpdmVzIGFuZCBvYmplY3RzLAogICAgICAvLyBhcyBlcXVhbC4gU2VlIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1yZWdleHAucHJvdG90eXBlLnRvc3RyaW5nCiAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuCiAgICAgIHJldHVybiBvYmplY3QgPT0gb3RoZXIgKyAnJzsKICAgIGNhc2UgbWFwVGFnJDI6CiAgICAgIHZhciBjb252ZXJ0ID0gbWFwVG9BcnJheTsKICAgIGNhc2Ugc2V0VGFnJDI6CiAgICAgIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNDsKICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpOwogICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC4KICAgICAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTsKICAgICAgaWYgKHN0YWNrZWQpIHsKICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjsKICAgICAgfQogICAgICBiaXRtYXNrIHw9IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMjsKCiAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLgogICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7CiAgICAgIHZhciByZXN1bHQgPSBlcXVhbEFycmF5cyhjb252ZXJ0KG9iamVjdCksIGNvbnZlcnQob3RoZXIpLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTsKICAgICAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICBjYXNlIHN5bWJvbFRhZzoKICAgICAgaWYgKHN5bWJvbFZhbHVlT2YpIHsKICAgICAgICByZXR1cm4gc3ltYm9sVmFsdWVPZi5jYWxsKG9iamVjdCkgPT0gc3ltYm9sVmFsdWVPZi5jYWxsKG90aGVyKTsKICAgICAgfQogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBBcHBlbmRzIHRoZSBlbGVtZW50cyBvZiBgdmFsdWVzYCB0byBgYXJyYXlgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LgogKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcHBlbmQuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLgogKi8KZnVuY3Rpb24gYXJyYXlQdXNoKGFycmF5LCB2YWx1ZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsCiAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGFycmF5W29mZnNldCArIGluZGV4XSA9IHZhbHVlc1tpbmRleF07CiAgfQogIHJldHVybiBhcnJheTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRBbGxLZXlzYCBhbmQgYGdldEFsbEtleXNJbmAgd2hpY2ggdXNlcwogKiBga2V5c0Z1bmNgIGFuZCBgc3ltYm9sc0Z1bmNgIHRvIGdldCB0aGUgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQKICogc3ltYm9scyBvZiBgb2JqZWN0YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBzeW1ib2xzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBzeW1ib2xzIG9mIGBvYmplY3RgLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLgogKi8KZnVuY3Rpb24gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzRnVuYywgc3ltYm9sc0Z1bmMpIHsKICB2YXIgcmVzdWx0ID0ga2V5c0Z1bmMob2JqZWN0KTsKICByZXR1cm4gaXNBcnJheSQxKG9iamVjdCkgPyByZXN1bHQgOiBhcnJheVB1c2gocmVzdWx0LCBzeW1ib2xzRnVuYyhvYmplY3QpKTsKfQoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5maWx0ZXJgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS4KICovCmZ1bmN0aW9uIGFycmF5RmlsdGVyKGFycmF5LCBwcmVkaWNhdGUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLAogICAgcmVzSW5kZXggPSAwLAogICAgcmVzdWx0ID0gW107CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTsKICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHsKICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWU7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBUaGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGVtcHR5IGFycmF5LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjEzLjAKICogQGNhdGVnb3J5IFV0aWwKICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZW1wdHkgYXJyYXkuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBhcnJheXMgPSBfLnRpbWVzKDIsIF8uc3R1YkFycmF5KTsKICoKICogY29uc29sZS5sb2coYXJyYXlzKTsKICogLy8gPT4gW1tdLCBbXV0KICoKICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gc3R1YkFycmF5KCkgewogIHJldHVybiBbXTsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kMiA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8kMi5wcm9wZXJ0eUlzRW51bWVyYWJsZTsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi8KdmFyIG5hdGl2ZUdldFN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzOwoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBzeW1ib2xzLgogKi8KdmFyIGdldFN5bWJvbHMgPSAhbmF0aXZlR2V0U3ltYm9scyA/IHN0dWJBcnJheSA6IGZ1bmN0aW9uIChvYmplY3QpIHsKICBpZiAob2JqZWN0ID09IG51bGwpIHsKICAgIHJldHVybiBbXTsKICB9CiAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7CiAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24gKHN5bWJvbCkgewogICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpOwogIH0pOwp9Owp2YXIgZ2V0U3ltYm9scyQxID0gZ2V0U3ltYm9sczsKCi8qKgogKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuCiAqLwpmdW5jdGlvbiBnZXRBbGxLZXlzKG9iamVjdCkgewogIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXMsIGdldFN5bWJvbHMkMSk7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckMyA9IDE7CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQxID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkMSA9IG9iamVjdFByb3RvJDEuaGFzT3duUHJvcGVydHk7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3IKICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7CiAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyQzLAogICAgb2JqUHJvcHMgPSBnZXRBbGxLZXlzKG9iamVjdCksCiAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsCiAgICBvdGhQcm9wcyA9IGdldEFsbEtleXMob3RoZXIpLAogICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoOwogIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc1BhcnRpYWwpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoOwogIHdoaWxlIChpbmRleC0tKSB7CiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdOwogICAgaWYgKCEoaXNQYXJ0aWFsID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkkMS5jYWxsKG90aGVyLCBrZXkpKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQogIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuCiAgdmFyIG9ialN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTsKICB2YXIgb3RoU3RhY2tlZCA9IHN0YWNrLmdldChvdGhlcik7CiAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkgewogICAgcmV0dXJuIG9ialN0YWNrZWQgPT0gb3RoZXIgJiYgb3RoU3RhY2tlZCA9PSBvYmplY3Q7CiAgfQogIHZhciByZXN1bHQgPSB0cnVlOwogIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTsKICBzdGFjay5zZXQob3RoZXIsIG9iamVjdCk7CiAgdmFyIHNraXBDdG9yID0gaXNQYXJ0aWFsOwogIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7CiAgICBrZXkgPSBvYmpQcm9wc1tpbmRleF07CiAgICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSwKICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldOwogICAgaWYgKGN1c3RvbWl6ZXIpIHsKICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spIDogY3VzdG9taXplcihvYmpWYWx1ZSwgb3RoVmFsdWUsIGtleSwgb2JqZWN0LCBvdGhlciwgc3RhY2spOwogICAgfQogICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICBpZiAoIShjb21wYXJlZCA9PT0gdW5kZWZpbmVkID8gb2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSA6IGNvbXBhcmVkKSkgewogICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgYnJlYWs7CiAgICB9CiAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7CiAgfQogIGlmIChyZXN1bHQgJiYgIXNraXBDdG9yKSB7CiAgICB2YXIgb2JqQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvciwKICAgICAgb3RoQ3RvciA9IG90aGVyLmNvbnN0cnVjdG9yOwoKICAgIC8vIE5vbiBgT2JqZWN0YCBvYmplY3QgaW5zdGFuY2VzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWFsLgogICAgaWYgKG9iakN0b3IgIT0gb3RoQ3RvciAmJiAnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyICYmICEodHlwZW9mIG9iakN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvYmpDdG9yIGluc3RhbmNlb2Ygb2JqQ3RvciAmJiB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkgewogICAgICByZXN1bHQgPSBmYWxzZTsKICAgIH0KICB9CiAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7CiAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTsKICByZXR1cm4gcmVzdWx0Owp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBEYXRhVmlldyA9IGdldE5hdGl2ZShyb290JDEsICdEYXRhVmlldycpOwp2YXIgRGF0YVZpZXckMSA9IERhdGFWaWV3OwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgUHJvbWlzZSQxID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ1Byb21pc2UnKTsKdmFyIFByb21pc2UkMiA9IFByb21pc2UkMTsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi8KdmFyIFNldCA9IGdldE5hdGl2ZShyb290JDEsICdTZXQnKTsKdmFyIFNldCQxID0gU2V0OwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgV2Vha01hcCA9IGdldE5hdGl2ZShyb290JDEsICdXZWFrTWFwJyk7CnZhciBXZWFrTWFwJDEgPSBXZWFrTWFwOwoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgbWFwVGFnJDEgPSAnW29iamVjdCBNYXBdJywKICBvYmplY3RUYWckMSA9ICdbb2JqZWN0IE9iamVjdF0nLAogIHByb21pc2VUYWcgPSAnW29iamVjdCBQcm9taXNlXScsCiAgc2V0VGFnJDEgPSAnW29iamVjdCBTZXRdJywKICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nOwp2YXIgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IG1hcHMsIHNldHMsIGFuZCB3ZWFrbWFwcy4gKi8KdmFyIGRhdGFWaWV3Q3RvclN0cmluZyA9IHRvU291cmNlKERhdGFWaWV3JDEpLAogIG1hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShNYXAkMSksCiAgcHJvbWlzZUN0b3JTdHJpbmcgPSB0b1NvdXJjZShQcm9taXNlJDIpLAogIHNldEN0b3JTdHJpbmcgPSB0b1NvdXJjZShTZXQkMSksCiAgd2Vha01hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShXZWFrTWFwJDEpOwoKLyoqCiAqIEdldHMgdGhlIGB0b1N0cmluZ1RhZ2Agb2YgYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuCiAqLwp2YXIgZ2V0VGFnID0gYmFzZUdldFRhZzsKCi8vIEZhbGxiYWNrIGZvciBkYXRhIHZpZXdzLCBtYXBzLCBzZXRzLCBhbmQgd2VhayBtYXBzIGluIElFIDExIGFuZCBwcm9taXNlcyBpbiBOb2RlLmpzIDwgNi4KaWYgKERhdGFWaWV3JDEgJiYgZ2V0VGFnKG5ldyBEYXRhVmlldyQxKG5ldyBBcnJheUJ1ZmZlcigxKSkpICE9IGRhdGFWaWV3VGFnIHx8IE1hcCQxICYmIGdldFRhZyhuZXcgTWFwJDEoKSkgIT0gbWFwVGFnJDEgfHwgUHJvbWlzZSQyICYmIGdldFRhZyhQcm9taXNlJDIucmVzb2x2ZSgpKSAhPSBwcm9taXNlVGFnIHx8IFNldCQxICYmIGdldFRhZyhuZXcgU2V0JDEoKSkgIT0gc2V0VGFnJDEgfHwgV2Vha01hcCQxICYmIGdldFRhZyhuZXcgV2Vha01hcCQxKCkpICE9IHdlYWtNYXBUYWcpIHsKICBnZXRUYWcgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgIHZhciByZXN1bHQgPSBiYXNlR2V0VGFnKHZhbHVlKSwKICAgICAgQ3RvciA9IHJlc3VsdCA9PSBvYmplY3RUYWckMSA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLAogICAgICBjdG9yU3RyaW5nID0gQ3RvciA/IHRvU291cmNlKEN0b3IpIDogJyc7CiAgICBpZiAoY3RvclN0cmluZykgewogICAgICBzd2l0Y2ggKGN0b3JTdHJpbmcpIHsKICAgICAgICBjYXNlIGRhdGFWaWV3Q3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBkYXRhVmlld1RhZzsKICAgICAgICBjYXNlIG1hcEN0b3JTdHJpbmc6CiAgICAgICAgICByZXR1cm4gbWFwVGFnJDE7CiAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBwcm9taXNlVGFnOwogICAgICAgIGNhc2Ugc2V0Q3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBzZXRUYWckMTsKICAgICAgICBjYXNlIHdlYWtNYXBDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIHdlYWtNYXBUYWc7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKfQp2YXIgZ2V0VGFnJDEgPSBnZXRUYWc7CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDIgPSAxOwoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLAogIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJywKICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJzsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zCiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXIKICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy4KICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7CiAgdmFyIG9iaklzQXJyID0gaXNBcnJheSQxKG9iamVjdCksCiAgICBvdGhJc0FyciA9IGlzQXJyYXkkMShvdGhlciksCiAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnJDEob2JqZWN0KSwKICAgIG90aFRhZyA9IG90aElzQXJyID8gYXJyYXlUYWcgOiBnZXRUYWckMShvdGhlcik7CiAgb2JqVGFnID0gb2JqVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvYmpUYWc7CiAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7CiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZywKICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZywKICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7CiAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlciQxKG9iamVjdCkpIHsKICAgIGlmICghaXNCdWZmZXIkMShvdGhlcikpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgb2JqSXNBcnIgPSB0cnVlOwogICAgb2JqSXNPYmogPSBmYWxzZTsKICB9CiAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHsKICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjaygpKTsKICAgIHJldHVybiBvYmpJc0FyciB8fCBpc1R5cGVkQXJyYXkkMShvYmplY3QpID8gZXF1YWxBcnJheXMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykgOiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIG9ialRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7CiAgfQogIGlmICghKGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyQyKSkgewogICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSwKICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7CiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkgewogICAgICB2YXIgb2JqVW53cmFwcGVkID0gb2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsCiAgICAgICAgb3RoVW53cmFwcGVkID0gb3RoSXNXcmFwcGVkID8gb3RoZXIudmFsdWUoKSA6IG90aGVyOwogICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2soKSk7CiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTsKICAgIH0KICB9CiAgaWYgKCFpc1NhbWVUYWcpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKCkpOwogIHJldHVybiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zCiAqIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4KICogIDEgLSBVbm9yZGVyZWQgY29tcGFyaXNvbgogKiAgMiAtIFBhcnRpYWwgY29tcGFyaXNvbgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSB7CiAgaWYgKHZhbHVlID09PSBvdGhlcikgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmICh2YWx1ZSA9PSBudWxsIHx8IG90aGVyID09IG51bGwgfHwgIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpIHsKICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyOwogIH0KICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgYmFzZUlzRXF1YWwsIHN0YWNrKTsKfQoKLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovCnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyQxID0gMSwKICBDT01QQVJFX1VOT1JERVJFRF9GTEFHJDEgPSAyOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWF0Y2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuCiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guCiAqIEBwYXJhbSB7QXJyYXl9IG1hdGNoRGF0YSBUaGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3MgdG8gbWF0Y2guCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIG1hdGNoRGF0YSwgY3VzdG9taXplcikgewogIHZhciBpbmRleCA9IG1hdGNoRGF0YS5sZW5ndGgsCiAgICBsZW5ndGggPSBpbmRleCwKICAgIG5vQ3VzdG9taXplciA9ICFjdXN0b21pemVyOwogIGlmIChvYmplY3QgPT0gbnVsbCkgewogICAgcmV0dXJuICFsZW5ndGg7CiAgfQogIG9iamVjdCA9IE9iamVjdChvYmplY3QpOwogIHdoaWxlIChpbmRleC0tKSB7CiAgICB2YXIgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07CiAgICBpZiAobm9DdXN0b21pemVyICYmIGRhdGFbMl0gPyBkYXRhWzFdICE9PSBvYmplY3RbZGF0YVswXV0gOiAhKGRhdGFbMF0gaW4gb2JqZWN0KSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTsKICAgIHZhciBrZXkgPSBkYXRhWzBdLAogICAgICBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLAogICAgICBzcmNWYWx1ZSA9IGRhdGFbMV07CiAgICBpZiAobm9DdXN0b21pemVyICYmIGRhdGFbMl0pIHsKICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgdmFyIHN0YWNrID0gbmV3IFN0YWNrKCk7CiAgICAgIGlmIChjdXN0b21pemVyKSB7CiAgICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjayk7CiAgICAgIH0KICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWQgPyBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIENPTVBBUkVfUEFSVElBTF9GTEFHJDEgfCBDT01QQVJFX1VOT1JERVJFRF9GTEFHJDEsIGN1c3RvbWl6ZXIsIHN0YWNrKSA6IHJlc3VsdCkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn0KCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdAogKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTsKfQoKLyoqCiAqIEdldHMgdGhlIHByb3BlcnR5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC4KICovCmZ1bmN0aW9uIGdldE1hdGNoRGF0YShvYmplY3QpIHsKICB2YXIgcmVzdWx0ID0ga2V5cyhvYmplY3QpLAogICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDsKICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgIHZhciBrZXkgPSByZXN1bHRbbGVuZ3RoXSwKICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTsKICAgIHJlc3VsdFtsZW5ndGhdID0gW2tleSwgdmFsdWUsIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSldOwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBtYXRjaGVzUHJvcGVydHlgIGZvciBzb3VyY2UgdmFsdWVzIHN1aXRhYmxlCiAqIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKGtleSwgc3JjVmFsdWUpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgaWYgKG9iamVjdCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiBvYmplY3Rba2V5XSA9PT0gc3JjVmFsdWUgJiYgKHNyY1ZhbHVlICE9PSB1bmRlZmluZWQgfHwga2V5IGluIE9iamVjdChvYmplY3QpKTsKICB9Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lc24ndCBjbG9uZSBgc291cmNlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VNYXRjaGVzKHNvdXJjZSkgewogIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTsKICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkgewogICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKG1hdGNoRGF0YVswXVswXSwgbWF0Y2hEYXRhWzBdWzFdKTsKICB9CiAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QpIHsKICAgIHJldHVybiBvYmplY3QgPT09IHNvdXJjZSB8fCBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhKTsKICB9Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaGFzSW5gIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBrZXkgVGhlIGtleSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUhhc0luKG9iamVjdCwga2V5KSB7CiAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGtleSBpbiBPYmplY3Qob2JqZWN0KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgcGF0aGAgZXhpc3RzIG9uIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNGdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjayBwcm9wZXJ0aWVzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHBhdGhgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzUGF0aChvYmplY3QsIHBhdGgsIGhhc0Z1bmMpIHsKICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoLAogICAgcmVzdWx0ID0gZmFsc2U7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBrZXkgPSB0b0tleShwYXRoW2luZGV4XSk7CiAgICBpZiAoIShyZXN1bHQgPSBvYmplY3QgIT0gbnVsbCAmJiBoYXNGdW5jKG9iamVjdCwga2V5KSkpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgICBvYmplY3QgPSBvYmplY3Rba2V5XTsKICB9CiAgaWYgKHJlc3VsdCB8fCArK2luZGV4ICE9IGxlbmd0aCkgewogICAgcmV0dXJuIHJlc3VsdDsKICB9CiAgbGVuZ3RoID0gb2JqZWN0ID09IG51bGwgPyAwIDogb2JqZWN0Lmxlbmd0aDsKICByZXR1cm4gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSAmJiAoaXNBcnJheSQxKG9iamVjdCkgfHwgaXNBcmd1bWVudHMkMShvYmplY3QpKTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgcGF0aGAgaXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG9mIGBvYmplY3RgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgT2JqZWN0CiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBvYmplY3QgPSBfLmNyZWF0ZSh7ICdhJzogXy5jcmVhdGUoeyAnYic6IDIgfSkgfSk7CiAqCiAqIF8uaGFzSW4ob2JqZWN0LCAnYScpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaGFzSW4ob2JqZWN0LCAnYS5iJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5oYXNJbihvYmplY3QsIFsnYScsICdiJ10pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaGFzSW4ob2JqZWN0LCAnYicpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaGFzSW4ob2JqZWN0LCBwYXRoKSB7CiAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGhhc1BhdGgob2JqZWN0LCBwYXRoLCBiYXNlSGFzSW4pOwp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMSwKICBDT01QQVJFX1VOT1JERVJFRF9GTEFHID0gMjsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzUHJvcGVydHlgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNyY1ZhbHVlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7CiAgaWYgKGlzS2V5KHBhdGgpICYmIGlzU3RyaWN0Q29tcGFyYWJsZShzcmNWYWx1ZSkpIHsKICAgIHJldHVybiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZSh0b0tleShwYXRoKSwgc3JjVmFsdWUpOwogIH0KICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgdmFyIG9ialZhbHVlID0gZ2V0KG9iamVjdCwgcGF0aCk7CiAgICByZXR1cm4gb2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvYmpWYWx1ZSA9PT0gc3JjVmFsdWUgPyBoYXNJbihvYmplY3QsIHBhdGgpIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eWAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlUHJvcGVydHkoa2V5KSB7CiAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QpIHsKICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldOwogIH07Cn0KCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VQcm9wZXJ0eWAgd2hpY2ggc3VwcG9ydHMgZGVlcCBwYXRocy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgcmV0dXJuIGJhc2VHZXQob2JqZWN0LCBwYXRoKTsKICB9Owp9CgovKioKICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgdmFsdWUgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAyLjQuMAogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdHMgPSBbCiAqICAgeyAnYSc6IHsgJ2InOiAyIH0gfSwKICogICB7ICdhJzogeyAnYic6IDEgfSB9CiAqIF07CiAqCiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYicpKTsKICogLy8gPT4gWzIsIDFdCiAqCiAqIF8ubWFwKF8uc29ydEJ5KG9iamVjdHMsIF8ucHJvcGVydHkoWydhJywgJ2InXSkpLCAnYS5iJyk7CiAqIC8vID0+IFsxLCAyXQogKi8KZnVuY3Rpb24gcHJvcGVydHkocGF0aCkgewogIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eSh0b0tleShwYXRoKSkgOiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXRlcmF0ZWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IFt2YWx1ZT1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhbiBpdGVyYXRlZS4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBpdGVyYXRlZS4KICovCmZ1bmN0aW9uIGJhc2VJdGVyYXRlZSh2YWx1ZSkgewogIC8vIERvbid0IHN0b3JlIHRoZSBgdHlwZW9mYCByZXN1bHQgaW4gYSB2YXJpYWJsZSB0byBhdm9pZCBhIEpJVCBidWcgaW4gU2FmYXJpIDkuCiAgLy8gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNTYwMzQgZm9yIG1vcmUgZGV0YWlscy4KICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CiAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgIHJldHVybiBpZGVudGl0eSQxOwogIH0KICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7CiAgICByZXR1cm4gaXNBcnJheSQxKHZhbHVlKSA/IGJhc2VNYXRjaGVzUHJvcGVydHkodmFsdWVbMF0sIHZhbHVlWzFdKSA6IGJhc2VNYXRjaGVzKHZhbHVlKTsKICB9CiAgcmV0dXJuIHByb3BlcnR5KHZhbHVlKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hcGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS4KICovCmZ1bmN0aW9uIGJhc2VNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107CiAgYmFzZUVhY2gkMShjb2xsZWN0aW9uLCBmdW5jdGlvbiAodmFsdWUsIGtleSwgY29sbGVjdGlvbikgewogICAgcmVzdWx0WysraW5kZXhdID0gaXRlcmF0ZWUodmFsdWUsIGtleSwgY29sbGVjdGlvbik7CiAgfSk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJ1CiAqIGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOgogKiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuCiAqCiAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZQogKiBgXy5ldmVyeWAsIGBfLmZpbHRlcmAsIGBfLm1hcGAsIGBfLm1hcFZhbHVlc2AsIGBfLnJlamVjdGAsIGFuZCBgXy5zb21lYC4KICoKICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6CiAqIGBhcnlgLCBgY2h1bmtgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBldmVyeWAsCiAqIGBmaWxsYCwgYGludmVydGAsIGBwYXJzZUludGAsIGByYW5kb21gLCBgcmFuZ2VgLCBgcmFuZ2VSaWdodGAsIGByZXBlYXRgLAogKiBgc2FtcGxlU2l6ZWAsIGBzbGljZWAsIGBzb21lYCwgYHNvcnRCeWAsIGBzcGxpdGAsIGB0YWtlYCwgYHRha2VSaWdodGAsCiAqIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1FbmRgLCBgdHJpbVN0YXJ0YCwgYW5kIGB3b3Jkc2AKICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IENvbGxlY3Rpb24KICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LgogKiBAZXhhbXBsZQogKgogKiBmdW5jdGlvbiBzcXVhcmUobikgewogKiAgIHJldHVybiBuICogbjsKICogfQogKgogKiBfLm1hcChbNCwgOF0sIHNxdWFyZSk7CiAqIC8vID0+IFsxNiwgNjRdCiAqCiAqIF8ubWFwKHsgJ2EnOiA0LCAnYic6IDggfSwgc3F1YXJlKTsKICogLy8gPT4gWzE2LCA2NF0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkKICoKICogdmFyIHVzZXJzID0gWwogKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LAogKiAgIHsgJ3VzZXInOiAnZnJlZCcgfQogKiBdOwogKgogKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC4KICogXy5tYXAodXNlcnMsICd1c2VyJyk7CiAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXQogKi8KZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7CiAgdmFyIGZ1bmMgPSBpc0FycmF5JDEoY29sbGVjdGlvbikgPyBhcnJheU1hcCA6IGJhc2VNYXA7CiAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgYmFzZUl0ZXJhdGVlKGl0ZXJhdGVlKSk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zdW1gIGFuZCBgXy5zdW1CeWAgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uCiAqLwpmdW5jdGlvbiBiYXNlU3VtKGFycmF5LCBpdGVyYXRlZSkgewogIHZhciByZXN1bHQsCiAgICBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgY3VycmVudCA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSk7CiAgICBpZiAoY3VycmVudCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gY3VycmVudCA6IHJlc3VsdCArIGN1cnJlbnQ7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBDb21wdXRlcyB0aGUgc3VtIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMy40LjAKICogQGNhdGVnb3J5IE1hdGgKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLgogKiBAZXhhbXBsZQogKgogKiBfLnN1bShbNCwgMiwgOCwgNl0pOwogKiAvLyA9PiAyMAogKi8KZnVuY3Rpb24gc3VtJDEoYXJyYXkpIHsKICByZXR1cm4gYXJyYXkgJiYgYXJyYXkubGVuZ3RoID8gYmFzZVN1bShhcnJheSwgaWRlbnRpdHkkMSkgOiAwOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3RyaW5nLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNTdHJpbmcoJ2FiYycpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNTdHJpbmcoMSk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgIWlzQXJyYXkkMSh2YWx1ZSkgJiYgaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBzdHJpbmdUYWc7Cn0KCi8qKgogKiBHZXRzIHRoZSBzaXplIG9mIGFuIEFTQ0lJIGBzdHJpbmdgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuCiAqLwp2YXIgYXNjaWlTaXplID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTsKdmFyIGFzY2lpU2l6ZSQxID0gYXNjaWlTaXplOwoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNoYXJhY3RlciBjbGFzc2VzLiAqLwp2YXIgcnNBc3RyYWxSYW5nZSQxID0gJ1xcdWQ4MDAtXFx1ZGZmZicsCiAgcnNDb21ib01hcmtzUmFuZ2UkMSA9ICdcXHUwMzAwLVxcdTAzNmYnLAogIHJlQ29tYm9IYWxmTWFya3NSYW5nZSQxID0gJ1xcdWZlMjAtXFx1ZmUyZicsCiAgcnNDb21ib1N5bWJvbHNSYW5nZSQxID0gJ1xcdTIwZDAtXFx1MjBmZicsCiAgcnNDb21ib1JhbmdlJDEgPSByc0NvbWJvTWFya3NSYW5nZSQxICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlJDEgKyByc0NvbWJvU3ltYm9sc1JhbmdlJDEsCiAgcnNWYXJSYW5nZSQxID0gJ1xcdWZlMGVcXHVmZTBmJzsKCi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi8KdmFyIHJzWldKJDEgPSAnXFx1MjAwZCc7CgovKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB3aXRoIFt6ZXJvLXdpZHRoIGpvaW5lcnMgb3IgY29kZSBwb2ludHMgZnJvbSB0aGUgYXN0cmFsIHBsYW5lc10oaHR0cDovL2Vldi5lZS9ibG9nLzIwMTUvMDkvMTIvZGFyay1jb3JuZXJzLW9mLXVuaWNvZGUvKS4gKi8KdmFyIHJlSGFzVW5pY29kZSA9IFJlZ0V4cCgnWycgKyByc1pXSiQxICsgcnNBc3RyYWxSYW5nZSQxICsgcnNDb21ib1JhbmdlJDEgKyByc1ZhclJhbmdlJDEgKyAnXScpOwoKLyoqCiAqIENoZWNrcyBpZiBgc3RyaW5nYCBjb250YWlucyBVbmljb2RlIHN5bWJvbHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYSBzeW1ib2wgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGhhc1VuaWNvZGUoc3RyaW5nKSB7CiAgcmV0dXJuIHJlSGFzVW5pY29kZS50ZXN0KHN0cmluZyk7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi8KdmFyIHJzQXN0cmFsUmFuZ2UgPSAnXFx1ZDgwMC1cXHVkZmZmJywKICByc0NvbWJvTWFya3NSYW5nZSA9ICdcXHUwMzAwLVxcdTAzNmYnLAogIHJlQ29tYm9IYWxmTWFya3NSYW5nZSA9ICdcXHVmZTIwLVxcdWZlMmYnLAogIHJzQ29tYm9TeW1ib2xzUmFuZ2UgPSAnXFx1MjBkMC1cXHUyMGZmJywKICByc0NvbWJvUmFuZ2UgPSByc0NvbWJvTWFya3NSYW5nZSArIHJlQ29tYm9IYWxmTWFya3NSYW5nZSArIHJzQ29tYm9TeW1ib2xzUmFuZ2UsCiAgcnNWYXJSYW5nZSA9ICdcXHVmZTBlXFx1ZmUwZic7CgovKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2FwdHVyZSBncm91cHMuICovCnZhciByc0FzdHJhbCA9ICdbJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsCiAgcnNDb21ibyA9ICdbJyArIHJzQ29tYm9SYW5nZSArICddJywKICByc0ZpdHogPSAnXFx1ZDgzY1tcXHVkZmZiLVxcdWRmZmZdJywKICByc01vZGlmaWVyID0gJyg/OicgKyByc0NvbWJvICsgJ3wnICsgcnNGaXR6ICsgJyknLAogIHJzTm9uQXN0cmFsID0gJ1teJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsCiAgcnNSZWdpb25hbCA9ICcoPzpcXHVkODNjW1xcdWRkZTYtXFx1ZGRmZl0pezJ9JywKICByc1N1cnJQYWlyID0gJ1tcXHVkODAwLVxcdWRiZmZdW1xcdWRjMDAtXFx1ZGZmZl0nLAogIHJzWldKID0gJ1xcdTIwMGQnOwoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIHJlZ2V4ZXMuICovCnZhciByZU9wdE1vZCA9IHJzTW9kaWZpZXIgKyAnPycsCiAgcnNPcHRWYXIgPSAnWycgKyByc1ZhclJhbmdlICsgJ10/JywKICByc09wdEpvaW4gPSAnKD86JyArIHJzWldKICsgJyg/OicgKyBbcnNOb25Bc3RyYWwsIHJzUmVnaW9uYWwsIHJzU3VyclBhaXJdLmpvaW4oJ3wnKSArICcpJyArIHJzT3B0VmFyICsgcmVPcHRNb2QgKyAnKSonLAogIHJzU2VxID0gcnNPcHRWYXIgKyByZU9wdE1vZCArIHJzT3B0Sm9pbiwKICByc1N5bWJvbCA9ICcoPzonICsgW3JzTm9uQXN0cmFsICsgcnNDb21ibyArICc/JywgcnNDb21ibywgcnNSZWdpb25hbCwgcnNTdXJyUGFpciwgcnNBc3RyYWxdLmpvaW4oJ3wnKSArICcpJzsKCi8qKiBVc2VkIHRvIG1hdGNoIFtzdHJpbmcgc3ltYm9sc10oaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtdW5pY29kZSkuICovCnZhciByZVVuaWNvZGUgPSBSZWdFeHAocnNGaXR6ICsgJyg/PScgKyByc0ZpdHogKyAnKXwnICsgcnNTeW1ib2wgKyByc1NlcSwgJ2cnKTsKCi8qKgogKiBHZXRzIHRoZSBzaXplIG9mIGEgVW5pY29kZSBgc3RyaW5nYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIGluc3BlY3QuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN0cmluZyBzaXplLgogKi8KZnVuY3Rpb24gdW5pY29kZVNpemUoc3RyaW5nKSB7CiAgdmFyIHJlc3VsdCA9IHJlVW5pY29kZS5sYXN0SW5kZXggPSAwOwogIHdoaWxlIChyZVVuaWNvZGUudGVzdChzdHJpbmcpKSB7CiAgICArK3Jlc3VsdDsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIEdldHMgdGhlIG51bWJlciBvZiBzeW1ib2xzIGluIGBzdHJpbmdgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuCiAqLwpmdW5jdGlvbiBzdHJpbmdTaXplKHN0cmluZykgewogIHJldHVybiBoYXNVbmljb2RlKHN0cmluZykgPyB1bmljb2RlU2l6ZShzdHJpbmcpIDogYXNjaWlTaXplJDEoc3RyaW5nKTsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsCiAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XSc7CgovKioKICogR2V0cyB0aGUgc2l6ZSBvZiBgY29sbGVjdGlvbmAgYnkgcmV0dXJuaW5nIGl0cyBsZW5ndGggZm9yIGFycmF5LWxpa2UKICogdmFsdWVzIG9yIHRoZSBudW1iZXIgb2Ygb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgZm9yIG9iamVjdHMuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIHNpemUuCiAqIEBleGFtcGxlCiAqCiAqIF8uc2l6ZShbMSwgMiwgM10pOwogKiAvLyA9PiAzCiAqCiAqIF8uc2l6ZSh7ICdhJzogMSwgJ2InOiAyIH0pOwogKiAvLyA9PiAyCiAqCiAqIF8uc2l6ZSgncGViYmxlcycpOwogKiAvLyA9PiA3CiAqLwpmdW5jdGlvbiBzaXplKGNvbGxlY3Rpb24pIHsKICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7CiAgICByZXR1cm4gMDsKICB9CiAgaWYgKGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7CiAgICByZXR1cm4gaXNTdHJpbmcoY29sbGVjdGlvbikgPyBzdHJpbmdTaXplKGNvbGxlY3Rpb24pIDogY29sbGVjdGlvbi5sZW5ndGg7CiAgfQogIHZhciB0YWcgPSBnZXRUYWckMShjb2xsZWN0aW9uKTsKICBpZiAodGFnID09IG1hcFRhZyB8fCB0YWcgPT0gc2V0VGFnKSB7CiAgICByZXR1cm4gY29sbGVjdGlvbi5zaXplOwogIH0KICByZXR1cm4gYmFzZUtleXMoY29sbGVjdGlvbikubGVuZ3RoOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYE51bWJlcmAgcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogKipOb3RlOioqIFRvIGV4Y2x1ZGUgYEluZmluaXR5YCwgYC1JbmZpbml0eWAsIGFuZCBgTmFOYCwgd2hpY2ggYXJlCiAqIGNsYXNzaWZpZWQgYXMgbnVtYmVycywgdXNlIHRoZSBgXy5pc0Zpbml0ZWAgbWV0aG9kLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBudW1iZXIsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc051bWJlcigzKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNOdW1iZXIoSW5maW5pdHkpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNOdW1iZXIoJzMnKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzTnVtYmVyKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IG51bWJlclRhZzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnianku7YNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc29iai50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNvYmooe30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzb2JqKHsgYTogMTIzIH0pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc29iaih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IE9iamVjdF0nOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuacieaViOeJqeS7tg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzb2JqLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VvYmooe30pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VvYmooeyBhOiAxMjMgfSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzZW9iaih2KSB7CiAgaWYgKGlzb2JqKHYpKSB7CiAgICBmb3IgKGxldCBrIGluIHYpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrpmaPliJcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2Fyci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNhcnIoW10pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzYXJyKFt7fV0pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2Fycih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IEFycmF5XSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K6dW5kZWZpbmVkDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXN1bmRlZmluZWQudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzdW5kZWZpbmVkKHVuZGVmaW5lZCkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzdW5kZWZpbmVkKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgVW5kZWZpbmVkXSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K6bnVsbA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzbnVsbC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNudWxsKG51bGwpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc251bGwodikgewogIGxldCBjID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpOwogIHJldHVybiBjID09PSAnW29iamVjdCBOdWxsXSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K656m654mp5Lu2DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNvYmowLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc29iajAoe30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzb2JqMCh7IGE6IDEyMyB9KSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzb2JqMCh2KSB7CiAgaWYgKGlzb2JqKHYpKSB7CiAgICBmb3IgKGxldCBrIGluIHYpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnqbrlrZfkuLINCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc3N0cjAudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyMCgnJykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIwKCcwJykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyMCgnYWJjMTI1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc3N0cjAodikgewogIGlmIChpc3N0cih2KSkgewogICAgaWYgKHYgPT09ICcnKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K654Sh5YWn5a656Zmj5YiXDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNhcnIwLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2FycihbXSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNhcnIoW3t9XSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2FycjAodikgewogIGlmIChpc2Fycih2KSkgewogICAgaWYgKHYubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8vIGltcG9ydCBpc05hTiBmcm9tICdsb2Rhc2gtZXMvaXNOYU4uanMnCgovKioNCiAqIOWIpOaWt+aYr+WQpueCuk5hTg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzbmFuLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc25hbihOYU4pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc25hbih2KSB7CiAgLy8gcmV0dXJuIGlzTmFOKHYpCiAgcmV0dXJuIHYgIT09IHY7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65buj576p54Sh5pWIDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNlci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNlcignMTJhNScpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKCcnKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKFtdKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKFt7fV0pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKFsnJ10pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKHt9KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKG51bGwpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIodW5kZWZpbmVkKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKE5hTikpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzZXIodikgewogIGlmIChpc3VuZGVmaW5lZCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc251bGwodikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICBpZiAoaXNvYmowKHYpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKGlzc3RyMCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc2FycjAodikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICBpZiAoaXNuYW4odikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pyJ5pWI6Zmj5YiX77yM6ZW35bqm6Iez5bCR5aSn5pa8562J5pa8Me+8jOWQhOWFg+e0oOiHs+WwkeeahueCuuacieaViA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzZWFyci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNlYXJyKFt7fV0pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VhcnIoW3sgYTogMTIzIH1dKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNlYXJyKHYpIHsKICAvL2NoZWNrCiAgaWYgKCFpc2Fycih2KSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy9jaGVjayBsZW5ndGgKICBpZiAodi5sZW5ndGggPT09IDApIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIC8vY2hlY2sgbGVuZ3RoPTEKICBpZiAodi5sZW5ndGggPT09IDEpIHsKICAgIGlmIChpc2VyKHZbMF0pKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pW45a2XDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNuYnIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbmJyKDEuMjUpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbmJyKCcxLjI1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc25icih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IE51bWJlcl0nOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuaVuOWtlw0KICoNCiAqIOazqOaEj++8muacrOWHveW8j+S4jeaUr+aPtEJpZ0ludO+8jHR5cGVvZiBCaWdJbnTlgLzngronYmlnaW50J+iAjOmdnidudW1iZXIn5pWFaXNuYnLliKTlrprngrpmYWxzZeOAgg0KICogQmlnSW506IiHTnVtYmVy5ZyoSlPngrrkupLkuI3nm7jlrrnnmoTnrpfooZPln58oYDFuICsgMWDjgIFgTWF0aC5mbG9vcigxbilgIOeahuaTslR5cGVFcnJvcinvvIwNCiAqIOiAjGlzbnVt55qE6Zqx5ZCr5aWR57SE5piv44CM6YCa6YGO5b6M5Y+v5YGaTnVtYmVy566X6KGT6YGL566X44CN77yMd3NlbWnlhafpgL42MOiZlWNhbGxzaXRl5L6d6LO05q2k5aWR57SEDQogKiAo5aaCYXJyTWF4L2Fyck1pbi9yb3VuZC9yYW5kb21SYW5nZeetiSnvvIzoi6XmlL7lr6xpc251beiqjUJpZ0ludOWwh+WwjuiHtOmAmeS6m2NhbGxzaXRl5Z+36KGM5pyf6Yyv6Kqk44CCDQogKiDmraToqK3oqIjoiIdsb2Rhc2ggYF8uaXNOdW1iZXJgIOWwh0JpZ0ludOaOkumZpOeahOiZleeQhuS4gOiHtOOAgkJpZ0ludOiri+WPpuS9nOeNqOeri+WIpOaWt+OAgg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzbnVtLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bSgwKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bSgxLjI1KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bSgnLTEyNScpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKDEyM24pKQ0KICogLy8gPT4gZmFsc2UgKEJpZ0ludOS4jeiiq+imlueCuuaVuOWtlywg6Kmz6KaL5LiK5pa56Kqq5piOKQ0KICoNCiAqLwpmdW5jdGlvbiBpc251bSh2KSB7CiAgbGV0IGIgPSBmYWxzZTsKICBpZiAoaXNlc3RyKHYpKSB7CiAgICBiID0gIWlzTmFOKE51bWJlcih2KSk7CiAgfSBlbHNlIGlmIChpc25icih2KSkgewogICAgLy/ms6jmhI9OYU7ngrpOdW1iZXIsIOaVhWlzbmJy5Zue5YKzdHJ1ZQogICAgaWYgKGlzbmFuKHYpKSB7CiAgICAgIHJldHVybiBmYWxzZTsgLy/mraTomZXliKTlrprngrrmnInmlYjmlbjlrZcsIOaVhU5hTumgiOWJlOmZpAogICAgfSBlbHNlIHsKICAgICAgYiA9IHRydWU7CiAgICB9CiAgfQogIHJldHVybiBiOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuWHveaVuA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzZnVuLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2Z1bignMS4yNScpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2Z1bihmdW5jdGlvbigpIHt9KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNmdW4odikgewogIGxldCBjID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpOwogIHJldHVybiBjID09PSAnW29iamVjdCBGdW5jdGlvbl0nIHx8IGMgPT09ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJzsKfQoKLyoqIFVzZWQgdG8gbWF0Y2ggYSBzaW5nbGUgd2hpdGVzcGFjZSBjaGFyYWN0ZXIuICovCnZhciByZVdoaXRlc3BhY2UgPSAvXHMvOwoKLyoqCiAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1FbmRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9uLXdoaXRlc3BhY2UKICogY2hhcmFjdGVyIG9mIGBzdHJpbmdgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyLgogKi8KZnVuY3Rpb24gdHJpbW1lZEVuZEluZGV4KHN0cmluZykgewogIHZhciBpbmRleCA9IHN0cmluZy5sZW5ndGg7CiAgd2hpbGUgKGluZGV4LS0gJiYgcmVXaGl0ZXNwYWNlLnRlc3Qoc3RyaW5nLmNoYXJBdChpbmRleCkpKSB7fQogIHJldHVybiBpbmRleDsKfQoKLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyB3aGl0ZXNwYWNlLiAqLwp2YXIgcmVUcmltU3RhcnQgPSAvXlxzKy87CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udHJpbWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byB0cmltLgogKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy4KICovCmZ1bmN0aW9uIGJhc2VUcmltKHN0cmluZykgewogIHJldHVybiBzdHJpbmcgPyBzdHJpbmcuc2xpY2UoMCwgdHJpbW1lZEVuZEluZGV4KHN0cmluZykgKyAxKS5yZXBsYWNlKHJlVHJpbVN0YXJ0LCAnJykgOiBzdHJpbmc7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgTkFOJDEgPSAwIC8gMDsKCi8qKiBVc2VkIHRvIGRldGVjdCBiYWQgc2lnbmVkIGhleGFkZWNpbWFsIHN0cmluZyB2YWx1ZXMuICovCnZhciByZUlzQmFkSGV4ID0gL15bLStdMHhbMC05YS1mXSskL2k7CgovKiogVXNlZCB0byBkZXRlY3QgYmluYXJ5IHN0cmluZyB2YWx1ZXMuICovCnZhciByZUlzQmluYXJ5ID0gL14wYlswMV0rJC9pOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IG9jdGFsIHN0cmluZyB2YWx1ZXMuICovCnZhciByZUlzT2N0YWwgPSAvXjBvWzAtN10rJC9pOwoKLyoqIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHdpdGhvdXQgYSBkZXBlbmRlbmN5IG9uIGByb290YC4gKi8KdmFyIGZyZWVQYXJzZUludCA9IHBhcnNlSW50OwoKLyoqCiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBudW1iZXIuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci4KICogQGV4YW1wbGUKICoKICogXy50b051bWJlcigzLjIpOwogKiAvLyA9PiAzLjIKICoKICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTsKICogLy8gPT4gNWUtMzI0CiAqCiAqIF8udG9OdW1iZXIoSW5maW5pdHkpOwogKiAvLyA9PiBJbmZpbml0eQogKgogKiBfLnRvTnVtYmVyKCczLjInKTsKICogLy8gPT4gMy4yCiAqLwpmdW5jdGlvbiB0b051bWJlcih2YWx1ZSkgewogIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CiAgaWYgKGlzU3ltYm9sKHZhbHVlKSkgewogICAgcmV0dXJuIE5BTiQxOwogIH0KICBpZiAoaXNPYmplY3QodmFsdWUpKSB7CiAgICB2YXIgb3RoZXIgPSB0eXBlb2YgdmFsdWUudmFsdWVPZiA9PSAnZnVuY3Rpb24nID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7CiAgICB2YWx1ZSA9IGlzT2JqZWN0KG90aGVyKSA/IG90aGVyICsgJycgOiBvdGhlcjsKICB9CiAgaWYgKHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgewogICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7CiAgfQogIHZhbHVlID0gYmFzZVRyaW0odmFsdWUpOwogIHZhciBpc0JpbmFyeSA9IHJlSXNCaW5hcnkudGVzdCh2YWx1ZSk7CiAgcmV0dXJuIGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOCkgOiByZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOJDEgOiArdmFsdWU7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgSU5GSU5JVFkgPSAxIC8gMCwKICBNQVhfSU5URUdFUiA9IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4OwoKLyoqCiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBmaW5pdGUgbnVtYmVyLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjEyLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIG51bWJlci4KICogQGV4YW1wbGUKICoKICogXy50b0Zpbml0ZSgzLjIpOwogKiAvLyA9PiAzLjIKICoKICogXy50b0Zpbml0ZShOdW1iZXIuTUlOX1ZBTFVFKTsKICogLy8gPT4gNWUtMzI0CiAqCiAqIF8udG9GaW5pdGUoSW5maW5pdHkpOwogKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOAogKgogKiBfLnRvRmluaXRlKCczLjInKTsKICogLy8gPT4gMy4yCiAqLwpmdW5jdGlvbiB0b0Zpbml0ZSh2YWx1ZSkgewogIGlmICghdmFsdWUpIHsKICAgIHJldHVybiB2YWx1ZSA9PT0gMCA/IHZhbHVlIDogMDsKICB9CiAgdmFsdWUgPSB0b051bWJlcih2YWx1ZSk7CiAgaWYgKHZhbHVlID09PSBJTkZJTklUWSB8fCB2YWx1ZSA9PT0gLUlORklOSVRZKSB7CiAgICB2YXIgc2lnbiA9IHZhbHVlIDwgMCA/IC0xIDogMTsKICAgIHJldHVybiBzaWduICogTUFYX0lOVEVHRVI7CiAgfQogIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgPyB2YWx1ZSA6IDA7Cn0KCi8qKg0KICog5pW45a2X5oiW5a2X5Liy6L2J5rWu6bue5pW4DQogKiDoi6XovLjlhaXpnZ7mlbjlrZfliYflm57lgrMwDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvY2RibC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7TnVtYmVyfFN0cmluZ30gdiDovLjlhaXmlbjlrZfmiJblrZfkuLINCiAqIEByZXR1cm5zIHtOdW1iZXJ9IOWbnuWCs+aVuOWtlw0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhjZGJsKCcyNScpKQ0KICogLy8gPT4gMjUNCiAqDQogKi8KZnVuY3Rpb24gY2RibCh2KSB7CiAgLy9jaGVjawogIGlmICghaXNudW0odikpIHsKICAgIHJldHVybiAwOwogIH0KICBsZXQgciA9IHRvRmluaXRlKHYpOwogIHJldHVybiByOwp9CgovKioNCiAqIOWIpOaWt+eJqeS7tuaYr+WQpuaciWtleeWxrOaApw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2hhc2tleS50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmog6Ly45YWl54mp5Lu2DQogKiBAcGFyYW0ge1N0cmluZ30ga2V5IOi8uOWFpeimgeafpeaJvueahGtleeWtl+S4sg0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhoYXNrZXkoeyBhOiAxMjMsIGI6ICd4eXonLCBjOiAnNDVvcCcsIGQ6IG51bGwgfSwgJ2EnKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaGFza2V5KG9iaiwga2V5KSB7CiAgLy9jaGVjawogIGlmICghaXNvYmoob2JqKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICBpZiAoIWlzZXN0cihrZXkpICYmICFpc251bShrZXkpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiBrZXkgaW4gb2JqOwp9CgovKioNCiAqIOaPkOWPlum7numZo+WIl+WFp+S5i+m7nlswLDFd5oiWe3gseX3miJbmjIflrprpjbXlgLzmiJDngrrpu557eCx5feeJqeS7tumZo+WIlw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L3B0c1hZdG9BcnIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwcyDovLjlhaXpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MX0se3g6eDIseTp5Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIl++8jOaIlltbeDEseTFdLFt4Mix5Ml0sLi4uXem7nuW6p+aomemZo+WIl+S5i+mZo+WIlw0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlYPSd4J10g6Ly45YWl6bue54mp5Lu2eOW6p+aomemNteWtl+S4su+8jOmgkOiorSd4Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neSddIOi8uOWFpem7nueJqeS7tnnluqfmqJnpjbXlrZfkuLLvvIzpoJDoqK0neScNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleUluZD0naW5kJ10g6Ly45YWl6bue54mp5Lu25oyH5qiZ6Y215a2X5Liy77yM6aCQ6KitJ2luZCcNCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC5yZXR1cm5PYmpBcnJheT10cnVlXSDovLjlhaXmmK/lkKblm57lgrPnianku7bpmaPliJfvvIzoi6V0cnVl5Luj6KGo5Zue5YKz6bue54K654mp5Lu2e3gseX3kuYvpmaPliJfvvIzoi6VmYWxzZeWbnuWCs+m7numZo+WIl1t4LHld5LmL6Zmj5YiX77yM6aCQ6KitdHJ1ZQ0KICogQHJldHVybnMge0FycmF5fSDlm57lgrPpu57pmaPliJcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBzDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW1syNDMsIDIwNl0sIFsyMzMsIDIyNV0sIFsyMSwgMzI1XV0NCiAqIHIgPSBwdHNYWXRvQXJyKHBzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNiwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIGluZDogMSB9LA0KICogLy8gICB7IHg6IDIxLCB5OiAzMjUsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyAneCc6IDI0MywgJ3knOiAyMDYgfSwgeyAneCc6IDIzMywgJ3knOiAyMjUgfSwgeyAneCc6IDIxLCAneSc6IDMyNSB9XQ0KICogciA9IHB0c1hZdG9BcnIocHMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7ICdhJzogMjQzLCAnYic6IDIwNiB9LCB7ICdhJzogMjMzLCAnYic6IDIyNSB9LCB7ICdhJzogMjEsICdiJzogMzI1IH1dDQogKiByID0gcHRzWFl0b0FycihwcywgeyBrZXlYOiAnYScsIGtleVk6ICdiJyB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNiwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIGluZDogMSB9LA0KICogLy8gICB7IHg6IDIxLCB5OiAzMjUsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICovCmZ1bmN0aW9uIHB0c1hZdG9BcnIocHMsIG9wdCA9IHt9KSB7CiAgLy/oi6XnhKHmlbjmk5rlm57lgrPnqbrpmaPliJcKICBpZiAoc2l6ZShwcykgPD0gMCkgewogICAgcmV0dXJuIFtdOwogIH0KCiAgLy9rZXlYCiAgbGV0IGtleVggPSBnZXQob3B0LCAna2V5WCcpOwogIGlmICghaXNlc3RyKGtleVgpKSB7CiAgICBrZXlYID0gJ3gnOwogIH0KCiAgLy9rZXlZCiAgbGV0IGtleVkgPSBnZXQob3B0LCAna2V5WScpOwogIGlmICghaXNlc3RyKGtleVkpKSB7CiAgICBrZXlZID0gJ3knOwogIH0KCiAgLy9rZXlJbmQKICBsZXQga2V5SW5kID0gZ2V0KG9wdCwgJ2tleUluZCcsICcnKTsKICBpZiAoIWlzZXN0cihrZXlJbmQpKSB7CiAgICBrZXlJbmQgPSAnaW5kJzsKICB9CgogIC8vcmV0dXJuT2JqQXJyYXkKICBsZXQgcmV0dXJuT2JqQXJyYXkgPSBnZXQob3B0LCAncmV0dXJuT2JqQXJyYXknKTsKICBpZiAoIWlzYm9sKHJldHVybk9iakFycmF5KSkgewogICAgcmV0dXJuT2JqQXJyYXkgPSB0cnVlOwogIH0KCiAgLy9ycwogIGxldCBycyA9IFtdOwogIGZvckVhY2gocHMsICh2LCBrKSA9PiB7CiAgICBsZXQgeCA9IG51bGw7CiAgICBsZXQgeSA9IG51bGw7CiAgICBpZiAoaXNhcnIodikgJiYgc2l6ZSh2KSA+PSAyKSB7CiAgICAgIHggPSBnZXQodiwgMCk7CiAgICAgIHkgPSBnZXQodiwgMSk7CiAgICB9IGVsc2UgewogICAgICB4ID0gZ2V0KHYsIGtleVgsIG51bGwpOwogICAgICB5ID0gZ2V0KHYsIGtleVksIG51bGwpOwogICAgfQogICAgaWYgKGlzbnVtKHgpICYmIGlzbnVtKHkpKSB7CiAgICAgIHggPSB0b051bWJlcih4KTsKICAgICAgeSA9IHRvTnVtYmVyKHkpOwogICAgICBycy5wdXNoKHsKICAgICAgICB4LAogICAgICAgIHksCiAgICAgICAgW2tleUluZF06IGsKICAgICAgfSk7CiAgICB9CiAgfSk7CgogIC8vcmV0dXJuT2JqQXJyYXkKICBpZiAoIXJldHVybk9iakFycmF5KSB7CiAgICBycyA9IG1hcChycywgdiA9PiB7CiAgICAgIHJldHVybiBbdi54LCB2LnksIHZba2V5SW5kXV07CiAgICB9KTsKICB9CiAgcmV0dXJuIHJzOwp9CgovKioNCiAqIOaPkOWPlum7numZo+WIl+WFp+S5i+m7nlswLDEsMl3miJZ7eCx5LHp95oiW5oyH5a6a6Y215YC85oiQ54K66buee3gseSx6feeJqeS7tumZo+WIlw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L3B0c1hZWnRvQXJyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcHMg6Ly45YWl6bue6Zmj5YiX77yM54K6W3t4OngxLHk6eTEsejp6MX0se3g6eDIseTp5Mix6OnoyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiX77yM5oiWW1t4MSx5MSx6MV0sW3gyLHkyLHoyXSwuLi5d6bue5bqn5qiZ6Zmj5YiX5LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7Z45bqn5qiZ6Y215a2X5Liy77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu2eeW6p+aomemNteWtl+S4su+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neiddIOi8uOWFpem7nueJqeS7tnrluqfmqJnpjbXlrZfkuLLvvIzpoJDoqK0neicNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleUluZD0naW5kJ10g6Ly45YWl6bue54mp5Lu25oyH5qiZ6Y215a2X5Liy77yM6aCQ6KitJ2luZCcNCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC5yZXR1cm5PYmpBcnJheT10cnVlXSDovLjlhaXmmK/lkKblm57lgrPnianku7bpmaPliJfvvIzoi6V0cnVl5Luj6KGo5Zue5YKz6bue54K654mp5Lu2e3gseSx6feS5i+mZo+WIl++8jOiLpWZhbHNl5Zue5YKz6bue6Zmj5YiXW3gseSx6XeS5i+mZo+WIl++8jOmgkOiorXRydWUNCiAqIEByZXR1cm5zIHtBcnJheX0g5Zue5YKz6buee3gseSx6femZo+WIlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCByDQogKg0KICogcHMgPSBbWzI0MywgMjA2LCA5NV0sIFsyMzMsIDIyNSwgMTQ2XSwgWzIxLCAzMjUsIDIyXV0NCiAqIHIgPSBwdHNYWVp0b0FycihwcykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDYsIHo6IDk1LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2LCBpbmQ6IDEgfSwNCiAqIC8vICAgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7ICd4JzogMjQzLCAneSc6IDIwNiwgJ3onOiA5NSB9LCB7ICd4JzogMjMzLCAneSc6IDIyNSwgJ3onOiAxNDYgfSwgeyAneCc6IDIxLCAneSc6IDMyNSwgJ3onOiAyMiB9XQ0KICogciA9IHB0c1hZWnRvQXJyKHBzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNiwgejogOTUsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYsIGluZDogMSB9LA0KICogLy8gICB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyLCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgJ2EnOiAyNDMsICdiJzogMjA2LCAnYyc6IDk1IH0sIHsgJ2EnOiAyMzMsICdiJzogMjI1LCAnYyc6IDE0NiB9LCB7ICdhJzogMjEsICdiJzogMzI1LCAnYyc6IDIyIH1dDQogKiByID0gcHRzWFladG9BcnIocHMsIHsga2V5WDogJ2EnLCBrZXlZOiAnYicsIGtleVo6ICdjJyB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNiwgejogOTUsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYsIGluZDogMSB9LA0KICogLy8gICB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyLCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqLwpmdW5jdGlvbiBwdHNYWVp0b0Fycihwcywgb3B0ID0ge30pIHsKICAvL+iLpeeEoeaVuOaTmuWbnuWCs+epuumZo+WIlwogIGlmIChzaXplKHBzKSA8PSAwKSB7CiAgICByZXR1cm4gW107CiAgfQoKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleVoKICBsZXQga2V5WiA9IGdldChvcHQsICdrZXlaJywgJycpOwogIGlmICghaXNlc3RyKGtleVopKSB7CiAgICBrZXlaID0gJ3onOwogIH0KCiAgLy9rZXlJbmQKICBsZXQga2V5SW5kID0gZ2V0KG9wdCwgJ2tleUluZCcsICcnKTsKICBpZiAoIWlzZXN0cihrZXlJbmQpKSB7CiAgICBrZXlJbmQgPSAnaW5kJzsKICB9CgogIC8vcmV0dXJuT2JqQXJyYXkKICBsZXQgcmV0dXJuT2JqQXJyYXkgPSBnZXQob3B0LCAncmV0dXJuT2JqQXJyYXknKTsKICBpZiAoIWlzYm9sKHJldHVybk9iakFycmF5KSkgewogICAgcmV0dXJuT2JqQXJyYXkgPSB0cnVlOwogIH0KCiAgLy9ycwogIGxldCBycyA9IFtdOwogIGZvckVhY2gocHMsICh2LCBrKSA9PiB7CiAgICBsZXQgeCA9IG51bGw7CiAgICBsZXQgeSA9IG51bGw7CiAgICBsZXQgeiA9IG51bGw7CiAgICBpZiAoaXNhcnIodikgJiYgc2l6ZSh2KSA+PSAzKSB7CiAgICAgIHggPSBnZXQodiwgMCk7CiAgICAgIHkgPSBnZXQodiwgMSk7CiAgICAgIHogPSBnZXQodiwgMik7CiAgICB9IGVsc2UgewogICAgICB4ID0gZ2V0KHYsIGtleVgsIG51bGwpOwogICAgICB5ID0gZ2V0KHYsIGtleVksIG51bGwpOwogICAgICB6ID0gZ2V0KHYsIGtleVosIG51bGwpOwogICAgfQogICAgaWYgKGlzbnVtKHgpICYmIGlzbnVtKHkpICYmIGlzbnVtKHopKSB7CiAgICAgIHggPSB0b051bWJlcih4KTsKICAgICAgeSA9IHRvTnVtYmVyKHkpOwogICAgICB6ID0gdG9OdW1iZXIoeik7CiAgICAgIHJzLnB1c2goewogICAgICAgIHgsCiAgICAgICAgeSwKICAgICAgICB6LAogICAgICAgIFtrZXlJbmRdOiBrCiAgICAgIH0pOwogICAgfQogIH0pOwoKICAvL3JldHVybk9iakFycmF5CiAgaWYgKCFyZXR1cm5PYmpBcnJheSkgewogICAgcnMgPSBtYXAocnMsIHYgPT4gewogICAgICByZXR1cm4gW3YueCwgdi55LCB2LnosIHZba2V5SW5kXV07CiAgICB9KTsKICB9CiAgcmV0dXJuIHJzOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLm1heGAgYW5kIGBfLm1pbmAgd2hpY2ggYWNjZXB0cyBhCiAqIGBjb21wYXJhdG9yYCB0byBkZXRlcm1pbmUgdGhlIGV4dHJlbXVtIHZhbHVlLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBjb21wYXJhdG9yIHVzZWQgdG8gY29tcGFyZSB2YWx1ZXMuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBleHRyZW11bSB2YWx1ZS4KICovCmZ1bmN0aW9uIGJhc2VFeHRyZW11bShhcnJheSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLAogICAgICBjdXJyZW50ID0gaXRlcmF0ZWUodmFsdWUpOwogICAgaWYgKGN1cnJlbnQgIT0gbnVsbCAmJiAoY29tcHV0ZWQgPT09IHVuZGVmaW5lZCA/IGN1cnJlbnQgPT09IGN1cnJlbnQgJiYgIWlzU3ltYm9sKGN1cnJlbnQpIDogY29tcGFyYXRvcihjdXJyZW50LCBjb21wdXRlZCkpKSB7CiAgICAgIHZhciBjb21wdXRlZCA9IGN1cnJlbnQsCiAgICAgICAgcmVzdWx0ID0gdmFsdWU7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5sdGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLgogKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCwKICogIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGJhc2VMdCh2YWx1ZSwgb3RoZXIpIHsKICByZXR1cm4gdmFsdWUgPCBvdGhlcjsKfQoKLyoqCiAqIENvbXB1dGVzIHRoZSBtaW5pbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LAogKiBgdW5kZWZpbmVkYCBpcyByZXR1cm5lZC4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IE1hdGgKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUuCiAqIEBleGFtcGxlCiAqCiAqIF8ubWluKFs0LCAyLCA4LCA2XSk7CiAqIC8vID0+IDIKICoKICogXy5taW4oW10pOwogKiAvLyA9PiB1bmRlZmluZWQKICovCmZ1bmN0aW9uIG1pbihhcnJheSkgewogIHJldHVybiBhcnJheSAmJiBhcnJheS5sZW5ndGggPyBiYXNlRXh0cmVtdW0oYXJyYXksIGlkZW50aXR5JDEsIGJhc2VMdCkgOiB1bmRlZmluZWQ7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5ndGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLgogKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYCwKICogIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGJhc2VHdCh2YWx1ZSwgb3RoZXIpIHsKICByZXR1cm4gdmFsdWUgPiBvdGhlcjsKfQoKLyoqCiAqIENvbXB1dGVzIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LAogKiBgdW5kZWZpbmVkYCBpcyByZXR1cm5lZC4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IE1hdGgKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUuCiAqIEBleGFtcGxlCiAqCiAqIF8ubWF4KFs0LCAyLCA4LCA2XSk7CiAqIC8vID0+IDgKICoKICogXy5tYXgoW10pOwogKiAvLyA9PiB1bmRlZmluZWQKICovCmZ1bmN0aW9uIG1heChhcnJheSkgewogIHJldHVybiBhcnJheSAmJiBhcnJheS5sZW5ndGggPyBiYXNlRXh0cmVtdW0oYXJyYXksIGlkZW50aXR5JDEsIGJhc2VHdCkgOiB1bmRlZmluZWQ7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maWx0ZXJgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuCiAqLwpmdW5jdGlvbiBiYXNlRmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkgewogIHZhciByZXN1bHQgPSBbXTsKICBiYXNlRWFjaCQxKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHsKICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSkgewogICAgICByZXN1bHQucHVzaCh2YWx1ZSk7CiAgICB9CiAgfSk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgYWxsIGVsZW1lbnRzCiAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhyZWUKICogYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuCiAqCiAqICoqTm90ZToqKiBVbmxpa2UgYF8ucmVtb3ZlYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IENvbGxlY3Rpb24KICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LgogKiBAc2VlIF8ucmVqZWN0CiAqIEBleGFtcGxlCiAqCiAqIHZhciB1c2VycyA9IFsKICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSwKICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0KICogXTsKICoKICogXy5maWx0ZXIodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7CiAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddCiAqCiAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuCiAqIF8uZmlsdGVyKHVzZXJzLCB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSk7CiAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J10KICoKICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLgogKiBfLmZpbHRlcih1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pOwogKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXQogKgogKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC4KICogXy5maWx0ZXIodXNlcnMsICdhY3RpdmUnKTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXQogKgogKiAvLyBDb21iaW5pbmcgc2V2ZXJhbCBwcmVkaWNhdGVzIHVzaW5nIGBfLm92ZXJFdmVyeWAgb3IgYF8ub3ZlclNvbWVgLgogKiBfLmZpbHRlcih1c2VycywgXy5vdmVyU29tZShbeyAnYWdlJzogMzYgfSwgWydhZ2UnLCA0MF1dKSk7CiAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCcsICdiYXJuZXknXQogKi8KZnVuY3Rpb24gZmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkgewogIHZhciBmdW5jID0gaXNBcnJheSQxKGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyOwogIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGJhc2VJdGVyYXRlZShwcmVkaWNhdGUpKTsKfQoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqLwp2YXIgbmF0aXZlQ2VpbCA9IE1hdGguY2VpbCwKICBuYXRpdmVNYXggPSBNYXRoLm1heDsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yYW5nZWAgYW5kIGBfLnJhbmdlUmlnaHRgIHdoaWNoIGRvZXNuJ3QKICogY29lcmNlIGFyZ3VtZW50cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuCiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuCiAqIEBwYXJhbSB7bnVtYmVyfSBzdGVwIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LgogKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5nZSBvZiBudW1iZXJzLgogKi8KZnVuY3Rpb24gYmFzZVJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXAsIGZyb21SaWdodCkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gbmF0aXZlTWF4KG5hdGl2ZUNlaWwoKGVuZCAtIHN0YXJ0KSAvIChzdGVwIHx8IDEpKSwgMCksCiAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpOwogIHdoaWxlIChsZW5ndGgtLSkgewogICAgcmVzdWx0W2Zyb21SaWdodCA/IGxlbmd0aCA6ICsraW5kZXhdID0gc3RhcnQ7CiAgICBzdGFydCArPSBzdGVwOwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LgogKiBAcGFyYW0geyp9IGluZGV4IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgaW5kZXggb3Iga2V5IGFyZ3VtZW50LgogKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCwKICogIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzSXRlcmF0ZWVDYWxsKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7CiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHZhciB0eXBlID0gdHlwZW9mIGluZGV4OwogIGlmICh0eXBlID09ICdudW1iZXInID8gaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSA6IHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KSB7CiAgICByZXR1cm4gZXEob2JqZWN0W2luZGV4XSwgdmFsdWUpOwogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBDcmVhdGVzIGEgYF8ucmFuZ2VgIG9yIGBfLnJhbmdlUmlnaHRgIGZ1bmN0aW9uLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmFuZ2UgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBjcmVhdGVSYW5nZShmcm9tUmlnaHQpIHsKICByZXR1cm4gZnVuY3Rpb24gKHN0YXJ0LCBlbmQsIHN0ZXApIHsKICAgIGlmIChzdGVwICYmIHR5cGVvZiBzdGVwICE9ICdudW1iZXInICYmIGlzSXRlcmF0ZWVDYWxsKHN0YXJ0LCBlbmQsIHN0ZXApKSB7CiAgICAgIGVuZCA9IHN0ZXAgPSB1bmRlZmluZWQ7CiAgICB9CiAgICAvLyBFbnN1cmUgdGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuCiAgICBzdGFydCA9IHRvRmluaXRlKHN0YXJ0KTsKICAgIGlmIChlbmQgPT09IHVuZGVmaW5lZCkgewogICAgICBlbmQgPSBzdGFydDsKICAgICAgc3RhcnQgPSAwOwogICAgfSBlbHNlIHsKICAgICAgZW5kID0gdG9GaW5pdGUoZW5kKTsKICAgIH0KICAgIHN0ZXAgPSBzdGVwID09PSB1bmRlZmluZWQgPyBzdGFydCA8IGVuZCA/IDEgOiAtMSA6IHRvRmluaXRlKHN0ZXApOwogICAgcmV0dXJuIGJhc2VSYW5nZShzdGFydCwgZW5kLCBzdGVwLCBmcm9tUmlnaHQpOwogIH07Cn0KCi8qKgogKiBDcmVhdGVzIGFuIGFycmF5IG9mIG51bWJlcnMgKHBvc2l0aXZlIGFuZC9vciBuZWdhdGl2ZSkgcHJvZ3Jlc3NpbmcgZnJvbQogKiBgc3RhcnRgIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgYGVuZGAuIEEgc3RlcCBvZiBgLTFgIGlzIHVzZWQgaWYgYSBuZWdhdGl2ZQogKiBgc3RhcnRgIGlzIHNwZWNpZmllZCB3aXRob3V0IGFuIGBlbmRgIG9yIGBzdGVwYC4gSWYgYGVuZGAgaXMgbm90IHNwZWNpZmllZCwKICogaXQncyBzZXQgdG8gYHN0YXJ0YCB3aXRoIGBzdGFydGAgdGhlbiBzZXQgdG8gYDBgLgogKgogKiAqKk5vdGU6KiogSmF2YVNjcmlwdCBmb2xsb3dzIHRoZSBJRUVFLTc1NCBzdGFuZGFyZCBmb3IgcmVzb2x2aW5nCiAqIGZsb2F0aW5nLXBvaW50IHZhbHVlcyB3aGljaCBjYW4gcHJvZHVjZSB1bmV4cGVjdGVkIHJlc3VsdHMuCiAqCiAqIEBzdGF0aWMKICogQHNpbmNlIDAuMS4wCiAqIEBtZW1iZXJPZiBfCiAqIEBjYXRlZ29yeSBVdGlsCiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS4KICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS4KICogQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTFdIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuCiAqIEBzZWUgXy5pblJhbmdlLCBfLnJhbmdlUmlnaHQKICogQGV4YW1wbGUKICoKICogXy5yYW5nZSg0KTsKICogLy8gPT4gWzAsIDEsIDIsIDNdCiAqCiAqIF8ucmFuZ2UoLTQpOwogKiAvLyA9PiBbMCwgLTEsIC0yLCAtM10KICoKICogXy5yYW5nZSgxLCA1KTsKICogLy8gPT4gWzEsIDIsIDMsIDRdCiAqCiAqIF8ucmFuZ2UoMCwgMjAsIDUpOwogKiAvLyA9PiBbMCwgNSwgMTAsIDE1XQogKgogKiBfLnJhbmdlKDAsIC00LCAtMSk7CiAqIC8vID0+IFswLCAtMSwgLTIsIC0zXQogKgogKiBfLnJhbmdlKDEsIDQsIDApOwogKiAvLyA9PiBbMSwgMSwgMV0KICoKICogXy5yYW5nZSgwKTsKICogLy8gPT4gW10KICovCnZhciByYW5nZSA9IGNyZWF0ZVJhbmdlKCk7CnZhciByYW5nZSQxID0gcmFuZ2U7CgovKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi8KdmFyIE5BTiA9IDAgLyAwOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1lYW5gIGFuZCBgXy5tZWFuQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IKICogaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbWVhbi4KICovCmZ1bmN0aW9uIGJhc2VNZWFuKGFycmF5LCBpdGVyYXRlZSkgewogIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDsKICByZXR1cm4gbGVuZ3RoID8gYmFzZVN1bShhcnJheSwgaXRlcmF0ZWUpIC8gbGVuZ3RoIDogTkFOOwp9CgovKioKICogQ29tcHV0ZXMgdGhlIG1lYW4gb2YgdGhlIHZhbHVlcyBpbiBgYXJyYXlgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTWF0aAogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLgogKiBAZXhhbXBsZQogKgogKiBfLm1lYW4oWzQsIDIsIDgsIDZdKTsKICogLy8gPT4gNQogKi8KZnVuY3Rpb24gbWVhbihhcnJheSkgewogIHJldHVybiBiYXNlTWVhbihhcnJheSwgaWRlbnRpdHkkMSk7Cn0KCmZ1bmN0aW9uIG5vcm1hbGl6ZUFycmF5Q29yZShhcnIpIHsKICAvL2NoZWNrIHBzU3JjCiAgaWYgKCFpc2VhcnIoYXJyKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAnYXJyIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXknCiAgICB9OwogIH0KCiAgLy92MAogIGxldCB2MCA9IGdldChhcnIsIDApOwoKICAvL24KICBsZXQgbiA9IDA7IC8vMWQgYXJyYXkKICBpZiAoaXNlYXJyKHYwKSkgewogICAgbiA9IHNpemUodjApOyAvL25kIGFycmF5CiAgfQoKICAvL2VhcnIKICBsZXQgZWFyciA9IFtdOwogIGlmIChuID09PSAwKSB7CiAgICBlYXJyID0gZmlsdGVyKGFyciwgaXNudW0pOwogICAgZWFyciA9IG1hcChlYXJyLCBjZGJsKTsKICB9IGVsc2UgewogICAgZm9yRWFjaChhcnIsIHZzID0+IHsKICAgICAgLy9iCiAgICAgIGxldCBiID0gdHJ1ZTsKICAgICAgbGV0IGNzID0gW107CiAgICAgIGZvckVhY2gocmFuZ2UkMShuKSwgaSA9PiB7CiAgICAgICAgLy92CiAgICAgICAgbGV0IHYgPSBnZXQodnMsIGkpOwoKICAgICAgICAvL2NoZWNrCiAgICAgICAgaWYgKCFpc251bSh2KSkgewogICAgICAgICAgYiA9IGZhbHNlOwogICAgICAgICAgLy/ot7Plh7rmj5vkuIvkuIDlgIsKICAgICAgICB9CgogICAgICAgIC8vcHVzaAogICAgICAgIGNzLnB1c2goY2RibCh2KSk7CiAgICAgIH0pOwoKICAgICAgLy9jaGVjawogICAgICBpZiAoYikgewogICAgICAgIGVhcnIucHVzaChjcyk7CiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy9jaGVjawogIGlmIChzaXplKGVhcnIpID09PSAwKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdhcnIgaGFzIG5vIGVmZmVjdGl2ZSBkYXRhJwogICAgfTsKICB9CgogIC8vc3RhCiAgbGV0IHN0YSA9IGFyciA9PiB7CiAgICBsZXQgcm1pbiA9IG1pbihhcnIpOwogICAgbGV0IHJtYXggPSBtYXgoYXJyKTsKICAgIHJldHVybiB7CiAgICAgIG1pbjogcm1pbiwKICAgICAgbWF4OiBybWF4LAogICAgICByYW5nZTogcm1heCAtIHJtaW4sCiAgICAgIG1pZDogKHJtYXggKyBybWluKSAvIDIsCiAgICAgIGF2ZzogbWVhbihhcnIpCiAgICB9OwogIH07CgogIC8vbm1hcnIKICBsZXQgbm1hcnIgPSAoYXJyLCBybWluLCBybWF4LCBycm5nKSA9PiB7CiAgICByZXR1cm4gbWFwKGFyciwgdiA9PiB7CiAgICAgIHJldHVybiAodiAtIHJtaW4pIC8gcnJuZzsKICAgIH0pOwogIH07CgogIC8vbm0KICBsZXQgbm0gPSBhcnIgPT4gewogICAgbGV0IHMgPSBzdGEoYXJyKTsKICAgIGxldCBhcnJ0ID0gbm1hcnIoYXJyLCBzLm1pbiwgcy5tYXgsIHMucmFuZ2UpOwogICAgcmV0dXJuIHsKICAgICAgYXJyOiBhcnJ0LAogICAgICAuLi5zCiAgICB9OwogIH07CgogIC8vcgogIGxldCByID0gbnVsbDsKICBpZiAobiA9PT0gMCkgewogICAgciA9IG5tKGVhcnIpOwogIH0gZWxzZSB7CiAgICByID0gbWFwKHJhbmdlJDEobiksIGkgPT4gewogICAgICBsZXQgZWFycnQgPSBtYXAoZWFyciwgaSk7CiAgICAgIHJldHVybiBubShlYXJydCk7CiAgICB9KTsKICB9CiAgcmV0dXJuIHI7Cn0KCi8qKg0KICog6Yed5bCN5LiA57at5oiW5LqM57at6Zmj5YiX5q2j6KaP5YyWDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3Qvbm9ybWFsaXplQXJyYXkudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBhcnIg6Ly45YWl6LOH5paZ6Zmj5YiX77yM54K6W3gxLHgyLC4uLl3kuYvkuIDntq3pmaPliJfvvIzmiJZbW3gxLHkxXSxbeDIseTJdLC4uLl3kuYvkuozntq3pmaPliJcNCiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IOWbnuWCs+ato+imj+WMluaVuOaTmuS5i+eJqeS7tuaIlumZo+WIlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgYXJyDQogKiBsZXQgcg0KICoNCiAqIGFyciA9IFsNCiAqICAgICBbMjQzLCAyMDYsIDk1XSwNCiAqICAgICBbMjMzLCAyMjUsIDE0Nl0sDQogKiAgICAgWzIxLCAzMjUsIDIyXSwNCiAqICAgICBbOTUzLCAyOCwgMjIzXSwNCiAqICAgICBbMTA5MiwgMjkwLCAzOV0sDQogKiAgICAgWzc0NCwgMjAwLCAxOTFdLA0KICogICAgIFsxNzQsIDMsIDIyXSwNCiAqICAgICBbNTM3LCAzNjgsIDI0OV0sDQogKiAgICAgWzExNTEsIDM3MSwgODZdLA0KICogICAgIFs4MTQsIDI1MiwgMTI1XQ0KICogXQ0KICogciA9IG5vcm1hbGl6ZUFycmF5KGFycikNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsNCiAqIC8vICAgICBhcnI6IFsNCiAqIC8vICAgICAgIDAuMTk2NDYwMTc2OTkxMTUwNDUsDQogKiAvLyAgICAgICAwLjE4NzYxMDYxOTQ2OTAyNjU1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODI0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuOTQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgICAgMC42Mzk4MjMwMDg4NDk1NTc2LA0KICogLy8gICAgICAgMC4xMzUzOTgyMzAwODg0OTU1OCwNCiAqIC8vICAgICAgIDAuNDU2NjM3MTY4MTQxNTkyOTQsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC43MDE3Njk5MTE1MDQ0MjQ4DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDIxLA0KICogLy8gICAgIG1heDogMTE1MSwNCiAqIC8vICAgICByYW5nZTogMTEzMCwNCiAqIC8vICAgICBhdmc6IDU5Ni4yDQogKiAvLyAgIH0sDQogKiAvLyAgIHsNCiAqIC8vICAgICBhcnI6IFsNCiAqIC8vICAgICAgIDAuNTUxNjMwNDM0NzgyNjA4NiwNCiAqIC8vICAgICAgIDAuNjAzMjYwODY5NTY1MjE3NCwNCiAqIC8vICAgICAgIDAuODc1LA0KICogLy8gICAgICAgMC4wNjc5MzQ3ODI2MDg2OTU2NSwNCiAqIC8vICAgICAgIDAuNzc5ODkxMzA0MzQ3ODI2LA0KICogLy8gICAgICAgMC41MzUzMjYwODY5NTY1MjE3LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuOTkxODQ3ODI2MDg2OTU2NSwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjY3NjYzMDQzNDc4MjYwODYNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMywNCiAqIC8vICAgICBtYXg6IDM3MSwNCiAqIC8vICAgICByYW5nZTogMzY4LA0KICogLy8gICAgIGF2ZzogMjI2LjgNCiAqIC8vICAgfSwNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC4zMjE1ODU5MDMwODM3MDA0NCwNCiAqIC8vICAgICAgIDAuNTQ2MjU1NTA2NjA3OTI5NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjg4NTQ2MjU1NTA2NjA3OTMsDQogKiAvLyAgICAgICAwLjA3NDg4OTg2Nzg0MTQwOTY5LA0KICogLy8gICAgICAgMC43NDQ0OTMzOTIwNzA0ODQ2LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjI4MTkzODMyNTk5MTE4OTQ1LA0KICogLy8gICAgICAgMC40NTM3NDQ0OTMzOTIwNzA0Ng0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAyMiwNCiAqIC8vICAgICBtYXg6IDI0OSwNCiAqIC8vICAgICByYW5nZTogMjI3LA0KICogLy8gICAgIGF2ZzogMTE5LjgNCiAqIC8vICAgfQ0KICogLy8gXQ0KICoNCiAqIGFyciA9IFsNCiAqICAgICAyNDMsIDIzMywgMjEsDQogKiAgICAgOTUzLCAxMDkyLCA3NDQsDQogKiAgICAgMTc0LCA1MzcsIDExNTEsDQogKiAgICAgODE0DQogKiBdDQogKiByID0gbm9ybWFsaXplQXJyYXkoYXJyKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsNCiAqIC8vICAgYXJyOiBbDQogKiAvLyAgICAgMC4xOTY0NjAxNzY5OTExNTA0NSwNCiAqIC8vICAgICAwLjE4NzYxMDYxOTQ2OTAyNjU1LA0KICogLy8gICAgIDAsDQogKiAvLyAgICAgMC44MjQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgIDAuOTQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgIDAuNjM5ODIzMDA4ODQ5NTU3NiwNCiAqIC8vICAgICAwLjEzNTM5ODIzMDA4ODQ5NTU4LA0KICogLy8gICAgIDAuNDU2NjM3MTY4MTQxNTkyOTQsDQogKiAvLyAgICAgMSwNCiAqIC8vICAgICAwLjcwMTc2OTkxMTUwNDQyNDgNCiAqIC8vICAgXSwNCiAqIC8vICAgbWluOiAyMSwNCiAqIC8vICAgbWF4OiAxMTUxLA0KICogLy8gICByYW5nZTogMTEzMCwNCiAqIC8vICAgYXZnOiA1OTYuMg0KICogLy8gfQ0KICoNCiAqIGFyciA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogciA9IG5vcm1hbGl6ZUFycmF5KGFyciwgWyd4JywgJ3knLCAneiddKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC4xOTY0NjAxNzY5OTExNTA0NSwNCiAqIC8vICAgICAgIDAuMTg3NjEwNjE5NDY5MDI2NTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44MjQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgICAgMC45NDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjYzOTgyMzAwODg0OTU1NzYsDQogKiAvLyAgICAgICAwLjEzNTM5ODIzMDA4ODQ5NTU4LA0KICogLy8gICAgICAgMC40NTY2MzcxNjgxNDE1OTI5NCwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjcwMTc2OTkxMTUwNDQyNDgNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMjEsDQogKiAvLyAgICAgbWF4OiAxMTUxLA0KICogLy8gICAgIHJhbmdlOiAxMTMwLA0KICogLy8gICAgIGF2ZzogNTk2LjINCiAqIC8vICAgfSwNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC41NTE2MzA0MzQ3ODI2MDg2LA0KICogLy8gICAgICAgMC42MDMyNjA4Njk1NjUyMTc0LA0KICogLy8gICAgICAgMC44NzUsDQogKiAvLyAgICAgICAwLjA2NzkzNDc4MjYwODY5NTY1LA0KICogLy8gICAgICAgMC43Nzk4OTEzMDQzNDc4MjYsDQogKiAvLyAgICAgICAwLjUzNTMyNjA4Njk1NjUyMTcsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC45OTE4NDc4MjYwODY5NTY1LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNjc2NjMwNDM0NzgyNjA4Ng0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAzLA0KICogLy8gICAgIG1heDogMzcxLA0KICogLy8gICAgIHJhbmdlOiAzNjgsDQogKiAvLyAgICAgYXZnOiAyMjYuOA0KICogLy8gICB9LA0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjMyMTU4NTkwMzA4MzcwMDQ0LA0KICogLy8gICAgICAgMC41NDYyNTU1MDY2MDc5Mjk1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODg1NDYyNTU1MDY2MDc5MywNCiAqIC8vICAgICAgIDAuMDc0ODg5ODY3ODQxNDA5NjksDQogKiAvLyAgICAgICAwLjc0NDQ5MzM5MjA3MDQ4NDYsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuMjgxOTM4MzI1OTkxMTg5NDUsDQogKiAvLyAgICAgICAwLjQ1Mzc0NDQ5MzM5MjA3MDQ2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDIyLA0KICogLy8gICAgIG1heDogMjQ5LA0KICogLy8gICAgIHJhbmdlOiAyMjcsDQogKiAvLyAgICAgYXZnOiAxMTkuOA0KICogLy8gICB9DQogKiAvLyBdDQogKg0KICovCmZ1bmN0aW9uIG5vcm1hbGl6ZUFycmF5KGFyciwga2V5cyA9IFtdKSB7CiAgLy9jaGVjayBwc1NyYwogIGlmICghaXNlYXJyKGFycikpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ2FyciBpcyBub3QgYW4gZWZmZWN0aXZlIGFycmF5JwogICAgfTsKICB9CgogIC8va2V5cwogIGlmIChzaXplKGtleXMpID4gMCkgewogICAgLy9jaGVjawogICAgbGV0IHYwID0gZ2V0KGFyciwgMCk7CiAgICBpZiAoIWlzZW9iaih2MCkpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICBlcnI6ICdhcnIgaXMgbm90IGFuIGVmZmVjdGl2ZSBhcnJheSBvZiBvYmplY3RzJwogICAgICB9OwogICAgfQoKICAgIC8vYXJydCwg5o+Q5Y+W5oyH5a6aa2V5cwogICAgbGV0IGFycnQgPSBbXTsKICAgIGZvckVhY2goYXJyLCBkdCA9PiB7CiAgICAgIGxldCBjcyA9IFtdOwogICAgICBmb3JFYWNoKGtleXMsIGsgPT4gewogICAgICAgIGNzLnB1c2goZ2V0KGR0LCBrLCAnJykpOwogICAgICB9KTsKICAgICAgYXJydC5wdXNoKGNzKTsKICAgIH0pOwoKICAgIC8vc2F2ZQogICAgYXJyID0gYXJydDsKICB9CgogIC8vbm9ybWFsaXplQXJyYXlDb3JlCiAgbGV0IHIgPSBub3JtYWxpemVBcnJheUNvcmUoYXJyKTsKICByZXR1cm4gcjsKfQoKLyoqDQogKiDlhafmj5LnlKjmraPopo/ljJbmlbjmk5oNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9pbnRlcnAyTm9ybWFsaXplLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcHMg6Ly45YWl5LqM57at5bqn5qiZ5Yqg6KeA5ris5pW45pOa6bue6Zmj5YiX77yM54K6W3t4OngxLHk6eTEsejp6MX0se3g6eDIseTp5Mix6OnoyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7bkuYt45qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu25LmLeeashOS9jeWtl+S4su+8jOeCuuW6p+aome+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5Wj0neiddIOi8uOWFpem7nueJqeS7tuS5i3rmrITkvY3lrZfkuLLvvIzngrrop4DmuKzlgLzvvIzpoJDoqK0neicNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleUluZD0naW5kJ10g6Ly45YWl6bue54mp5Lu25LmLaW5k5qyE5L2N5a2X5Liy77yM5q2j6KaP5YyW5b6M5Y+v5Y+N5p+l5Y6f5aeL5pW45pOa5LmL5oyH5qiZ77yM6aCQ6KitJ2luZCcNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LnNjYWxlPTFdIOi8uOWFpeato+imj+WMluevhOWcjeaVuOWAvO+8jOWboOiZleeQhuWkmumCiuW9ouaZguacieaVuOWAvOWuueioseiqpOW3ru+8jOaVhemgiOmAmumBjue4ruaUvuWAvOWfn+S+hua4m+WwkeWVj+mhjO+8jOmgkOiorTHmmK/mraPopo/ljJYw6IezMeS5i+mWk++8jOS9v+eUqHNjYWxlWFnliYfmmK/mraPopo/ljJbngrow6Iezc2NhbGVYWeS5i+mWk++8jOmgkOiorTENCiAqIEByZXR1cm5zIHtPYmplY3R9IOWbnuWCs+ato+imj+WMluaVuOaTmueJqeS7tg0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCByDQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHIgPSBpbnRlcnAyTm9ybWFsaXplKHBzKQ0KICogZGVsZXRlIHIubnYNCiAqIGRlbGV0ZSByLmludg0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiB7InBzIjpbeyJ4IjowLjE5NjQ2MDE3Njk5MTE1MDQ1LCJ5IjowLjUxNjgxNDE1OTI5MjAzNTQsInoiOjAuMzIxNTg1OTAzMDgzNzAwNDQsImluZCI6bnVsbH0seyJ4IjowLjE4NzYxMDYxOTQ2OTAyNjU1LCJ5IjowLjUzMzYyODMxODU4NDA3MDgsInoiOjAuNTQ2MjU1NTA2NjA3OTI5NSwiaW5kIjpudWxsfSx7IngiOjAsInkiOjAuNjIyMTIzODkzODA1MzA5NywieiI6MCwiaW5kIjpudWxsfSx7IngiOjAuODI0Nzc4NzYxMDYxOTQ2OSwieSI6MC4zNTkyOTIwMzUzOTgyMzAwNywieiI6MC44ODU0NjI1NTUwNjYwNzkzLCJpbmQiOm51bGx9LHsieCI6MC45NDc3ODc2MTA2MTk0NjksInkiOjAuNTkxMTUwNDQyNDc3ODc2MSwieiI6MC4wNzQ4ODk4Njc4NDE0MDk2OSwiaW5kIjpudWxsfSx7IngiOjAuNjM5ODIzMDA4ODQ5NTU3NiwieSI6MC41MTE1MDQ0MjQ3Nzg3NjEsInoiOjAuNzQ0NDkzMzkyMDcwNDg0NiwiaW5kIjpudWxsfSx7IngiOjAuMTM1Mzk4MjMwMDg4NDk1NTgsInkiOjAuMzM3MTY4MTQxNTkyOTIwMzYsInoiOjAsImluZCI6bnVsbH0seyJ4IjowLjQ1NjYzNzE2ODE0MTU5Mjk0LCJ5IjowLjY2MDE3Njk5MTE1MDQ0MjUsInoiOjEsImluZCI6bnVsbH0seyJ4IjoxLCJ5IjowLjY2MjgzMTg1ODQwNzA3OTcsInoiOjAuMjgxOTM4MzI1OTkxMTg5NDUsImluZCI6bnVsbH0seyJ4IjowLjcwMTc2OTkxMTUwNDQyNDgsInkiOjAuNTU3NTIyMTIzODkzODA1MywieiI6MC40NTM3NDQ0OTMzOTIwNzA0NiwiaW5kIjpudWxsfV0sInBzTWluTWF4Ijp7InhtaW4iOjAsInhtYXgiOjEsInltaW4iOjAuMzM3MTY4MTQxNTkyOTIwMzYsInltYXgiOjAuNjYyODMxODU4NDA3MDc5Nywiem1pbiI6MCwiem1heCI6MX0sInN0Ijp7IngiOnsibWluIjoyMSwibWF4IjoxMTUxLCJyYW5nZSI6MTEzMH0sInkiOnsibWluIjotMzc4LCJtYXgiOjc1MiwicmFuZ2UiOjExMzB9LCJ6Ijp7Im1pbiI6MjIsIm1heCI6MjQ5LCJyYW5nZSI6MjI3fX19DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHIgPSBpbnRlcnAyTm9ybWFsaXplKHBzLCB7IHNjYWxlOiAxMDAgfSkNCiAqIGRlbGV0ZSByLm52DQogKiBkZWxldGUgci5pbnYNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4geyJwcyI6W3sieCI6MTkuNjQ2MDE3Njk5MTE1MDQ1LCJ5Ijo1MS42ODE0MTU5MjkyMDM1NDYsInoiOjMyLjE1ODU5MDMwODM3MDA0NCwiaW5kIjpudWxsfSx7IngiOjE4Ljc2MTA2MTk0NjkwMjY1NCwieSI6NTMuMzYyODMxODU4NDA3MDgsInoiOjU0LjYyNTU1MDY2MDc5Mjk1LCJpbmQiOm51bGx9LHsieCI6MCwieSI6NjIuMjEyMzg5MzgwNTMwOTcsInoiOjAsImluZCI6bnVsbH0seyJ4Ijo4Mi40Nzc4NzYxMDYxOTQ2OSwieSI6MzUuOTI5MjAzNTM5ODIzMDEsInoiOjg4LjU0NjI1NTUwNjYwNzkzLCJpbmQiOm51bGx9LHsieCI6OTQuNzc4NzYxMDYxOTQ2OTEsInkiOjU5LjExNTA0NDI0Nzc4NzYxLCJ6Ijo3LjQ4ODk4Njc4NDE0MDk2OSwiaW5kIjpudWxsfSx7IngiOjYzLjk4MjMwMDg4NDk1NTc1NSwieSI6NTEuMTUwNDQyNDc3ODc2MSwieiI6NzQuNDQ5MzM5MjA3MDQ4NDUsImluZCI6bnVsbH0seyJ4IjoxMy41Mzk4MjMwMDg4NDk1NTgsInkiOjMzLjcxNjgxNDE1OTI5MjAzNSwieiI6MCwiaW5kIjpudWxsfSx7IngiOjQ1LjY2MzcxNjgxNDE1OTI5NCwieSI6NjYuMDE3Njk5MTE1MDQ0MjUsInoiOjEwMCwiaW5kIjpudWxsfSx7IngiOjEwMCwieSI6NjYuMjgzMTg1ODQwNzA3OTcsInoiOjI4LjE5MzgzMjU5OTExODk0NSwiaW5kIjpudWxsfSx7IngiOjcwLjE3Njk5MTE1MDQ0MjQ4LCJ5Ijo1NS43NTIyMTIzODkzODA1MywieiI6NDUuMzc0NDQ5MzM5MjA3MDUsImluZCI6bnVsbH1dLCJwc01pbk1heCI6eyJ4bWluIjowLCJ4bWF4IjoxMDAsInltaW4iOjMzLjcxNjgxNDE1OTI5MjAzNSwieW1heCI6NjYuMjgzMTg1ODQwNzA3OTcsInptaW4iOjAsInptYXgiOjEwMH0sInN0Ijp7IngiOnsibWluIjoyMSwibWF4IjoxMTUxLCJyYW5nZSI6MTEzMH0sInkiOnsibWluIjotMzc4LCJtYXgiOjc1MiwicmFuZ2UiOjExMzB9LCJ6Ijp7Im1pbiI6MjIsIm1heCI6MjQ5LCJyYW5nZSI6MjI3fX19DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUsIGluZDogMTAxIH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiwgaW5kOiAxMDIgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiwgaW5kOiAxMDMgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMsIGluZDogMTA0IH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSwgaW5kOiAxMDUgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxLCBpbmQ6IDEwNiB9LCB7IHg6IDE3NCwgeTogMywgejogMjIsIGluZDogMTA3IH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSwgaW5kOiAxMDggfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2LCBpbmQ6IDEwOSB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUsIGluZDogMTEwIH1dDQogKiByID0gaW50ZXJwMk5vcm1hbGl6ZShwcywgeyBrZXlJbmQ6ICdpbmQnIH0pDQogKiBkZWxldGUgci5udg0KICogZGVsZXRlIHIuaW52DQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IHsicHMiOlt7IngiOjAuMTk2NDYwMTc2OTkxMTUwNDUsInkiOjAuNTE2ODE0MTU5MjkyMDM1NCwieiI6MC4zMjE1ODU5MDMwODM3MDA0NCwiaW5kIjoxMDF9LHsieCI6MC4xODc2MTA2MTk0NjkwMjY1NSwieSI6MC41MzM2MjgzMTg1ODQwNzA4LCJ6IjowLjU0NjI1NTUwNjYwNzkyOTUsImluZCI6MTAyfSx7IngiOjAsInkiOjAuNjIyMTIzODkzODA1MzA5NywieiI6MCwiaW5kIjoxMDN9LHsieCI6MC44MjQ3Nzg3NjEwNjE5NDY5LCJ5IjowLjM1OTI5MjAzNTM5ODIzMDA3LCJ6IjowLjg4NTQ2MjU1NTA2NjA3OTMsImluZCI6MTA0fSx7IngiOjAuOTQ3Nzg3NjEwNjE5NDY5LCJ5IjowLjU5MTE1MDQ0MjQ3Nzg3NjEsInoiOjAuMDc0ODg5ODY3ODQxNDA5NjksImluZCI6MTA1fSx7IngiOjAuNjM5ODIzMDA4ODQ5NTU3NiwieSI6MC41MTE1MDQ0MjQ3Nzg3NjEsInoiOjAuNzQ0NDkzMzkyMDcwNDg0NiwiaW5kIjoxMDZ9LHsieCI6MC4xMzUzOTgyMzAwODg0OTU1OCwieSI6MC4zMzcxNjgxNDE1OTI5MjAzNiwieiI6MCwiaW5kIjoxMDd9LHsieCI6MC40NTY2MzcxNjgxNDE1OTI5NCwieSI6MC42NjAxNzY5OTExNTA0NDI1LCJ6IjoxLCJpbmQiOjEwOH0seyJ4IjoxLCJ5IjowLjY2MjgzMTg1ODQwNzA3OTcsInoiOjAuMjgxOTM4MzI1OTkxMTg5NDUsImluZCI6MTA5fSx7IngiOjAuNzAxNzY5OTExNTA0NDI0OCwieSI6MC41NTc1MjIxMjM4OTM4MDUzLCJ6IjowLjQ1Mzc0NDQ5MzM5MjA3MDQ2LCJpbmQiOjExMH1dLCJwc01pbk1heCI6eyJ4bWluIjowLCJ4bWF4IjoxLCJ5bWluIjowLjMzNzE2ODE0MTU5MjkyMDM2LCJ5bWF4IjowLjY2MjgzMTg1ODQwNzA3OTcsInptaW4iOjAsInptYXgiOjF9LCJzdCI6eyJ4Ijp7Im1pbiI6MjEsIm1heCI6MTE1MSwicmFuZ2UiOjExMzB9LCJ5Ijp7Im1pbiI6LTM3OCwibWF4Ijo3NTIsInJhbmdlIjoxMTMwfSwieiI6eyJtaW4iOjIyLCJtYXgiOjI0OSwicmFuZ2UiOjIyN319fQ0KICoNCiAqLwpmdW5jdGlvbiBpbnRlcnAyTm9ybWFsaXplKHBzLCBvcHQgPSB7fSkgewogIC8va2V5WAogIGxldCBrZXlYID0gZ2V0KG9wdCwgJ2tleVgnKTsKICBpZiAoIWlzZXN0cihrZXlYKSkgewogICAga2V5WCA9ICd4JzsKICB9CgogIC8va2V5WQogIGxldCBrZXlZID0gZ2V0KG9wdCwgJ2tleVknKTsKICBpZiAoIWlzZXN0cihrZXlZKSkgewogICAga2V5WSA9ICd5JzsKICB9CgogIC8va2V5WgogIGxldCBrZXlaID0gZ2V0KG9wdCwgJ2tleVonLCAnJyk7CiAgaWYgKCFpc2VzdHIoa2V5WikpIHsKICAgIGtleVogPSAneic7CiAgfQoKICAvL2tleUluZAogIGxldCBrZXlJbmQgPSBnZXQob3B0LCAna2V5SW5kJywgJycpOwogIGlmICghaXNlc3RyKGtleUluZCkpIHsKICAgIGtleUluZCA9ICdpbmQnOwogIH0KCiAgLy9zY2FsZQogIGxldCBzY2FsZSA9IGdldChvcHQsICdzY2FsZScpOwogIGlmICghaXNudW0oc2NhbGUpKSB7CiAgICBzY2FsZSA9IDE7CiAgfQogIHNjYWxlID0gY2RibChzY2FsZSk7CiAgaWYgKHNjYWxlIDw9IDApIHsKICAgIHRocm93IG5ldyBFcnJvcihgc2NhbGUgbmVlZCA+PSAwYCk7CiAgfQogIC8vIGNvbnNvbGUubG9nKCdzY2FsZScsIHNjYWxlKQoKICAvL254LCBueSwgbnoKICBsZXQgbnggPSBub3JtYWxpemVBcnJheShtYXAocHMsIGtleVgpKTsKICBsZXQgbnkgPSBub3JtYWxpemVBcnJheShtYXAocHMsIGtleVkpKTsKICBsZXQgbnogPSBub3JtYWxpemVBcnJheShtYXAocHMsIGtleVopKTsKICAvLyBjb25zb2xlLmxvZygnbngnLCBueCkKICAvLyBjb25zb2xlLmxvZygnbnknLCBueSkKICAvLyBjb25zb2xlLmxvZygnbnonLCBueikKCiAgLy9yYW5nZVhZCiAgbGV0IHJhbmdlWFkgPSBNYXRoLm1heChueC5yYW5nZSwgbnkucmFuZ2UpOwoKICAvL3JhbmdlWFlIYWxmCiAgbGV0IHJhbmdlWFlIYWxmID0gcmFuZ2VYWSAvIDI7CgogIC8vc3QsIHgseeS9v+eUqOWQjOe2suagvOWwuuWvuOe4ruaUvgogIGxldCBzdCA9IHsKICAgIHg6IHsKICAgICAgbWluOiBueC5taWQgLSByYW5nZVhZSGFsZiwKICAgICAgbWF4OiBueC5taWQgKyByYW5nZVhZSGFsZiwKICAgICAgcmFuZ2U6IHJhbmdlWFkKICAgIH0sCiAgICB5OiB7CiAgICAgIG1pbjogbnkubWlkIC0gcmFuZ2VYWUhhbGYsCiAgICAgIG1heDogbnkubWlkICsgcmFuZ2VYWUhhbGYsCiAgICAgIHJhbmdlOiByYW5nZVhZCiAgICB9LAogICAgejogewogICAgICBtaW46IG56Lm1pbiwKICAgICAgbWF4OiBuei5tYXgsCiAgICAgIHJhbmdlOiBuei5yYW5nZQogICAgfQogIH07CiAgLy8gY29uc29sZS5sb2coJ3N0Jywgc3QpCgogIC8vbnYKICBsZXQgbnYgPSAodiwgZGlyKSA9PiB7CiAgICBpZiAoIWlzTnVtYmVyKHYpKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgaWYgKHN0W2Rpcl0ucmFuZ2UgPD0gMCkgewogICAgICByZXR1cm4gdjsKICAgIH0KICAgIHJldHVybiAodiAtIHN0W2Rpcl0ubWluKSAvIHN0W2Rpcl0ucmFuZ2UgKiBzY2FsZTsKICB9OwoKICAvL2ludgogIGxldCBpbnYgPSAoaXYsIGRpcikgPT4gewogICAgaWYgKCFpc051bWJlcihpdikpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZiAoc2NhbGUgPD0gMCkgewogICAgICByZXR1cm4gaXY7CiAgICB9CiAgICByZXR1cm4gaXYgLyBzY2FsZSAqIHN0W2Rpcl0ucmFuZ2UgKyBzdFtkaXJdLm1pbjsKICB9OwoKICAvL25vcm1hbGl6ZSBwcwogIHBzID0gbWFwKHBzLCB2ID0+IHsKICAgIGxldCB4ID0gbnYodltrZXlYXSwgJ3gnKTsKICAgIGxldCB5ID0gbnYodltrZXlZXSwgJ3knKTsKICAgIGxldCB6ID0gbnYodltrZXlaXSwgJ3onKTsKICAgIGxldCBpbmQgPSBnZXQodiwga2V5SW5kLCBudWxsKTsKICAgIHJldHVybiB7CiAgICAgIFtrZXlYXTogeCwKICAgICAgW2tleVldOiB5LAogICAgICBba2V5Wl06IHosCiAgICAgIFtrZXlJbmRdOiBpbmQKICAgIH07CiAgfSk7CiAgLy8gY29uc29sZS5sb2coJ25vcm1hbGl6ZSBwcycsIHBzKQoKICAvL3BzTWluTWF4CiAgbGV0IHBzeCA9IG1hcChwcywga2V5WCk7CiAgbGV0IHBzeE1pbiA9IG1pbihwc3gpOwogIGxldCBwc3hNYXggPSBtYXgocHN4KTsKICBsZXQgcHN5ID0gbWFwKHBzLCBrZXlZKTsKICBsZXQgcHN5TWluID0gbWluKHBzeSk7CiAgbGV0IHBzeU1heCA9IG1heChwc3kpOwogIGxldCBwc3ogPSBtYXAocHMsIGtleVopOwogIGxldCBwc3pNaW4gPSBtaW4ocHN6KTsKICBsZXQgcHN6TWF4ID0gbWF4KHBzeik7CiAgbGV0IHBzTWluTWF4ID0gewogICAgeG1pbjogcHN4TWluLAogICAgeG1heDogcHN4TWF4LAogICAgeW1pbjogcHN5TWluLAogICAgeW1heDogcHN5TWF4LAogICAgem1pbjogcHN6TWluLAogICAgem1heDogcHN6TWF4CiAgfTsKICByZXR1cm4gewogICAgcHMsCiAgICBwc01pbk1heCwKICAgIHN0LAogICAgbnYsCiAgICBpbnYKICB9Owp9CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHNwcmVhZGFibGVTeW1ib2wgPSBTeW1ib2wkMSA/IFN5bWJvbCQxLmlzQ29uY2F0U3ByZWFkYWJsZSA6IHVuZGVmaW5lZDsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGZsYXR0ZW5hYmxlIGBhcmd1bWVudHNgIG9iamVjdCBvciBhcnJheS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZsYXR0ZW5hYmxlLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc0ZsYXR0ZW5hYmxlKHZhbHVlKSB7CiAgcmV0dXJuIGlzQXJyYXkkMSh2YWx1ZSkgfHwgaXNBcmd1bWVudHMkMSh2YWx1ZSkgfHwgISEoc3ByZWFkYWJsZVN5bWJvbCAmJiB2YWx1ZSAmJiB2YWx1ZVtzcHJlYWRhYmxlU3ltYm9sXSk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mbGF0dGVuYCB3aXRoIHN1cHBvcnQgZm9yIHJlc3RyaWN0aW5nIGZsYXR0ZW5pbmcuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLgogKiBAcGFyYW0ge251bWJlcn0gZGVwdGggVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLgogKiBAcGFyYW0ge2Jvb2xlYW59IFtwcmVkaWNhdGU9aXNGbGF0dGVuYWJsZV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHBhcmFtIHtib29sZWFufSBbaXNTdHJpY3RdIFJlc3RyaWN0IHRvIHZhbHVlcyB0aGF0IHBhc3MgYHByZWRpY2F0ZWAgY2hlY2tzLgogKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0PVtdXSBUaGUgaW5pdGlhbCByZXN1bHQgdmFsdWUuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS4KICovCmZ1bmN0aW9uIGJhc2VGbGF0dGVuKGFycmF5LCBkZXB0aCwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7CiAgcHJlZGljYXRlIHx8IChwcmVkaWNhdGUgPSBpc0ZsYXR0ZW5hYmxlKTsKICByZXN1bHQgfHwgKHJlc3VsdCA9IFtdKTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdOwogICAgaWYgKGRlcHRoID4gMCAmJiBwcmVkaWNhdGUodmFsdWUpKSB7CiAgICAgIGlmIChkZXB0aCA+IDEpIHsKICAgICAgICAvLyBSZWN1cnNpdmVseSBmbGF0dGVuIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLgogICAgICAgIGJhc2VGbGF0dGVuKHZhbHVlLCBkZXB0aCAtIDEsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYXJyYXlQdXNoKHJlc3VsdCwgdmFsdWUpOwogICAgICB9CiAgICB9IGVsc2UgaWYgKCFpc1N0cmljdCkgewogICAgICByZXN1bHRbcmVzdWx0Lmxlbmd0aF0gPSB2YWx1ZTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIEZsYXR0ZW5zIGBhcnJheWAgYSBzaW5nbGUgbGV2ZWwgZGVlcC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IEFycmF5CiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuCiAqIEBleGFtcGxlCiAqCiAqIF8uZmxhdHRlbihbMSwgWzIsIFszLCBbNF1dLCA1XV0pOwogKiAvLyA9PiBbMSwgMiwgWzMsIFs0XV0sIDVdCiAqLwpmdW5jdGlvbiBmbGF0dGVuKGFycmF5KSB7CiAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoOwogIHJldHVybiBsZW5ndGggPyBiYXNlRmxhdHRlbihhcnJheSwgMSkgOiBbXTsKfQoKLyoqDQogKiDoqIjnrpfmlbjmk5rlhafpu57nianku7bmt7HluqYNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9nZXRQb2ludERlcHRoLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtPYmplY3R9IHAg6Ly45YWl6bue5bqn5qiZ54mp5Lu2DQogKiBAcmV0dXJucyB7SW50ZWdlcn0g5Zue5YKz5rex5bqm5pW05pW4DQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwDQogKiBsZXQgcg0KICoNCiAqIHRyeSB7DQogKiAgICAgcCA9IFtbW1tbMSwgMi41XSwgWzEuMSwgMi4zXV1dXV0NCiAqICAgICByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogfQ0KICogY2F0Y2ggKGVycikgew0KICogICAgIHIgPSBlcnIubWVzc2FnZQ0KICogfQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IGludmFsaWQgcFtbW1tbWzEsMi41XSxbMS4xLDIuM11dXV1dXQ0KICoNCiAqIHAgPSBbW1tbMSwgMi41XSwgWzEuMSwgMi4zXV1dXQ0KICogciA9IGdldFBvaW50RGVwdGgocCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAzDQogKg0KICogcCA9IFtbW1sxLCAyLjVdXV1dDQogKiByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDMNCiAqDQogKiBwID0gW1tbMSwgMi41XV1dDQogKiByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDINCiAqDQogKiBwID0gW1sxLCAyLjVdXQ0KICogciA9IGdldFBvaW50RGVwdGgocCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxDQogKg0KICogdHJ5IHsNCiAqICAgICBwID0gW3sgeDogMSwgeTogMi41IH1dDQogKiAgICAgciA9IGdldFBvaW50RGVwdGgocCkNCiAqIH0NCiAqIGNhdGNoIChlcnIpIHsNCiAqICAgICByID0gZXJyLm1lc3NhZ2UNCiAqIH0NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBpbnZhbGlkIHBbW3sieCI6MSwieSI6Mi41fV1dDQogKg0KICovCmZ1bmN0aW9uIGdldFBvaW50RGVwdGgocCkgewogIGxldCB2MSA9IGdldChwLCAnMCcsIG51bGwpOwogIGxldCBpcDEgPSBzaXplKHYxKTsKICBsZXQgdDEgPSBpc051bWJlcih2MSk7CiAgbGV0IHYyID0gZ2V0KHAsICcwLjAnLCBudWxsKTsKICBsZXQgaXAyID0gc2l6ZSh2Mik7CiAgbGV0IHQyID0gaXNOdW1iZXIodjIpOwogIGxldCB2MyA9IGdldChwLCAnMC4wLjAnLCBudWxsKTsKICBsZXQgaXAzID0gc2l6ZSh2Myk7CiAgbGV0IHQzID0gaXNOdW1iZXIodjMpOwogIGxldCB2NCA9IGdldChwLCAnMC4wLjAuMCcsIG51bGwpOwogIC8vIGxldCBpcDQgPSBzaXplKHY0KQogIGxldCB0NCA9IGlzTnVtYmVyKHY0KTsKICBpZiAoaXAzID09PSAyICYmIHQ0KSB7CiAgICByZXR1cm4gMzsKICB9CiAgaWYgKGlwMiA9PT0gMiAmJiB0MykgewogICAgcmV0dXJuIDI7CiAgfQogIGlmIChpcDEgPT09IDIgJiYgdDIpIHsKICAgIHJldHVybiAxOwogIH0KICBpZiAoaXAxID09PSAwICYmIHQxKSB7CiAgICByZXR1cm4gMDsKICB9CiAgLy8gY29uc29sZS5sb2coJ3YxJywgdjEsICdpcDEnLCBpcDEsICd0MicsIHQyKQogIC8vIGNvbnNvbGUubG9nKCd2MicsIHYyLCAnaXAyJywgaXAyLCAndDMnLCB0MykKICAvLyBjb25zb2xlLmxvZygndjMnLCB2MywgJ2lwMycsIGlwMywgJ3Q0JywgdDQpCiAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHBbJHtKU09OLnN0cmluZ2lmeShwKX1dYCk7Cn0KCi8qKg0KICog6L2J5o+bUmluZ1N0cmluZ+OAgXBvbHlnb27jgIFNdWx0aVBvbHlnb27miJDngrpQb2x5Z29uDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvdG9Qb2x5Z29uLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gdiDovLjlhaXos4fmlpnpmaPliJcNCiAqIEByZXR1cm5zIHtBcnJheX0g5Zue5YKz6LOH5paZ6Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBycw0KICogbGV0IHINCiAqDQogKiBycyA9IFsgLy9yaW5nU3RyaW5nDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqICAgICBbMCwgMF0sIC8v6ZaJ5ZCIDQogKiBdDQogKiByID0gdG9Qb2x5Z29uKHJzKQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxMDAsMF0sWzEwMCwxXSxbMCwxXSxbMCwwXV1dDQogKg0KICogcnMgPSBbIC8vcmluZ1N0cmluZw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiBdDQogKiByID0gdG9Qb2x5Z29uKHJzKQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxMDAsMF0sWzEwMCwxXSxbMCwxXV1dDQogKg0KICogcnMgPSBbIC8vcG9seWdvbg0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gdG9Qb2x5Z29uKHJzKQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxMDAsMF0sWzEwMCwxXSxbMCwxXV1dDQogKg0KICogcnMgPSBbIC8vcG9seWdvbg0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAsIDBdLA0KICogICAgICAgICBbMTAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IHRvUG9seWdvbihycykNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMCwwXSxbMTAsMF0sWzEwLDFdLFswLDFdXV0NCiAqDQogKiBycyA9IFsgLy9wb2x5Z29uDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0sDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gdG9Qb2x5Z29uKHJzKQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxMDAsMF0sWzEwMCwxXSxbMCwxXV0sW1swLDBdLFsxMCwwXSxbMTAsMV0sWzAsMV1dXQ0KICoNCiAqIHJzID0gWyAvL211bHRpUG9seWdvbg0KICogICAgIFsNCiAqICAgICAgICAgWw0KICogICAgICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgICAgIFswLCAxXSwNCiAqICAgICAgICAgXSwNCiAqICAgICAgICAgWw0KICogICAgICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICAgICAgWzEwLCAwXSwNCiAqICAgICAgICAgICAgIFsxMCwgMV0sDQogKiAgICAgICAgICAgICBbMCwgMV0sDQogKiAgICAgICAgIF0NCiAqICAgICBdDQogKiBdDQogKiByID0gdG9Qb2x5Z29uKHJzKQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxMDAsMF0sWzEwMCwxXSxbMCwxXV0sW1swLDBdLFsxMCwwXSxbMTAsMV0sWzAsMV1dXQ0KICoNCiAqLwpmdW5jdGlvbiB0b1BvbHlnb24odikgewogIGxldCBkID0gZ2V0UG9pbnREZXB0aCh2KTsKICBpZiAoZCA9PT0gMykgewogICAgcmV0dXJuIGZsYXR0ZW4odik7CiAgfSBlbHNlIGlmIChkID09PSAyKSB7CiAgICByZXR1cm4gdjsKICB9IGVsc2UgaWYgKGQgPT09IDEpIHsKICAgIHJldHVybiBbdl07CiAgfSBlbHNlIGlmIChkID09PSAwKSB7CiAgICByZXR1cm4gW107CiAgfQogIHJldHVybiB2Owp9CgovKioNCiAqIOioiOeul1JpbmdTdHJpbmfpnaLnqY0NCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9nZXRBcmVhUmluZ1N0cmluZy50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHJzIOi8uOWFpVJpbmdTdHJpbmfos4fmlpnpmaPliJfvvIzngrpbW3gxLHkxXSxbeDIseTJdLC4uLl3mp4vmiJDkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnVzZUFicz10cnVlXSDovLjlhaXpnaLnqY3mmK/lkKblj5bntZXlsI3lgLzvvIzpoJDoqK10cnVlDQogKiBAcmV0dXJucyB7TnVtYmVyfSDlm57lgrPpnaLnqY3mlbjlrZcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHJzDQogKiBsZXQgcg0KICoNCiAqIHJzID0gWw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiAgICAgWzAsIDBdLCAvL+mWieWQiA0KICogXQ0KICogciA9IGdldEFyZWFSaW5nU3RyaW5nKHJzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDEwMA0KICoNCiAqIHJzID0gWw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiBdDQogKiByID0gZ2V0QXJlYVJpbmdTdHJpbmcocnMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTAwDQogKg0KICogcnMgPSBbDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSBnZXRBcmVhUmluZ1N0cmluZyhycykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAwDQogKg0KICovCmZ1bmN0aW9uIGdldEFyZWFSaW5nU3RyaW5nKHJzLCBvcHQgPSB7fSkgewogIC8vdXNlQWJzCiAgbGV0IHVzZUFicyA9IGdldChvcHQsICd1c2VBYnMnKTsKICBpZiAoIWlzYm9sKHVzZUFicykpIHsKICAgIHVzZUFicyA9IHRydWU7CiAgfQoKICAvL2NoZWNrCiAgaWYgKCFpc2VhcnIocnMpKSB7CiAgICByZXR1cm4gMDsKICB9CgogIC8vZXJzCiAgbGV0IGVycyA9IFtdOwogIGZvckVhY2gocnMsIHYgPT4gewogICAgaWYgKHNpemUodikgPT09IDIpIHsKICAgICAgaWYgKGlzbnVtKHZbMF0pICYmIGlzbnVtKHZbMV0pKSB7CiAgICAgICAgZXJzLnB1c2goW2NkYmwodlswXSksIGNkYmwodlsxXSldKTsKICAgICAgfQogICAgfQogIH0pOwoKICAvL2NoZWNrCiAgaWYgKCFpc2VhcnIoZXJzKSkgewogICAgcmV0dXJuIDA7CiAgfQoKICAvL2FyZWEKICBsZXQgaSA9IC0xOwogIGxldCBuID0gc2l6ZShlcnMpOwogIGxldCBhOwogIGxldCBiID0gZXJzW24gLSAxXTsKICBsZXQgYXJlYSA9IDA7CiAgd2hpbGUgKCsraSA8IG4pIHsKICAgIGEgPSBiOwogICAgYiA9IGVyc1tpXTsKICAgIGFyZWEgKz0gYVsxXSAqIGJbMF0gLSBhWzBdICogYlsxXTsKICB9CiAgbGV0IHIgPSBhcmVhIC8gMjsKCiAgLy91c2VBYnMKICBpZiAodXNlQWJzKSB7CiAgICByID0gTWF0aC5hYnMocik7CiAgfQogIHJldHVybiByOwp9CgovLyBpbXBvcnQgZ2V0IGZyb20gJ2xvZGFzaC1lcy9nZXQuanMnCgovKioNCiAqIOioiOeul1BvbHlnb27pnaLnqY0NCiAqIOW+l+imgeiAg+aFruWkmuWNgOWfn+OAgeWJlOmZpOWNgOWfn+S5i+e1hOWQiDogaHR0cDovL2VzcmkuZ2l0aHViLmlvL2dlb21ldHJ5LWFwaS1qYXZhL2RvYy9Qb2x5Z29uLmh0bWwNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9nZXRBcmVhUG9seWdvbi50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBnIOi8uOWFpVBvbHlnb27os4fmlpnpmaPliJfvvIzngrpbW1t4MSx5MV0sW3gyLHkyXSwuLi5dXeani+aIkOS5i+mZo+WIlw0KICogQHJldHVybnMge051bWJlcn0g5Zue5YKz6Z2i56mN5pW45a2XDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwZw0KICogbGV0IHINCiAqDQogKiBwZyA9IFsNCiAqICAgICBbMCwgMF0sDQogKiAgICAgWzEwMCwgMF0sDQogKiAgICAgWzEwMCwgMV0sDQogKiAgICAgWzAsIDFdLA0KICogICAgIFswLCAwXSwgLy/plonlkIgNCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMDANCiAqDQogKiBwZyA9IFsNCiAqICAgICBbMCwgMF0sDQogKiAgICAgWzEwMCwgMF0sDQogKiAgICAgWzEwMCwgMV0sDQogKiAgICAgWzAsIDFdLA0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDEwMA0KICoNCiAqIHBnID0gWw0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTAwDQogKg0KICogcGcgPSBbDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTANCiAqDQogKiBwZyA9IFsNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXSwNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwLCAwXSwNCiAqICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiA5MA0KICoNCiAqIHBnID0gWw0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdLA0KICogICAgIFsgLy/nrKwgMiBSaW5nU3RyaW5nIOiIh+esrCAxIFJpbmdTdHJpbmcg5LiN6YeN55aKLCDkvYZwb2x5Z29u56ysMeWAi+eCuuS4u+imgeWNgCwg5YW25b6M54K65YmU6Zmk5Y2ALCDmraTngrrmnInllY/poYzlpJrpgorlvaINCiAqICAgICAgICAgWzIwMCwgMF0sDQogKiAgICAgICAgIFsyMTAsIDBdLA0KICogICAgICAgICBbMjEwLCAxXSwNCiAqICAgICAgICAgWzIwMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDkwLCDlr6bpmpvngroxMTANCiAqDQogKi8KZnVuY3Rpb24gZ2V0QXJlYVBvbHlnb24ocGcsIG9wdCA9IHt9KSB7CiAgLy8gLy9lcHNpbG9uCiAgLy8gbGV0IGVwc2lsb24gPSBnZXQob3B0LCAnZXBzaWxvbicsIDAuMDAwMDAwMDAwMDAxKQoKICAvL2NoZWNrCiAgaWYgKCFpc2VhcnIocGcpKSB7CiAgICByZXR1cm4gMDsKICB9CgogIC8vdG9Qb2x5Z29uCiAgcGcgPSB0b1BvbHlnb24ocGcpOwogIC8vIGNvbnNvbGUubG9nKCd0b1BvbHlnb24gcGcnLCBwZykKCiAgLy9yCiAgbGV0IHIgPSAwOwogIGZvckVhY2gocGcsICh2LCBrKSA9PiB7CiAgICAvL3BvbHlnb27ngrrlpJrlgIvlpJrpgorlvaLntYTmiJAsIOesrDHlgIvngrrkuLvopoHljYAsIOS5i+W+jOeCuuWJlOmZpOWNgAogICAgbGV0IGEgPSBnZXRBcmVhUmluZ1N0cmluZyh2KTsKICAgIGlmIChrID09PSAwKSB7CiAgICAgIHIgPSBhOwogICAgfSBlbHNlIHsKICAgICAgciAtPSBhOwogICAgfQogIH0pOwoKICAvL2NoZWNrCiAgaWYgKHIgPCAwKSB7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIHI7Cn0KCi8vIChjKSBDb3B5cmlnaHQgMjAxNiwgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwovLyBNSVQgTGljZW5zZQovLyBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwoKLy8KLy8gdXNlZCBzdHJpY3RseSBmb3IgbG9nZ2luZyB0aGUgcHJvY2Vzc2luZyBvZiB0aGUgYWxnb3JpdGhtLi4uIG9ubHkgdXNlZnVsIGlmIHlvdSBpbnRlbmQgb24KLy8gbG9va2luZyB1bmRlciB0aGUgY292ZXJzIChmb3IgcHJldHR5IFVJJ3Mgb3IgZGVidWdnaW5nKQovLwoKZnVuY3Rpb24gQnVpbGRMb2ckMSgpIHsKICB2YXIgbXk7CiAgdmFyIG5leHRTZWdtZW50SWQgPSAwOwogIHZhciBjdXJWZXJ0ID0gZmFsc2U7CiAgZnVuY3Rpb24gcHVzaCh0eXBlLCBkYXRhKSB7CiAgICBteS5saXN0LnB1c2goewogICAgICB0eXBlOiB0eXBlLAogICAgICBkYXRhOiBkYXRhID8gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhKSkgOiB2b2lkIDAKICAgIH0pOwogICAgcmV0dXJuIG15OwogIH0KICBteSA9IHsKICAgIGxpc3Q6IFtdLAogICAgc2VnbWVudElkOiBmdW5jdGlvbiAoKSB7CiAgICAgIHJldHVybiBuZXh0U2VnbWVudElkKys7CiAgICB9LAogICAgY2hlY2tJbnRlcnNlY3Rpb246IGZ1bmN0aW9uIChzZWcxLCBzZWcyKSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGVjaycsIHsKICAgICAgICBzZWcxOiBzZWcxLAogICAgICAgIHNlZzI6IHNlZzIKICAgICAgfSk7CiAgICB9LAogICAgc2VnbWVudENob3A6IGZ1bmN0aW9uIChzZWcsIGVuZCkgewogICAgICBwdXNoKCdkaXZfc2VnJywgewogICAgICAgIHNlZzogc2VnLAogICAgICAgIHB0OiBlbmQKICAgICAgfSk7CiAgICAgIHJldHVybiBwdXNoKCdjaG9wJywgewogICAgICAgIHNlZzogc2VnLAogICAgICAgIHB0OiBlbmQKICAgICAgfSk7CiAgICB9LAogICAgc3RhdHVzUmVtb3ZlOiBmdW5jdGlvbiAoc2VnKSB7CiAgICAgIHJldHVybiBwdXNoKCdwb3Bfc2VnJywgewogICAgICAgIHNlZzogc2VnCiAgICAgIH0pOwogICAgfSwKICAgIHNlZ21lbnRVcGRhdGU6IGZ1bmN0aW9uIChzZWcpIHsKICAgICAgcmV0dXJuIHB1c2goJ3NlZ191cGRhdGUnLCB7CiAgICAgICAgc2VnOiBzZWcKICAgICAgfSk7CiAgICB9LAogICAgc2VnbWVudE5ldzogZnVuY3Rpb24gKHNlZywgcHJpbWFyeSkgewogICAgICByZXR1cm4gcHVzaCgnbmV3X3NlZycsIHsKICAgICAgICBzZWc6IHNlZywKICAgICAgICBwcmltYXJ5OiBwcmltYXJ5CiAgICAgIH0pOwogICAgfSwKICAgIHNlZ21lbnRSZW1vdmU6IGZ1bmN0aW9uIChzZWcpIHsKICAgICAgcmV0dXJuIHB1c2goJ3JlbV9zZWcnLCB7CiAgICAgICAgc2VnOiBzZWcKICAgICAgfSk7CiAgICB9LAogICAgdGVtcFN0YXR1czogZnVuY3Rpb24gKHNlZywgYWJvdmUsIGJlbG93KSB7CiAgICAgIHJldHVybiBwdXNoKCd0ZW1wX3N0YXR1cycsIHsKICAgICAgICBzZWc6IHNlZywKICAgICAgICBhYm92ZTogYWJvdmUsCiAgICAgICAgYmVsb3c6IGJlbG93CiAgICAgIH0pOwogICAgfSwKICAgIHJld2luZDogZnVuY3Rpb24gKHNlZykgewogICAgICByZXR1cm4gcHVzaCgncmV3aW5kJywgewogICAgICAgIHNlZzogc2VnCiAgICAgIH0pOwogICAgfSwKICAgIHN0YXR1czogZnVuY3Rpb24gKHNlZywgYWJvdmUsIGJlbG93KSB7CiAgICAgIHJldHVybiBwdXNoKCdzdGF0dXMnLCB7CiAgICAgICAgc2VnOiBzZWcsCiAgICAgICAgYWJvdmU6IGFib3ZlLAogICAgICAgIGJlbG93OiBiZWxvdwogICAgICB9KTsKICAgIH0sCiAgICB2ZXJ0OiBmdW5jdGlvbiAoeCkgewogICAgICBpZiAoeCA9PT0gY3VyVmVydCkgcmV0dXJuIG15OwogICAgICBjdXJWZXJ0ID0geDsKICAgICAgcmV0dXJuIHB1c2goJ3ZlcnQnLCB7CiAgICAgICAgeDogeAogICAgICB9KTsKICAgIH0sCiAgICBsb2c6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgIGlmICh0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycpIGRhdGEgPSBKU09OLnN0cmluZ2lmeShkYXRhLCBmYWxzZSwgJyAgJyk7CiAgICAgIHJldHVybiBwdXNoKCdsb2cnLCB7CiAgICAgICAgdHh0OiBkYXRhCiAgICAgIH0pOwogICAgfSwKICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgIHJldHVybiBwdXNoKCdyZXNldCcpOwogICAgfSwKICAgIHNlbGVjdGVkOiBmdW5jdGlvbiAoc2VncykgewogICAgICByZXR1cm4gcHVzaCgnc2VsZWN0ZWQnLCB7CiAgICAgICAgc2Vnczogc2VncwogICAgICB9KTsKICAgIH0sCiAgICBjaGFpblN0YXJ0OiBmdW5jdGlvbiAoc2VnKSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9zdGFydCcsIHsKICAgICAgICBzZWc6IHNlZwogICAgICB9KTsKICAgIH0sCiAgICBjaGFpblJlbW92ZUhlYWQ6IGZ1bmN0aW9uIChpbmRleCwgcHQpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX3JlbV9oZWFkJywgewogICAgICAgIGluZGV4OiBpbmRleCwKICAgICAgICBwdDogcHQKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5SZW1vdmVUYWlsOiBmdW5jdGlvbiAoaW5kZXgsIHB0KSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9yZW1fdGFpbCcsIHsKICAgICAgICBpbmRleDogaW5kZXgsCiAgICAgICAgcHQ6IHB0CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluTmV3OiBmdW5jdGlvbiAocHQxLCBwdDIpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX25ldycsIHsKICAgICAgICBwdDE6IHB0MSwKICAgICAgICBwdDI6IHB0MgogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbk1hdGNoOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX21hdGNoJywgewogICAgICAgIGluZGV4OiBpbmRleAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbkNsb3NlOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX2Nsb3NlJywgewogICAgICAgIGluZGV4OiBpbmRleAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbkFkZEhlYWQ6IGZ1bmN0aW9uIChpbmRleCwgcHQpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX2FkZF9oZWFkJywgewogICAgICAgIGluZGV4OiBpbmRleCwKICAgICAgICBwdDogcHQKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5BZGRUYWlsOiBmdW5jdGlvbiAoaW5kZXgsIHB0KSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9hZGRfdGFpbCcsIHsKICAgICAgICBpbmRleDogaW5kZXgsCiAgICAgICAgcHQ6IHB0CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluQ29ubmVjdDogZnVuY3Rpb24gKGluZGV4MSwgaW5kZXgyKSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9jb24nLCB7CiAgICAgICAgaW5kZXgxOiBpbmRleDEsCiAgICAgICAgaW5kZXgyOiBpbmRleDIKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5SZXZlcnNlOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX3JldicsIHsKICAgICAgICBpbmRleDogaW5kZXgKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5Kb2luOiBmdW5jdGlvbiAoaW5kZXgxLCBpbmRleDIpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX2pvaW4nLCB7CiAgICAgICAgaW5kZXgxOiBpbmRleDEsCiAgICAgICAgaW5kZXgyOiBpbmRleDIKICAgICAgfSk7CiAgICB9LAogICAgZG9uZTogZnVuY3Rpb24gKCkgewogICAgICByZXR1cm4gcHVzaCgnZG9uZScpOwogICAgfQogIH07CiAgcmV0dXJuIG15Owp9CnZhciBidWlsZExvZyQxID0gQnVpbGRMb2ckMTsKCi8vIChjKSBDb3B5cmlnaHQgMjAxNiwgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwovLyBNSVQgTGljZW5zZQovLyBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwoKLy8KLy8gcHJvdmlkZXMgdGhlIHJhdyBjb21wdXRhdGlvbiBmdW5jdGlvbnMgdGhhdCB0YWtlcyBlcHNpbG9uIGludG8gYWNjb3VudAovLwovLyB6ZXJvIGlzIGRlZmluZWQgdG8gYmUgYmV0d2VlbiAoLWVwc2lsb24sIGVwc2lsb24pIGV4Y2x1c2l2ZQovLwoKZnVuY3Rpb24gRXBzaWxvbiQxKGVwcykgewogIGlmICh0eXBlb2YgZXBzICE9PSAnbnVtYmVyJykgZXBzID0gMC4wMDAwMDAwMDAxOyAvLyBzYW5lIGRlZmF1bHQ/IHN1cmUgd2h5IG5vdAogIHZhciBteSA9IHsKICAgIGVwc2lsb246IGZ1bmN0aW9uICh2KSB7CiAgICAgIGlmICh0eXBlb2YgdiA9PT0gJ251bWJlcicpIGVwcyA9IHY7CiAgICAgIHJldHVybiBlcHM7CiAgICB9LAogICAgcG9pbnRBYm92ZU9yT25MaW5lOiBmdW5jdGlvbiAocHQsIGxlZnQsIHJpZ2h0KSB7CiAgICAgIHZhciBBeCA9IGxlZnRbMF07CiAgICAgIHZhciBBeSA9IGxlZnRbMV07CiAgICAgIHZhciBCeCA9IHJpZ2h0WzBdOwogICAgICB2YXIgQnkgPSByaWdodFsxXTsKICAgICAgdmFyIEN4ID0gcHRbMF07CiAgICAgIHZhciBDeSA9IHB0WzFdOwogICAgICByZXR1cm4gKEJ4IC0gQXgpICogKEN5IC0gQXkpIC0gKEJ5IC0gQXkpICogKEN4IC0gQXgpID49IC1lcHM7CiAgICB9LAogICAgcG9pbnRCZXR3ZWVuOiBmdW5jdGlvbiAocCwgbGVmdCwgcmlnaHQpIHsKICAgICAgLy8gcCBtdXN0IGJlIGNvbGxpbmVhciB3aXRoIGxlZnQtPnJpZ2h0CiAgICAgIC8vIHJldHVybnMgZmFsc2UgaWYgcCA9PSBsZWZ0LCBwID09IHJpZ2h0LCBvciBsZWZ0ID09IHJpZ2h0CiAgICAgIHZhciBkX3B5X2x5ID0gcFsxXSAtIGxlZnRbMV07CiAgICAgIHZhciBkX3J4X2x4ID0gcmlnaHRbMF0gLSBsZWZ0WzBdOwogICAgICB2YXIgZF9weF9seCA9IHBbMF0gLSBsZWZ0WzBdOwogICAgICB2YXIgZF9yeV9seSA9IHJpZ2h0WzFdIC0gbGVmdFsxXTsKICAgICAgdmFyIGRvdCA9IGRfcHhfbHggKiBkX3J4X2x4ICsgZF9weV9seSAqIGRfcnlfbHk7CiAgICAgIC8vIGlmIGBkb3RgIGlzIDAsIHRoZW4gYHBgID09IGBsZWZ0YCBvciBgbGVmdGAgPT0gYHJpZ2h0YCAocmVqZWN0KQogICAgICAvLyBpZiBgZG90YCBpcyBsZXNzIHRoYW4gMCwgdGhlbiBgcGAgaXMgdG8gdGhlIGxlZnQgb2YgYGxlZnRgIChyZWplY3QpCiAgICAgIGlmIChkb3QgPCBlcHMpIHJldHVybiBmYWxzZTsKICAgICAgdmFyIHNxbGVuID0gZF9yeF9seCAqIGRfcnhfbHggKyBkX3J5X2x5ICogZF9yeV9seTsKICAgICAgLy8gaWYgYGRvdGAgPiBgc3FsZW5gLCB0aGVuIGBwYCBpcyB0byB0aGUgcmlnaHQgb2YgYHJpZ2h0YCAocmVqZWN0KQogICAgICAvLyB0aGVyZWZvcmUsIGlmIGBkb3QgLSBzcWxlbmAgaXMgZ3JlYXRlciB0aGFuIDAsIHRoZW4gYHBgIGlzIHRvIHRoZSByaWdodCBvZiBgcmlnaHRgIChyZWplY3QpCiAgICAgIGlmIChkb3QgLSBzcWxlbiA+IC1lcHMpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9LAogICAgcG9pbnRzU2FtZVg6IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgICAgcmV0dXJuIE1hdGguYWJzKHAxWzBdIC0gcDJbMF0pIDwgZXBzOwogICAgfSwKICAgIHBvaW50c1NhbWVZOiBmdW5jdGlvbiAocDEsIHAyKSB7CiAgICAgIHJldHVybiBNYXRoLmFicyhwMVsxXSAtIHAyWzFdKSA8IGVwczsKICAgIH0sCiAgICBwb2ludHNTYW1lOiBmdW5jdGlvbiAocDEsIHAyKSB7CiAgICAgIHJldHVybiBteS5wb2ludHNTYW1lWChwMSwgcDIpICYmIG15LnBvaW50c1NhbWVZKHAxLCBwMik7CiAgICB9LAogICAgcG9pbnRzQ29tcGFyZTogZnVuY3Rpb24gKHAxLCBwMikgewogICAgICAvLyByZXR1cm5zIC0xIGlmIHAxIGlzIHNtYWxsZXIsIDEgaWYgcDIgaXMgc21hbGxlciwgMCBpZiBlcXVhbAogICAgICBpZiAobXkucG9pbnRzU2FtZVgocDEsIHAyKSkgcmV0dXJuIG15LnBvaW50c1NhbWVZKHAxLCBwMikgPyAwIDogcDFbMV0gPCBwMlsxXSA/IC0xIDogMTsKICAgICAgcmV0dXJuIHAxWzBdIDwgcDJbMF0gPyAtMSA6IDE7CiAgICB9LAogICAgcG9pbnRzQ29sbGluZWFyOiBmdW5jdGlvbiAocHQxLCBwdDIsIHB0MykgewogICAgICAvLyBkb2VzIHB0MS0+cHQyLT5wdDMgbWFrZSBhIHN0cmFpZ2h0IGxpbmU/CiAgICAgIC8vIGVzc2VudGlhbGx5IHRoaXMgaXMganVzdCBjaGVja2luZyB0byBzZWUgaWYgdGhlIHNsb3BlKHB0MS0+cHQyKSA9PT0gc2xvcGUocHQyLT5wdDMpCiAgICAgIC8vIGlmIHNsb3BlcyBhcmUgZXF1YWwsIHRoZW4gdGhleSBtdXN0IGJlIGNvbGxpbmVhciwgYmVjYXVzZSB0aGV5IHNoYXJlIHB0MgogICAgICB2YXIgZHgxID0gcHQxWzBdIC0gcHQyWzBdOwogICAgICB2YXIgZHkxID0gcHQxWzFdIC0gcHQyWzFdOwogICAgICB2YXIgZHgyID0gcHQyWzBdIC0gcHQzWzBdOwogICAgICB2YXIgZHkyID0gcHQyWzFdIC0gcHQzWzFdOwogICAgICByZXR1cm4gTWF0aC5hYnMoZHgxICogZHkyIC0gZHgyICogZHkxKSA8IGVwczsKICAgIH0sCiAgICBsaW5lc0ludGVyc2VjdDogZnVuY3Rpb24gKGEwLCBhMSwgYjAsIGIxKSB7CiAgICAgIC8vIHJldHVybnMgZmFsc2UgaWYgdGhlIGxpbmVzIGFyZSBjb2luY2lkZW50IChlLmcuLCBwYXJhbGxlbCBvciBvbiB0b3Agb2YgZWFjaCBvdGhlcikKICAgICAgLy8KICAgICAgLy8gcmV0dXJucyBhbiBvYmplY3QgaWYgdGhlIGxpbmVzIGludGVyc2VjdDoKICAgICAgLy8gICB7CiAgICAgIC8vICAgICBwdDogW3gsIHldLCAgICB3aGVyZSB0aGUgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGF0CiAgICAgIC8vICAgICBhbG9uZ0E6IHdoZXJlIGludGVyc2VjdGlvbiBwb2ludCBpcyBhbG9uZyBBLAogICAgICAvLyAgICAgYWxvbmdCOiB3aGVyZSBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYWxvbmcgQgogICAgICAvLyAgIH0KICAgICAgLy8KICAgICAgLy8gIGFsb25nQSBhbmQgYWxvbmdCIHdpbGwgZWFjaCBiZSBvbmUgb2Y6IC0yLCAtMSwgMCwgMSwgMgogICAgICAvLwogICAgICAvLyAgd2l0aCB0aGUgZm9sbG93aW5nIG1lYW5pbmc6CiAgICAgIC8vCiAgICAgIC8vICAgIC0yICAgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGJlZm9yZSBzZWdtZW50J3MgZmlyc3QgcG9pbnQKICAgICAgLy8gICAgLTEgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgZGlyZWN0bHkgb24gc2VnbWVudCdzIGZpcnN0IHBvaW50CiAgICAgIC8vICAgICAwICAgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGJldHdlZW4gc2VnbWVudCdzIGZpcnN0IGFuZCBzZWNvbmQgcG9pbnRzIChleGNsdXNpdmUpCiAgICAgIC8vICAgICAxICAgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGRpcmVjdGx5IG9uIHNlZ21lbnQncyBzZWNvbmQgcG9pbnQKICAgICAgLy8gICAgIDIgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYWZ0ZXIgc2VnbWVudCdzIHNlY29uZCBwb2ludAogICAgICB2YXIgYWR4ID0gYTFbMF0gLSBhMFswXTsKICAgICAgdmFyIGFkeSA9IGExWzFdIC0gYTBbMV07CiAgICAgIHZhciBiZHggPSBiMVswXSAtIGIwWzBdOwogICAgICB2YXIgYmR5ID0gYjFbMV0gLSBiMFsxXTsKICAgICAgdmFyIGF4YiA9IGFkeCAqIGJkeSAtIGFkeSAqIGJkeDsKICAgICAgaWYgKE1hdGguYWJzKGF4YikgPCBlcHMpIHJldHVybiBmYWxzZTsgLy8gbGluZXMgYXJlIGNvaW5jaWRlbnQKCiAgICAgIHZhciBkeCA9IGEwWzBdIC0gYjBbMF07CiAgICAgIHZhciBkeSA9IGEwWzFdIC0gYjBbMV07CiAgICAgIHZhciBBID0gKGJkeCAqIGR5IC0gYmR5ICogZHgpIC8gYXhiOwogICAgICB2YXIgQiA9IChhZHggKiBkeSAtIGFkeSAqIGR4KSAvIGF4YjsKICAgICAgdmFyIHJldCA9IHsKICAgICAgICBhbG9uZ0E6IDAsCiAgICAgICAgYWxvbmdCOiAwLAogICAgICAgIHB0OiBbYTBbMF0gKyBBICogYWR4LCBhMFsxXSArIEEgKiBhZHldCiAgICAgIH07CgogICAgICAvLyBjYXRlZ29yaXplIHdoZXJlIGludGVyc2VjdGlvbiBwb2ludCBpcyBhbG9uZyBBIGFuZCBCCgogICAgICBpZiAoQSA8PSAtZXBzKSByZXQuYWxvbmdBID0gLTI7ZWxzZSBpZiAoQSA8IGVwcykgcmV0LmFsb25nQSA9IC0xO2Vsc2UgaWYgKEEgLSAxIDw9IC1lcHMpIHJldC5hbG9uZ0EgPSAwO2Vsc2UgaWYgKEEgLSAxIDwgZXBzKSByZXQuYWxvbmdBID0gMTtlbHNlIHJldC5hbG9uZ0EgPSAyOwogICAgICBpZiAoQiA8PSAtZXBzKSByZXQuYWxvbmdCID0gLTI7ZWxzZSBpZiAoQiA8IGVwcykgcmV0LmFsb25nQiA9IC0xO2Vsc2UgaWYgKEIgLSAxIDw9IC1lcHMpIHJldC5hbG9uZ0IgPSAwO2Vsc2UgaWYgKEIgLSAxIDwgZXBzKSByZXQuYWxvbmdCID0gMTtlbHNlIHJldC5hbG9uZ0IgPSAyOwogICAgICByZXR1cm4gcmV0OwogICAgfSwKICAgIHBvaW50SW5zaWRlUmVnaW9uOiBmdW5jdGlvbiAocHQsIHJlZ2lvbikgewogICAgICB2YXIgeCA9IHB0WzBdOwogICAgICB2YXIgeSA9IHB0WzFdOwogICAgICB2YXIgbGFzdF94ID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXVswXTsKICAgICAgdmFyIGxhc3RfeSA9IHJlZ2lvbltyZWdpb24ubGVuZ3RoIC0gMV1bMV07CiAgICAgIHZhciBpbnNpZGUgPSBmYWxzZTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWdpb24ubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgY3Vycl94ID0gcmVnaW9uW2ldWzBdOwogICAgICAgIHZhciBjdXJyX3kgPSByZWdpb25baV1bMV07CgogICAgICAgIC8vIGlmIHkgaXMgYmV0d2VlbiBjdXJyX3kgYW5kIGxhc3RfeSwgYW5kCiAgICAgICAgLy8geCBpcyB0byB0aGUgcmlnaHQgb2YgdGhlIGJvdW5kYXJ5IGNyZWF0ZWQgYnkgdGhlIGxpbmUKICAgICAgICBpZiAoY3Vycl95IC0geSA+IGVwcyAhPSBsYXN0X3kgLSB5ID4gZXBzICYmIChsYXN0X3ggLSBjdXJyX3gpICogKHkgLSBjdXJyX3kpIC8gKGxhc3RfeSAtIGN1cnJfeSkgKyBjdXJyX3ggLSB4ID4gZXBzKSBpbnNpZGUgPSAhaW5zaWRlOwogICAgICAgIGxhc3RfeCA9IGN1cnJfeDsKICAgICAgICBsYXN0X3kgPSBjdXJyX3k7CiAgICAgIH0KICAgICAgcmV0dXJuIGluc2lkZTsKICAgIH0KICB9OwogIHJldHVybiBteTsKfQp2YXIgZXBzaWxvbiQzID0gRXBzaWxvbiQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyBzaW1wbGUgbGlua2VkIGxpc3QgaW1wbGVtZW50YXRpb24gdGhhdCBhbGxvd3MgeW91IHRvIHRyYXZlcnNlIGRvd24gbm9kZXMgYW5kIHNhdmUgcG9zaXRpb25zCi8vCgp2YXIgTGlua2VkTGlzdCQxID0gewogIGNyZWF0ZTogZnVuY3Rpb24gKCkgewogICAgdmFyIG15ID0gewogICAgICByb290OiB7CiAgICAgICAgcm9vdDogdHJ1ZSwKICAgICAgICBuZXh0OiBudWxsCiAgICAgIH0sCiAgICAgIGV4aXN0czogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICBpZiAobm9kZSA9PT0gbnVsbCB8fCBub2RlID09PSBteS5yb290KSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0sCiAgICAgIGlzRW1wdHk6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gbXkucm9vdC5uZXh0ID09PSBudWxsOwogICAgICB9LAogICAgICBnZXRIZWFkOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIG15LnJvb3QubmV4dDsKICAgICAgfSwKICAgICAgaW5zZXJ0QmVmb3JlOiBmdW5jdGlvbiAobm9kZSwgY2hlY2spIHsKICAgICAgICB2YXIgbGFzdCA9IG15LnJvb3Q7CiAgICAgICAgdmFyIGhlcmUgPSBteS5yb290Lm5leHQ7CiAgICAgICAgd2hpbGUgKGhlcmUgIT09IG51bGwpIHsKICAgICAgICAgIGlmIChjaGVjayhoZXJlKSkgewogICAgICAgICAgICBub2RlLnByZXYgPSBoZXJlLnByZXY7CiAgICAgICAgICAgIG5vZGUubmV4dCA9IGhlcmU7CiAgICAgICAgICAgIGhlcmUucHJldi5uZXh0ID0gbm9kZTsKICAgICAgICAgICAgaGVyZS5wcmV2ID0gbm9kZTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgbGFzdCA9IGhlcmU7CiAgICAgICAgICBoZXJlID0gaGVyZS5uZXh0OwogICAgICAgIH0KICAgICAgICBsYXN0Lm5leHQgPSBub2RlOwogICAgICAgIG5vZGUucHJldiA9IGxhc3Q7CiAgICAgICAgbm9kZS5uZXh0ID0gbnVsbDsKICAgICAgfSwKICAgICAgZmluZFRyYW5zaXRpb246IGZ1bmN0aW9uIChjaGVjaykgewogICAgICAgIHZhciBwcmV2ID0gbXkucm9vdDsKICAgICAgICB2YXIgaGVyZSA9IG15LnJvb3QubmV4dDsKICAgICAgICB3aGlsZSAoaGVyZSAhPT0gbnVsbCkgewogICAgICAgICAgaWYgKGNoZWNrKGhlcmUpKSBicmVhazsKICAgICAgICAgIHByZXYgPSBoZXJlOwogICAgICAgICAgaGVyZSA9IGhlcmUubmV4dDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIGJlZm9yZTogcHJldiA9PT0gbXkucm9vdCA/IG51bGwgOiBwcmV2LAogICAgICAgICAgYWZ0ZXI6IGhlcmUsCiAgICAgICAgICBpbnNlcnQ6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIG5vZGUucHJldiA9IHByZXY7CiAgICAgICAgICAgIG5vZGUubmV4dCA9IGhlcmU7CiAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGU7CiAgICAgICAgICAgIGlmIChoZXJlICE9PSBudWxsKSBoZXJlLnByZXYgPSBub2RlOwogICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICB9CiAgICB9OwogICAgcmV0dXJuIG15OwogIH0sCiAgbm9kZTogZnVuY3Rpb24gKGRhdGEpIHsKICAgIGRhdGEucHJldiA9IG51bGw7CiAgICBkYXRhLm5leHQgPSBudWxsOwogICAgZGF0YS5yZW1vdmUgPSBmdW5jdGlvbiAoKSB7CiAgICAgIGRhdGEucHJldi5uZXh0ID0gZGF0YS5uZXh0OwogICAgICBpZiAoZGF0YS5uZXh0KSBkYXRhLm5leHQucHJldiA9IGRhdGEucHJldjsKICAgICAgZGF0YS5wcmV2ID0gbnVsbDsKICAgICAgZGF0YS5uZXh0ID0gbnVsbDsKICAgIH07CiAgICByZXR1cm4gZGF0YTsKICB9Cn07CnZhciBsaW5rZWRMaXN0ID0gTGlua2VkTGlzdCQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyB0aGlzIGlzIHRoZSBjb3JlIHdvcmstaG9yc2UKLy8KCnZhciBMaW5rZWRMaXN0ID0gbGlua2VkTGlzdDsKZnVuY3Rpb24gSW50ZXJzZWN0ZXIkMShzZWxmSW50ZXJzZWN0aW9uLCBlcHMsIGJ1aWxkTG9nKSB7CiAgLy8gc2VsZkludGVyc2VjdGlvbiBpcyB0cnVlL2ZhbHNlIGRlcGVuZGluZyBvbiB0aGUgcGhhc2Ugb2YgdGhlIG92ZXJhbGwgYWxnb3JpdGhtCgogIC8vCiAgLy8gc2VnbWVudCBjcmVhdGlvbgogIC8vCgogIGZ1bmN0aW9uIHNlZ21lbnROZXcoc3RhcnQsIGVuZCkgewogICAgcmV0dXJuIHsKICAgICAgaWQ6IGJ1aWxkTG9nID8gYnVpbGRMb2cuc2VnbWVudElkKCkgOiAtMSwKICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICBlbmQ6IGVuZCwKICAgICAgbXlGaWxsOiB7CiAgICAgICAgYWJvdmU6IG51bGwsCiAgICAgICAgLy8gaXMgdGhlcmUgZmlsbCBhYm92ZSB1cz8KICAgICAgICBiZWxvdzogbnVsbCAvLyBpcyB0aGVyZSBmaWxsIGJlbG93IHVzPwogICAgICB9LAoKICAgICAgb3RoZXJGaWxsOiBudWxsCiAgICB9OwogIH0KICBmdW5jdGlvbiBzZWdtZW50Q29weShzdGFydCwgZW5kLCBzZWcpIHsKICAgIHJldHVybiB7CiAgICAgIGlkOiBidWlsZExvZyA/IGJ1aWxkTG9nLnNlZ21lbnRJZCgpIDogLTEsCiAgICAgIHN0YXJ0OiBzdGFydCwKICAgICAgZW5kOiBlbmQsCiAgICAgIG15RmlsbDogewogICAgICAgIGFib3ZlOiBzZWcubXlGaWxsLmFib3ZlLAogICAgICAgIGJlbG93OiBzZWcubXlGaWxsLmJlbG93CiAgICAgIH0sCiAgICAgIG90aGVyRmlsbDogbnVsbAogICAgfTsKICB9CgogIC8vCiAgLy8gZXZlbnQgbG9naWMKICAvLwoKICB2YXIgZXZlbnRfcm9vdCA9IExpbmtlZExpc3QuY3JlYXRlKCk7CiAgZnVuY3Rpb24gZXZlbnRDb21wYXJlKHAxX2lzU3RhcnQsIHAxXzEsIHAxXzIsIHAyX2lzU3RhcnQsIHAyXzEsIHAyXzIpIHsKICAgIC8vIGNvbXBhcmUgdGhlIHNlbGVjdGVkIHBvaW50cyBmaXJzdAogICAgdmFyIGNvbXAgPSBlcHMucG9pbnRzQ29tcGFyZShwMV8xLCBwMl8xKTsKICAgIGlmIChjb21wICE9PSAwKSByZXR1cm4gY29tcDsKICAgIC8vIHRoZSBzZWxlY3RlZCBwb2ludHMgYXJlIHRoZSBzYW1lCgogICAgaWYgKGVwcy5wb2ludHNTYW1lKHAxXzIsIHAyXzIpKQogICAgICAvLyBpZiB0aGUgbm9uLXNlbGVjdGVkIHBvaW50cyBhcmUgdGhlIHNhbWUgdG9vLi4uCiAgICAgIHJldHVybiAwOyAvLyB0aGVuIHRoZSBzZWdtZW50cyBhcmUgZXF1YWwKCiAgICBpZiAocDFfaXNTdGFydCAhPT0gcDJfaXNTdGFydCkKICAgICAgLy8gaWYgb25lIGlzIGEgc3RhcnQgYW5kIHRoZSBvdGhlciBpc24ndC4uLgogICAgICByZXR1cm4gcDFfaXNTdGFydCA/IDEgOiAtMTsgLy8gZmF2b3IgdGhlIG9uZSB0aGF0IGlzbid0IHRoZSBzdGFydAoKICAgIC8vIG90aGVyd2lzZSwgd2UnbGwgaGF2ZSB0byBjYWxjdWxhdGUgd2hpY2ggb25lIGlzIGJlbG93IHRoZSBvdGhlciBtYW51YWxseQogICAgcmV0dXJuIGVwcy5wb2ludEFib3ZlT3JPbkxpbmUocDFfMiwgcDJfaXNTdGFydCA/IHAyXzEgOiBwMl8yLAogICAgLy8gb3JkZXIgbWF0dGVycwogICAgcDJfaXNTdGFydCA/IHAyXzIgOiBwMl8xKSA/IDEgOiAtMTsKICB9CiAgZnVuY3Rpb24gZXZlbnRBZGQoZXYsIG90aGVyX3B0KSB7CiAgICBldmVudF9yb290Lmluc2VydEJlZm9yZShldiwgZnVuY3Rpb24gKGhlcmUpIHsKICAgICAgLy8gc2hvdWxkIGV2IGJlIGluc2VydGVkIGJlZm9yZSBoZXJlPwogICAgICB2YXIgY29tcCA9IGV2ZW50Q29tcGFyZShldi5pc1N0YXJ0LCBldi5wdCwgb3RoZXJfcHQsIGhlcmUuaXNTdGFydCwgaGVyZS5wdCwgaGVyZS5vdGhlci5wdCk7CiAgICAgIHJldHVybiBjb21wIDwgMDsKICAgIH0pOwogIH0KICBmdW5jdGlvbiBldmVudEFkZFNlZ21lbnRTdGFydChzZWcsIHByaW1hcnkpIHsKICAgIHZhciBldl9zdGFydCA9IExpbmtlZExpc3Qubm9kZSh7CiAgICAgIGlzU3RhcnQ6IHRydWUsCiAgICAgIHB0OiBzZWcuc3RhcnQsCiAgICAgIHNlZzogc2VnLAogICAgICBwcmltYXJ5OiBwcmltYXJ5LAogICAgICBvdGhlcjogbnVsbCwKICAgICAgc3RhdHVzOiBudWxsCiAgICB9KTsKICAgIGV2ZW50QWRkKGV2X3N0YXJ0LCBzZWcuZW5kKTsKICAgIHJldHVybiBldl9zdGFydDsKICB9CiAgZnVuY3Rpb24gZXZlbnRBZGRTZWdtZW50RW5kKGV2X3N0YXJ0LCBzZWcsIHByaW1hcnkpIHsKICAgIHZhciBldl9lbmQgPSBMaW5rZWRMaXN0Lm5vZGUoewogICAgICBpc1N0YXJ0OiBmYWxzZSwKICAgICAgcHQ6IHNlZy5lbmQsCiAgICAgIHNlZzogc2VnLAogICAgICBwcmltYXJ5OiBwcmltYXJ5LAogICAgICBvdGhlcjogZXZfc3RhcnQsCiAgICAgIHN0YXR1czogbnVsbAogICAgfSk7CiAgICBldl9zdGFydC5vdGhlciA9IGV2X2VuZDsKICAgIGV2ZW50QWRkKGV2X2VuZCwgZXZfc3RhcnQucHQpOwogIH0KICBmdW5jdGlvbiBldmVudEFkZFNlZ21lbnQoc2VnLCBwcmltYXJ5KSB7CiAgICB2YXIgZXZfc3RhcnQgPSBldmVudEFkZFNlZ21lbnRTdGFydChzZWcsIHByaW1hcnkpOwogICAgZXZlbnRBZGRTZWdtZW50RW5kKGV2X3N0YXJ0LCBzZWcsIHByaW1hcnkpOwogICAgcmV0dXJuIGV2X3N0YXJ0OwogIH0KICBmdW5jdGlvbiBldmVudFVwZGF0ZUVuZChldiwgZW5kKSB7CiAgICAvLyBzbGlkZXMgYW4gZW5kIGJhY2t3YXJkcwogICAgLy8gICAoc3RhcnQpLS0tLS0tLS0tLS0tKGVuZCkgICAgdG86CiAgICAvLyAgIChzdGFydCktLS0oZW5kKQoKICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuc2VnbWVudENob3AoZXYuc2VnLCBlbmQpOwogICAgZXYub3RoZXIucmVtb3ZlKCk7CiAgICBldi5zZWcuZW5kID0gZW5kOwogICAgZXYub3RoZXIucHQgPSBlbmQ7CiAgICBldmVudEFkZChldi5vdGhlciwgZXYucHQpOwogIH0KICBmdW5jdGlvbiBldmVudERpdmlkZShldiwgcHQpIHsKICAgIHZhciBucyA9IHNlZ21lbnRDb3B5KHB0LCBldi5zZWcuZW5kLCBldi5zZWcpOwogICAgZXZlbnRVcGRhdGVFbmQoZXYsIHB0KTsKICAgIHJldHVybiBldmVudEFkZFNlZ21lbnQobnMsIGV2LnByaW1hcnkpOwogIH0KICBmdW5jdGlvbiBjYWxjdWxhdGUocHJpbWFyeVBvbHlJbnZlcnRlZCwgc2Vjb25kYXJ5UG9seUludmVydGVkKSB7CiAgICAvLyBpZiBzZWxmSW50ZXJzZWN0aW9uIGlzIHRydWUgdGhlbiB0aGVyZSBpcyBubyBzZWNvbmRhcnkgcG9seWdvbiwgc28gdGhhdCBpc24ndCB1c2VkCgogICAgLy8KICAgIC8vIHN0YXR1cyBsb2dpYwogICAgLy8KCiAgICB2YXIgc3RhdHVzX3Jvb3QgPSBMaW5rZWRMaXN0LmNyZWF0ZSgpOwogICAgZnVuY3Rpb24gc3RhdHVzQ29tcGFyZShldjEsIGV2MikgewogICAgICB2YXIgYTEgPSBldjEuc2VnLnN0YXJ0OwogICAgICB2YXIgYTIgPSBldjEuc2VnLmVuZDsKICAgICAgdmFyIGIxID0gZXYyLnNlZy5zdGFydDsKICAgICAgdmFyIGIyID0gZXYyLnNlZy5lbmQ7CiAgICAgIGlmIChlcHMucG9pbnRzQ29sbGluZWFyKGExLCBiMSwgYjIpKSB7CiAgICAgICAgaWYgKGVwcy5wb2ludHNDb2xsaW5lYXIoYTIsIGIxLCBiMikpIHJldHVybiAxOyAvL2V2ZW50Q29tcGFyZSh0cnVlLCBhMSwgYTIsIHRydWUsIGIxLCBiMik7CiAgICAgICAgcmV0dXJuIGVwcy5wb2ludEFib3ZlT3JPbkxpbmUoYTIsIGIxLCBiMikgPyAxIDogLTE7CiAgICAgIH0KICAgICAgcmV0dXJuIGVwcy5wb2ludEFib3ZlT3JPbkxpbmUoYTEsIGIxLCBiMikgPyAxIDogLTE7CiAgICB9CiAgICBmdW5jdGlvbiBzdGF0dXNGaW5kU3Vycm91bmRpbmcoZXYpIHsKICAgICAgcmV0dXJuIHN0YXR1c19yb290LmZpbmRUcmFuc2l0aW9uKGZ1bmN0aW9uIChoZXJlKSB7CiAgICAgICAgdmFyIGNvbXAgPSBzdGF0dXNDb21wYXJlKGV2LCBoZXJlLmV2KTsKICAgICAgICByZXR1cm4gY29tcCA+IDA7CiAgICAgIH0pOwogICAgfQogICAgZnVuY3Rpb24gY2hlY2tJbnRlcnNlY3Rpb24oZXYxLCBldjIpIHsKICAgICAgLy8gcmV0dXJucyB0aGUgc2VnbWVudCBlcXVhbCB0byBldjEsIG9yIGZhbHNlIGlmIG5vdGhpbmcgZXF1YWwKCiAgICAgIHZhciBzZWcxID0gZXYxLnNlZzsKICAgICAgdmFyIHNlZzIgPSBldjIuc2VnOwogICAgICB2YXIgYTEgPSBzZWcxLnN0YXJ0OwogICAgICB2YXIgYTIgPSBzZWcxLmVuZDsKICAgICAgdmFyIGIxID0gc2VnMi5zdGFydDsKICAgICAgdmFyIGIyID0gc2VnMi5lbmQ7CiAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hlY2tJbnRlcnNlY3Rpb24oc2VnMSwgc2VnMik7CiAgICAgIHZhciBpID0gZXBzLmxpbmVzSW50ZXJzZWN0KGExLCBhMiwgYjEsIGIyKTsKICAgICAgaWYgKGkgPT09IGZhbHNlKSB7CiAgICAgICAgLy8gc2VnbWVudHMgYXJlIHBhcmFsbGVsIG9yIGNvaW5jaWRlbnQKCiAgICAgICAgLy8gaWYgcG9pbnRzIGFyZW4ndCBjb2xsaW5lYXIsIHRoZW4gdGhlIHNlZ21lbnRzIGFyZSBwYXJhbGxlbCwgc28gbm8gaW50ZXJzZWN0aW9ucwogICAgICAgIGlmICghZXBzLnBvaW50c0NvbGxpbmVhcihhMSwgYTIsIGIxKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIC8vIG90aGVyd2lzZSwgc2VnbWVudHMgYXJlIG9uIHRvcCBvZiBlYWNoIG90aGVyIHNvbWVob3cgKGFrYSBjb2luY2lkZW50KQoKICAgICAgICBpZiAoZXBzLnBvaW50c1NhbWUoYTEsIGIyKSB8fCBlcHMucG9pbnRzU2FtZShhMiwgYjEpKSByZXR1cm4gZmFsc2U7IC8vIHNlZ21lbnRzIHRvdWNoIGF0IGVuZHBvaW50cy4uLiBubyBpbnRlcnNlY3Rpb24KCiAgICAgICAgdmFyIGExX2VxdV9iMSA9IGVwcy5wb2ludHNTYW1lKGExLCBiMSk7CiAgICAgICAgdmFyIGEyX2VxdV9iMiA9IGVwcy5wb2ludHNTYW1lKGEyLCBiMik7CiAgICAgICAgaWYgKGExX2VxdV9iMSAmJiBhMl9lcXVfYjIpIHJldHVybiBldjI7IC8vIHNlZ21lbnRzIGFyZSBleGFjdGx5IGVxdWFsCgogICAgICAgIHZhciBhMV9iZXR3ZWVuID0gIWExX2VxdV9iMSAmJiBlcHMucG9pbnRCZXR3ZWVuKGExLCBiMSwgYjIpOwogICAgICAgIHZhciBhMl9iZXR3ZWVuID0gIWEyX2VxdV9iMiAmJiBlcHMucG9pbnRCZXR3ZWVuKGEyLCBiMSwgYjIpOwoKICAgICAgICAvLyBoYW5keSBmb3IgZGVidWdnaW5nOgogICAgICAgIC8vIGJ1aWxkTG9nLmxvZyh7CiAgICAgICAgLy8JYTFfZXF1X2IxOiBhMV9lcXVfYjEsCiAgICAgICAgLy8JYTJfZXF1X2IyOiBhMl9lcXVfYjIsCiAgICAgICAgLy8JYTFfYmV0d2VlbjogYTFfYmV0d2VlbiwKICAgICAgICAvLwlhMl9iZXR3ZWVuOiBhMl9iZXR3ZWVuCiAgICAgICAgLy8gfSk7CgogICAgICAgIGlmIChhMV9lcXVfYjEpIHsKICAgICAgICAgIGlmIChhMl9iZXR3ZWVuKSB7CiAgICAgICAgICAgIC8vICAoYTEpLS0tKGEyKQogICAgICAgICAgICAvLyAgKGIxKS0tLS0tLS0tLS0oYjIpCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgYTIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gIChhMSktLS0tLS0tLS0tKGEyKQogICAgICAgICAgICAvLyAgKGIxKS0tLShiMikKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBiMik7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZXYyOwogICAgICAgIH0gZWxzZSBpZiAoYTFfYmV0d2VlbikgewogICAgICAgICAgaWYgKCFhMl9lcXVfYjIpIHsKICAgICAgICAgICAgLy8gbWFrZSBhMiBlcXVhbCB0byBiMgogICAgICAgICAgICBpZiAoYTJfYmV0d2VlbikgewogICAgICAgICAgICAgIC8vICAgICAgICAgKGExKS0tLShhMikKICAgICAgICAgICAgICAvLyAgKGIxKS0tLS0tLS0tLS0tLS0tLS0tKGIyKQogICAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgYTIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vICAgICAgICAgKGExKS0tLS0tLS0tLS0oYTIpCiAgICAgICAgICAgICAgLy8gIChiMSktLS0tLS0tLS0tKGIyKQogICAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MSwgYjIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgLy8gICAgICAgICAoYTEpLS0tKGEyKQogICAgICAgICAgLy8gIChiMSktLS0tLS0tLS0tKGIyKQogICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBhMSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIG90aGVyd2lzZSwgbGluZXMgaW50ZXJzZWN0IGF0IGkucHQsIHdoaWNoIG1heSBvciBtYXkgbm90IGJlIGJldHdlZW4gdGhlIGVuZHBvaW50cwoKICAgICAgICAvLyBpcyBBIGRpdmlkZWQgYmV0d2VlbiBpdHMgZW5kcG9pbnRzPyAoZXhjbHVzaXZlKQogICAgICAgIGlmIChpLmFsb25nQSA9PT0gMCkgewogICAgICAgICAgaWYgKGkuYWxvbmdCID09PSAtMSkKICAgICAgICAgICAgLy8geWVzLCBhdCBleGFjdGx5IGIxCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MSwgYjEpO2Vsc2UgaWYgKGkuYWxvbmdCID09PSAwKQogICAgICAgICAgICAvLyB5ZXMsIHNvbWV3aGVyZSBiZXR3ZWVuIEIncyBlbmRwb2ludHMKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBpLnB0KTtlbHNlIGlmIChpLmFsb25nQiA9PT0gMSkKICAgICAgICAgICAgLy8geWVzLCBhdCBleGFjdGx5IGIyCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MSwgYjIpOwogICAgICAgIH0KCiAgICAgICAgLy8gaXMgQiBkaXZpZGVkIGJldHdlZW4gaXRzIGVuZHBvaW50cz8gKGV4Y2x1c2l2ZSkKICAgICAgICBpZiAoaS5hbG9uZ0IgPT09IDApIHsKICAgICAgICAgIGlmIChpLmFsb25nQSA9PT0gLTEpCiAgICAgICAgICAgIC8vIHllcywgYXQgZXhhY3RseSBhMQogICAgICAgICAgICBldmVudERpdmlkZShldjIsIGExKTtlbHNlIGlmIChpLmFsb25nQSA9PT0gMCkKICAgICAgICAgICAgLy8geWVzLCBzb21ld2hlcmUgYmV0d2VlbiBBJ3MgZW5kcG9pbnRzIChleGNsdXNpdmUpCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgaS5wdCk7ZWxzZSBpZiAoaS5hbG9uZ0EgPT09IDEpCiAgICAgICAgICAgIC8vIHllcywgYXQgZXhhY3RseSBhMgogICAgICAgICAgICBldmVudERpdmlkZShldjIsIGEyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vCiAgICAvLyBtYWluIGV2ZW50IGxvb3AKICAgIC8vCiAgICB2YXIgc2VnbWVudHMgPSBbXTsKICAgIHdoaWxlICghZXZlbnRfcm9vdC5pc0VtcHR5KCkpIHsKICAgICAgdmFyIGV2ID0gZXZlbnRfcm9vdC5nZXRIZWFkKCk7CiAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cudmVydChldi5wdFswXSk7CiAgICAgIGlmIChldi5pc1N0YXJ0KSB7CiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5zZWdtZW50TmV3KGV2LnNlZywgZXYucHJpbWFyeSk7CiAgICAgICAgdmFyIHN1cnJvdW5kaW5nID0gc3RhdHVzRmluZFN1cnJvdW5kaW5nKGV2KTsKICAgICAgICB2YXIgYWJvdmUgPSBzdXJyb3VuZGluZy5iZWZvcmUgPyBzdXJyb3VuZGluZy5iZWZvcmUuZXYgOiBudWxsOwogICAgICAgIHZhciBiZWxvdyA9IHN1cnJvdW5kaW5nLmFmdGVyID8gc3Vycm91bmRpbmcuYWZ0ZXIuZXYgOiBudWxsOwogICAgICAgIGlmIChidWlsZExvZykgewogICAgICAgICAgYnVpbGRMb2cudGVtcFN0YXR1cyhldi5zZWcsIGFib3ZlID8gYWJvdmUuc2VnIDogZmFsc2UsIGJlbG93ID8gYmVsb3cuc2VnIDogZmFsc2UpOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBjaGVja0JvdGhJbnRlcnNlY3Rpb25zKCkgewogICAgICAgICAgaWYgKGFib3ZlKSB7CiAgICAgICAgICAgIHZhciBldmUgPSBjaGVja0ludGVyc2VjdGlvbihldiwgYWJvdmUpOwogICAgICAgICAgICBpZiAoZXZlKSByZXR1cm4gZXZlOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJlbG93KSByZXR1cm4gY2hlY2tJbnRlcnNlY3Rpb24oZXYsIGJlbG93KTsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgdmFyIGV2ZSA9IGNoZWNrQm90aEludGVyc2VjdGlvbnMoKTsKICAgICAgICBpZiAoZXZlKSB7CiAgICAgICAgICAvLyBldiBhbmQgZXZlIGFyZSBlcXVhbAogICAgICAgICAgLy8gd2UnbGwga2VlcCBldmUgYW5kIHRocm93IGF3YXkgZXYKCiAgICAgICAgICAvLyBtZXJnZSBldi5zZWcncyBmaWxsIGluZm9ybWF0aW9uIGludG8gZXZlLnNlZwoKICAgICAgICAgIGlmIChzZWxmSW50ZXJzZWN0aW9uKSB7CiAgICAgICAgICAgIHZhciB0b2dnbGU7IC8vIGFyZSB3ZSBhIHRvZ2dsaW5nIGVkZ2U/CiAgICAgICAgICAgIGlmIChldi5zZWcubXlGaWxsLmJlbG93ID09PSBudWxsKSB0b2dnbGUgPSB0cnVlO2Vsc2UgdG9nZ2xlID0gZXYuc2VnLm15RmlsbC5hYm92ZSAhPT0gZXYuc2VnLm15RmlsbC5iZWxvdzsKCiAgICAgICAgICAgIC8vIG1lcmdlIHR3byBzZWdtZW50cyB0aGF0IGJlbG9uZyB0byB0aGUgc2FtZSBwb2x5Z29uCiAgICAgICAgICAgIC8vIHRoaW5rIG9mIHRoaXMgYXMgc2FuZHdpY2hpbmcgdHdvIHNlZ21lbnRzIHRvZ2V0aGVyLCB3aGVyZSBgZXZlLnNlZ2AgaXMKICAgICAgICAgICAgLy8gdGhlIGJvdHRvbSAtLSB0aGlzIHdpbGwgY2F1c2UgdGhlIGFib3ZlIGZpbGwgZmxhZyB0byB0b2dnbGUKICAgICAgICAgICAgaWYgKHRvZ2dsZSkgZXZlLnNlZy5teUZpbGwuYWJvdmUgPSAhZXZlLnNlZy5teUZpbGwuYWJvdmU7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBtZXJnZSB0d28gc2VnbWVudHMgdGhhdCBiZWxvbmcgdG8gZGlmZmVyZW50IHBvbHlnb25zCiAgICAgICAgICAgIC8vIGVhY2ggc2VnbWVudCBoYXMgZGlzdGluY3Qga25vd2xlZGdlLCBzbyBubyBzcGVjaWFsIGxvZ2ljIGlzIG5lZWRlZAogICAgICAgICAgICAvLyBub3RlIHRoYXQgdGhpcyBjYW4gb25seSBoYXBwZW4gb25jZSBwZXIgc2VnbWVudCBpbiB0aGlzIHBoYXNlLCBiZWNhdXNlIHdlCiAgICAgICAgICAgIC8vIGFyZSBndWFyYW50ZWVkIHRoYXQgYWxsIHNlbGYtaW50ZXJzZWN0aW9ucyBhcmUgZ29uZQogICAgICAgICAgICBldmUuc2VnLm90aGVyRmlsbCA9IGV2LnNlZy5teUZpbGw7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnNlZ21lbnRVcGRhdGUoZXZlLnNlZyk7CiAgICAgICAgICBldi5vdGhlci5yZW1vdmUoKTsKICAgICAgICAgIGV2LnJlbW92ZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoZXZlbnRfcm9vdC5nZXRIZWFkKCkgIT09IGV2KSB7CiAgICAgICAgICAvLyBzb21ldGhpbmcgd2FzIGluc2VydGVkIGJlZm9yZSB1cyBpbiB0aGUgZXZlbnQgcXVldWUsIHNvIGxvb3AgYmFjayBhcm91bmQgYW5kCiAgICAgICAgICAvLyBwcm9jZXNzIGl0IGJlZm9yZSBjb250aW51aW5nCiAgICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnJld2luZChldi5zZWcpOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICAvLwogICAgICAgIC8vIGNhbGN1bGF0ZSBmaWxsIGZsYWdzCiAgICAgICAgLy8KICAgICAgICBpZiAoc2VsZkludGVyc2VjdGlvbikgewogICAgICAgICAgdmFyIHRvZ2dsZTsgLy8gYXJlIHdlIGEgdG9nZ2xpbmcgZWRnZT8KICAgICAgICAgIGlmIChldi5zZWcubXlGaWxsLmJlbG93ID09PSBudWxsKQogICAgICAgICAgICAvLyBpZiB3ZSBhcmUgYSBuZXcgc2VnbWVudC4uLgogICAgICAgICAgICB0b2dnbGUgPSB0cnVlOyAvLyB0aGVuIHdlIHRvZ2dsZQogICAgICAgICAgZWxzZQogICAgICAgICAgICAvLyB3ZSBhcmUgYSBzZWdtZW50IHRoYXQgaGFzIHByZXZpb3VzIGtub3dsZWRnZSBmcm9tIGEgZGl2aXNpb24KICAgICAgICAgICAgdG9nZ2xlID0gZXYuc2VnLm15RmlsbC5hYm92ZSAhPT0gZXYuc2VnLm15RmlsbC5iZWxvdzsgLy8gY2FsY3VsYXRlIHRvZ2dsZQoKICAgICAgICAgIC8vIG5leHQsIGNhbGN1bGF0ZSB3aGV0aGVyIHdlIGFyZSBmaWxsZWQgYmVsb3cgdXMKICAgICAgICAgIGlmICghYmVsb3cpIHsKICAgICAgICAgICAgLy8gaWYgbm90aGluZyBpcyBiZWxvdyB1cy4uLgogICAgICAgICAgICAvLyB3ZSBhcmUgZmlsbGVkIGJlbG93IHVzIGlmIHRoZSBwb2x5Z29uIGlzIGludmVydGVkCiAgICAgICAgICAgIGV2LnNlZy5teUZpbGwuYmVsb3cgPSBwcmltYXJ5UG9seUludmVydGVkOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCB3ZSBrbm93IHRoZSBhbnN3ZXIgLS0gaXQncyB0aGUgc2FtZSBpZiB3aGF0ZXZlciBpcyBiZWxvdwogICAgICAgICAgICAvLyB1cyBpcyBmaWxsZWQgYWJvdmUgaXQKICAgICAgICAgICAgZXYuc2VnLm15RmlsbC5iZWxvdyA9IGJlbG93LnNlZy5teUZpbGwuYWJvdmU7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gc2luY2Ugbm93IHdlIGtub3cgaWYgd2UncmUgZmlsbGVkIGJlbG93IHVzLCB3ZSBjYW4gY2FsY3VsYXRlIHdoZXRoZXIKICAgICAgICAgIC8vIHdlJ3JlIGZpbGxlZCBhYm92ZSB1cyBieSBhcHBseWluZyB0b2dnbGUgdG8gd2hhdGV2ZXIgaXMgYmVsb3cgdXMKICAgICAgICAgIGlmICh0b2dnbGUpIGV2LnNlZy5teUZpbGwuYWJvdmUgPSAhZXYuc2VnLm15RmlsbC5iZWxvdztlbHNlIGV2LnNlZy5teUZpbGwuYWJvdmUgPSBldi5zZWcubXlGaWxsLmJlbG93OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBub3cgd2UgZmlsbCBpbiBhbnkgbWlzc2luZyB0cmFuc2l0aW9uIGluZm9ybWF0aW9uLCBzaW5jZSB3ZSBhcmUgYWxsLWtub3dpbmcKICAgICAgICAgIC8vIGF0IHRoaXMgcG9pbnQKCiAgICAgICAgICBpZiAoZXYuc2VnLm90aGVyRmlsbCA9PT0gbnVsbCkgewogICAgICAgICAgICAvLyBpZiB3ZSBkb24ndCBoYXZlIG90aGVyIGluZm9ybWF0aW9uLCB0aGVuIHdlIG5lZWQgdG8gZmlndXJlIG91dCBpZiB3ZSdyZQogICAgICAgICAgICAvLyBpbnNpZGUgdGhlIG90aGVyIHBvbHlnb24KICAgICAgICAgICAgdmFyIGluc2lkZTsKICAgICAgICAgICAgaWYgKCFiZWxvdykgewogICAgICAgICAgICAgIC8vIGlmIG5vdGhpbmcgaXMgYmVsb3cgdXMsIHRoZW4gd2UncmUgaW5zaWRlIGlmIHRoZSBvdGhlciBwb2x5Z29uIGlzCiAgICAgICAgICAgICAgLy8gaW52ZXJ0ZWQKICAgICAgICAgICAgICBpbnNpZGUgPSBldi5wcmltYXJ5ID8gc2Vjb25kYXJ5UG9seUludmVydGVkIDogcHJpbWFyeVBvbHlJbnZlcnRlZDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAvLyBvdGhlcndpc2UsIHNvbWV0aGluZyBpcyBiZWxvdyB1cwogICAgICAgICAgICAgIC8vIHNvIGNvcHkgdGhlIGJlbG93IHNlZ21lbnQncyBvdGhlciBwb2x5Z29uJ3MgYWJvdmUKICAgICAgICAgICAgICBpZiAoZXYucHJpbWFyeSA9PT0gYmVsb3cucHJpbWFyeSkgaW5zaWRlID0gYmVsb3cuc2VnLm90aGVyRmlsbC5hYm92ZTtlbHNlIGluc2lkZSA9IGJlbG93LnNlZy5teUZpbGwuYWJvdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZXYuc2VnLm90aGVyRmlsbCA9IHsKICAgICAgICAgICAgICBhYm92ZTogaW5zaWRlLAogICAgICAgICAgICAgIGJlbG93OiBpbnNpZGUKICAgICAgICAgICAgfTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGJ1aWxkTG9nKSB7CiAgICAgICAgICBidWlsZExvZy5zdGF0dXMoZXYuc2VnLCBhYm92ZSA/IGFib3ZlLnNlZyA6IGZhbHNlLCBiZWxvdyA/IGJlbG93LnNlZyA6IGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIC8vIGluc2VydCB0aGUgc3RhdHVzIGFuZCByZW1lbWJlciBpdCBmb3IgbGF0ZXIgcmVtb3ZhbAogICAgICAgIGV2Lm90aGVyLnN0YXR1cyA9IHN1cnJvdW5kaW5nLmluc2VydChMaW5rZWRMaXN0Lm5vZGUoewogICAgICAgICAgZXY6IGV2CiAgICAgICAgfSkpOwogICAgICB9IGVsc2UgewogICAgICAgIHZhciBzdCA9IGV2LnN0YXR1czsKICAgICAgICBpZiAoc3QgPT09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUG9seUJvb2w6IFplcm8tbGVuZ3RoIHNlZ21lbnQgZGV0ZWN0ZWQ7IHlvdXIgZXBzaWxvbiBpcyAnICsgJ3Byb2JhYmx5IHRvbyBzbWFsbCBvciB0b28gbGFyZ2UnKTsKICAgICAgICB9CgogICAgICAgIC8vIHJlbW92aW5nIHRoZSBzdGF0dXMgd2lsbCBjcmVhdGUgdHdvIG5ldyBhZGphY2VudCBlZGdlcywgc28gd2UnbGwgbmVlZCB0byBjaGVjawogICAgICAgIC8vIGZvciB0aG9zZQogICAgICAgIGlmIChzdGF0dXNfcm9vdC5leGlzdHMoc3QucHJldikgJiYgc3RhdHVzX3Jvb3QuZXhpc3RzKHN0Lm5leHQpKSBjaGVja0ludGVyc2VjdGlvbihzdC5wcmV2LmV2LCBzdC5uZXh0LmV2KTsKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnN0YXR1c1JlbW92ZShzdC5ldi5zZWcpOwoKICAgICAgICAvLyByZW1vdmUgdGhlIHN0YXR1cwogICAgICAgIHN0LnJlbW92ZSgpOwoKICAgICAgICAvLyBpZiB3ZSd2ZSByZWFjaGVkIHRoaXMgcG9pbnQsIHdlJ3ZlIGNhbGN1bGF0ZWQgZXZlcnl0aGluZyB0aGVyZSBpcyB0byBrbm93LCBzbwogICAgICAgIC8vIHNhdmUgdGhlIHNlZ21lbnQgZm9yIHJlcG9ydGluZwogICAgICAgIGlmICghZXYucHJpbWFyeSkgewogICAgICAgICAgLy8gbWFrZSBzdXJlIGBzZWcubXlGaWxsYCBhY3R1YWxseSBwb2ludHMgdG8gdGhlIHByaW1hcnkgcG9seWdvbiB0aG91Z2gKICAgICAgICAgIHZhciBzID0gZXYuc2VnLm15RmlsbDsKICAgICAgICAgIGV2LnNlZy5teUZpbGwgPSBldi5zZWcub3RoZXJGaWxsOwogICAgICAgICAgZXYuc2VnLm90aGVyRmlsbCA9IHM7CiAgICAgICAgfQogICAgICAgIHNlZ21lbnRzLnB1c2goZXYuc2VnKTsKICAgICAgfQoKICAgICAgLy8gcmVtb3ZlIHRoZSBldmVudCBhbmQgY29udGludWUKICAgICAgZXZlbnRfcm9vdC5nZXRIZWFkKCkucmVtb3ZlKCk7CiAgICB9CiAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmRvbmUoKTsKICAgIHJldHVybiBzZWdtZW50czsKICB9CgogIC8vIHJldHVybiB0aGUgYXBwcm9wcmlhdGUgQVBJIGRlcGVuZGluZyBvbiB3aGF0IHdlJ3JlIGRvaW5nCiAgaWYgKCFzZWxmSW50ZXJzZWN0aW9uKSB7CiAgICAvLyBwZXJmb3JtaW5nIGNvbWJpbmF0aW9uIG9mIHBvbHlnb25zLCBzbyBvbmx5IGRlYWwgd2l0aCBhbHJlYWR5LXByb2Nlc3NlZCBzZWdtZW50cwogICAgcmV0dXJuIHsKICAgICAgY2FsY3VsYXRlOiBmdW5jdGlvbiAoc2VnbWVudHMxLCBpbnZlcnRlZDEsIHNlZ21lbnRzMiwgaW52ZXJ0ZWQyKSB7CiAgICAgICAgLy8gc2VnbWVudHNYIGNvbWUgZnJvbSB0aGUgc2VsZi1pbnRlcnNlY3Rpb24gQVBJLCBvciB0aGlzIEFQSQogICAgICAgIC8vIGludmVydGVkWCBpcyB3aGV0aGVyIHdlIHRyZWF0IHRoYXQgbGlzdCBvZiBzZWdtZW50cyBhcyBhbiBpbnZlcnRlZCBwb2x5Z29uIG9yIG5vdAogICAgICAgIC8vIHJldHVybnMgc2VnbWVudHMgdGhhdCBjYW4gYmUgdXNlZCBmb3IgZnVydGhlciBvcGVyYXRpb25zCiAgICAgICAgc2VnbWVudHMxLmZvckVhY2goZnVuY3Rpb24gKHNlZykgewogICAgICAgICAgZXZlbnRBZGRTZWdtZW50KHNlZ21lbnRDb3B5KHNlZy5zdGFydCwgc2VnLmVuZCwgc2VnKSwgdHJ1ZSk7CiAgICAgICAgfSk7CiAgICAgICAgc2VnbWVudHMyLmZvckVhY2goZnVuY3Rpb24gKHNlZykgewogICAgICAgICAgZXZlbnRBZGRTZWdtZW50KHNlZ21lbnRDb3B5KHNlZy5zdGFydCwgc2VnLmVuZCwgc2VnKSwgZmFsc2UpOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBjYWxjdWxhdGUoaW52ZXJ0ZWQxLCBpbnZlcnRlZDIpOwogICAgICB9CiAgICB9OwogIH0KCiAgLy8gb3RoZXJ3aXNlLCBwZXJmb3JtaW5nIHNlbGYtaW50ZXJzZWN0aW9uLCBzbyBkZWFsIHdpdGggcmVnaW9ucwogIHJldHVybiB7CiAgICBhZGRSZWdpb246IGZ1bmN0aW9uIChyZWdpb24pIHsKICAgICAgLy8gcmVnaW9ucyBhcmUgYSBsaXN0IG9mIHBvaW50czoKICAgICAgLy8gIFsgWzAsIDBdLCBbMTAwLCAwXSwgWzUwLCAxMDBdIF0KICAgICAgLy8geW91IGNhbiBhZGQgbXVsdGlwbGUgcmVnaW9ucyBiZWZvcmUgcnVubmluZyBjYWxjdWxhdGUKICAgICAgdmFyIHB0MTsKICAgICAgdmFyIHB0MiA9IHJlZ2lvbltyZWdpb24ubGVuZ3RoIC0gMV07CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVnaW9uLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgcHQxID0gcHQyOwogICAgICAgIHB0MiA9IHJlZ2lvbltpXTsKICAgICAgICB2YXIgZm9yd2FyZCA9IGVwcy5wb2ludHNDb21wYXJlKHB0MSwgcHQyKTsKICAgICAgICBpZiAoZm9yd2FyZCA9PT0gMCkKICAgICAgICAgIC8vIHBvaW50cyBhcmUgZXF1YWwsIHNvIHdlIGhhdmUgYSB6ZXJvLWxlbmd0aCBzZWdtZW50CiAgICAgICAgICBjb250aW51ZTsgLy8ganVzdCBza2lwIGl0CgogICAgICAgIGV2ZW50QWRkU2VnbWVudChzZWdtZW50TmV3KGZvcndhcmQgPCAwID8gcHQxIDogcHQyLCBmb3J3YXJkIDwgMCA/IHB0MiA6IHB0MSksIHRydWUpOwogICAgICB9CiAgICB9LAogICAgY2FsY3VsYXRlOiBmdW5jdGlvbiAoaW52ZXJ0ZWQpIHsKICAgICAgLy8gaXMgdGhlIHBvbHlnb24gaW52ZXJ0ZWQ/CiAgICAgIC8vIHJldHVybnMgc2VnbWVudHMKICAgICAgcmV0dXJuIGNhbGN1bGF0ZShpbnZlcnRlZCwgZmFsc2UpOwogICAgfQogIH07Cn0KdmFyIGludGVyc2VjdGVyID0gSW50ZXJzZWN0ZXIkMTsKCi8vIChjKSBDb3B5cmlnaHQgMjAxNiwgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwovLyBNSVQgTGljZW5zZQovLyBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwoKLy8KLy8gY29udmVydHMgYSBsaXN0IG9mIHNlZ21lbnRzIGludG8gYSBsaXN0IG9mIHJlZ2lvbnMsIHdoaWxlIGFsc28gcmVtb3ZpbmcgdW5uZWNlc3NhcnkgdmVydGljaWVzCi8vCgpmdW5jdGlvbiBTZWdtZW50Q2hhaW5lciQxKHNlZ21lbnRzLCBlcHMsIGJ1aWxkTG9nKSB7CiAgdmFyIGNoYWlucyA9IFtdOwogIHZhciByZWdpb25zID0gW107CiAgc2VnbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoc2VnKSB7CiAgICB2YXIgcHQxID0gc2VnLnN0YXJ0OwogICAgdmFyIHB0MiA9IHNlZy5lbmQ7CiAgICBpZiAoZXBzLnBvaW50c1NhbWUocHQxLCBwdDIpKSB7CiAgICAgIGNvbnNvbGUud2FybignUG9seUJvb2w6IFdhcm5pbmc6IFplcm8tbGVuZ3RoIHNlZ21lbnQgZGV0ZWN0ZWQ7IHlvdXIgZXBzaWxvbiBpcyAnICsgJ3Byb2JhYmx5IHRvbyBzbWFsbCBvciB0b28gbGFyZ2UnKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblN0YXJ0KHNlZyk7CgogICAgLy8gc2VhcmNoIGZvciB0d28gY2hhaW5zIHRoYXQgdGhpcyBzZWdtZW50IG1hdGNoZXMKICAgIHZhciBmaXJzdF9tYXRjaCA9IHsKICAgICAgaW5kZXg6IDAsCiAgICAgIG1hdGNoZXNfaGVhZDogZmFsc2UsCiAgICAgIG1hdGNoZXNfcHQxOiBmYWxzZQogICAgfTsKICAgIHZhciBzZWNvbmRfbWF0Y2ggPSB7CiAgICAgIGluZGV4OiAwLAogICAgICBtYXRjaGVzX2hlYWQ6IGZhbHNlLAogICAgICBtYXRjaGVzX3B0MTogZmFsc2UKICAgIH07CiAgICB2YXIgbmV4dF9tYXRjaCA9IGZpcnN0X21hdGNoOwogICAgZnVuY3Rpb24gc2V0TWF0Y2goaW5kZXgsIG1hdGNoZXNfaGVhZCwgbWF0Y2hlc19wdDEpIHsKICAgICAgLy8gcmV0dXJuIHRydWUgaWYgd2UndmUgbWF0Y2hlZCB0d2ljZQogICAgICBuZXh0X21hdGNoLmluZGV4ID0gaW5kZXg7CiAgICAgIG5leHRfbWF0Y2gubWF0Y2hlc19oZWFkID0gbWF0Y2hlc19oZWFkOwogICAgICBuZXh0X21hdGNoLm1hdGNoZXNfcHQxID0gbWF0Y2hlc19wdDE7CiAgICAgIGlmIChuZXh0X21hdGNoID09PSBmaXJzdF9tYXRjaCkgewogICAgICAgIG5leHRfbWF0Y2ggPSBzZWNvbmRfbWF0Y2g7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG5leHRfbWF0Y2ggPSBudWxsOwogICAgICByZXR1cm4gdHJ1ZTsgLy8gd2UndmUgbWF0Y2hlZCB0d2ljZSwgd2UncmUgZG9uZSBoZXJlCiAgICB9CgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGFpbnMubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGNoYWluID0gY2hhaW5zW2ldOwogICAgICB2YXIgaGVhZCA9IGNoYWluWzBdOwogICAgICBjaGFpblsxXTsKICAgICAgdmFyIHRhaWwgPSBjaGFpbltjaGFpbi5sZW5ndGggLSAxXTsKICAgICAgY2hhaW5bY2hhaW4ubGVuZ3RoIC0gMl07CiAgICAgIGlmIChlcHMucG9pbnRzU2FtZShoZWFkLCBwdDEpKSB7CiAgICAgICAgaWYgKHNldE1hdGNoKGksIHRydWUsIHRydWUpKSBicmVhazsKICAgICAgfSBlbHNlIGlmIChlcHMucG9pbnRzU2FtZShoZWFkLCBwdDIpKSB7CiAgICAgICAgaWYgKHNldE1hdGNoKGksIHRydWUsIGZhbHNlKSkgYnJlYWs7CiAgICAgIH0gZWxzZSBpZiAoZXBzLnBvaW50c1NhbWUodGFpbCwgcHQxKSkgewogICAgICAgIGlmIChzZXRNYXRjaChpLCBmYWxzZSwgdHJ1ZSkpIGJyZWFrOwogICAgICB9IGVsc2UgaWYgKGVwcy5wb2ludHNTYW1lKHRhaWwsIHB0MikpIHsKICAgICAgICBpZiAoc2V0TWF0Y2goaSwgZmFsc2UsIGZhbHNlKSkgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmIChuZXh0X21hdGNoID09PSBmaXJzdF9tYXRjaCkgewogICAgICAvLyB3ZSBkaWRuJ3QgbWF0Y2ggYW55dGhpbmcsIHNvIGNyZWF0ZSBhIG5ldyBjaGFpbgogICAgICBjaGFpbnMucHVzaChbcHQxLCBwdDJdKTsKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbk5ldyhwdDEsIHB0Mik7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChuZXh0X21hdGNoID09PSBzZWNvbmRfbWF0Y2gpIHsKICAgICAgLy8gd2UgbWF0Y2hlZCBhIHNpbmdsZSBjaGFpbgoKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbk1hdGNoKGZpcnN0X21hdGNoLmluZGV4KTsKCiAgICAgIC8vIGFkZCB0aGUgb3RoZXIgcG9pbnQgdG8gdGhlIGFwcG9ycHJpYXRlIGVuZCwgYW5kIGNoZWNrIHRvIHNlZSBpZiB3ZSd2ZSBjbG9zZWQgdGhlCiAgICAgIC8vIGNoYWluIGludG8gYSBsb29wCgogICAgICB2YXIgaW5kZXggPSBmaXJzdF9tYXRjaC5pbmRleDsKICAgICAgdmFyIHB0ID0gZmlyc3RfbWF0Y2gubWF0Y2hlc19wdDEgPyBwdDIgOiBwdDE7IC8vIGlmIHdlIG1hdGNoZWQgcHQxLCB0aGVuIHdlIGFkZCBwdDIsIGV0YwogICAgICB2YXIgYWRkVG9IZWFkID0gZmlyc3RfbWF0Y2gubWF0Y2hlc19oZWFkOyAvLyBpZiB3ZSBtYXRjaGVkIGF0IGhlYWQsIHRoZW4gYWRkIHRvIHRoZSBoZWFkCgogICAgICB2YXIgY2hhaW4gPSBjaGFpbnNbaW5kZXhdOwogICAgICB2YXIgZ3JvdyA9IGFkZFRvSGVhZCA/IGNoYWluWzBdIDogY2hhaW5bY2hhaW4ubGVuZ3RoIC0gMV07CiAgICAgIHZhciBncm93MiA9IGFkZFRvSGVhZCA/IGNoYWluWzFdIDogY2hhaW5bY2hhaW4ubGVuZ3RoIC0gMl07CiAgICAgIHZhciBvcHBvID0gYWRkVG9IZWFkID8gY2hhaW5bY2hhaW4ubGVuZ3RoIC0gMV0gOiBjaGFpblswXTsKICAgICAgdmFyIG9wcG8yID0gYWRkVG9IZWFkID8gY2hhaW5bY2hhaW4ubGVuZ3RoIC0gMl0gOiBjaGFpblsxXTsKICAgICAgaWYgKGVwcy5wb2ludHNDb2xsaW5lYXIoZ3JvdzIsIGdyb3csIHB0KSkgewogICAgICAgIC8vIGdyb3cgaXNuJ3QgbmVlZGVkIGJlY2F1c2UgaXQncyBkaXJlY3RseSBiZXR3ZWVuIGdyb3cyIGFuZCBwdDoKICAgICAgICAvLyBncm93MiAtLS1ncm93LS0tPiBwdAogICAgICAgIGlmIChhZGRUb0hlYWQpIHsKICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVIZWFkKGZpcnN0X21hdGNoLmluZGV4LCBwdCk7CiAgICAgICAgICBjaGFpbi5zaGlmdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlVGFpbChmaXJzdF9tYXRjaC5pbmRleCwgcHQpOwogICAgICAgICAgY2hhaW4ucG9wKCk7CiAgICAgICAgfQogICAgICAgIGdyb3cgPSBncm93MjsgLy8gb2xkIGdyb3cgaXMgZ29uZS4uLiBuZXcgZ3JvdyBpcyB3aGF0IGdyb3cyIHdhcwogICAgICB9CgogICAgICBpZiAoZXBzLnBvaW50c1NhbWUob3BwbywgcHQpKSB7CiAgICAgICAgLy8gd2UncmUgY2xvc2luZyB0aGUgbG9vcCwgc28gcmVtb3ZlIGNoYWluIGZyb20gY2hhaW5zCiAgICAgICAgY2hhaW5zLnNwbGljZShpbmRleCwgMSk7CiAgICAgICAgaWYgKGVwcy5wb2ludHNDb2xsaW5lYXIob3BwbzIsIG9wcG8sIGdyb3cpKSB7CiAgICAgICAgICAvLyBvcHBvIGlzbid0IG5lZWRlZCBiZWNhdXNlIGl0J3MgZGlyZWN0bHkgYmV0d2VlbiBvcHBvMiBhbmQgZ3JvdzoKICAgICAgICAgIC8vIG9wcG8yIC0tLW9wcG8tLS0+Z3JvdwogICAgICAgICAgaWYgKGFkZFRvSGVhZCkgewogICAgICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlVGFpbChmaXJzdF9tYXRjaC5pbmRleCwgZ3Jvdyk7CiAgICAgICAgICAgIGNoYWluLnBvcCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJlbW92ZUhlYWQoZmlyc3RfbWF0Y2guaW5kZXgsIGdyb3cpOwogICAgICAgICAgICBjaGFpbi5zaGlmdCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluQ2xvc2UoZmlyc3RfbWF0Y2guaW5kZXgpOwoKICAgICAgICAvLyB3ZSBoYXZlIGEgY2xvc2VkIGNoYWluIQogICAgICAgIHJlZ2lvbnMucHVzaChjaGFpbik7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAvLyBub3QgY2xvc2luZyBhIGxvb3AsIHNvIGp1c3QgYWRkIGl0IHRvIHRoZSBhcHBvcnByaWF0ZSBzaWRlCiAgICAgIGlmIChhZGRUb0hlYWQpIHsKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluQWRkSGVhZChmaXJzdF9tYXRjaC5pbmRleCwgcHQpOwogICAgICAgIGNoYWluLnVuc2hpZnQocHQpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5BZGRUYWlsKGZpcnN0X21hdGNoLmluZGV4LCBwdCk7CiAgICAgICAgY2hhaW4ucHVzaChwdCk7CiAgICAgIH0KICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIG90aGVyd2lzZSwgd2UgbWF0Y2hlZCB0d28gY2hhaW5zLCBzbyB3ZSBuZWVkIHRvIGNvbWJpbmUgdGhvc2UgY2hhaW5zIHRvZ2V0aGVyCgogICAgZnVuY3Rpb24gcmV2ZXJzZUNoYWluKGluZGV4KSB7CiAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZXZlcnNlKGluZGV4KTsKICAgICAgY2hhaW5zW2luZGV4XS5yZXZlcnNlKCk7IC8vIGdlZSwgdGhhdCdzIGVhc3kKICAgIH0KCiAgICBmdW5jdGlvbiBhcHBlbmRDaGFpbihpbmRleDEsIGluZGV4MikgewogICAgICAvLyBpbmRleDEgZ2V0cyBpbmRleDIgYXBwZW5kZWQgdG8gaXQsIGFuZCBpbmRleDIgaXMgcmVtb3ZlZAogICAgICB2YXIgY2hhaW4xID0gY2hhaW5zW2luZGV4MV07CiAgICAgIHZhciBjaGFpbjIgPSBjaGFpbnNbaW5kZXgyXTsKICAgICAgdmFyIHRhaWwgPSBjaGFpbjFbY2hhaW4xLmxlbmd0aCAtIDFdOwogICAgICB2YXIgdGFpbDIgPSBjaGFpbjFbY2hhaW4xLmxlbmd0aCAtIDJdOwogICAgICB2YXIgaGVhZCA9IGNoYWluMlswXTsKICAgICAgdmFyIGhlYWQyID0gY2hhaW4yWzFdOwogICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcih0YWlsMiwgdGFpbCwgaGVhZCkpIHsKICAgICAgICAvLyB0YWlsIGlzbid0IG5lZWRlZCBiZWNhdXNlIGl0J3MgZGlyZWN0bHkgYmV0d2VlbiB0YWlsMiBhbmQgaGVhZAogICAgICAgIC8vIHRhaWwyIC0tLXRhaWwtLS0+IGhlYWQKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlVGFpbChpbmRleDEsIHRhaWwpOwogICAgICAgIGNoYWluMS5wb3AoKTsKICAgICAgICB0YWlsID0gdGFpbDI7IC8vIG9sZCB0YWlsIGlzIGdvbmUuLi4gbmV3IHRhaWwgaXMgd2hhdCB0YWlsMiB3YXMKICAgICAgfQoKICAgICAgaWYgKGVwcy5wb2ludHNDb2xsaW5lYXIodGFpbCwgaGVhZCwgaGVhZDIpKSB7CiAgICAgICAgLy8gaGVhZCBpc24ndCBuZWVkZWQgYmVjYXVzZSBpdCdzIGRpcmVjdGx5IGJldHdlZW4gdGFpbCBhbmQgaGVhZDIKICAgICAgICAvLyB0YWlsIC0tLWhlYWQtLS0+IGhlYWQyCiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJlbW92ZUhlYWQoaW5kZXgyLCBoZWFkKTsKICAgICAgICBjaGFpbjIuc2hpZnQoKTsKICAgICAgfQogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluSm9pbihpbmRleDEsIGluZGV4Mik7CiAgICAgIGNoYWluc1tpbmRleDFdID0gY2hhaW4xLmNvbmNhdChjaGFpbjIpOwogICAgICBjaGFpbnMuc3BsaWNlKGluZGV4MiwgMSk7CiAgICB9CiAgICB2YXIgRiA9IGZpcnN0X21hdGNoLmluZGV4OwogICAgdmFyIFMgPSBzZWNvbmRfbWF0Y2guaW5kZXg7CiAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluQ29ubmVjdChGLCBTKTsKICAgIHZhciByZXZlcnNlRiA9IGNoYWluc1tGXS5sZW5ndGggPCBjaGFpbnNbU10ubGVuZ3RoOyAvLyByZXZlcnNlIHRoZSBzaG9ydGVyIGNoYWluLCBpZiBuZWVkZWQKICAgIGlmIChmaXJzdF9tYXRjaC5tYXRjaGVzX2hlYWQpIHsKICAgICAgaWYgKHNlY29uZF9tYXRjaC5tYXRjaGVzX2hlYWQpIHsKICAgICAgICBpZiAocmV2ZXJzZUYpIHsKICAgICAgICAgIC8vIDw8PDwgRiA8PDw8IC0tLSA+Pj4+IFMgPj4+PgogICAgICAgICAgcmV2ZXJzZUNoYWluKEYpOwogICAgICAgICAgLy8gPj4+PiBGID4+Pj4gLS0tID4+Pj4gUyA+Pj4+CiAgICAgICAgICBhcHBlbmRDaGFpbihGLCBTKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gPDw8PCBGIDw8PDwgLS0tID4+Pj4gUyA+Pj4+CiAgICAgICAgICByZXZlcnNlQ2hhaW4oUyk7CiAgICAgICAgICAvLyA8PDw8IEYgPDw8PCAtLS0gPDw8PCBTIDw8PDwgICBsb2dpY2FsbHkgc2FtZSBhczoKICAgICAgICAgIC8vID4+Pj4gUyA+Pj4+IC0tLSA+Pj4+IEYgPj4+PgogICAgICAgICAgYXBwZW5kQ2hhaW4oUywgRik7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIDw8PDwgRiA8PDw8IC0tLSA8PDw8IFMgPDw8PCAgIGxvZ2ljYWxseSBzYW1lIGFzOgogICAgICAgIC8vID4+Pj4gUyA+Pj4+IC0tLSA+Pj4+IEYgPj4+PgogICAgICAgIGFwcGVuZENoYWluKFMsIEYpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBpZiAoc2Vjb25kX21hdGNoLm1hdGNoZXNfaGVhZCkgewogICAgICAgIC8vID4+Pj4gRiA+Pj4+IC0tLSA+Pj4+IFMgPj4+PgogICAgICAgIGFwcGVuZENoYWluKEYsIFMpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChyZXZlcnNlRikgewogICAgICAgICAgLy8gPj4+PiBGID4+Pj4gLS0tIDw8PDwgUyA8PDw8CiAgICAgICAgICByZXZlcnNlQ2hhaW4oRik7CiAgICAgICAgICAvLyA8PDw8IEYgPDw8PCAtLS0gPDw8PCBTIDw8PDwgICBsb2dpY2FsbHkgc2FtZSBhczoKICAgICAgICAgIC8vID4+Pj4gUyA+Pj4+IC0tLSA+Pj4+IEYgPj4+PgogICAgICAgICAgYXBwZW5kQ2hhaW4oUywgRik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vID4+Pj4gRiA+Pj4+IC0tLSA8PDw8IFMgPDw8PAogICAgICAgICAgcmV2ZXJzZUNoYWluKFMpOwogICAgICAgICAgLy8gPj4+PiBGID4+Pj4gLS0tID4+Pj4gUyA+Pj4+CiAgICAgICAgICBhcHBlbmRDaGFpbihGLCBTKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9KTsKICByZXR1cm4gcmVnaW9uczsKfQp2YXIgc2VnbWVudENoYWluZXIgPSBTZWdtZW50Q2hhaW5lciQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyBmaWx0ZXIgYSBsaXN0IG9mIHNlZ21lbnRzIGJhc2VkIG9uIGJvb2xlYW4gb3BlcmF0aW9ucwovLwoKZnVuY3Rpb24gc2VsZWN0KHNlZ21lbnRzLCBzZWxlY3Rpb24sIGJ1aWxkTG9nKSB7CiAgdmFyIHJlc3VsdCA9IFtdOwogIHNlZ21lbnRzLmZvckVhY2goZnVuY3Rpb24gKHNlZykgewogICAgdmFyIGluZGV4ID0gKHNlZy5teUZpbGwuYWJvdmUgPyA4IDogMCkgKyAoc2VnLm15RmlsbC5iZWxvdyA/IDQgOiAwKSArIChzZWcub3RoZXJGaWxsICYmIHNlZy5vdGhlckZpbGwuYWJvdmUgPyAyIDogMCkgKyAoc2VnLm90aGVyRmlsbCAmJiBzZWcub3RoZXJGaWxsLmJlbG93ID8gMSA6IDApOwogICAgaWYgKHNlbGVjdGlvbltpbmRleF0gIT09IDApIHsKICAgICAgLy8gY29weSB0aGUgc2VnbWVudCB0byB0aGUgcmVzdWx0cywgd2hpbGUgYWxzbyBjYWxjdWxhdGluZyB0aGUgZmlsbCBzdGF0dXMKICAgICAgcmVzdWx0LnB1c2goewogICAgICAgIGlkOiBidWlsZExvZyA/IGJ1aWxkTG9nLnNlZ21lbnRJZCgpIDogLTEsCiAgICAgICAgc3RhcnQ6IHNlZy5zdGFydCwKICAgICAgICBlbmQ6IHNlZy5lbmQsCiAgICAgICAgbXlGaWxsOiB7CiAgICAgICAgICBhYm92ZTogc2VsZWN0aW9uW2luZGV4XSA9PT0gMSwKICAgICAgICAgIC8vIDEgaWYgZmlsbGVkIGFib3ZlCiAgICAgICAgICBiZWxvdzogc2VsZWN0aW9uW2luZGV4XSA9PT0gMiAvLyAyIGlmIGZpbGxlZCBiZWxvdwogICAgICAgIH0sCgogICAgICAgIG90aGVyRmlsbDogbnVsbAogICAgICB9KTsKICAgIH0KICB9KTsKICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnNlbGVjdGVkKHJlc3VsdCk7CiAgcmV0dXJuIHJlc3VsdDsKfQp2YXIgU2VnbWVudFNlbGVjdG9yJDEgPSB7CiAgdW5pb246IGZ1bmN0aW9uIChzZWdtZW50cywgYnVpbGRMb2cpIHsKICAgIC8vIHByaW1hcnkgfCBzZWNvbmRhcnkKICAgIC8vIGFib3ZlMSBiZWxvdzEgYWJvdmUyIGJlbG93MiAgICBLZWVwPyAgICAgICAgICAgICAgIFZhbHVlCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIHJldHVybiBzZWxlY3Qoc2VnbWVudHMsIFswLCAyLCAxLCAwLCAyLCAyLCAwLCAwLCAxLCAwLCAxLCAwLCAwLCAwLCAwLCAwXSwgYnVpbGRMb2cpOwogIH0sCiAgaW50ZXJzZWN0OiBmdW5jdGlvbiAoc2VnbWVudHMsIGJ1aWxkTG9nKSB7CiAgICAvLyBwcmltYXJ5ICYgc2Vjb25kYXJ5CiAgICAvLyBhYm92ZTEgYmVsb3cxIGFib3ZlMiBiZWxvdzIgICAgS2VlcD8gICAgICAgICAgICAgICBWYWx1ZQogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICByZXR1cm4gc2VsZWN0KHNlZ21lbnRzLCBbMCwgMCwgMCwgMCwgMCwgMiwgMCwgMiwgMCwgMCwgMSwgMSwgMCwgMiwgMSwgMF0sIGJ1aWxkTG9nKTsKICB9LAogIGRpZmZlcmVuY2U6IGZ1bmN0aW9uIChzZWdtZW50cywgYnVpbGRMb2cpIHsKICAgIC8vIHByaW1hcnkgLSBzZWNvbmRhcnkKICAgIC8vIGFib3ZlMSBiZWxvdzEgYWJvdmUyIGJlbG93MiAgICBLZWVwPyAgICAgICAgICAgICAgIFZhbHVlCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIHJldHVybiBzZWxlY3Qoc2VnbWVudHMsIFswLCAwLCAwLCAwLCAyLCAwLCAyLCAwLCAxLCAxLCAwLCAwLCAwLCAxLCAyLCAwXSwgYnVpbGRMb2cpOwogIH0sCiAgZGlmZmVyZW5jZVJldjogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gc2Vjb25kYXJ5IC0gcHJpbWFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDIsIDEsIDAsIDAsIDAsIDEsIDEsIDAsIDIsIDAsIDIsIDAsIDAsIDAsIDBdLCBidWlsZExvZyk7CiAgfSwKICB4b3I6IGZ1bmN0aW9uIChzZWdtZW50cywgYnVpbGRMb2cpIHsKICAgIC8vIHByaW1hcnkgXiBzZWNvbmRhcnkKICAgIC8vIGFib3ZlMSBiZWxvdzEgYWJvdmUyIGJlbG93MiAgICBLZWVwPyAgICAgICAgICAgICAgIFZhbHVlCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIHJldHVybiBzZWxlY3Qoc2VnbWVudHMsIFswLCAyLCAxLCAwLCAyLCAwLCAwLCAxLCAxLCAwLCAwLCAyLCAwLCAxLCAyLCAwXSwgYnVpbGRMb2cpOwogIH0KfTsKdmFyIHNlZ21lbnRTZWxlY3RvciA9IFNlZ21lbnRTZWxlY3RvciQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE3LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyBjb252ZXJ0IGJldHdlZW4gUG9seUJvb2wgcG9seWdvbiBmb3JtYXQgYW5kIEdlb0pTT04gZm9ybWF0cyAoUG9seWdvbiBhbmQgTXVsdGlQb2x5Z29uKQovLwoKdmFyIEdlb0pTT04kMSA9IHsKICAvLyBjb252ZXJ0IGEgR2VvSlNPTiBvYmplY3QgdG8gYSBQb2x5Qm9vbCBwb2x5Z29uCiAgdG9Qb2x5Z29uOiBmdW5jdGlvbiAoUG9seUJvb2wsIGdlb2pzb24pIHsKICAgIC8vIGNvbnZlcnRzIGxpc3Qgb2YgTGluZVN0cmluZydzIHRvIHNlZ21lbnRzCiAgICBmdW5jdGlvbiBHZW9Qb2x5KGNvb3JkcykgewogICAgICAvLyBjaGVjayBmb3IgZW1wdHkgY29vcmRzCiAgICAgIGlmIChjb29yZHMubGVuZ3RoIDw9IDApIHJldHVybiBQb2x5Qm9vbC5zZWdtZW50cyh7CiAgICAgICAgaW52ZXJ0ZWQ6IGZhbHNlLAogICAgICAgIHJlZ2lvbnM6IFtdCiAgICAgIH0pOwoKICAgICAgLy8gY29udmVydCBMaW5lU3RyaW5nIHRvIHNlZ21lbnRzCiAgICAgIGZ1bmN0aW9uIExpbmVTdHJpbmcobHMpIHsKICAgICAgICAvLyByZW1vdmUgdGFpbCB3aGljaCBzaG91bGQgYmUgdGhlIHNhbWUgYXMgaGVhZAogICAgICAgIHZhciByZWcgPSBscy5zbGljZSgwLCBscy5sZW5ndGggLSAxKTsKICAgICAgICByZXR1cm4gUG9seUJvb2wuc2VnbWVudHMoewogICAgICAgICAgaW52ZXJ0ZWQ6IGZhbHNlLAogICAgICAgICAgcmVnaW9uczogW3JlZ10KICAgICAgICB9KTsKICAgICAgfQoKICAgICAgLy8gdGhlIGZpcnN0IExpbmVTdHJpbmcgaXMgY29uc2lkZXJlZCB0aGUgb3V0c2lkZQogICAgICB2YXIgb3V0ID0gTGluZVN0cmluZyhjb29yZHNbMF0pOwoKICAgICAgLy8gdGhlIHJlc3Qgb2YgdGhlIExpbmVTdHJpbmdzIGFyZSBjb25zaWRlcmVkIGludGVyaW9yIGhvbGVzLCBzbyBzdWJ0cmFjdCB0aGVtIGZyb20gdGhlCiAgICAgIC8vIGN1cnJlbnQgcmVzdWx0CiAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgY29vcmRzLmxlbmd0aDsgaSsrKSBvdXQgPSBQb2x5Qm9vbC5zZWxlY3REaWZmZXJlbmNlKFBvbHlCb29sLmNvbWJpbmUob3V0LCBMaW5lU3RyaW5nKGNvb3Jkc1tpXSkpKTsKICAgICAgcmV0dXJuIG91dDsKICAgIH0KICAgIGlmIChnZW9qc29uLnR5cGUgPT09ICdQb2x5Z29uJykgewogICAgICAvLyBzaW5nbGUgcG9seWdvbiwgc28ganVzdCBjb252ZXJ0IGl0IGFuZCB3ZSdyZSBkb25lCiAgICAgIHJldHVybiBQb2x5Qm9vbC5wb2x5Z29uKEdlb1BvbHkoZ2VvanNvbi5jb29yZGluYXRlcykpOwogICAgfSBlbHNlIGlmIChnZW9qc29uLnR5cGUgPT09ICdNdWx0aVBvbHlnb24nKSB7CiAgICAgIC8vIG11bHRpcGxlIHBvbHlnb25zLCBzbyB1bmlvbiBhbGwgdGhlIHBvbHlnb25zIHRvZ2V0aGVyCiAgICAgIHZhciBvdXQgPSBQb2x5Qm9vbC5zZWdtZW50cyh7CiAgICAgICAgaW52ZXJ0ZWQ6IGZhbHNlLAogICAgICAgIHJlZ2lvbnM6IFtdCiAgICAgIH0pOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdlb2pzb24uY29vcmRpbmF0ZXMubGVuZ3RoOyBpKyspIG91dCA9IFBvbHlCb29sLnNlbGVjdFVuaW9uKFBvbHlCb29sLmNvbWJpbmUob3V0LCBHZW9Qb2x5KGdlb2pzb24uY29vcmRpbmF0ZXNbaV0pKSk7CiAgICAgIHJldHVybiBQb2x5Qm9vbC5wb2x5Z29uKG91dCk7CiAgICB9CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvbHlCb29sOiBDYW5ub3QgY29udmVydCBHZW9KU09OIG9iamVjdCB0byBQb2x5Qm9vbCBwb2x5Z29uJyk7CiAgfSwKICAvLyBjb252ZXJ0IGEgUG9seUJvb2wgcG9seWdvbiB0byBhIEdlb0pTT04gb2JqZWN0CiAgZnJvbVBvbHlnb246IGZ1bmN0aW9uIChQb2x5Qm9vbCwgZXBzLCBwb2x5KSB7CiAgICAvLyBtYWtlIHN1cmUgb3V0IHBvbHlnb24gaXMgY2xlYW4KICAgIHBvbHkgPSBQb2x5Qm9vbC5wb2x5Z29uKFBvbHlCb29sLnNlZ21lbnRzKHBvbHkpKTsKCiAgICAvLyB0ZXN0IGlmIHIxIGlzIGluc2lkZSByMgogICAgZnVuY3Rpb24gcmVnaW9uSW5zaWRlUmVnaW9uKHIxLCByMikgewogICAgICAvLyB3ZSdyZSBndWFyYW50ZWVkIG5vIGxpbmVzIGludGVyc2VjdCAoYmVjYXVzZSB0aGUgcG9seWdvbiBpcyBjbGVhbiksIGJ1dCBhIHZlcnRleAogICAgICAvLyBjb3VsZCBiZSBvbiB0aGUgZWRnZSAtLSBzbyB3ZSBqdXN0IGF2ZXJhZ2UgcHRbMF0gYW5kIHB0WzFdIHRvIHByb2R1Y2UgYSBwb2ludCBvbiB0aGUKICAgICAgLy8gZWRnZSBvZiB0aGUgZmlyc3QgbGluZSwgd2hpY2ggY2Fubm90IGJlIG9uIGFuIGVkZ2UKICAgICAgcmV0dXJuIGVwcy5wb2ludEluc2lkZVJlZ2lvbihbKHIxWzBdWzBdICsgcjFbMV1bMF0pICogMC41LCAocjFbMF1bMV0gKyByMVsxXVsxXSkgKiAwLjVdLCByMik7CiAgICB9CgogICAgLy8gY2FsY3VsYXRlIGluc2lkZSBoZWlyYXJjaHkKICAgIC8vCiAgICAvLyAgX19fX19fX19fX19fX19fX19fX19fICAgX19fX19fXyAgICByb290cyAtPiBBICAgICAgIC0+IEYKICAgIC8vIHwgICAgICAgICAgQSAgICAgICAgICB8IHwgICBGICAgfCAgICAgICAgICAgIHwgICAgICAgICAgfAogICAgLy8gfCAgX19fX19fXyAgIF9fX19fX18gIHwgfCAgX19fICB8ICAgICAgICAgICAgKy0tIEIgICAgICArLS0gRwogICAgLy8gfCB8ICAgQiAgIHwgfCAgIEMgICB8IHwgfCB8ICAgfCB8ICAgICAgICAgICAgfCAgIHwKICAgIC8vIHwgfCAgX19fICB8IHwgIF9fXyAgfCB8IHwgfCAgIHwgfCAgICAgICAgICAgIHwgICArLS0gRAogICAgLy8gfCB8IHwgRCB8IHwgfCB8IEUgfCB8IHwgfCB8IEcgfCB8ICAgICAgICAgICAgfAogICAgLy8gfCB8IHxfX198IHwgfCB8X19ffCB8IHwgfCB8ICAgfCB8ICAgICAgICAgICAgKy0tIEMKICAgIC8vIHwgfF9fX19fX198IHxfX19fX19ffCB8IHwgfF9fX3wgfCAgICAgICAgICAgICAgICB8CiAgICAvLyB8X19fX19fX19fX19fX19fX19fX19ffCB8X19fX19fX3wgICAgICAgICAgICAgICAgKy0tIEUKCiAgICBmdW5jdGlvbiBuZXdOb2RlKHJlZ2lvbikgewogICAgICByZXR1cm4gewogICAgICAgIHJlZ2lvbjogcmVnaW9uLAogICAgICAgIGNoaWxkcmVuOiBbXQogICAgICB9OwogICAgfQogICAgdmFyIHJvb3RzID0gbmV3Tm9kZShudWxsKTsKICAgIGZ1bmN0aW9uIGFkZENoaWxkKHJvb3QsIHJlZ2lvbikgewogICAgICAvLyBmaXJzdCBjaGVjayBpZiB3ZSdyZSBpbnNpZGUgYW55IGNoaWxkcmVuCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcm9vdC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBjaGlsZCA9IHJvb3QuY2hpbGRyZW5baV07CiAgICAgICAgaWYgKHJlZ2lvbkluc2lkZVJlZ2lvbihyZWdpb24sIGNoaWxkLnJlZ2lvbikpIHsKICAgICAgICAgIC8vIHdlIGFyZSwgc28gaW5zZXJ0IGluc2lkZSB0aGVtIGluc3RlYWQKICAgICAgICAgIGFkZENoaWxkKGNoaWxkLCByZWdpb24pOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm90IGluc2lkZSBhbnkgY2hpbGRyZW4sIHNvIGNoZWNrIHRvIHNlZSBpZiBhbnkgY2hpbGRyZW4gYXJlIGluc2lkZSB1cwogICAgICB2YXIgbm9kZSA9IG5ld05vZGUocmVnaW9uKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb290LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGNoaWxkID0gcm9vdC5jaGlsZHJlbltpXTsKICAgICAgICBpZiAocmVnaW9uSW5zaWRlUmVnaW9uKGNoaWxkLnJlZ2lvbiwgcmVnaW9uKSkgewogICAgICAgICAgLy8gb29wcy4uLiBtb3ZlIHRoZSBjaGlsZCBiZW5lYXRoIHVzLCBhbmQgcmVtb3ZlIHRoZW0gZnJvbSByb290CiAgICAgICAgICBub2RlLmNoaWxkcmVuLnB1c2goY2hpbGQpOwogICAgICAgICAgcm9vdC5jaGlsZHJlbi5zcGxpY2UoaSwgMSk7CiAgICAgICAgICBpLS07CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBub3cgd2UgY2FuIGFkZCBvdXJzZWx2ZXMKICAgICAgcm9vdC5jaGlsZHJlbi5wdXNoKG5vZGUpOwogICAgfQoKICAgIC8vIGFkZCBhbGwgcmVnaW9ucyB0byB0aGUgcm9vdAogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2x5LnJlZ2lvbnMubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIHJlZ2lvbiA9IHBvbHkucmVnaW9uc1tpXTsKICAgICAgaWYgKHJlZ2lvbi5sZW5ndGggPCAzKQogICAgICAgIC8vIHJlZ2lvbnMgbXVzdCBoYXZlIGF0IGxlYXN0IDMgcG9pbnRzIChzYW5pdHkgY2hlY2spCiAgICAgICAgY29udGludWU7CiAgICAgIGFkZENoaWxkKHJvb3RzLCByZWdpb24pOwogICAgfQoKICAgIC8vIHdpdGggb3VyIGhlaXJhcmNoeSwgd2UgY2FuIGRpc3Rpbmd1aXNoIGJldHdlZW4gZXh0ZXJpb3IgYm9yZGVycywgYW5kIGludGVyaW9yIGhvbGVzCiAgICAvLyB0aGUgcm9vdCBub2RlcyBhcmUgZXh0ZXJpb3IsIGNoaWxkcmVuIGFyZSBpbnRlcmlvciwgY2hpbGRyZW4ncyBjaGlsZHJlbiBhcmUgZXh0ZXJpb3IsCiAgICAvLyBjaGlsZHJlbidzIGNoaWxkcmVuJ3MgY2hpbGRyZW4gYXJlIGludGVyaW9yLCBldGMKCiAgICAvLyB3aGlsZSB3ZSdyZSBhdCBpdCwgZXh0ZXJpb3JzIGFyZSBjb3VudGVyLWNsb2Nrd2lzZSwgYW5kIGludGVyaW9ycyBhcmUgY2xvY2t3aXNlCgogICAgZnVuY3Rpb24gZm9yY2VXaW5kaW5nKHJlZ2lvbiwgY2xvY2t3aXNlKSB7CiAgICAgIC8vIGZpcnN0LCBzZWUgaWYgd2UncmUgY2xvY2t3aXNlIG9yIGNvdW50ZXItY2xvY2t3aXNlCiAgICAgIC8vIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1Nob2VsYWNlX2Zvcm11bGEKICAgICAgdmFyIHdpbmRpbmcgPSAwOwogICAgICB2YXIgbGFzdF94ID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXVswXTsKICAgICAgdmFyIGxhc3RfeSA9IHJlZ2lvbltyZWdpb24ubGVuZ3RoIC0gMV1bMV07CiAgICAgIHZhciBjb3B5ID0gW107CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVnaW9uLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGN1cnJfeCA9IHJlZ2lvbltpXVswXTsKICAgICAgICB2YXIgY3Vycl95ID0gcmVnaW9uW2ldWzFdOwogICAgICAgIGNvcHkucHVzaChbY3Vycl94LCBjdXJyX3ldKTsgLy8gY3JlYXRlIGEgY29weSB3aGlsZSB3ZSdyZSBhdCBpdAogICAgICAgIHdpbmRpbmcgKz0gY3Vycl95ICogbGFzdF94IC0gY3Vycl94ICogbGFzdF95OwogICAgICAgIGxhc3RfeCA9IGN1cnJfeDsKICAgICAgICBsYXN0X3kgPSBjdXJyX3k7CiAgICAgIH0KICAgICAgLy8gdGhpcyBhc3N1bWVzIENhcnRlc2lhbiBjb29yZGluYXRlcyAoWSBpcyBwb3NpdGl2ZSBnb2luZyB1cCkKICAgICAgdmFyIGlzY2xvY2t3aXNlID0gd2luZGluZyA8IDA7CiAgICAgIGlmIChpc2Nsb2Nrd2lzZSAhPT0gY2xvY2t3aXNlKSBjb3B5LnJldmVyc2UoKTsKICAgICAgLy8gd2hpbGUgd2UncmUgaGVyZSwgdGhlIGxhc3QgcG9pbnQgbXVzdCBiZSB0aGUgZmlyc3QgcG9pbnQuLi4KICAgICAgY29weS5wdXNoKFtjb3B5WzBdWzBdLCBjb3B5WzBdWzFdXSk7CiAgICAgIHJldHVybiBjb3B5OwogICAgfQogICAgdmFyIGdlb3BvbHlzID0gW107CiAgICBmdW5jdGlvbiBhZGRFeHRlcmlvcihub2RlKSB7CiAgICAgIHZhciBwb2x5ID0gW2ZvcmNlV2luZGluZyhub2RlLnJlZ2lvbiwgZmFsc2UpXTsKICAgICAgZ2VvcG9seXMucHVzaChwb2x5KTsKICAgICAgLy8gY2hpbGRyZW4gb2YgZXh0ZXJpb3JzIGFyZSBpbnRlcmlvcgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHBvbHkucHVzaChnZXRJbnRlcmlvcihub2RlLmNoaWxkcmVuW2ldKSk7CiAgICB9CiAgICBmdW5jdGlvbiBnZXRJbnRlcmlvcihub2RlKSB7CiAgICAgIC8vIGNoaWxkcmVuIG9mIGludGVyaW9ycyBhcmUgZXh0ZXJpb3IKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSBhZGRFeHRlcmlvcihub2RlLmNoaWxkcmVuW2ldKTsKICAgICAgLy8gcmV0dXJuIHRoZSBjbG9ja3dpc2UgaW50ZXJpb3IKICAgICAgcmV0dXJuIGZvcmNlV2luZGluZyhub2RlLnJlZ2lvbiwgdHJ1ZSk7CiAgICB9CgogICAgLy8gcm9vdCBub2RlcyBhcmUgZXh0ZXJpb3IKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcm9vdHMuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIGFkZEV4dGVyaW9yKHJvb3RzLmNoaWxkcmVuW2ldKTsKCiAgICAvLyBsYXN0bHksIGNvbnN0cnVjdCB0aGUgYXBwcm9ycHJpYXRlIEdlb0pTT04gb2JqZWN0CgogICAgaWYgKGdlb3BvbHlzLmxlbmd0aCA8PSAwKQogICAgICAvLyBlbXB0eSBHZW9KU09OIFBvbHlnb24KICAgICAgcmV0dXJuIHsKICAgICAgICB0eXBlOiAnUG9seWdvbicsCiAgICAgICAgY29vcmRpbmF0ZXM6IFtdCiAgICAgIH07CiAgICBpZiAoZ2VvcG9seXMubGVuZ3RoID09IDEpCiAgICAgIC8vIHVzZSBhIEdlb0pTT04gUG9seWdvbgogICAgICByZXR1cm4gewogICAgICAgIHR5cGU6ICdQb2x5Z29uJywKICAgICAgICBjb29yZGluYXRlczogZ2VvcG9seXNbMF0KICAgICAgfTsKICAgIHJldHVybiB7CiAgICAgIC8vIG90aGVyd2lzZSwgdXNlIGEgR2VvSlNPTiBNdWx0aVBvbHlnb24KICAgICAgdHlwZTogJ011bHRpUG9seWdvbicsCiAgICAgIGNvb3JkaW5hdGVzOiBnZW9wb2x5cwogICAgfTsKICB9Cn07CnZhciBnZW9qc29uID0gR2VvSlNPTiQxOwoKLyoKICogQGNvcHlyaWdodCAyMDE2IFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKICogQGxpY2Vuc2UgTUlUCiAqIEBwcmVzZXJ2ZSBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwogKi8KdmFyIEJ1aWxkTG9nID0gYnVpbGRMb2ckMTsKdmFyIEVwc2lsb24gPSBlcHNpbG9uJDM7CnZhciBJbnRlcnNlY3RlciA9IGludGVyc2VjdGVyOwp2YXIgU2VnbWVudENoYWluZXIgPSBzZWdtZW50Q2hhaW5lcjsKdmFyIFNlZ21lbnRTZWxlY3RvciA9IHNlZ21lbnRTZWxlY3RvcjsKdmFyIEdlb0pTT04gPSBnZW9qc29uOwp2YXIgYnVpbGRMb2cgPSBmYWxzZTsKdmFyIGVwc2lsb24kMiA9IEVwc2lsb24oKTsKdmFyIFBvbHlCb29sOwpQb2x5Qm9vbCA9IHsKICAvLyBnZXR0ZXIvc2V0dGVyIGZvciBidWlsZExvZwogIGJ1aWxkTG9nOiBmdW5jdGlvbiAoYmwpIHsKICAgIGlmIChibCA9PT0gdHJ1ZSkgYnVpbGRMb2cgPSBCdWlsZExvZygpO2Vsc2UgaWYgKGJsID09PSBmYWxzZSkgYnVpbGRMb2cgPSBmYWxzZTsKICAgIHJldHVybiBidWlsZExvZyA9PT0gZmFsc2UgPyBmYWxzZSA6IGJ1aWxkTG9nLmxpc3Q7CiAgfSwKICAvLyBnZXR0ZXIvc2V0dGVyIGZvciBlcHNpbG9uCiAgZXBzaWxvbjogZnVuY3Rpb24gKHYpIHsKICAgIHJldHVybiBlcHNpbG9uJDIuZXBzaWxvbih2KTsKICB9LAogIC8vIGNvcmUgQVBJCiAgc2VnbWVudHM6IGZ1bmN0aW9uIChwb2x5KSB7CiAgICB2YXIgaSA9IEludGVyc2VjdGVyKHRydWUsIGVwc2lsb24kMiwgYnVpbGRMb2cpOwogICAgcG9seS5yZWdpb25zLmZvckVhY2goaS5hZGRSZWdpb24pOwogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IGkuY2FsY3VsYXRlKHBvbHkuaW52ZXJ0ZWQpLAogICAgICBpbnZlcnRlZDogcG9seS5pbnZlcnRlZAogICAgfTsKICB9LAogIGNvbWJpbmU6IGZ1bmN0aW9uIChzZWdtZW50czEsIHNlZ21lbnRzMikgewogICAgdmFyIGkzID0gSW50ZXJzZWN0ZXIoZmFsc2UsIGVwc2lsb24kMiwgYnVpbGRMb2cpOwogICAgcmV0dXJuIHsKICAgICAgY29tYmluZWQ6IGkzLmNhbGN1bGF0ZShzZWdtZW50czEuc2VnbWVudHMsIHNlZ21lbnRzMS5pbnZlcnRlZCwgc2VnbWVudHMyLnNlZ21lbnRzLCBzZWdtZW50czIuaW52ZXJ0ZWQpLAogICAgICBpbnZlcnRlZDE6IHNlZ21lbnRzMS5pbnZlcnRlZCwKICAgICAgaW52ZXJ0ZWQyOiBzZWdtZW50czIuaW52ZXJ0ZWQKICAgIH07CiAgfSwKICBzZWxlY3RVbmlvbjogZnVuY3Rpb24gKGNvbWJpbmVkKSB7CiAgICByZXR1cm4gewogICAgICBzZWdtZW50czogU2VnbWVudFNlbGVjdG9yLnVuaW9uKGNvbWJpbmVkLmNvbWJpbmVkLCBidWlsZExvZyksCiAgICAgIGludmVydGVkOiBjb21iaW5lZC5pbnZlcnRlZDEgfHwgY29tYmluZWQuaW52ZXJ0ZWQyCiAgICB9OwogIH0sCiAgc2VsZWN0SW50ZXJzZWN0OiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IuaW50ZXJzZWN0KGNvbWJpbmVkLmNvbWJpbmVkLCBidWlsZExvZyksCiAgICAgIGludmVydGVkOiBjb21iaW5lZC5pbnZlcnRlZDEgJiYgY29tYmluZWQuaW52ZXJ0ZWQyCiAgICB9OwogIH0sCiAgc2VsZWN0RGlmZmVyZW5jZTogZnVuY3Rpb24gKGNvbWJpbmVkKSB7CiAgICByZXR1cm4gewogICAgICBzZWdtZW50czogU2VnbWVudFNlbGVjdG9yLmRpZmZlcmVuY2UoY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IGNvbWJpbmVkLmludmVydGVkMSAmJiAhY29tYmluZWQuaW52ZXJ0ZWQyCiAgICB9OwogIH0sCiAgc2VsZWN0RGlmZmVyZW5jZVJldjogZnVuY3Rpb24gKGNvbWJpbmVkKSB7CiAgICByZXR1cm4gewogICAgICBzZWdtZW50czogU2VnbWVudFNlbGVjdG9yLmRpZmZlcmVuY2VSZXYoY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6ICFjb21iaW5lZC5pbnZlcnRlZDEgJiYgY29tYmluZWQuaW52ZXJ0ZWQyCiAgICB9OwogIH0sCiAgc2VsZWN0WG9yOiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IueG9yKGNvbWJpbmVkLmNvbWJpbmVkLCBidWlsZExvZyksCiAgICAgIGludmVydGVkOiBjb21iaW5lZC5pbnZlcnRlZDEgIT09IGNvbWJpbmVkLmludmVydGVkMgogICAgfTsKICB9LAogIHBvbHlnb246IGZ1bmN0aW9uIChzZWdtZW50cykgewogICAgcmV0dXJuIHsKICAgICAgcmVnaW9uczogU2VnbWVudENoYWluZXIoc2VnbWVudHMuc2VnbWVudHMsIGVwc2lsb24kMiwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogc2VnbWVudHMuaW52ZXJ0ZWQKICAgIH07CiAgfSwKICAvLyBHZW9KU09OIGNvbnZlcnRlcnMKICBwb2x5Z29uRnJvbUdlb0pTT046IGZ1bmN0aW9uIChnZW9qc29uKSB7CiAgICByZXR1cm4gR2VvSlNPTi50b1BvbHlnb24oUG9seUJvb2wsIGdlb2pzb24pOwogIH0sCiAgcG9seWdvblRvR2VvSlNPTjogZnVuY3Rpb24gKHBvbHkpIHsKICAgIHJldHVybiBHZW9KU09OLmZyb21Qb2x5Z29uKFBvbHlCb29sLCBlcHNpbG9uJDIsIHBvbHkpOwogIH0sCiAgLy8gaGVscGVyIGZ1bmN0aW9ucyBmb3IgY29tbW9uIG9wZXJhdGlvbnMKICB1bmlvbjogZnVuY3Rpb24gKHBvbHkxLCBwb2x5MikgewogICAgcmV0dXJuIG9wZXJhdGUocG9seTEsIHBvbHkyLCBQb2x5Qm9vbC5zZWxlY3RVbmlvbik7CiAgfSwKICBpbnRlcnNlY3Q6IGZ1bmN0aW9uIChwb2x5MSwgcG9seTIpIHsKICAgIHJldHVybiBvcGVyYXRlKHBvbHkxLCBwb2x5MiwgUG9seUJvb2wuc2VsZWN0SW50ZXJzZWN0KTsKICB9LAogIGRpZmZlcmVuY2U6IGZ1bmN0aW9uIChwb2x5MSwgcG9seTIpIHsKICAgIHJldHVybiBvcGVyYXRlKHBvbHkxLCBwb2x5MiwgUG9seUJvb2wuc2VsZWN0RGlmZmVyZW5jZSk7CiAgfSwKICBkaWZmZXJlbmNlUmV2OiBmdW5jdGlvbiAocG9seTEsIHBvbHkyKSB7CiAgICByZXR1cm4gb3BlcmF0ZShwb2x5MSwgcG9seTIsIFBvbHlCb29sLnNlbGVjdERpZmZlcmVuY2VSZXYpOwogIH0sCiAgeG9yOiBmdW5jdGlvbiAocG9seTEsIHBvbHkyKSB7CiAgICByZXR1cm4gb3BlcmF0ZShwb2x5MSwgcG9seTIsIFBvbHlCb29sLnNlbGVjdFhvcik7CiAgfQp9OwpmdW5jdGlvbiBvcGVyYXRlKHBvbHkxLCBwb2x5Miwgc2VsZWN0b3IpIHsKICB2YXIgc2VnMSA9IFBvbHlCb29sLnNlZ21lbnRzKHBvbHkxKTsKICB2YXIgc2VnMiA9IFBvbHlCb29sLnNlZ21lbnRzKHBvbHkyKTsKICB2YXIgY29tYiA9IFBvbHlCb29sLmNvbWJpbmUoc2VnMSwgc2VnMik7CiAgdmFyIHNlZzMgPSBzZWxlY3Rvcihjb21iKTsKICByZXR1cm4gUG9seUJvb2wucG9seWdvbihzZWczKTsKfQppZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHdpbmRvdy5Qb2x5Qm9vbCA9IFBvbHlCb29sOwp2YXIgcG9seWJvb2xqcyA9IFBvbHlCb29sOwoKLyoqCiAqIFBlcmZvcm1zIGEgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUKICogZXF1aXZhbGVudC4KICoKICogKipOb3RlOioqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIGNvbXBhcmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLAogKiBkYXRlIG9iamVjdHMsIGVycm9yIG9iamVjdHMsIG1hcHMsIG51bWJlcnMsIGBPYmplY3RgIG9iamVjdHMsIHJlZ2V4ZXMsCiAqIHNldHMsIHN0cmluZ3MsIHN5bWJvbHMsIGFuZCB0eXBlZCBhcnJheXMuIGBPYmplY3RgIG9iamVjdHMgYXJlIGNvbXBhcmVkCiAqIGJ5IHRoZWlyIG93biwgbm90IGluaGVyaXRlZCwgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLiBGdW5jdGlvbnMgYW5kIERPTQogKiBub2RlcyBhcmUgY29tcGFyZWQgYnkgc3RyaWN0IGVxdWFsaXR5LCBpLmUuIGA9PT1gLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLgogKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEgfTsKICogdmFyIG90aGVyID0geyAnYSc6IDEgfTsKICoKICogXy5pc0VxdWFsKG9iamVjdCwgb3RoZXIpOwogKiAvLyA9PiB0cnVlCiAqCiAqIG9iamVjdCA9PT0gb3RoZXI7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0VxdWFsKHZhbHVlLCBvdGhlcikgewogIHJldHVybiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIpOwp9CgovKioNCiAqIOS/ruW+qVBvbHlnb27lhaflkIRSaW5nU3RyaW5n54K66ZaJ5ZCIDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvZml4Q2xvc2VQb2x5Z29uLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcGdzIOi8uOWFpVBvbHlnb27os4fmlpnpmaPliJfvvIzngrpbWyBbW3gxMSx5MTFdLFt4MTIseTEyXSwuLi5dLCBbW3gyMSx5MjFdLFt4MjIseTIyXSwuLi5dIF1d5qeL5oiQ5LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEByZXR1cm5zIHtBcnJheX0g5Zue5YKzUG9seWdvbumZo+WIlw0KICogQGV4YW1wbGUNCg0KICovCmZ1bmN0aW9uIGZpeENsb3NlUG9seWdvbihwZ3MsIG9wdCA9IHt9KSB7CiAgLy9jaGVjayBwZ3MKICBpZiAoIWlzZWFycihwZ3MpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIHBnc2ApOwogIH0KCiAgLy90b1BvbHlnb24KICBwZ3MgPSB0b1BvbHlnb24ocGdzKTsKCiAgLy/kv67lvqnmiJDngrrplonlkIgKICBwZ3MgPSBtYXAocGdzLCBycyA9PiB7CiAgICBsZXQgaTAgPSAwOwogICAgbGV0IGkxID0gc2l6ZShycykgLSAxOwogICAgbGV0IHJzMCA9IHJzW2kwXTsKICAgIGxldCByczEgPSByc1tpMV07CiAgICBpZiAoIWlzRXF1YWwocnMwLCByczEpKSB7CiAgICAgIHJzLnB1c2gocnMwKTsKICAgIH0KICAgIHJldHVybiByczsKICB9KTsKICByZXR1cm4gcGdzOwp9CgovKioNCiAqIOmHneWwjVBvbHlnb27pgLLooYzkuqTpm4YoaW50ZXJzZWN0KeiZleeQhg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ludGVyc2VjdFBvbHlnb24udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwZ3MxIOi8uOWFpeesrDHlgItQb2x5Z29u6LOH5paZ6Zmj5YiX77yM54K6WyBbW3gxMSx5MTFdLFt4MTIseTEyXSwuLi5dLCBbW3gyMSx5MjFdLFt4MjIseTIyXSwuLi5dIF3mp4vmiJDkuYvpmaPliJcNCiAqIEBwYXJhbSB7QXJyYXl9IHBnczIg6Ly45YWl56ysMuWAi1BvbHlnb27os4fmlpnpmaPliJfvvIzngrpbIFtbeDExLHkxMV0sW3gxMix5MTJdLC4uLl0sIFtbeDIxLHkyMV0sW3gyMix5MjJdLC4uLl0gXeani+aIkOS5i+mZo+WIlw0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5lcHNpbG9uPTAuMDAwMDAwMDAwMDAxXSDovLjlhaUgcG9seWJvb2xqcyDoqIjnrpflrrnoqLHoqqTlt64NCiAqIEByZXR1cm5zIHtBcnJheX0g5Zue5YKzUG9seWdvbumZo+WIlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcGdzMQ0KICogbGV0IHBnczINCiAqIGxldCByDQogKg0KICogcGdzMSA9ICdub3QgYXJyYXknDQogKiBwZ3MyID0gW1tbMiwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMiwgNF1dXSAvL3BvbHlnb24NCiAqIHRyeSB7DQogKiAgICAgciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiB9DQogKiBjYXRjaCAoZXJyKSB7DQogKiAgICAgciA9IGVyci5tZXNzYWdlDQogKiB9DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gbm8gcGdzMQ0KICoNCiAqIHBnczEgPSBbW1swLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFswLCA0XV1dIC8vcG9seWdvbg0KICogcGdzMiA9ICdub3QgYXJyYXknDQogKiB0cnkgew0KICogICAgIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogfQ0KICogY2F0Y2ggKGVycikgew0KICogICAgIHIgPSBlcnIubWVzc2FnZQ0KICogfQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IGludmFsaWQgcGdzMg0KICoNCiAqIHBnczEgPSBbW1swLCAwXSwgWzEsIDBdLCBbMSwgMV0sIFswLCAxXV1dIC8vcG9seWdvbg0KICogcGdzMiA9IFtdDQogKiByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMCwwXSxbMSwwXSxbMSwxXSxbMCwxXSxbMCwwXV1dDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW1tbMiwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMiwgNF1dXSAvL3BvbHlnb24NCiAqIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1s0LDRdLFs0LDBdLFsyLDBdLFsyLDRdLFs0LDRdXV0NCiAqDQogKiBwZ3MxID0gW1tbMCwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMCwgNF1dXSAvL3BvbHlnb24NCiAqIHBnczIgPSBbW1swLCAwXSwgWzIsIDBdLCBbMiwgMl0sIFswLCAyXV1dIC8vcG9seWdvbg0KICogciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzIsMl0sWzIsMF0sWzAsMF0sWzAsMl0sWzIsMl1dXQ0KICoNCiAqIHBnczEgPSBbW1swLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFswLCA0XV1dIC8vcG9seWdvbg0KICogcGdzMiA9IFtbWzAsIDBdLCBbMiwgMl0sIFswLCA0XV1dIC8vcG9seWdvbg0KICogciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzIsMl0sWzAsMF0sWzAsNF0sWzIsMl1dXQ0KICoNCiAqIHBnczEgPSBbW1swLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFswLCA0XV1dIC8vcG9seWdvbg0KICogcGdzMiA9IFtbWy0xLCAwXSwgWzIsIDFdLCBbLTEsIDRdXV0gLy9wb2x5Z29uDQogKiByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMiwxXSxbMCwwLjMzMzMzMzMzMzMzMzMzMzNdLFswLDNdLFsyLDFdXV0NCiAqDQogKi8KZnVuY3Rpb24gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCBvcHQgPSB7fSkgewogIC8vdHVyZueahGludGVyc2VjdOa6lueiuuaAp+iIh+mBqeeUqOaAp+avlOi8g+W3riwg5b6X5L2/55SocG9seWJvb2xqc+avlOi8g+WlvQoKICAvL2NoZWNrIHBnczEKICBpZiAoIWlzZWFycihwZ3MxKSkgewogICAgdGhyb3cgbmV3IEVycm9yKGBubyBwZ3MxYCk7CiAgfQoKICAvL2NoZWNrIHBnczIKICBpZiAoaXNhcnIocGdzMikgJiYgc2l6ZShwZ3MyKSA9PT0gMCkgewogICAgcGdzMSA9IGZpeENsb3NlUG9seWdvbihwZ3MxKTsKICAgIHJldHVybiBwZ3MxOwogIH0KICBpZiAoIWlzYXJyKHBnczIpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgcGdzMmApOwogIH0KCiAgLy9lcHNpbG9uCiAgbGV0IGVwc2lsb24gPSBnZXQob3B0LCAnZXBzaWxvbicsIDAuMDAwMDAwMDAwMDAxKTsKCiAgLy90b1BvbHlnb24KICBwZ3MxID0gdG9Qb2x5Z29uKHBnczEpOwogIHBnczIgPSB0b1BvbHlnb24ocGdzMik7CiAgLy8gY29uc29sZS5sb2coJ3BnczEnLCBwZ3MxKQogIC8vIGNvbnNvbGUubG9nKCdwZ3MyJywgcGdzMikKCiAgLy9pbnRlcnNlY3QKICBwb2x5Ym9vbGpzLmVwc2lsb24oZXBzaWxvbik7CiAgbGV0IGludHMgPSBwb2x5Ym9vbGpzLmludGVyc2VjdCh7CiAgICByZWdpb25zOiBwZ3MxCiAgfSwgewogICAgcmVnaW9uczogcGdzMgogIH0pOwogIC8vIGNvbnNvbGUubG9nKCdpbnRzJywgaW50cykKCiAgLy9wZ3MKICBsZXQgcGdzID0gZ2V0KGludHMsICdyZWdpb25zJywgW10pOwoKICAvL2ZpeENsb3NlUG9seWdvbgogIHBncyA9IGZpeENsb3NlUG9seWdvbihwZ3MpOwogIHJldHVybiBwZ3M7Cn0KCmNvbnN0IGVwc2lsb24kMSA9IDEuMTEwMjIzMDI0NjI1MTU2NWUtMTY7CmNvbnN0IHNwbGl0dGVyID0gMTM0MjE3NzI5Owpjb25zdCByZXN1bHRlcnJib3VuZCA9ICgzICsgOCAqIGVwc2lsb24kMSkgKiBlcHNpbG9uJDE7CgovLyBmYXN0X2V4cGFuc2lvbl9zdW1femVyb2VsaW0gcm91dGluZSBmcm9tIG9yaXRpbmFsIGNvZGUKZnVuY3Rpb24gc3VtKGVsZW4sIGUsIGZsZW4sIGYsIGgpIHsKICBsZXQgUSwgUW5ldywgaGgsIGJ2aXJ0OwogIGxldCBlbm93ID0gZVswXTsKICBsZXQgZm5vdyA9IGZbMF07CiAgbGV0IGVpbmRleCA9IDA7CiAgbGV0IGZpbmRleCA9IDA7CiAgaWYgKGZub3cgPiBlbm93ID09PSBmbm93ID4gLWVub3cpIHsKICAgIFEgPSBlbm93OwogICAgZW5vdyA9IGVbKytlaW5kZXhdOwogIH0gZWxzZSB7CiAgICBRID0gZm5vdzsKICAgIGZub3cgPSBmWysrZmluZGV4XTsKICB9CiAgbGV0IGhpbmRleCA9IDA7CiAgaWYgKGVpbmRleCA8IGVsZW4gJiYgZmluZGV4IDwgZmxlbikgewogICAgaWYgKGZub3cgPiBlbm93ID09PSBmbm93ID4gLWVub3cpIHsKICAgICAgUW5ldyA9IGVub3cgKyBROwogICAgICBoaCA9IFEgLSAoUW5ldyAtIGVub3cpOwogICAgICBlbm93ID0gZVsrK2VpbmRleF07CiAgICB9IGVsc2UgewogICAgICBRbmV3ID0gZm5vdyArIFE7CiAgICAgIGhoID0gUSAtIChRbmV3IC0gZm5vdyk7CiAgICAgIGZub3cgPSBmWysrZmluZGV4XTsKICAgIH0KICAgIFEgPSBRbmV3OwogICAgaWYgKGhoICE9PSAwKSB7CiAgICAgIGhbaGluZGV4KytdID0gaGg7CiAgICB9CiAgICB3aGlsZSAoZWluZGV4IDwgZWxlbiAmJiBmaW5kZXggPCBmbGVuKSB7CiAgICAgIGlmIChmbm93ID4gZW5vdyA9PT0gZm5vdyA+IC1lbm93KSB7CiAgICAgICAgUW5ldyA9IFEgKyBlbm93OwogICAgICAgIGJ2aXJ0ID0gUW5ldyAtIFE7CiAgICAgICAgaGggPSBRIC0gKFFuZXcgLSBidmlydCkgKyAoZW5vdyAtIGJ2aXJ0KTsKICAgICAgICBlbm93ID0gZVsrK2VpbmRleF07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgUW5ldyA9IFEgKyBmbm93OwogICAgICAgIGJ2aXJ0ID0gUW5ldyAtIFE7CiAgICAgICAgaGggPSBRIC0gKFFuZXcgLSBidmlydCkgKyAoZm5vdyAtIGJ2aXJ0KTsKICAgICAgICBmbm93ID0gZlsrK2ZpbmRleF07CiAgICAgIH0KICAgICAgUSA9IFFuZXc7CiAgICAgIGlmIChoaCAhPT0gMCkgewogICAgICAgIGhbaGluZGV4KytdID0gaGg7CiAgICAgIH0KICAgIH0KICB9CiAgd2hpbGUgKGVpbmRleCA8IGVsZW4pIHsKICAgIFFuZXcgPSBRICsgZW5vdzsKICAgIGJ2aXJ0ID0gUW5ldyAtIFE7CiAgICBoaCA9IFEgLSAoUW5ldyAtIGJ2aXJ0KSArIChlbm93IC0gYnZpcnQpOwogICAgZW5vdyA9IGVbKytlaW5kZXhdOwogICAgUSA9IFFuZXc7CiAgICBpZiAoaGggIT09IDApIHsKICAgICAgaFtoaW5kZXgrK10gPSBoaDsKICAgIH0KICB9CiAgd2hpbGUgKGZpbmRleCA8IGZsZW4pIHsKICAgIFFuZXcgPSBRICsgZm5vdzsKICAgIGJ2aXJ0ID0gUW5ldyAtIFE7CiAgICBoaCA9IFEgLSAoUW5ldyAtIGJ2aXJ0KSArIChmbm93IC0gYnZpcnQpOwogICAgZm5vdyA9IGZbKytmaW5kZXhdOwogICAgUSA9IFFuZXc7CiAgICBpZiAoaGggIT09IDApIHsKICAgICAgaFtoaW5kZXgrK10gPSBoaDsKICAgIH0KICB9CiAgaWYgKFEgIT09IDAgfHwgaGluZGV4ID09PSAwKSB7CiAgICBoW2hpbmRleCsrXSA9IFE7CiAgfQogIHJldHVybiBoaW5kZXg7Cn0KZnVuY3Rpb24gZXN0aW1hdGUoZWxlbiwgZSkgewogIGxldCBRID0gZVswXTsKICBmb3IgKGxldCBpID0gMTsgaSA8IGVsZW47IGkrKykgUSArPSBlW2ldOwogIHJldHVybiBROwp9CmZ1bmN0aW9uIHZlYyhuKSB7CiAgcmV0dXJuIG5ldyBGbG9hdDY0QXJyYXkobik7Cn0KCmNvbnN0IGNjd2VycmJvdW5kQSA9ICgzICsgMTYgKiBlcHNpbG9uJDEpICogZXBzaWxvbiQxOwpjb25zdCBjY3dlcnJib3VuZEIgPSAoMiArIDEyICogZXBzaWxvbiQxKSAqIGVwc2lsb24kMTsKY29uc3QgY2N3ZXJyYm91bmRDID0gKDkgKyA2NCAqIGVwc2lsb24kMSkgKiBlcHNpbG9uJDEgKiBlcHNpbG9uJDE7CmNvbnN0IEIgPSB2ZWMoNCk7CmNvbnN0IEMxID0gdmVjKDgpOwpjb25zdCBDMiA9IHZlYygxMik7CmNvbnN0IEQgPSB2ZWMoMTYpOwpjb25zdCB1ID0gdmVjKDQpOwpmdW5jdGlvbiBvcmllbnQyZGFkYXB0KGF4LCBheSwgYngsIGJ5LCBjeCwgY3ksIGRldHN1bSkgewogIGxldCBhY3h0YWlsLCBhY3l0YWlsLCBiY3h0YWlsLCBiY3l0YWlsOwogIGxldCBidmlydCwgYywgYWhpLCBhbG8sIGJoaSwgYmxvLCBfaSwgX2osIF8wLCBzMSwgczAsIHQxLCB0MCwgdTM7CiAgY29uc3QgYWN4ID0gYXggLSBjeDsKICBjb25zdCBiY3ggPSBieCAtIGN4OwogIGNvbnN0IGFjeSA9IGF5IC0gY3k7CiAgY29uc3QgYmN5ID0gYnkgLSBjeTsKICBzMSA9IGFjeCAqIGJjeTsKICBjID0gc3BsaXR0ZXIgKiBhY3g7CiAgYWhpID0gYyAtIChjIC0gYWN4KTsKICBhbG8gPSBhY3ggLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN5OwogIGJoaSA9IGMgLSAoYyAtIGJjeSk7CiAgYmxvID0gYmN5IC0gYmhpOwogIHMwID0gYWxvICogYmxvIC0gKHMxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICB0MSA9IGFjeSAqIGJjeDsKICBjID0gc3BsaXR0ZXIgKiBhY3k7CiAgYWhpID0gYyAtIChjIC0gYWN5KTsKICBhbG8gPSBhY3kgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN4OwogIGJoaSA9IGMgLSAoYyAtIGJjeCk7CiAgYmxvID0gYmN4IC0gYmhpOwogIHQwID0gYWxvICogYmxvIC0gKHQxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICBfaSA9IHMwIC0gdDA7CiAgYnZpcnQgPSBzMCAtIF9pOwogIEJbMF0gPSBzMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQwKTsKICBfaiA9IHMxICsgX2k7CiAgYnZpcnQgPSBfaiAtIHMxOwogIF8wID0gczEgLSAoX2ogLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgX2kgPSBfMCAtIHQxOwogIGJ2aXJ0ID0gXzAgLSBfaTsKICBCWzFdID0gXzAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MSk7CiAgdTMgPSBfaiArIF9pOwogIGJ2aXJ0ID0gdTMgLSBfajsKICBCWzJdID0gX2ogLSAodTMgLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgQlszXSA9IHUzOwogIGxldCBkZXQgPSBlc3RpbWF0ZSg0LCBCKTsKICBsZXQgZXJyYm91bmQgPSBjY3dlcnJib3VuZEIgKiBkZXRzdW07CiAgaWYgKGRldCA+PSBlcnJib3VuZCB8fCAtZGV0ID49IGVycmJvdW5kKSB7CiAgICByZXR1cm4gZGV0OwogIH0KICBidmlydCA9IGF4IC0gYWN4OwogIGFjeHRhaWwgPSBheCAtIChhY3ggKyBidmlydCkgKyAoYnZpcnQgLSBjeCk7CiAgYnZpcnQgPSBieCAtIGJjeDsKICBiY3h0YWlsID0gYnggLSAoYmN4ICsgYnZpcnQpICsgKGJ2aXJ0IC0gY3gpOwogIGJ2aXJ0ID0gYXkgLSBhY3k7CiAgYWN5dGFpbCA9IGF5IC0gKGFjeSArIGJ2aXJ0KSArIChidmlydCAtIGN5KTsKICBidmlydCA9IGJ5IC0gYmN5OwogIGJjeXRhaWwgPSBieSAtIChiY3kgKyBidmlydCkgKyAoYnZpcnQgLSBjeSk7CiAgaWYgKGFjeHRhaWwgPT09IDAgJiYgYWN5dGFpbCA9PT0gMCAmJiBiY3h0YWlsID09PSAwICYmIGJjeXRhaWwgPT09IDApIHsKICAgIHJldHVybiBkZXQ7CiAgfQogIGVycmJvdW5kID0gY2N3ZXJyYm91bmRDICogZGV0c3VtICsgcmVzdWx0ZXJyYm91bmQgKiBNYXRoLmFicyhkZXQpOwogIGRldCArPSBhY3ggKiBiY3l0YWlsICsgYmN5ICogYWN4dGFpbCAtIChhY3kgKiBiY3h0YWlsICsgYmN4ICogYWN5dGFpbCk7CiAgaWYgKGRldCA+PSBlcnJib3VuZCB8fCAtZGV0ID49IGVycmJvdW5kKSByZXR1cm4gZGV0OwogIHMxID0gYWN4dGFpbCAqIGJjeTsKICBjID0gc3BsaXR0ZXIgKiBhY3h0YWlsOwogIGFoaSA9IGMgLSAoYyAtIGFjeHRhaWwpOwogIGFsbyA9IGFjeHRhaWwgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN5OwogIGJoaSA9IGMgLSAoYyAtIGJjeSk7CiAgYmxvID0gYmN5IC0gYmhpOwogIHMwID0gYWxvICogYmxvIC0gKHMxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICB0MSA9IGFjeXRhaWwgKiBiY3g7CiAgYyA9IHNwbGl0dGVyICogYWN5dGFpbDsKICBhaGkgPSBjIC0gKGMgLSBhY3l0YWlsKTsKICBhbG8gPSBhY3l0YWlsIC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeDsKICBiaGkgPSBjIC0gKGMgLSBiY3gpOwogIGJsbyA9IGJjeCAtIGJoaTsKICB0MCA9IGFsbyAqIGJsbyAtICh0MSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgX2kgPSBzMCAtIHQwOwogIGJ2aXJ0ID0gczAgLSBfaTsKICB1WzBdID0gczAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MCk7CiAgX2ogPSBzMSArIF9pOwogIGJ2aXJ0ID0gX2ogLSBzMTsKICBfMCA9IHMxIC0gKF9qIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIF9pID0gXzAgLSB0MTsKICBidmlydCA9IF8wIC0gX2k7CiAgdVsxXSA9IF8wIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDEpOwogIHUzID0gX2ogKyBfaTsKICBidmlydCA9IHUzIC0gX2o7CiAgdVsyXSA9IF9qIC0gKHUzIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIHVbM10gPSB1MzsKICBjb25zdCBDMWxlbiA9IHN1bSg0LCBCLCA0LCB1LCBDMSk7CiAgczEgPSBhY3ggKiBiY3l0YWlsOwogIGMgPSBzcGxpdHRlciAqIGFjeDsKICBhaGkgPSBjIC0gKGMgLSBhY3gpOwogIGFsbyA9IGFjeCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3l0YWlsOwogIGJoaSA9IGMgLSAoYyAtIGJjeXRhaWwpOwogIGJsbyA9IGJjeXRhaWwgLSBiaGk7CiAgczAgPSBhbG8gKiBibG8gLSAoczEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIHQxID0gYWN5ICogYmN4dGFpbDsKICBjID0gc3BsaXR0ZXIgKiBhY3k7CiAgYWhpID0gYyAtIChjIC0gYWN5KTsKICBhbG8gPSBhY3kgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN4dGFpbDsKICBiaGkgPSBjIC0gKGMgLSBiY3h0YWlsKTsKICBibG8gPSBiY3h0YWlsIC0gYmhpOwogIHQwID0gYWxvICogYmxvIC0gKHQxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICBfaSA9IHMwIC0gdDA7CiAgYnZpcnQgPSBzMCAtIF9pOwogIHVbMF0gPSBzMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQwKTsKICBfaiA9IHMxICsgX2k7CiAgYnZpcnQgPSBfaiAtIHMxOwogIF8wID0gczEgLSAoX2ogLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgX2kgPSBfMCAtIHQxOwogIGJ2aXJ0ID0gXzAgLSBfaTsKICB1WzFdID0gXzAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MSk7CiAgdTMgPSBfaiArIF9pOwogIGJ2aXJ0ID0gdTMgLSBfajsKICB1WzJdID0gX2ogLSAodTMgLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgdVszXSA9IHUzOwogIGNvbnN0IEMybGVuID0gc3VtKEMxbGVuLCBDMSwgNCwgdSwgQzIpOwogIHMxID0gYWN4dGFpbCAqIGJjeXRhaWw7CiAgYyA9IHNwbGl0dGVyICogYWN4dGFpbDsKICBhaGkgPSBjIC0gKGMgLSBhY3h0YWlsKTsKICBhbG8gPSBhY3h0YWlsIC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeXRhaWw7CiAgYmhpID0gYyAtIChjIC0gYmN5dGFpbCk7CiAgYmxvID0gYmN5dGFpbCAtIGJoaTsKICBzMCA9IGFsbyAqIGJsbyAtIChzMSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgdDEgPSBhY3l0YWlsICogYmN4dGFpbDsKICBjID0gc3BsaXR0ZXIgKiBhY3l0YWlsOwogIGFoaSA9IGMgLSAoYyAtIGFjeXRhaWwpOwogIGFsbyA9IGFjeXRhaWwgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN4dGFpbDsKICBiaGkgPSBjIC0gKGMgLSBiY3h0YWlsKTsKICBibG8gPSBiY3h0YWlsIC0gYmhpOwogIHQwID0gYWxvICogYmxvIC0gKHQxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICBfaSA9IHMwIC0gdDA7CiAgYnZpcnQgPSBzMCAtIF9pOwogIHVbMF0gPSBzMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQwKTsKICBfaiA9IHMxICsgX2k7CiAgYnZpcnQgPSBfaiAtIHMxOwogIF8wID0gczEgLSAoX2ogLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgX2kgPSBfMCAtIHQxOwogIGJ2aXJ0ID0gXzAgLSBfaTsKICB1WzFdID0gXzAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MSk7CiAgdTMgPSBfaiArIF9pOwogIGJ2aXJ0ID0gdTMgLSBfajsKICB1WzJdID0gX2ogLSAodTMgLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgdVszXSA9IHUzOwogIGNvbnN0IERsZW4gPSBzdW0oQzJsZW4sIEMyLCA0LCB1LCBEKTsKICByZXR1cm4gRFtEbGVuIC0gMV07Cn0KZnVuY3Rpb24gb3JpZW50MmQoYXgsIGF5LCBieCwgYnksIGN4LCBjeSkgewogIGNvbnN0IGRldGxlZnQgPSAoYXkgLSBjeSkgKiAoYnggLSBjeCk7CiAgY29uc3QgZGV0cmlnaHQgPSAoYXggLSBjeCkgKiAoYnkgLSBjeSk7CiAgY29uc3QgZGV0ID0gZGV0bGVmdCAtIGRldHJpZ2h0OwogIGlmIChkZXRsZWZ0ID09PSAwIHx8IGRldHJpZ2h0ID09PSAwIHx8IGRldGxlZnQgPiAwICE9PSBkZXRyaWdodCA+IDApIHJldHVybiBkZXQ7CiAgY29uc3QgZGV0c3VtID0gTWF0aC5hYnMoZGV0bGVmdCArIGRldHJpZ2h0KTsKICBpZiAoTWF0aC5hYnMoZGV0KSA+PSBjY3dlcnJib3VuZEEgKiBkZXRzdW0pIHJldHVybiBkZXQ7CiAgcmV0dXJuIC1vcmllbnQyZGFkYXB0KGF4LCBheSwgYngsIGJ5LCBjeCwgY3ksIGRldHN1bSk7Cn0KCmNvbnN0IEVQU0lMT04gPSBNYXRoLnBvdygyLCAtNTIpOwpjb25zdCBFREdFX1NUQUNLID0gbmV3IFVpbnQzMkFycmF5KDUxMik7CmNsYXNzIERlbGF1bmF0b3IgewogIHN0YXRpYyBmcm9tKHBvaW50cywgZ2V0WCA9IGRlZmF1bHRHZXRYLCBnZXRZID0gZGVmYXVsdEdldFkpIHsKICAgIGNvbnN0IG4gPSBwb2ludHMubGVuZ3RoOwogICAgY29uc3QgY29vcmRzID0gbmV3IEZsb2F0NjRBcnJheShuICogMik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBjb25zdCBwID0gcG9pbnRzW2ldOwogICAgICBjb29yZHNbMiAqIGldID0gZ2V0WChwKTsKICAgICAgY29vcmRzWzIgKiBpICsgMV0gPSBnZXRZKHApOwogICAgfQogICAgcmV0dXJuIG5ldyBEZWxhdW5hdG9yKGNvb3Jkcyk7CiAgfQogIGNvbnN0cnVjdG9yKGNvb3JkcykgewogICAgY29uc3QgbiA9IGNvb3Jkcy5sZW5ndGggPj4gMTsKICAgIGlmIChuID4gMCAmJiB0eXBlb2YgY29vcmRzWzBdICE9PSAnbnVtYmVyJykgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBjb29yZHMgdG8gY29udGFpbiBudW1iZXJzLicpOwogICAgdGhpcy5jb29yZHMgPSBjb29yZHM7CgogICAgLy8gYXJyYXlzIHRoYXQgd2lsbCBzdG9yZSB0aGUgdHJpYW5ndWxhdGlvbiBncmFwaAogICAgY29uc3QgbWF4VHJpYW5nbGVzID0gTWF0aC5tYXgoMiAqIG4gLSA1LCAwKTsKICAgIHRoaXMuX3RyaWFuZ2xlcyA9IG5ldyBVaW50MzJBcnJheShtYXhUcmlhbmdsZXMgKiAzKTsKICAgIHRoaXMuX2hhbGZlZGdlcyA9IG5ldyBJbnQzMkFycmF5KG1heFRyaWFuZ2xlcyAqIDMpOwoKICAgIC8vIHRlbXBvcmFyeSBhcnJheXMgZm9yIHRyYWNraW5nIHRoZSBlZGdlcyBvZiB0aGUgYWR2YW5jaW5nIGNvbnZleCBodWxsCiAgICB0aGlzLl9oYXNoU2l6ZSA9IE1hdGguY2VpbChNYXRoLnNxcnQobikpOwogICAgdGhpcy5faHVsbFByZXYgPSBuZXcgVWludDMyQXJyYXkobik7IC8vIGVkZ2UgdG8gcHJldiBlZGdlCiAgICB0aGlzLl9odWxsTmV4dCA9IG5ldyBVaW50MzJBcnJheShuKTsgLy8gZWRnZSB0byBuZXh0IGVkZ2UKICAgIHRoaXMuX2h1bGxUcmkgPSBuZXcgVWludDMyQXJyYXkobik7IC8vIGVkZ2UgdG8gYWRqYWNlbnQgdHJpYW5nbGUKICAgIHRoaXMuX2h1bGxIYXNoID0gbmV3IEludDMyQXJyYXkodGhpcy5faGFzaFNpemUpLmZpbGwoLTEpOyAvLyBhbmd1bGFyIGVkZ2UgaGFzaAoKICAgIC8vIHRlbXBvcmFyeSBhcnJheXMgZm9yIHNvcnRpbmcgcG9pbnRzCiAgICB0aGlzLl9pZHMgPSBuZXcgVWludDMyQXJyYXkobik7CiAgICB0aGlzLl9kaXN0cyA9IG5ldyBGbG9hdDY0QXJyYXkobik7CiAgICB0aGlzLnVwZGF0ZSgpOwogIH0KICB1cGRhdGUoKSB7CiAgICBjb25zdCB7CiAgICAgIGNvb3JkcywKICAgICAgX2h1bGxQcmV2OiBodWxsUHJldiwKICAgICAgX2h1bGxOZXh0OiBodWxsTmV4dCwKICAgICAgX2h1bGxUcmk6IGh1bGxUcmksCiAgICAgIF9odWxsSGFzaDogaHVsbEhhc2gKICAgIH0gPSB0aGlzOwogICAgY29uc3QgbiA9IGNvb3Jkcy5sZW5ndGggPj4gMTsKCiAgICAvLyBwb3B1bGF0ZSBhbiBhcnJheSBvZiBwb2ludCBpbmRpY2VzOyBjYWxjdWxhdGUgaW5wdXQgZGF0YSBiYm94CiAgICBsZXQgbWluWCA9IEluZmluaXR5OwogICAgbGV0IG1pblkgPSBJbmZpbml0eTsKICAgIGxldCBtYXhYID0gLUluZmluaXR5OwogICAgbGV0IG1heFkgPSAtSW5maW5pdHk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBjb25zdCB4ID0gY29vcmRzWzIgKiBpXTsKICAgICAgY29uc3QgeSA9IGNvb3Jkc1syICogaSArIDFdOwogICAgICBpZiAoeCA8IG1pblgpIG1pblggPSB4OwogICAgICBpZiAoeSA8IG1pblkpIG1pblkgPSB5OwogICAgICBpZiAoeCA+IG1heFgpIG1heFggPSB4OwogICAgICBpZiAoeSA+IG1heFkpIG1heFkgPSB5OwogICAgICB0aGlzLl9pZHNbaV0gPSBpOwogICAgfQogICAgY29uc3QgY3ggPSAobWluWCArIG1heFgpIC8gMjsKICAgIGNvbnN0IGN5ID0gKG1pblkgKyBtYXhZKSAvIDI7CiAgICBsZXQgbWluRGlzdCA9IEluZmluaXR5OwogICAgbGV0IGkwLCBpMSwgaTI7CgogICAgLy8gcGljayBhIHNlZWQgcG9pbnQgY2xvc2UgdG8gdGhlIGNlbnRlcgogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgY29uc3QgZCA9IGRpc3QoY3gsIGN5LCBjb29yZHNbMiAqIGldLCBjb29yZHNbMiAqIGkgKyAxXSk7CiAgICAgIGlmIChkIDwgbWluRGlzdCkgewogICAgICAgIGkwID0gaTsKICAgICAgICBtaW5EaXN0ID0gZDsKICAgICAgfQogICAgfQogICAgY29uc3QgaTB4ID0gY29vcmRzWzIgKiBpMF07CiAgICBjb25zdCBpMHkgPSBjb29yZHNbMiAqIGkwICsgMV07CiAgICBtaW5EaXN0ID0gSW5maW5pdHk7CgogICAgLy8gZmluZCB0aGUgcG9pbnQgY2xvc2VzdCB0byB0aGUgc2VlZAogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgaWYgKGkgPT09IGkwKSBjb250aW51ZTsKICAgICAgY29uc3QgZCA9IGRpc3QoaTB4LCBpMHksIGNvb3Jkc1syICogaV0sIGNvb3Jkc1syICogaSArIDFdKTsKICAgICAgaWYgKGQgPCBtaW5EaXN0ICYmIGQgPiAwKSB7CiAgICAgICAgaTEgPSBpOwogICAgICAgIG1pbkRpc3QgPSBkOwogICAgICB9CiAgICB9CiAgICBsZXQgaTF4ID0gY29vcmRzWzIgKiBpMV07CiAgICBsZXQgaTF5ID0gY29vcmRzWzIgKiBpMSArIDFdOwogICAgbGV0IG1pblJhZGl1cyA9IEluZmluaXR5OwoKICAgIC8vIGZpbmQgdGhlIHRoaXJkIHBvaW50IHdoaWNoIGZvcm1zIHRoZSBzbWFsbGVzdCBjaXJjdW1jaXJjbGUgd2l0aCB0aGUgZmlyc3QgdHdvCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBpZiAoaSA9PT0gaTAgfHwgaSA9PT0gaTEpIGNvbnRpbnVlOwogICAgICBjb25zdCByID0gY2lyY3VtcmFkaXVzKGkweCwgaTB5LCBpMXgsIGkxeSwgY29vcmRzWzIgKiBpXSwgY29vcmRzWzIgKiBpICsgMV0pOwogICAgICBpZiAociA8IG1pblJhZGl1cykgewogICAgICAgIGkyID0gaTsKICAgICAgICBtaW5SYWRpdXMgPSByOwogICAgICB9CiAgICB9CiAgICBsZXQgaTJ4ID0gY29vcmRzWzIgKiBpMl07CiAgICBsZXQgaTJ5ID0gY29vcmRzWzIgKiBpMiArIDFdOwogICAgaWYgKG1pblJhZGl1cyA9PT0gSW5maW5pdHkpIHsKICAgICAgLy8gb3JkZXIgY29sbGluZWFyIHBvaW50cyBieSBkeCAob3IgZHkgaWYgYWxsIHggYXJlIGlkZW50aWNhbCkKICAgICAgLy8gYW5kIHJldHVybiB0aGUgbGlzdCBhcyBhIGh1bGwKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICB0aGlzLl9kaXN0c1tpXSA9IGNvb3Jkc1syICogaV0gLSBjb29yZHNbMF0gfHwgY29vcmRzWzIgKiBpICsgMV0gLSBjb29yZHNbMV07CiAgICAgIH0KICAgICAgcXVpY2tzb3J0KHRoaXMuX2lkcywgdGhpcy5fZGlzdHMsIDAsIG4gLSAxKTsKICAgICAgY29uc3QgaHVsbCA9IG5ldyBVaW50MzJBcnJheShuKTsKICAgICAgbGV0IGogPSAwOwogICAgICBmb3IgKGxldCBpID0gMCwgZDAgPSAtSW5maW5pdHk7IGkgPCBuOyBpKyspIHsKICAgICAgICBjb25zdCBpZCA9IHRoaXMuX2lkc1tpXTsKICAgICAgICBpZiAodGhpcy5fZGlzdHNbaWRdID4gZDApIHsKICAgICAgICAgIGh1bGxbaisrXSA9IGlkOwogICAgICAgICAgZDAgPSB0aGlzLl9kaXN0c1tpZF07CiAgICAgICAgfQogICAgICB9CiAgICAgIHRoaXMuaHVsbCA9IGh1bGwuc3ViYXJyYXkoMCwgaik7CiAgICAgIHRoaXMudHJpYW5nbGVzID0gbmV3IFVpbnQzMkFycmF5KDApOwogICAgICB0aGlzLmhhbGZlZGdlcyA9IG5ldyBVaW50MzJBcnJheSgwKTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIHN3YXAgdGhlIG9yZGVyIG9mIHRoZSBzZWVkIHBvaW50cyBmb3IgY291bnRlci1jbG9ja3dpc2Ugb3JpZW50YXRpb24KICAgIGlmIChvcmllbnQyZChpMHgsIGkweSwgaTF4LCBpMXksIGkyeCwgaTJ5KSA8IDApIHsKICAgICAgY29uc3QgaSA9IGkxOwogICAgICBjb25zdCB4ID0gaTF4OwogICAgICBjb25zdCB5ID0gaTF5OwogICAgICBpMSA9IGkyOwogICAgICBpMXggPSBpMng7CiAgICAgIGkxeSA9IGkyeTsKICAgICAgaTIgPSBpOwogICAgICBpMnggPSB4OwogICAgICBpMnkgPSB5OwogICAgfQogICAgY29uc3QgY2VudGVyID0gY2lyY3VtY2VudGVyKGkweCwgaTB5LCBpMXgsIGkxeSwgaTJ4LCBpMnkpOwogICAgdGhpcy5fY3ggPSBjZW50ZXIueDsKICAgIHRoaXMuX2N5ID0gY2VudGVyLnk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICB0aGlzLl9kaXN0c1tpXSA9IGRpc3QoY29vcmRzWzIgKiBpXSwgY29vcmRzWzIgKiBpICsgMV0sIGNlbnRlci54LCBjZW50ZXIueSk7CiAgICB9CgogICAgLy8gc29ydCB0aGUgcG9pbnRzIGJ5IGRpc3RhbmNlIGZyb20gdGhlIHNlZWQgdHJpYW5nbGUgY2lyY3VtY2VudGVyCiAgICBxdWlja3NvcnQodGhpcy5faWRzLCB0aGlzLl9kaXN0cywgMCwgbiAtIDEpOwoKICAgIC8vIHNldCB1cCB0aGUgc2VlZCB0cmlhbmdsZSBhcyB0aGUgc3RhcnRpbmcgaHVsbAogICAgdGhpcy5faHVsbFN0YXJ0ID0gaTA7CiAgICBsZXQgaHVsbFNpemUgPSAzOwogICAgaHVsbE5leHRbaTBdID0gaHVsbFByZXZbaTJdID0gaTE7CiAgICBodWxsTmV4dFtpMV0gPSBodWxsUHJldltpMF0gPSBpMjsKICAgIGh1bGxOZXh0W2kyXSA9IGh1bGxQcmV2W2kxXSA9IGkwOwogICAgaHVsbFRyaVtpMF0gPSAwOwogICAgaHVsbFRyaVtpMV0gPSAxOwogICAgaHVsbFRyaVtpMl0gPSAyOwogICAgaHVsbEhhc2guZmlsbCgtMSk7CiAgICBodWxsSGFzaFt0aGlzLl9oYXNoS2V5KGkweCwgaTB5KV0gPSBpMDsKICAgIGh1bGxIYXNoW3RoaXMuX2hhc2hLZXkoaTF4LCBpMXkpXSA9IGkxOwogICAgaHVsbEhhc2hbdGhpcy5faGFzaEtleShpMngsIGkyeSldID0gaTI7CiAgICB0aGlzLnRyaWFuZ2xlc0xlbiA9IDA7CiAgICB0aGlzLl9hZGRUcmlhbmdsZShpMCwgaTEsIGkyLCAtMSwgLTEsIC0xKTsKICAgIGZvciAobGV0IGsgPSAwLCB4cCwgeXA7IGsgPCB0aGlzLl9pZHMubGVuZ3RoOyBrKyspIHsKICAgICAgY29uc3QgaSA9IHRoaXMuX2lkc1trXTsKICAgICAgY29uc3QgeCA9IGNvb3Jkc1syICogaV07CiAgICAgIGNvbnN0IHkgPSBjb29yZHNbMiAqIGkgKyAxXTsKCiAgICAgIC8vIHNraXAgbmVhci1kdXBsaWNhdGUgcG9pbnRzCiAgICAgIGlmIChrID4gMCAmJiBNYXRoLmFicyh4IC0geHApIDw9IEVQU0lMT04gJiYgTWF0aC5hYnMoeSAtIHlwKSA8PSBFUFNJTE9OKSBjb250aW51ZTsKICAgICAgeHAgPSB4OwogICAgICB5cCA9IHk7CgogICAgICAvLyBza2lwIHNlZWQgdHJpYW5nbGUgcG9pbnRzCiAgICAgIGlmIChpID09PSBpMCB8fCBpID09PSBpMSB8fCBpID09PSBpMikgY29udGludWU7CgogICAgICAvLyBmaW5kIGEgdmlzaWJsZSBlZGdlIG9uIHRoZSBjb252ZXggaHVsbCB1c2luZyBlZGdlIGhhc2gKICAgICAgbGV0IHN0YXJ0ID0gMDsKICAgICAgZm9yIChsZXQgaiA9IDAsIGtleSA9IHRoaXMuX2hhc2hLZXkoeCwgeSk7IGogPCB0aGlzLl9oYXNoU2l6ZTsgaisrKSB7CiAgICAgICAgc3RhcnQgPSBodWxsSGFzaFsoa2V5ICsgaikgJSB0aGlzLl9oYXNoU2l6ZV07CiAgICAgICAgaWYgKHN0YXJ0ICE9PSAtMSAmJiBzdGFydCAhPT0gaHVsbE5leHRbc3RhcnRdKSBicmVhazsKICAgICAgfQogICAgICBzdGFydCA9IGh1bGxQcmV2W3N0YXJ0XTsKICAgICAgbGV0IGUgPSBzdGFydCwKICAgICAgICBxOwogICAgICB3aGlsZSAocSA9IGh1bGxOZXh0W2VdLCBvcmllbnQyZCh4LCB5LCBjb29yZHNbMiAqIGVdLCBjb29yZHNbMiAqIGUgKyAxXSwgY29vcmRzWzIgKiBxXSwgY29vcmRzWzIgKiBxICsgMV0pID49IDApIHsKICAgICAgICBlID0gcTsKICAgICAgICBpZiAoZSA9PT0gc3RhcnQpIHsKICAgICAgICAgIGUgPSAtMTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoZSA9PT0gLTEpIGNvbnRpbnVlOyAvLyBsaWtlbHkgYSBuZWFyLWR1cGxpY2F0ZSBwb2ludDsgc2tpcCBpdAoKICAgICAgLy8gYWRkIHRoZSBmaXJzdCB0cmlhbmdsZSBmcm9tIHRoZSBwb2ludAogICAgICBsZXQgdCA9IHRoaXMuX2FkZFRyaWFuZ2xlKGUsIGksIGh1bGxOZXh0W2VdLCAtMSwgLTEsIGh1bGxUcmlbZV0pOwoKICAgICAgLy8gcmVjdXJzaXZlbHkgZmxpcCB0cmlhbmdsZXMgZnJvbSB0aGUgcG9pbnQgdW50aWwgdGhleSBzYXRpc2Z5IHRoZSBEZWxhdW5heSBjb25kaXRpb24KICAgICAgaHVsbFRyaVtpXSA9IHRoaXMuX2xlZ2FsaXplKHQgKyAyKTsKICAgICAgaHVsbFRyaVtlXSA9IHQ7IC8vIGtlZXAgdHJhY2sgb2YgYm91bmRhcnkgdHJpYW5nbGVzIG9uIHRoZSBodWxsCiAgICAgIGh1bGxTaXplKys7CgogICAgICAvLyB3YWxrIGZvcndhcmQgdGhyb3VnaCB0aGUgaHVsbCwgYWRkaW5nIG1vcmUgdHJpYW5nbGVzIGFuZCBmbGlwcGluZyByZWN1cnNpdmVseQogICAgICBsZXQgbiA9IGh1bGxOZXh0W2VdOwogICAgICB3aGlsZSAocSA9IGh1bGxOZXh0W25dLCBvcmllbnQyZCh4LCB5LCBjb29yZHNbMiAqIG5dLCBjb29yZHNbMiAqIG4gKyAxXSwgY29vcmRzWzIgKiBxXSwgY29vcmRzWzIgKiBxICsgMV0pIDwgMCkgewogICAgICAgIHQgPSB0aGlzLl9hZGRUcmlhbmdsZShuLCBpLCBxLCBodWxsVHJpW2ldLCAtMSwgaHVsbFRyaVtuXSk7CiAgICAgICAgaHVsbFRyaVtpXSA9IHRoaXMuX2xlZ2FsaXplKHQgKyAyKTsKICAgICAgICBodWxsTmV4dFtuXSA9IG47IC8vIG1hcmsgYXMgcmVtb3ZlZAogICAgICAgIGh1bGxTaXplLS07CiAgICAgICAgbiA9IHE7CiAgICAgIH0KCiAgICAgIC8vIHdhbGsgYmFja3dhcmQgZnJvbSB0aGUgb3RoZXIgc2lkZSwgYWRkaW5nIG1vcmUgdHJpYW5nbGVzIGFuZCBmbGlwcGluZwogICAgICBpZiAoZSA9PT0gc3RhcnQpIHsKICAgICAgICB3aGlsZSAocSA9IGh1bGxQcmV2W2VdLCBvcmllbnQyZCh4LCB5LCBjb29yZHNbMiAqIHFdLCBjb29yZHNbMiAqIHEgKyAxXSwgY29vcmRzWzIgKiBlXSwgY29vcmRzWzIgKiBlICsgMV0pIDwgMCkgewogICAgICAgICAgdCA9IHRoaXMuX2FkZFRyaWFuZ2xlKHEsIGksIGUsIC0xLCBodWxsVHJpW2VdLCBodWxsVHJpW3FdKTsKICAgICAgICAgIHRoaXMuX2xlZ2FsaXplKHQgKyAyKTsKICAgICAgICAgIGh1bGxUcmlbcV0gPSB0OwogICAgICAgICAgaHVsbE5leHRbZV0gPSBlOyAvLyBtYXJrIGFzIHJlbW92ZWQKICAgICAgICAgIGh1bGxTaXplLS07CiAgICAgICAgICBlID0gcTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIHVwZGF0ZSB0aGUgaHVsbCBpbmRpY2VzCiAgICAgIHRoaXMuX2h1bGxTdGFydCA9IGh1bGxQcmV2W2ldID0gZTsKICAgICAgaHVsbE5leHRbZV0gPSBodWxsUHJldltuXSA9IGk7CiAgICAgIGh1bGxOZXh0W2ldID0gbjsKCiAgICAgIC8vIHNhdmUgdGhlIHR3byBuZXcgZWRnZXMgaW4gdGhlIGhhc2ggdGFibGUKICAgICAgaHVsbEhhc2hbdGhpcy5faGFzaEtleSh4LCB5KV0gPSBpOwogICAgICBodWxsSGFzaFt0aGlzLl9oYXNoS2V5KGNvb3Jkc1syICogZV0sIGNvb3Jkc1syICogZSArIDFdKV0gPSBlOwogICAgfQogICAgdGhpcy5odWxsID0gbmV3IFVpbnQzMkFycmF5KGh1bGxTaXplKTsKICAgIGZvciAobGV0IGkgPSAwLCBlID0gdGhpcy5faHVsbFN0YXJ0OyBpIDwgaHVsbFNpemU7IGkrKykgewogICAgICB0aGlzLmh1bGxbaV0gPSBlOwogICAgICBlID0gaHVsbE5leHRbZV07CiAgICB9CgogICAgLy8gdHJpbSB0eXBlZCB0cmlhbmdsZSBtZXNoIGFycmF5cwogICAgdGhpcy50cmlhbmdsZXMgPSB0aGlzLl90cmlhbmdsZXMuc3ViYXJyYXkoMCwgdGhpcy50cmlhbmdsZXNMZW4pOwogICAgdGhpcy5oYWxmZWRnZXMgPSB0aGlzLl9oYWxmZWRnZXMuc3ViYXJyYXkoMCwgdGhpcy50cmlhbmdsZXNMZW4pOwogIH0KICBfaGFzaEtleSh4LCB5KSB7CiAgICByZXR1cm4gTWF0aC5mbG9vcihwc2V1ZG9BbmdsZSh4IC0gdGhpcy5fY3gsIHkgLSB0aGlzLl9jeSkgKiB0aGlzLl9oYXNoU2l6ZSkgJSB0aGlzLl9oYXNoU2l6ZTsKICB9CiAgX2xlZ2FsaXplKGEpIHsKICAgIGNvbnN0IHsKICAgICAgX3RyaWFuZ2xlczogdHJpYW5nbGVzLAogICAgICBfaGFsZmVkZ2VzOiBoYWxmZWRnZXMsCiAgICAgIGNvb3JkcwogICAgfSA9IHRoaXM7CiAgICBsZXQgaSA9IDA7CiAgICBsZXQgYXIgPSAwOwoKICAgIC8vIHJlY3Vyc2lvbiBlbGltaW5hdGVkIHdpdGggYSBmaXhlZC1zaXplIHN0YWNrCiAgICB3aGlsZSAodHJ1ZSkgewogICAgICBjb25zdCBiID0gaGFsZmVkZ2VzW2FdOwoKICAgICAgLyogaWYgdGhlIHBhaXIgb2YgdHJpYW5nbGVzIGRvZXNuJ3Qgc2F0aXNmeSB0aGUgRGVsYXVuYXkgY29uZGl0aW9uCiAgICAgICAqIChwMSBpcyBpbnNpZGUgdGhlIGNpcmN1bWNpcmNsZSBvZiBbcDAsIHBsLCBwcl0pLCBmbGlwIHRoZW0sCiAgICAgICAqIHRoZW4gZG8gdGhlIHNhbWUgY2hlY2svZmxpcCByZWN1cnNpdmVseSBmb3IgdGhlIG5ldyBwYWlyIG9mIHRyaWFuZ2xlcwogICAgICAgKgogICAgICAgKiAgICAgICAgICAgcGwgICAgICAgICAgICAgICAgICAgIHBsCiAgICAgICAqICAgICAgICAgIC98fFwgICAgICAgICAgICAgICAgICAvICBcCiAgICAgICAqICAgICAgIGFsLyB8fCBcYmwgICAgICAgICAgICBhbC8gICAgXGEKICAgICAgICogICAgICAgIC8gIHx8ICBcICAgICAgICAgICAgICAvICAgICAgXAogICAgICAgKiAgICAgICAvICBhfHxiICBcICAgIGZsaXAgICAgL19fX2FyX19fXAogICAgICAgKiAgICAgcDBcICAgfHwgICAvcDEgICA9PiAgIHAwXC0tLWJsLS0tL3AxCiAgICAgICAqICAgICAgICBcICB8fCAgLyAgICAgICAgICAgICAgXCAgICAgIC8KICAgICAgICogICAgICAgYXJcIHx8IC9iciAgICAgICAgICAgICBiXCAgICAvYnIKICAgICAgICogICAgICAgICAgXHx8LyAgICAgICAgICAgICAgICAgIFwgIC8KICAgICAgICogICAgICAgICAgIHByICAgICAgICAgICAgICAgICAgICBwcgogICAgICAgKi8KICAgICAgY29uc3QgYTAgPSBhIC0gYSAlIDM7CiAgICAgIGFyID0gYTAgKyAoYSArIDIpICUgMzsKICAgICAgaWYgKGIgPT09IC0xKSB7CiAgICAgICAgLy8gY29udmV4IGh1bGwgZWRnZQogICAgICAgIGlmIChpID09PSAwKSBicmVhazsKICAgICAgICBhID0gRURHRV9TVEFDS1stLWldOwogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGNvbnN0IGIwID0gYiAtIGIgJSAzOwogICAgICBjb25zdCBhbCA9IGEwICsgKGEgKyAxKSAlIDM7CiAgICAgIGNvbnN0IGJsID0gYjAgKyAoYiArIDIpICUgMzsKICAgICAgY29uc3QgcDAgPSB0cmlhbmdsZXNbYXJdOwogICAgICBjb25zdCBwciA9IHRyaWFuZ2xlc1thXTsKICAgICAgY29uc3QgcGwgPSB0cmlhbmdsZXNbYWxdOwogICAgICBjb25zdCBwMSA9IHRyaWFuZ2xlc1tibF07CiAgICAgIGNvbnN0IGlsbGVnYWwgPSBpbkNpcmNsZShjb29yZHNbMiAqIHAwXSwgY29vcmRzWzIgKiBwMCArIDFdLCBjb29yZHNbMiAqIHByXSwgY29vcmRzWzIgKiBwciArIDFdLCBjb29yZHNbMiAqIHBsXSwgY29vcmRzWzIgKiBwbCArIDFdLCBjb29yZHNbMiAqIHAxXSwgY29vcmRzWzIgKiBwMSArIDFdKTsKICAgICAgaWYgKGlsbGVnYWwpIHsKICAgICAgICB0cmlhbmdsZXNbYV0gPSBwMTsKICAgICAgICB0cmlhbmdsZXNbYl0gPSBwMDsKICAgICAgICBjb25zdCBoYmwgPSBoYWxmZWRnZXNbYmxdOwoKICAgICAgICAvLyBlZGdlIHN3YXBwZWQgb24gdGhlIG90aGVyIHNpZGUgb2YgdGhlIGh1bGwgKHJhcmUpOyBmaXggdGhlIGhhbGZlZGdlIHJlZmVyZW5jZQogICAgICAgIGlmIChoYmwgPT09IC0xKSB7CiAgICAgICAgICBsZXQgZSA9IHRoaXMuX2h1bGxTdGFydDsKICAgICAgICAgIGRvIHsKICAgICAgICAgICAgaWYgKHRoaXMuX2h1bGxUcmlbZV0gPT09IGJsKSB7CiAgICAgICAgICAgICAgdGhpcy5faHVsbFRyaVtlXSA9IGE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZSA9IHRoaXMuX2h1bGxQcmV2W2VdOwogICAgICAgICAgfSB3aGlsZSAoZSAhPT0gdGhpcy5faHVsbFN0YXJ0KTsKICAgICAgICB9CiAgICAgICAgdGhpcy5fbGluayhhLCBoYmwpOwogICAgICAgIHRoaXMuX2xpbmsoYiwgaGFsZmVkZ2VzW2FyXSk7CiAgICAgICAgdGhpcy5fbGluayhhciwgYmwpOwogICAgICAgIGNvbnN0IGJyID0gYjAgKyAoYiArIDEpICUgMzsKCiAgICAgICAgLy8gZG9uJ3Qgd29ycnkgYWJvdXQgaGl0dGluZyB0aGUgY2FwOiBpdCBjYW4gb25seSBoYXBwZW4gb24gZXh0cmVtZWx5IGRlZ2VuZXJhdGUgaW5wdXQKICAgICAgICBpZiAoaSA8IEVER0VfU1RBQ0subGVuZ3RoKSB7CiAgICAgICAgICBFREdFX1NUQUNLW2krK10gPSBicjsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGkgPT09IDApIGJyZWFrOwogICAgICAgIGEgPSBFREdFX1NUQUNLWy0taV07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhcjsKICB9CiAgX2xpbmsoYSwgYikgewogICAgdGhpcy5faGFsZmVkZ2VzW2FdID0gYjsKICAgIGlmIChiICE9PSAtMSkgdGhpcy5faGFsZmVkZ2VzW2JdID0gYTsKICB9CgogIC8vIGFkZCBhIG5ldyB0cmlhbmdsZSBnaXZlbiB2ZXJ0ZXggaW5kaWNlcyBhbmQgYWRqYWNlbnQgaGFsZi1lZGdlIGlkcwogIF9hZGRUcmlhbmdsZShpMCwgaTEsIGkyLCBhLCBiLCBjKSB7CiAgICBjb25zdCB0ID0gdGhpcy50cmlhbmdsZXNMZW47CiAgICB0aGlzLl90cmlhbmdsZXNbdF0gPSBpMDsKICAgIHRoaXMuX3RyaWFuZ2xlc1t0ICsgMV0gPSBpMTsKICAgIHRoaXMuX3RyaWFuZ2xlc1t0ICsgMl0gPSBpMjsKICAgIHRoaXMuX2xpbmsodCwgYSk7CiAgICB0aGlzLl9saW5rKHQgKyAxLCBiKTsKICAgIHRoaXMuX2xpbmsodCArIDIsIGMpOwogICAgdGhpcy50cmlhbmdsZXNMZW4gKz0gMzsKICAgIHJldHVybiB0OwogIH0KfQoKLy8gbW9ub3RvbmljYWxseSBpbmNyZWFzZXMgd2l0aCByZWFsIGFuZ2xlLCBidXQgZG9lc24ndCBuZWVkIGV4cGVuc2l2ZSB0cmlnb25vbWV0cnkKZnVuY3Rpb24gcHNldWRvQW5nbGUoZHgsIGR5KSB7CiAgY29uc3QgcCA9IGR4IC8gKE1hdGguYWJzKGR4KSArIE1hdGguYWJzKGR5KSk7CiAgcmV0dXJuIChkeSA+IDAgPyAzIC0gcCA6IDEgKyBwKSAvIDQ7IC8vIFswLi4xXQp9CgpmdW5jdGlvbiBkaXN0KGF4LCBheSwgYngsIGJ5KSB7CiAgY29uc3QgZHggPSBheCAtIGJ4OwogIGNvbnN0IGR5ID0gYXkgLSBieTsKICByZXR1cm4gZHggKiBkeCArIGR5ICogZHk7Cn0KZnVuY3Rpb24gaW5DaXJjbGUoYXgsIGF5LCBieCwgYnksIGN4LCBjeSwgcHgsIHB5KSB7CiAgY29uc3QgZHggPSBheCAtIHB4OwogIGNvbnN0IGR5ID0gYXkgLSBweTsKICBjb25zdCBleCA9IGJ4IC0gcHg7CiAgY29uc3QgZXkgPSBieSAtIHB5OwogIGNvbnN0IGZ4ID0gY3ggLSBweDsKICBjb25zdCBmeSA9IGN5IC0gcHk7CiAgY29uc3QgYXAgPSBkeCAqIGR4ICsgZHkgKiBkeTsKICBjb25zdCBicCA9IGV4ICogZXggKyBleSAqIGV5OwogIGNvbnN0IGNwID0gZnggKiBmeCArIGZ5ICogZnk7CiAgcmV0dXJuIGR4ICogKGV5ICogY3AgLSBicCAqIGZ5KSAtIGR5ICogKGV4ICogY3AgLSBicCAqIGZ4KSArIGFwICogKGV4ICogZnkgLSBleSAqIGZ4KSA8IDA7Cn0KZnVuY3Rpb24gY2lyY3VtcmFkaXVzKGF4LCBheSwgYngsIGJ5LCBjeCwgY3kpIHsKICBjb25zdCBkeCA9IGJ4IC0gYXg7CiAgY29uc3QgZHkgPSBieSAtIGF5OwogIGNvbnN0IGV4ID0gY3ggLSBheDsKICBjb25zdCBleSA9IGN5IC0gYXk7CiAgY29uc3QgYmwgPSBkeCAqIGR4ICsgZHkgKiBkeTsKICBjb25zdCBjbCA9IGV4ICogZXggKyBleSAqIGV5OwogIGNvbnN0IGQgPSAwLjUgLyAoZHggKiBleSAtIGR5ICogZXgpOwogIGNvbnN0IHggPSAoZXkgKiBibCAtIGR5ICogY2wpICogZDsKICBjb25zdCB5ID0gKGR4ICogY2wgLSBleCAqIGJsKSAqIGQ7CiAgcmV0dXJuIHggKiB4ICsgeSAqIHk7Cn0KZnVuY3Rpb24gY2lyY3VtY2VudGVyKGF4LCBheSwgYngsIGJ5LCBjeCwgY3kpIHsKICBjb25zdCBkeCA9IGJ4IC0gYXg7CiAgY29uc3QgZHkgPSBieSAtIGF5OwogIGNvbnN0IGV4ID0gY3ggLSBheDsKICBjb25zdCBleSA9IGN5IC0gYXk7CiAgY29uc3QgYmwgPSBkeCAqIGR4ICsgZHkgKiBkeTsKICBjb25zdCBjbCA9IGV4ICogZXggKyBleSAqIGV5OwogIGNvbnN0IGQgPSAwLjUgLyAoZHggKiBleSAtIGR5ICogZXgpOwogIGNvbnN0IHggPSBheCArIChleSAqIGJsIC0gZHkgKiBjbCkgKiBkOwogIGNvbnN0IHkgPSBheSArIChkeCAqIGNsIC0gZXggKiBibCkgKiBkOwogIHJldHVybiB7CiAgICB4LAogICAgeQogIH07Cn0KZnVuY3Rpb24gcXVpY2tzb3J0KGlkcywgZGlzdHMsIGxlZnQsIHJpZ2h0KSB7CiAgaWYgKHJpZ2h0IC0gbGVmdCA8PSAyMCkgewogICAgZm9yIChsZXQgaSA9IGxlZnQgKyAxOyBpIDw9IHJpZ2h0OyBpKyspIHsKICAgICAgY29uc3QgdGVtcCA9IGlkc1tpXTsKICAgICAgY29uc3QgdGVtcERpc3QgPSBkaXN0c1t0ZW1wXTsKICAgICAgbGV0IGogPSBpIC0gMTsKICAgICAgd2hpbGUgKGogPj0gbGVmdCAmJiBkaXN0c1tpZHNbal1dID4gdGVtcERpc3QpIGlkc1tqICsgMV0gPSBpZHNbai0tXTsKICAgICAgaWRzW2ogKyAxXSA9IHRlbXA7CiAgICB9CiAgfSBlbHNlIHsKICAgIGNvbnN0IG1lZGlhbiA9IGxlZnQgKyByaWdodCA+PiAxOwogICAgbGV0IGkgPSBsZWZ0ICsgMTsKICAgIGxldCBqID0gcmlnaHQ7CiAgICBzd2FwKGlkcywgbWVkaWFuLCBpKTsKICAgIGlmIChkaXN0c1tpZHNbbGVmdF1dID4gZGlzdHNbaWRzW3JpZ2h0XV0pIHN3YXAoaWRzLCBsZWZ0LCByaWdodCk7CiAgICBpZiAoZGlzdHNbaWRzW2ldXSA+IGRpc3RzW2lkc1tyaWdodF1dKSBzd2FwKGlkcywgaSwgcmlnaHQpOwogICAgaWYgKGRpc3RzW2lkc1tsZWZ0XV0gPiBkaXN0c1tpZHNbaV1dKSBzd2FwKGlkcywgbGVmdCwgaSk7CiAgICBjb25zdCB0ZW1wID0gaWRzW2ldOwogICAgY29uc3QgdGVtcERpc3QgPSBkaXN0c1t0ZW1wXTsKICAgIHdoaWxlICh0cnVlKSB7CiAgICAgIGRvIGkrKzsgd2hpbGUgKGRpc3RzW2lkc1tpXV0gPCB0ZW1wRGlzdCk7CiAgICAgIGRvIGotLTsgd2hpbGUgKGRpc3RzW2lkc1tqXV0gPiB0ZW1wRGlzdCk7CiAgICAgIGlmIChqIDwgaSkgYnJlYWs7CiAgICAgIHN3YXAoaWRzLCBpLCBqKTsKICAgIH0KICAgIGlkc1tsZWZ0ICsgMV0gPSBpZHNbal07CiAgICBpZHNbal0gPSB0ZW1wOwogICAgaWYgKHJpZ2h0IC0gaSArIDEgPj0gaiAtIGxlZnQpIHsKICAgICAgcXVpY2tzb3J0KGlkcywgZGlzdHMsIGksIHJpZ2h0KTsKICAgICAgcXVpY2tzb3J0KGlkcywgZGlzdHMsIGxlZnQsIGogLSAxKTsKICAgIH0gZWxzZSB7CiAgICAgIHF1aWNrc29ydChpZHMsIGRpc3RzLCBsZWZ0LCBqIC0gMSk7CiAgICAgIHF1aWNrc29ydChpZHMsIGRpc3RzLCBpLCByaWdodCk7CiAgICB9CiAgfQp9CmZ1bmN0aW9uIHN3YXAoYXJyLCBpLCBqKSB7CiAgY29uc3QgdG1wID0gYXJyW2ldOwogIGFycltpXSA9IGFycltqXTsKICBhcnJbal0gPSB0bXA7Cn0KZnVuY3Rpb24gZGVmYXVsdEdldFgocCkgewogIHJldHVybiBwWzBdOwp9CmZ1bmN0aW9uIGRlZmF1bHRHZXRZKHApIHsKICByZXR1cm4gcFsxXTsKfQoKY29uc3QgZXBzaWxvbiA9IDFlLTY7CmNsYXNzIFBhdGggewogIGNvbnN0cnVjdG9yKCkgewogICAgdGhpcy5feDAgPSB0aGlzLl95MCA9CiAgICAvLyBzdGFydCBvZiBjdXJyZW50IHN1YnBhdGgKICAgIHRoaXMuX3gxID0gdGhpcy5feTEgPSBudWxsOyAvLyBlbmQgb2YgY3VycmVudCBzdWJwYXRoCiAgICB0aGlzLl8gPSAiIjsKICB9CiAgbW92ZVRvKHgsIHkpIHsKICAgIHRoaXMuXyArPSBgTSR7dGhpcy5feDAgPSB0aGlzLl94MSA9ICt4fSwke3RoaXMuX3kwID0gdGhpcy5feTEgPSAreX1gOwogIH0KICBjbG9zZVBhdGgoKSB7CiAgICBpZiAodGhpcy5feDEgIT09IG51bGwpIHsKICAgICAgdGhpcy5feDEgPSB0aGlzLl94MCwgdGhpcy5feTEgPSB0aGlzLl95MDsKICAgICAgdGhpcy5fICs9ICJaIjsKICAgIH0KICB9CiAgbGluZVRvKHgsIHkpIHsKICAgIHRoaXMuXyArPSBgTCR7dGhpcy5feDEgPSAreH0sJHt0aGlzLl95MSA9ICt5fWA7CiAgfQogIGFyYyh4LCB5LCByKSB7CiAgICB4ID0gK3gsIHkgPSAreSwgciA9ICtyOwogICAgY29uc3QgeDAgPSB4ICsgcjsKICAgIGNvbnN0IHkwID0geTsKICAgIGlmIChyIDwgMCkgdGhyb3cgbmV3IEVycm9yKCJuZWdhdGl2ZSByYWRpdXMiKTsKICAgIGlmICh0aGlzLl94MSA9PT0gbnVsbCkgdGhpcy5fICs9IGBNJHt4MH0sJHt5MH1gO2Vsc2UgaWYgKE1hdGguYWJzKHRoaXMuX3gxIC0geDApID4gZXBzaWxvbiB8fCBNYXRoLmFicyh0aGlzLl95MSAtIHkwKSA+IGVwc2lsb24pIHRoaXMuXyArPSAiTCIgKyB4MCArICIsIiArIHkwOwogICAgaWYgKCFyKSByZXR1cm47CiAgICB0aGlzLl8gKz0gYEEke3J9LCR7cn0sMCwxLDEsJHt4IC0gcn0sJHt5fUEke3J9LCR7cn0sMCwxLDEsJHt0aGlzLl94MSA9IHgwfSwke3RoaXMuX3kxID0geTB9YDsKICB9CiAgcmVjdCh4LCB5LCB3LCBoKSB7CiAgICB0aGlzLl8gKz0gYE0ke3RoaXMuX3gwID0gdGhpcy5feDEgPSAreH0sJHt0aGlzLl95MCA9IHRoaXMuX3kxID0gK3l9aCR7K3d9diR7K2h9aCR7LXd9WmA7CiAgfQogIHZhbHVlKCkgewogICAgcmV0dXJuIHRoaXMuXyB8fCBudWxsOwogIH0KfQoKY2xhc3MgUG9seWdvbiB7CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLl8gPSBbXTsKICB9CiAgbW92ZVRvKHgsIHkpIHsKICAgIHRoaXMuXy5wdXNoKFt4LCB5XSk7CiAgfQogIGNsb3NlUGF0aCgpIHsKICAgIHRoaXMuXy5wdXNoKHRoaXMuX1swXS5zbGljZSgpKTsKICB9CiAgbGluZVRvKHgsIHkpIHsKICAgIHRoaXMuXy5wdXNoKFt4LCB5XSk7CiAgfQogIHZhbHVlKCkgewogICAgcmV0dXJuIHRoaXMuXy5sZW5ndGggPyB0aGlzLl8gOiBudWxsOwogIH0KfQoKY2xhc3MgVm9yb25vaSB7CiAgY29uc3RydWN0b3IoZGVsYXVuYXksIFt4bWluLCB5bWluLCB4bWF4LCB5bWF4XSA9IFswLCAwLCA5NjAsIDUwMF0pIHsKICAgIGlmICghKCh4bWF4ID0gK3htYXgpID49ICh4bWluID0gK3htaW4pKSB8fCAhKCh5bWF4ID0gK3ltYXgpID49ICh5bWluID0gK3ltaW4pKSkgdGhyb3cgbmV3IEVycm9yKCJpbnZhbGlkIGJvdW5kcyIpOwogICAgdGhpcy5kZWxhdW5heSA9IGRlbGF1bmF5OwogICAgdGhpcy5fY2lyY3VtY2VudGVycyA9IG5ldyBGbG9hdDY0QXJyYXkoZGVsYXVuYXkucG9pbnRzLmxlbmd0aCAqIDIpOwogICAgdGhpcy52ZWN0b3JzID0gbmV3IEZsb2F0NjRBcnJheShkZWxhdW5heS5wb2ludHMubGVuZ3RoICogMik7CiAgICB0aGlzLnhtYXggPSB4bWF4LCB0aGlzLnhtaW4gPSB4bWluOwogICAgdGhpcy55bWF4ID0geW1heCwgdGhpcy55bWluID0geW1pbjsKICAgIHRoaXMuX2luaXQoKTsKICB9CiAgdXBkYXRlKCkgewogICAgdGhpcy5kZWxhdW5heS51cGRhdGUoKTsKICAgIHRoaXMuX2luaXQoKTsKICAgIHJldHVybiB0aGlzOwogIH0KICBfaW5pdCgpIHsKICAgIGNvbnN0IHsKICAgICAgZGVsYXVuYXk6IHsKICAgICAgICBwb2ludHMsCiAgICAgICAgaHVsbCwKICAgICAgICB0cmlhbmdsZXMKICAgICAgfSwKICAgICAgdmVjdG9ycwogICAgfSA9IHRoaXM7CiAgICBsZXQgYngsIGJ5OyAvLyBsYXppbHkgY29tcHV0ZWQgYmFyeWNlbnRlciBvZiB0aGUgaHVsbAoKICAgIC8vIENvbXB1dGUgY2lyY3VtY2VudGVycy4KICAgIGNvbnN0IGNpcmN1bWNlbnRlcnMgPSB0aGlzLmNpcmN1bWNlbnRlcnMgPSB0aGlzLl9jaXJjdW1jZW50ZXJzLnN1YmFycmF5KDAsIHRyaWFuZ2xlcy5sZW5ndGggLyAzICogMik7CiAgICBmb3IgKGxldCBpID0gMCwgaiA9IDAsIG4gPSB0cmlhbmdsZXMubGVuZ3RoLCB4LCB5OyBpIDwgbjsgaSArPSAzLCBqICs9IDIpIHsKICAgICAgY29uc3QgdDEgPSB0cmlhbmdsZXNbaV0gKiAyOwogICAgICBjb25zdCB0MiA9IHRyaWFuZ2xlc1tpICsgMV0gKiAyOwogICAgICBjb25zdCB0MyA9IHRyaWFuZ2xlc1tpICsgMl0gKiAyOwogICAgICBjb25zdCB4MSA9IHBvaW50c1t0MV07CiAgICAgIGNvbnN0IHkxID0gcG9pbnRzW3QxICsgMV07CiAgICAgIGNvbnN0IHgyID0gcG9pbnRzW3QyXTsKICAgICAgY29uc3QgeTIgPSBwb2ludHNbdDIgKyAxXTsKICAgICAgY29uc3QgeDMgPSBwb2ludHNbdDNdOwogICAgICBjb25zdCB5MyA9IHBvaW50c1t0MyArIDFdOwogICAgICBjb25zdCBkeCA9IHgyIC0geDE7CiAgICAgIGNvbnN0IGR5ID0geTIgLSB5MTsKICAgICAgY29uc3QgZXggPSB4MyAtIHgxOwogICAgICBjb25zdCBleSA9IHkzIC0geTE7CiAgICAgIGNvbnN0IGFiID0gKGR4ICogZXkgLSBkeSAqIGV4KSAqIDI7CiAgICAgIGlmIChNYXRoLmFicyhhYikgPCAxZS05KSB7CiAgICAgICAgLy8gRm9yIGEgZGVnZW5lcmF0ZSB0cmlhbmdsZSwgdGhlIGNpcmN1bWNlbnRlciBpcyBhdCB0aGUgaW5maW5pdHksIGluIGEKICAgICAgICAvLyBkaXJlY3Rpb24gb3J0aG9nb25hbCB0byB0aGUgaGFsZmVkZ2UgYW5kIGF3YXkgZnJvbSB0aGUg4oCcY2VudGVy4oCdIG9mCiAgICAgICAgLy8gdGhlIGRpYWdyYW0gPGJ4LCBieT4sIGRlZmluZWQgYXMgdGhlIGh1bGzigJlzIGJhcnljZW50ZXIuCiAgICAgICAgaWYgKGJ4ID09PSB1bmRlZmluZWQpIHsKICAgICAgICAgIGJ4ID0gYnkgPSAwOwogICAgICAgICAgZm9yIChjb25zdCBpIG9mIGh1bGwpIGJ4ICs9IHBvaW50c1tpICogMl0sIGJ5ICs9IHBvaW50c1tpICogMiArIDFdOwogICAgICAgICAgYnggLz0gaHVsbC5sZW5ndGgsIGJ5IC89IGh1bGwubGVuZ3RoOwogICAgICAgIH0KICAgICAgICBjb25zdCBhID0gMWU5ICogTWF0aC5zaWduKChieCAtIHgxKSAqIGV5IC0gKGJ5IC0geTEpICogZXgpOwogICAgICAgIHggPSAoeDEgKyB4MykgLyAyIC0gYSAqIGV5OwogICAgICAgIHkgPSAoeTEgKyB5MykgLyAyICsgYSAqIGV4OwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IGQgPSAxIC8gYWI7CiAgICAgICAgY29uc3QgYmwgPSBkeCAqIGR4ICsgZHkgKiBkeTsKICAgICAgICBjb25zdCBjbCA9IGV4ICogZXggKyBleSAqIGV5OwogICAgICAgIHggPSB4MSArIChleSAqIGJsIC0gZHkgKiBjbCkgKiBkOwogICAgICAgIHkgPSB5MSArIChkeCAqIGNsIC0gZXggKiBibCkgKiBkOwogICAgICB9CiAgICAgIGNpcmN1bWNlbnRlcnNbal0gPSB4OwogICAgICBjaXJjdW1jZW50ZXJzW2ogKyAxXSA9IHk7CiAgICB9CgogICAgLy8gQ29tcHV0ZSBleHRlcmlvciBjZWxsIHJheXMuCiAgICBsZXQgaCA9IGh1bGxbaHVsbC5sZW5ndGggLSAxXTsKICAgIGxldCBwMCwKICAgICAgcDEgPSBoICogNDsKICAgIGxldCB4MCwKICAgICAgeDEgPSBwb2ludHNbMiAqIGhdOwogICAgbGV0IHkwLAogICAgICB5MSA9IHBvaW50c1syICogaCArIDFdOwogICAgdmVjdG9ycy5maWxsKDApOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBodWxsLmxlbmd0aDsgKytpKSB7CiAgICAgIGggPSBodWxsW2ldOwogICAgICBwMCA9IHAxLCB4MCA9IHgxLCB5MCA9IHkxOwogICAgICBwMSA9IGggKiA0LCB4MSA9IHBvaW50c1syICogaF0sIHkxID0gcG9pbnRzWzIgKiBoICsgMV07CiAgICAgIHZlY3RvcnNbcDAgKyAyXSA9IHZlY3RvcnNbcDFdID0geTAgLSB5MTsKICAgICAgdmVjdG9yc1twMCArIDNdID0gdmVjdG9yc1twMSArIDFdID0geDEgLSB4MDsKICAgIH0KICB9CiAgcmVuZGVyKGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgewogICAgICBkZWxhdW5heTogewogICAgICAgIGhhbGZlZGdlcywKICAgICAgICBpbmVkZ2VzLAogICAgICAgIGh1bGwKICAgICAgfSwKICAgICAgY2lyY3VtY2VudGVycywKICAgICAgdmVjdG9ycwogICAgfSA9IHRoaXM7CiAgICBpZiAoaHVsbC5sZW5ndGggPD0gMSkgcmV0dXJuIG51bGw7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IGhhbGZlZGdlcy5sZW5ndGg7IGkgPCBuOyArK2kpIHsKICAgICAgY29uc3QgaiA9IGhhbGZlZGdlc1tpXTsKICAgICAgaWYgKGogPCBpKSBjb250aW51ZTsKICAgICAgY29uc3QgdGkgPSBNYXRoLmZsb29yKGkgLyAzKSAqIDI7CiAgICAgIGNvbnN0IHRqID0gTWF0aC5mbG9vcihqIC8gMykgKiAyOwogICAgICBjb25zdCB4aSA9IGNpcmN1bWNlbnRlcnNbdGldOwogICAgICBjb25zdCB5aSA9IGNpcmN1bWNlbnRlcnNbdGkgKyAxXTsKICAgICAgY29uc3QgeGogPSBjaXJjdW1jZW50ZXJzW3RqXTsKICAgICAgY29uc3QgeWogPSBjaXJjdW1jZW50ZXJzW3RqICsgMV07CiAgICAgIHRoaXMuX3JlbmRlclNlZ21lbnQoeGksIHlpLCB4aiwgeWosIGNvbnRleHQpOwogICAgfQogICAgbGV0IGgwLAogICAgICBoMSA9IGh1bGxbaHVsbC5sZW5ndGggLSAxXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaHVsbC5sZW5ndGg7ICsraSkgewogICAgICBoMCA9IGgxLCBoMSA9IGh1bGxbaV07CiAgICAgIGNvbnN0IHQgPSBNYXRoLmZsb29yKGluZWRnZXNbaDFdIC8gMykgKiAyOwogICAgICBjb25zdCB4ID0gY2lyY3VtY2VudGVyc1t0XTsKICAgICAgY29uc3QgeSA9IGNpcmN1bWNlbnRlcnNbdCArIDFdOwogICAgICBjb25zdCB2ID0gaDAgKiA0OwogICAgICBjb25zdCBwID0gdGhpcy5fcHJvamVjdCh4LCB5LCB2ZWN0b3JzW3YgKyAyXSwgdmVjdG9yc1t2ICsgM10pOwogICAgICBpZiAocCkgdGhpcy5fcmVuZGVyU2VnbWVudCh4LCB5LCBwWzBdLCBwWzFdLCBjb250ZXh0KTsKICAgIH0KICAgIHJldHVybiBidWZmZXIgJiYgYnVmZmVyLnZhbHVlKCk7CiAgfQogIHJlbmRlckJvdW5kcyhjb250ZXh0KSB7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnRleHQucmVjdCh0aGlzLnhtaW4sIHRoaXMueW1pbiwgdGhpcy54bWF4IC0gdGhpcy54bWluLCB0aGlzLnltYXggLSB0aGlzLnltaW4pOwogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgcmVuZGVyQ2VsbChpLCBjb250ZXh0KSB7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IHBvaW50cyA9IHRoaXMuX2NsaXAoaSk7CiAgICBpZiAocG9pbnRzID09PSBudWxsIHx8ICFwb2ludHMubGVuZ3RoKSByZXR1cm47CiAgICBjb250ZXh0Lm1vdmVUbyhwb2ludHNbMF0sIHBvaW50c1sxXSk7CiAgICBsZXQgbiA9IHBvaW50cy5sZW5ndGg7CiAgICB3aGlsZSAocG9pbnRzWzBdID09PSBwb2ludHNbbiAtIDJdICYmIHBvaW50c1sxXSA9PT0gcG9pbnRzW24gLSAxXSAmJiBuID4gMSkgbiAtPSAyOwogICAgZm9yIChsZXQgaSA9IDI7IGkgPCBuOyBpICs9IDIpIHsKICAgICAgaWYgKHBvaW50c1tpXSAhPT0gcG9pbnRzW2kgLSAyXSB8fCBwb2ludHNbaSArIDFdICE9PSBwb2ludHNbaSAtIDFdKSBjb250ZXh0LmxpbmVUbyhwb2ludHNbaV0sIHBvaW50c1tpICsgMV0pOwogICAgfQogICAgY29udGV4dC5jbG9zZVBhdGgoKTsKICAgIHJldHVybiBidWZmZXIgJiYgYnVmZmVyLnZhbHVlKCk7CiAgfQogICpjZWxsUG9seWdvbnMoKSB7CiAgICBjb25zdCB7CiAgICAgIGRlbGF1bmF5OiB7CiAgICAgICAgcG9pbnRzCiAgICAgIH0KICAgIH0gPSB0aGlzOwogICAgZm9yIChsZXQgaSA9IDAsIG4gPSBwb2ludHMubGVuZ3RoIC8gMjsgaSA8IG47ICsraSkgewogICAgICBjb25zdCBjZWxsID0gdGhpcy5jZWxsUG9seWdvbihpKTsKICAgICAgaWYgKGNlbGwpIGNlbGwuaW5kZXggPSBpLCB5aWVsZCBjZWxsOwogICAgfQogIH0KICBjZWxsUG9seWdvbihpKSB7CiAgICBjb25zdCBwb2x5Z29uID0gbmV3IFBvbHlnb24oKTsKICAgIHRoaXMucmVuZGVyQ2VsbChpLCBwb2x5Z29uKTsKICAgIHJldHVybiBwb2x5Z29uLnZhbHVlKCk7CiAgfQogIF9yZW5kZXJTZWdtZW50KHgwLCB5MCwgeDEsIHkxLCBjb250ZXh0KSB7CiAgICBsZXQgUzsKICAgIGNvbnN0IGMwID0gdGhpcy5fcmVnaW9uY29kZSh4MCwgeTApOwogICAgY29uc3QgYzEgPSB0aGlzLl9yZWdpb25jb2RlKHgxLCB5MSk7CiAgICBpZiAoYzAgPT09IDAgJiYgYzEgPT09IDApIHsKICAgICAgY29udGV4dC5tb3ZlVG8oeDAsIHkwKTsKICAgICAgY29udGV4dC5saW5lVG8oeDEsIHkxKTsKICAgIH0gZWxzZSBpZiAoUyA9IHRoaXMuX2NsaXBTZWdtZW50KHgwLCB5MCwgeDEsIHkxLCBjMCwgYzEpKSB7CiAgICAgIGNvbnRleHQubW92ZVRvKFNbMF0sIFNbMV0pOwogICAgICBjb250ZXh0LmxpbmVUbyhTWzJdLCBTWzNdKTsKICAgIH0KICB9CiAgY29udGFpbnMoaSwgeCwgeSkgewogICAgaWYgKCh4ID0gK3gsIHggIT09IHgpIHx8ICh5ID0gK3ksIHkgIT09IHkpKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdGhpcy5kZWxhdW5heS5fc3RlcChpLCB4LCB5KSA9PT0gaTsKICB9CiAgKm5laWdoYm9ycyhpKSB7CiAgICBjb25zdCBjaSA9IHRoaXMuX2NsaXAoaSk7CiAgICBpZiAoY2kpIGZvciAoY29uc3QgaiBvZiB0aGlzLmRlbGF1bmF5Lm5laWdoYm9ycyhpKSkgewogICAgICBjb25zdCBjaiA9IHRoaXMuX2NsaXAoaik7CiAgICAgIC8vIGZpbmQgdGhlIGNvbW1vbiBlZGdlCiAgICAgIGlmIChjaikgbG9vcDogZm9yIChsZXQgYWkgPSAwLCBsaSA9IGNpLmxlbmd0aDsgYWkgPCBsaTsgYWkgKz0gMikgewogICAgICAgIGZvciAobGV0IGFqID0gMCwgbGogPSBjai5sZW5ndGg7IGFqIDwgbGo7IGFqICs9IDIpIHsKICAgICAgICAgIGlmIChjaVthaV0gPT09IGNqW2FqXSAmJiBjaVthaSArIDFdID09PSBjalthaiArIDFdICYmIGNpWyhhaSArIDIpICUgbGldID09PSBjalsoYWogKyBsaiAtIDIpICUgbGpdICYmIGNpWyhhaSArIDMpICUgbGldID09PSBjalsoYWogKyBsaiAtIDEpICUgbGpdKSB7CiAgICAgICAgICAgIHlpZWxkIGo7CiAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIF9jZWxsKGkpIHsKICAgIGNvbnN0IHsKICAgICAgY2lyY3VtY2VudGVycywKICAgICAgZGVsYXVuYXk6IHsKICAgICAgICBpbmVkZ2VzLAogICAgICAgIGhhbGZlZGdlcywKICAgICAgICB0cmlhbmdsZXMKICAgICAgfQogICAgfSA9IHRoaXM7CiAgICBjb25zdCBlMCA9IGluZWRnZXNbaV07CiAgICBpZiAoZTAgPT09IC0xKSByZXR1cm4gbnVsbDsgLy8gY29pbmNpZGVudCBwb2ludAogICAgY29uc3QgcG9pbnRzID0gW107CiAgICBsZXQgZSA9IGUwOwogICAgZG8gewogICAgICBjb25zdCB0ID0gTWF0aC5mbG9vcihlIC8gMyk7CiAgICAgIHBvaW50cy5wdXNoKGNpcmN1bWNlbnRlcnNbdCAqIDJdLCBjaXJjdW1jZW50ZXJzW3QgKiAyICsgMV0pOwogICAgICBlID0gZSAlIDMgPT09IDIgPyBlIC0gMiA6IGUgKyAxOwogICAgICBpZiAodHJpYW5nbGVzW2VdICE9PSBpKSBicmVhazsgLy8gYmFkIHRyaWFuZ3VsYXRpb24KICAgICAgZSA9IGhhbGZlZGdlc1tlXTsKICAgIH0gd2hpbGUgKGUgIT09IGUwICYmIGUgIT09IC0xKTsKICAgIHJldHVybiBwb2ludHM7CiAgfQogIF9jbGlwKGkpIHsKICAgIC8vIGRlZ2VuZXJhdGUgY2FzZSAoMSB2YWxpZCBwb2ludDogcmV0dXJuIHRoZSBib3gpCiAgICBpZiAoaSA9PT0gMCAmJiB0aGlzLmRlbGF1bmF5Lmh1bGwubGVuZ3RoID09PSAxKSB7CiAgICAgIHJldHVybiBbdGhpcy54bWF4LCB0aGlzLnltaW4sIHRoaXMueG1heCwgdGhpcy55bWF4LCB0aGlzLnhtaW4sIHRoaXMueW1heCwgdGhpcy54bWluLCB0aGlzLnltaW5dOwogICAgfQogICAgY29uc3QgcG9pbnRzID0gdGhpcy5fY2VsbChpKTsKICAgIGlmIChwb2ludHMgPT09IG51bGwpIHJldHVybiBudWxsOwogICAgY29uc3QgewogICAgICB2ZWN0b3JzOiBWCiAgICB9ID0gdGhpczsKICAgIGNvbnN0IHYgPSBpICogNDsKICAgIHJldHVybiB0aGlzLl9zaW1wbGlmeShWW3ZdIHx8IFZbdiArIDFdID8gdGhpcy5fY2xpcEluZmluaXRlKGksIHBvaW50cywgVlt2XSwgVlt2ICsgMV0sIFZbdiArIDJdLCBWW3YgKyAzXSkgOiB0aGlzLl9jbGlwRmluaXRlKGksIHBvaW50cykpOwogIH0KICBfY2xpcEZpbml0ZShpLCBwb2ludHMpIHsKICAgIGNvbnN0IG4gPSBwb2ludHMubGVuZ3RoOwogICAgbGV0IFAgPSBudWxsOwogICAgbGV0IHgwLAogICAgICB5MCwKICAgICAgeDEgPSBwb2ludHNbbiAtIDJdLAogICAgICB5MSA9IHBvaW50c1tuIC0gMV07CiAgICBsZXQgYzAsCiAgICAgIGMxID0gdGhpcy5fcmVnaW9uY29kZSh4MSwgeTEpOwogICAgbGV0IGUwLAogICAgICBlMSA9IDA7CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGogKz0gMikgewogICAgICB4MCA9IHgxLCB5MCA9IHkxLCB4MSA9IHBvaW50c1tqXSwgeTEgPSBwb2ludHNbaiArIDFdOwogICAgICBjMCA9IGMxLCBjMSA9IHRoaXMuX3JlZ2lvbmNvZGUoeDEsIHkxKTsKICAgICAgaWYgKGMwID09PSAwICYmIGMxID09PSAwKSB7CiAgICAgICAgZTAgPSBlMSwgZTEgPSAwOwogICAgICAgIGlmIChQKSBQLnB1c2goeDEsIHkxKTtlbHNlIFAgPSBbeDEsIHkxXTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsZXQgUywgc3gwLCBzeTAsIHN4MSwgc3kxOwogICAgICAgIGlmIChjMCA9PT0gMCkgewogICAgICAgICAgaWYgKChTID0gdGhpcy5fY2xpcFNlZ21lbnQoeDAsIHkwLCB4MSwgeTEsIGMwLCBjMSkpID09PSBudWxsKSBjb250aW51ZTsKICAgICAgICAgIFtzeDAsIHN5MCwgc3gxLCBzeTFdID0gUzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKChTID0gdGhpcy5fY2xpcFNlZ21lbnQoeDEsIHkxLCB4MCwgeTAsIGMxLCBjMCkpID09PSBudWxsKSBjb250aW51ZTsKICAgICAgICAgIFtzeDEsIHN5MSwgc3gwLCBzeTBdID0gUzsKICAgICAgICAgIGUwID0gZTEsIGUxID0gdGhpcy5fZWRnZWNvZGUoc3gwLCBzeTApOwogICAgICAgICAgaWYgKGUwICYmIGUxKSB0aGlzLl9lZGdlKGksIGUwLCBlMSwgUCwgUC5sZW5ndGgpOwogICAgICAgICAgaWYgKFApIFAucHVzaChzeDAsIHN5MCk7ZWxzZSBQID0gW3N4MCwgc3kwXTsKICAgICAgICB9CiAgICAgICAgZTAgPSBlMSwgZTEgPSB0aGlzLl9lZGdlY29kZShzeDEsIHN5MSk7CiAgICAgICAgaWYgKGUwICYmIGUxKSB0aGlzLl9lZGdlKGksIGUwLCBlMSwgUCwgUC5sZW5ndGgpOwogICAgICAgIGlmIChQKSBQLnB1c2goc3gxLCBzeTEpO2Vsc2UgUCA9IFtzeDEsIHN5MV07CiAgICAgIH0KICAgIH0KICAgIGlmIChQKSB7CiAgICAgIGUwID0gZTEsIGUxID0gdGhpcy5fZWRnZWNvZGUoUFswXSwgUFsxXSk7CiAgICAgIGlmIChlMCAmJiBlMSkgdGhpcy5fZWRnZShpLCBlMCwgZTEsIFAsIFAubGVuZ3RoKTsKICAgIH0gZWxzZSBpZiAodGhpcy5jb250YWlucyhpLCAodGhpcy54bWluICsgdGhpcy54bWF4KSAvIDIsICh0aGlzLnltaW4gKyB0aGlzLnltYXgpIC8gMikpIHsKICAgICAgcmV0dXJuIFt0aGlzLnhtYXgsIHRoaXMueW1pbiwgdGhpcy54bWF4LCB0aGlzLnltYXgsIHRoaXMueG1pbiwgdGhpcy55bWF4LCB0aGlzLnhtaW4sIHRoaXMueW1pbl07CiAgICB9CiAgICByZXR1cm4gUDsKICB9CiAgX2NsaXBTZWdtZW50KHgwLCB5MCwgeDEsIHkxLCBjMCwgYzEpIHsKICAgIC8vIGZvciBtb3JlIHJvYnVzdG5lc3MsIGFsd2F5cyBjb25zaWRlciB0aGUgc2VnbWVudCBpbiB0aGUgc2FtZSBvcmRlcgogICAgY29uc3QgZmxpcCA9IGMwIDwgYzE7CiAgICBpZiAoZmxpcCkgW3gwLCB5MCwgeDEsIHkxLCBjMCwgYzFdID0gW3gxLCB5MSwgeDAsIHkwLCBjMSwgYzBdOwogICAgd2hpbGUgKHRydWUpIHsKICAgICAgaWYgKGMwID09PSAwICYmIGMxID09PSAwKSByZXR1cm4gZmxpcCA/IFt4MSwgeTEsIHgwLCB5MF0gOiBbeDAsIHkwLCB4MSwgeTFdOwogICAgICBpZiAoYzAgJiBjMSkgcmV0dXJuIG51bGw7CiAgICAgIGxldCB4LAogICAgICAgIHksCiAgICAgICAgYyA9IGMwIHx8IGMxOwogICAgICBpZiAoYyAmIDBiMTAwMCkgeCA9IHgwICsgKHgxIC0geDApICogKHRoaXMueW1heCAtIHkwKSAvICh5MSAtIHkwKSwgeSA9IHRoaXMueW1heDtlbHNlIGlmIChjICYgMGIwMTAwKSB4ID0geDAgKyAoeDEgLSB4MCkgKiAodGhpcy55bWluIC0geTApIC8gKHkxIC0geTApLCB5ID0gdGhpcy55bWluO2Vsc2UgaWYgKGMgJiAwYjAwMTApIHkgPSB5MCArICh5MSAtIHkwKSAqICh0aGlzLnhtYXggLSB4MCkgLyAoeDEgLSB4MCksIHggPSB0aGlzLnhtYXg7ZWxzZSB5ID0geTAgKyAoeTEgLSB5MCkgKiAodGhpcy54bWluIC0geDApIC8gKHgxIC0geDApLCB4ID0gdGhpcy54bWluOwogICAgICBpZiAoYzApIHgwID0geCwgeTAgPSB5LCBjMCA9IHRoaXMuX3JlZ2lvbmNvZGUoeDAsIHkwKTtlbHNlIHgxID0geCwgeTEgPSB5LCBjMSA9IHRoaXMuX3JlZ2lvbmNvZGUoeDEsIHkxKTsKICAgIH0KICB9CiAgX2NsaXBJbmZpbml0ZShpLCBwb2ludHMsIHZ4MCwgdnkwLCB2eG4sIHZ5bikgewogICAgbGV0IFAgPSBBcnJheS5mcm9tKHBvaW50cyksCiAgICAgIHA7CiAgICBpZiAocCA9IHRoaXMuX3Byb2plY3QoUFswXSwgUFsxXSwgdngwLCB2eTApKSBQLnVuc2hpZnQocFswXSwgcFsxXSk7CiAgICBpZiAocCA9IHRoaXMuX3Byb2plY3QoUFtQLmxlbmd0aCAtIDJdLCBQW1AubGVuZ3RoIC0gMV0sIHZ4biwgdnluKSkgUC5wdXNoKHBbMF0sIHBbMV0pOwogICAgaWYgKFAgPSB0aGlzLl9jbGlwRmluaXRlKGksIFApKSB7CiAgICAgIGZvciAobGV0IGogPSAwLCBuID0gUC5sZW5ndGgsIGMwLCBjMSA9IHRoaXMuX2VkZ2Vjb2RlKFBbbiAtIDJdLCBQW24gLSAxXSk7IGogPCBuOyBqICs9IDIpIHsKICAgICAgICBjMCA9IGMxLCBjMSA9IHRoaXMuX2VkZ2Vjb2RlKFBbal0sIFBbaiArIDFdKTsKICAgICAgICBpZiAoYzAgJiYgYzEpIGogPSB0aGlzLl9lZGdlKGksIGMwLCBjMSwgUCwgaiksIG4gPSBQLmxlbmd0aDsKICAgICAgfQogICAgfSBlbHNlIGlmICh0aGlzLmNvbnRhaW5zKGksICh0aGlzLnhtaW4gKyB0aGlzLnhtYXgpIC8gMiwgKHRoaXMueW1pbiArIHRoaXMueW1heCkgLyAyKSkgewogICAgICBQID0gW3RoaXMueG1pbiwgdGhpcy55bWluLCB0aGlzLnhtYXgsIHRoaXMueW1pbiwgdGhpcy54bWF4LCB0aGlzLnltYXgsIHRoaXMueG1pbiwgdGhpcy55bWF4XTsKICAgIH0KICAgIHJldHVybiBQOwogIH0KICBfZWRnZShpLCBlMCwgZTEsIFAsIGopIHsKICAgIHdoaWxlIChlMCAhPT0gZTEpIHsKICAgICAgbGV0IHgsIHk7CiAgICAgIHN3aXRjaCAoZTApIHsKICAgICAgICBjYXNlIDBiMDEwMToKICAgICAgICAgIGUwID0gMGIwMTAwOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgLy8gdG9wLWxlZnQKICAgICAgICBjYXNlIDBiMDEwMDoKICAgICAgICAgIGUwID0gMGIwMTEwLCB4ID0gdGhpcy54bWF4LCB5ID0gdGhpcy55bWluOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gdG9wCiAgICAgICAgY2FzZSAwYjAxMTA6CiAgICAgICAgICBlMCA9IDBiMDAxMDsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIC8vIHRvcC1yaWdodAogICAgICAgIGNhc2UgMGIwMDEwOgogICAgICAgICAgZTAgPSAwYjEwMTAsIHggPSB0aGlzLnhtYXgsIHkgPSB0aGlzLnltYXg7CiAgICAgICAgICBicmVhazsKICAgICAgICAvLyByaWdodAogICAgICAgIGNhc2UgMGIxMDEwOgogICAgICAgICAgZTAgPSAwYjEwMDA7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICAvLyBib3R0b20tcmlnaHQKICAgICAgICBjYXNlIDBiMTAwMDoKICAgICAgICAgIGUwID0gMGIxMDAxLCB4ID0gdGhpcy54bWluLCB5ID0gdGhpcy55bWF4OwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gYm90dG9tCiAgICAgICAgY2FzZSAwYjEwMDE6CiAgICAgICAgICBlMCA9IDBiMDAwMTsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIC8vIGJvdHRvbS1sZWZ0CiAgICAgICAgY2FzZSAwYjAwMDE6CiAgICAgICAgICBlMCA9IDBiMDEwMSwgeCA9IHRoaXMueG1pbiwgeSA9IHRoaXMueW1pbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIGxlZnQKICAgICAgfQogICAgICAvLyBOb3RlOiB0aGlzIGltcGxpY2l0bHkgY2hlY2tzIGZvciBvdXQgb2YgYm91bmRzOiBpZiBQW2pdIG9yIFBbaisxXSBhcmUKICAgICAgLy8gdW5kZWZpbmVkLCB0aGUgY29uZGl0aW9uYWwgc3RhdGVtZW50IHdpbGwgYmUgZXhlY3V0ZWQuCiAgICAgIGlmICgoUFtqXSAhPT0geCB8fCBQW2ogKyAxXSAhPT0geSkgJiYgdGhpcy5jb250YWlucyhpLCB4LCB5KSkgewogICAgICAgIFAuc3BsaWNlKGosIDAsIHgsIHkpLCBqICs9IDI7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBqOwogIH0KICBfcHJvamVjdCh4MCwgeTAsIHZ4LCB2eSkgewogICAgbGV0IHQgPSBJbmZpbml0eSwKICAgICAgYywKICAgICAgeCwKICAgICAgeTsKICAgIGlmICh2eSA8IDApIHsKICAgICAgLy8gdG9wCiAgICAgIGlmICh5MCA8PSB0aGlzLnltaW4pIHJldHVybiBudWxsOwogICAgICBpZiAoKGMgPSAodGhpcy55bWluIC0geTApIC8gdnkpIDwgdCkgeSA9IHRoaXMueW1pbiwgeCA9IHgwICsgKHQgPSBjKSAqIHZ4OwogICAgfSBlbHNlIGlmICh2eSA+IDApIHsKICAgICAgLy8gYm90dG9tCiAgICAgIGlmICh5MCA+PSB0aGlzLnltYXgpIHJldHVybiBudWxsOwogICAgICBpZiAoKGMgPSAodGhpcy55bWF4IC0geTApIC8gdnkpIDwgdCkgeSA9IHRoaXMueW1heCwgeCA9IHgwICsgKHQgPSBjKSAqIHZ4OwogICAgfQogICAgaWYgKHZ4ID4gMCkgewogICAgICAvLyByaWdodAogICAgICBpZiAoeDAgPj0gdGhpcy54bWF4KSByZXR1cm4gbnVsbDsKICAgICAgaWYgKChjID0gKHRoaXMueG1heCAtIHgwKSAvIHZ4KSA8IHQpIHggPSB0aGlzLnhtYXgsIHkgPSB5MCArICh0ID0gYykgKiB2eTsKICAgIH0gZWxzZSBpZiAodnggPCAwKSB7CiAgICAgIC8vIGxlZnQKICAgICAgaWYgKHgwIDw9IHRoaXMueG1pbikgcmV0dXJuIG51bGw7CiAgICAgIGlmICgoYyA9ICh0aGlzLnhtaW4gLSB4MCkgLyB2eCkgPCB0KSB4ID0gdGhpcy54bWluLCB5ID0geTAgKyAodCA9IGMpICogdnk7CiAgICB9CiAgICByZXR1cm4gW3gsIHldOwogIH0KICBfZWRnZWNvZGUoeCwgeSkgewogICAgcmV0dXJuICh4ID09PSB0aGlzLnhtaW4gPyAwYjAwMDEgOiB4ID09PSB0aGlzLnhtYXggPyAwYjAwMTAgOiAwYjAwMDApIHwgKHkgPT09IHRoaXMueW1pbiA/IDBiMDEwMCA6IHkgPT09IHRoaXMueW1heCA/IDBiMTAwMCA6IDBiMDAwMCk7CiAgfQogIF9yZWdpb25jb2RlKHgsIHkpIHsKICAgIHJldHVybiAoeCA8IHRoaXMueG1pbiA/IDBiMDAwMSA6IHggPiB0aGlzLnhtYXggPyAwYjAwMTAgOiAwYjAwMDApIHwgKHkgPCB0aGlzLnltaW4gPyAwYjAxMDAgOiB5ID4gdGhpcy55bWF4ID8gMGIxMDAwIDogMGIwMDAwKTsKICB9CiAgX3NpbXBsaWZ5KFApIHsKICAgIGlmIChQICYmIFAubGVuZ3RoID4gNCkgewogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IFAubGVuZ3RoOyBpICs9IDIpIHsKICAgICAgICBjb25zdCBqID0gKGkgKyAyKSAlIFAubGVuZ3RoLAogICAgICAgICAgayA9IChpICsgNCkgJSBQLmxlbmd0aDsKICAgICAgICBpZiAoUFtpXSA9PT0gUFtqXSAmJiBQW2pdID09PSBQW2tdIHx8IFBbaSArIDFdID09PSBQW2ogKyAxXSAmJiBQW2ogKyAxXSA9PT0gUFtrICsgMV0pIHsKICAgICAgICAgIFAuc3BsaWNlKGosIDIpLCBpIC09IDI7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmICghUC5sZW5ndGgpIFAgPSBudWxsOwogICAgfQogICAgcmV0dXJuIFA7CiAgfQp9Cgpjb25zdCB0YXUgPSAyICogTWF0aC5QSSwKICBwb3cgPSBNYXRoLnBvdzsKZnVuY3Rpb24gcG9pbnRYKHApIHsKICByZXR1cm4gcFswXTsKfQpmdW5jdGlvbiBwb2ludFkocCkgewogIHJldHVybiBwWzFdOwp9CgovLyBBIHRyaWFuZ3VsYXRpb24gaXMgY29sbGluZWFyIGlmIGFsbCBpdHMgdHJpYW5nbGVzIGhhdmUgYSBub24tbnVsbCBhcmVhCmZ1bmN0aW9uIGNvbGxpbmVhcihkKSB7CiAgY29uc3QgewogICAgdHJpYW5nbGVzLAogICAgY29vcmRzCiAgfSA9IGQ7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0cmlhbmdsZXMubGVuZ3RoOyBpICs9IDMpIHsKICAgIGNvbnN0IGEgPSAyICogdHJpYW5nbGVzW2ldLAogICAgICBiID0gMiAqIHRyaWFuZ2xlc1tpICsgMV0sCiAgICAgIGMgPSAyICogdHJpYW5nbGVzW2kgKyAyXSwKICAgICAgY3Jvc3MgPSAoY29vcmRzW2NdIC0gY29vcmRzW2FdKSAqIChjb29yZHNbYiArIDFdIC0gY29vcmRzW2EgKyAxXSkgLSAoY29vcmRzW2JdIC0gY29vcmRzW2FdKSAqIChjb29yZHNbYyArIDFdIC0gY29vcmRzW2EgKyAxXSk7CiAgICBpZiAoY3Jvc3MgPiAxZS0xMCkgcmV0dXJuIGZhbHNlOwogIH0KICByZXR1cm4gdHJ1ZTsKfQpmdW5jdGlvbiBqaXR0ZXIoeCwgeSwgcikgewogIHJldHVybiBbeCArIE1hdGguc2luKHggKyB5KSAqIHIsIHkgKyBNYXRoLmNvcyh4IC0geSkgKiByXTsKfQpjbGFzcyBEZWxhdW5heSB7CiAgc3RhdGljIGZyb20ocG9pbnRzLCBmeCA9IHBvaW50WCwgZnkgPSBwb2ludFksIHRoYXQpIHsKICAgIHJldHVybiBuZXcgRGVsYXVuYXkoImxlbmd0aCIgaW4gcG9pbnRzID8gZmxhdEFycmF5KHBvaW50cywgZngsIGZ5LCB0aGF0KSA6IEZsb2F0NjRBcnJheS5mcm9tKGZsYXRJdGVyYWJsZShwb2ludHMsIGZ4LCBmeSwgdGhhdCkpKTsKICB9CiAgY29uc3RydWN0b3IocG9pbnRzKSB7CiAgICB0aGlzLl9kZWxhdW5hdG9yID0gbmV3IERlbGF1bmF0b3IocG9pbnRzKTsKICAgIHRoaXMuaW5lZGdlcyA9IG5ldyBJbnQzMkFycmF5KHBvaW50cy5sZW5ndGggLyAyKTsKICAgIHRoaXMuX2h1bGxJbmRleCA9IG5ldyBJbnQzMkFycmF5KHBvaW50cy5sZW5ndGggLyAyKTsKICAgIHRoaXMucG9pbnRzID0gdGhpcy5fZGVsYXVuYXRvci5jb29yZHM7CiAgICB0aGlzLl9pbml0KCk7CiAgfQogIHVwZGF0ZSgpIHsKICAgIHRoaXMuX2RlbGF1bmF0b3IudXBkYXRlKCk7CiAgICB0aGlzLl9pbml0KCk7CiAgICByZXR1cm4gdGhpczsKICB9CiAgX2luaXQoKSB7CiAgICBjb25zdCBkID0gdGhpcy5fZGVsYXVuYXRvciwKICAgICAgcG9pbnRzID0gdGhpcy5wb2ludHM7CgogICAgLy8gY2hlY2sgZm9yIGNvbGxpbmVhcgogICAgaWYgKGQuaHVsbCAmJiBkLmh1bGwubGVuZ3RoID4gMiAmJiBjb2xsaW5lYXIoZCkpIHsKICAgICAgdGhpcy5jb2xsaW5lYXIgPSBJbnQzMkFycmF5LmZyb20oewogICAgICAgIGxlbmd0aDogcG9pbnRzLmxlbmd0aCAvIDIKICAgICAgfSwgKF8sIGkpID0+IGkpLnNvcnQoKGksIGopID0+IHBvaW50c1syICogaV0gLSBwb2ludHNbMiAqIGpdIHx8IHBvaW50c1syICogaSArIDFdIC0gcG9pbnRzWzIgKiBqICsgMV0pOyAvLyBmb3IgZXhhY3QgbmVpZ2hib3JzCiAgICAgIGNvbnN0IGUgPSB0aGlzLmNvbGxpbmVhclswXSwKICAgICAgICBmID0gdGhpcy5jb2xsaW5lYXJbdGhpcy5jb2xsaW5lYXIubGVuZ3RoIC0gMV0sCiAgICAgICAgYm91bmRzID0gW3BvaW50c1syICogZV0sIHBvaW50c1syICogZSArIDFdLCBwb2ludHNbMiAqIGZdLCBwb2ludHNbMiAqIGYgKyAxXV0sCiAgICAgICAgciA9IDFlLTggKiBNYXRoLmh5cG90KGJvdW5kc1szXSAtIGJvdW5kc1sxXSwgYm91bmRzWzJdIC0gYm91bmRzWzBdKTsKICAgICAgZm9yIChsZXQgaSA9IDAsIG4gPSBwb2ludHMubGVuZ3RoIC8gMjsgaSA8IG47ICsraSkgewogICAgICAgIGNvbnN0IHAgPSBqaXR0ZXIocG9pbnRzWzIgKiBpXSwgcG9pbnRzWzIgKiBpICsgMV0sIHIpOwogICAgICAgIHBvaW50c1syICogaV0gPSBwWzBdOwogICAgICAgIHBvaW50c1syICogaSArIDFdID0gcFsxXTsKICAgICAgfQogICAgICB0aGlzLl9kZWxhdW5hdG9yID0gbmV3IERlbGF1bmF0b3IocG9pbnRzKTsKICAgIH0gZWxzZSB7CiAgICAgIGRlbGV0ZSB0aGlzLmNvbGxpbmVhcjsKICAgIH0KICAgIGNvbnN0IGhhbGZlZGdlcyA9IHRoaXMuaGFsZmVkZ2VzID0gdGhpcy5fZGVsYXVuYXRvci5oYWxmZWRnZXM7CiAgICBjb25zdCBodWxsID0gdGhpcy5odWxsID0gdGhpcy5fZGVsYXVuYXRvci5odWxsOwogICAgY29uc3QgdHJpYW5nbGVzID0gdGhpcy50cmlhbmdsZXMgPSB0aGlzLl9kZWxhdW5hdG9yLnRyaWFuZ2xlczsKICAgIGNvbnN0IGluZWRnZXMgPSB0aGlzLmluZWRnZXMuZmlsbCgtMSk7CiAgICBjb25zdCBodWxsSW5kZXggPSB0aGlzLl9odWxsSW5kZXguZmlsbCgtMSk7CgogICAgLy8gQ29tcHV0ZSBhbiBpbmRleCBmcm9tIGVhY2ggcG9pbnQgdG8gYW4gKGFyYml0cmFyeSkgaW5jb21pbmcgaGFsZmVkZ2UKICAgIC8vIFVzZWQgdG8gZ2l2ZSB0aGUgZmlyc3QgbmVpZ2hib3Igb2YgZWFjaCBwb2ludDsgZm9yIHRoaXMgcmVhc29uLAogICAgLy8gb24gdGhlIGh1bGwgd2UgZ2l2ZSBwcmlvcml0eSB0byBleHRlcmlvciBoYWxmZWRnZXMKICAgIGZvciAobGV0IGUgPSAwLCBuID0gaGFsZmVkZ2VzLmxlbmd0aDsgZSA8IG47ICsrZSkgewogICAgICBjb25zdCBwID0gdHJpYW5nbGVzW2UgJSAzID09PSAyID8gZSAtIDIgOiBlICsgMV07CiAgICAgIGlmIChoYWxmZWRnZXNbZV0gPT09IC0xIHx8IGluZWRnZXNbcF0gPT09IC0xKSBpbmVkZ2VzW3BdID0gZTsKICAgIH0KICAgIGZvciAobGV0IGkgPSAwLCBuID0gaHVsbC5sZW5ndGg7IGkgPCBuOyArK2kpIHsKICAgICAgaHVsbEluZGV4W2h1bGxbaV1dID0gaTsKICAgIH0KCiAgICAvLyBkZWdlbmVyYXRlIGNhc2U6IDEgb3IgMiAoZGlzdGluY3QpIHBvaW50cwogICAgaWYgKGh1bGwubGVuZ3RoIDw9IDIgJiYgaHVsbC5sZW5ndGggPiAwKSB7CiAgICAgIHRoaXMudHJpYW5nbGVzID0gbmV3IEludDMyQXJyYXkoMykuZmlsbCgtMSk7CiAgICAgIHRoaXMuaGFsZmVkZ2VzID0gbmV3IEludDMyQXJyYXkoMykuZmlsbCgtMSk7CiAgICAgIHRoaXMudHJpYW5nbGVzWzBdID0gaHVsbFswXTsKICAgICAgaW5lZGdlc1todWxsWzBdXSA9IDE7CiAgICAgIGlmIChodWxsLmxlbmd0aCA9PT0gMikgewogICAgICAgIGluZWRnZXNbaHVsbFsxXV0gPSAwOwogICAgICAgIHRoaXMudHJpYW5nbGVzWzFdID0gaHVsbFsxXTsKICAgICAgICB0aGlzLnRyaWFuZ2xlc1syXSA9IGh1bGxbMV07CiAgICAgIH0KICAgIH0KICB9CiAgdm9yb25vaShib3VuZHMpIHsKICAgIHJldHVybiBuZXcgVm9yb25vaSh0aGlzLCBib3VuZHMpOwogIH0KICAqbmVpZ2hib3JzKGkpIHsKICAgIGNvbnN0IHsKICAgICAgaW5lZGdlcywKICAgICAgaHVsbCwKICAgICAgX2h1bGxJbmRleCwKICAgICAgaGFsZmVkZ2VzLAogICAgICB0cmlhbmdsZXMsCiAgICAgIGNvbGxpbmVhcgogICAgfSA9IHRoaXM7CgogICAgLy8gZGVnZW5lcmF0ZSBjYXNlIHdpdGggc2V2ZXJhbCBjb2xsaW5lYXIgcG9pbnRzCiAgICBpZiAoY29sbGluZWFyKSB7CiAgICAgIGNvbnN0IGwgPSBjb2xsaW5lYXIuaW5kZXhPZihpKTsKICAgICAgaWYgKGwgPiAwKSB5aWVsZCBjb2xsaW5lYXJbbCAtIDFdOwogICAgICBpZiAobCA8IGNvbGxpbmVhci5sZW5ndGggLSAxKSB5aWVsZCBjb2xsaW5lYXJbbCArIDFdOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBlMCA9IGluZWRnZXNbaV07CiAgICBpZiAoZTAgPT09IC0xKSByZXR1cm47IC8vIGNvaW5jaWRlbnQgcG9pbnQKICAgIGxldCBlID0gZTAsCiAgICAgIHAwID0gLTE7CiAgICBkbyB7CiAgICAgIHlpZWxkIHAwID0gdHJpYW5nbGVzW2VdOwogICAgICBlID0gZSAlIDMgPT09IDIgPyBlIC0gMiA6IGUgKyAxOwogICAgICBpZiAodHJpYW5nbGVzW2VdICE9PSBpKSByZXR1cm47IC8vIGJhZCB0cmlhbmd1bGF0aW9uCiAgICAgIGUgPSBoYWxmZWRnZXNbZV07CiAgICAgIGlmIChlID09PSAtMSkgewogICAgICAgIGNvbnN0IHAgPSBodWxsWyhfaHVsbEluZGV4W2ldICsgMSkgJSBodWxsLmxlbmd0aF07CiAgICAgICAgaWYgKHAgIT09IHAwKSB5aWVsZCBwOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgfSB3aGlsZSAoZSAhPT0gZTApOwogIH0KICBmaW5kKHgsIHksIGkgPSAwKSB7CiAgICBpZiAoKHggPSAreCwgeCAhPT0geCkgfHwgKHkgPSAreSwgeSAhPT0geSkpIHJldHVybiAtMTsKICAgIGNvbnN0IGkwID0gaTsKICAgIGxldCBjOwogICAgd2hpbGUgKChjID0gdGhpcy5fc3RlcChpLCB4LCB5KSkgPj0gMCAmJiBjICE9PSBpICYmIGMgIT09IGkwKSBpID0gYzsKICAgIHJldHVybiBjOwogIH0KICBfc3RlcChpLCB4LCB5KSB7CiAgICBjb25zdCB7CiAgICAgIGluZWRnZXMsCiAgICAgIGh1bGwsCiAgICAgIF9odWxsSW5kZXgsCiAgICAgIGhhbGZlZGdlcywKICAgICAgdHJpYW5nbGVzLAogICAgICBwb2ludHMKICAgIH0gPSB0aGlzOwogICAgaWYgKGluZWRnZXNbaV0gPT09IC0xIHx8ICFwb2ludHMubGVuZ3RoKSByZXR1cm4gKGkgKyAxKSAlIChwb2ludHMubGVuZ3RoID4+IDEpOwogICAgbGV0IGMgPSBpOwogICAgbGV0IGRjID0gcG93KHggLSBwb2ludHNbaSAqIDJdLCAyKSArIHBvdyh5IC0gcG9pbnRzW2kgKiAyICsgMV0sIDIpOwogICAgY29uc3QgZTAgPSBpbmVkZ2VzW2ldOwogICAgbGV0IGUgPSBlMDsKICAgIGRvIHsKICAgICAgbGV0IHQgPSB0cmlhbmdsZXNbZV07CiAgICAgIGNvbnN0IGR0ID0gcG93KHggLSBwb2ludHNbdCAqIDJdLCAyKSArIHBvdyh5IC0gcG9pbnRzW3QgKiAyICsgMV0sIDIpOwogICAgICBpZiAoZHQgPCBkYykgZGMgPSBkdCwgYyA9IHQ7CiAgICAgIGUgPSBlICUgMyA9PT0gMiA/IGUgLSAyIDogZSArIDE7CiAgICAgIGlmICh0cmlhbmdsZXNbZV0gIT09IGkpIGJyZWFrOyAvLyBiYWQgdHJpYW5ndWxhdGlvbgogICAgICBlID0gaGFsZmVkZ2VzW2VdOwogICAgICBpZiAoZSA9PT0gLTEpIHsKICAgICAgICBlID0gaHVsbFsoX2h1bGxJbmRleFtpXSArIDEpICUgaHVsbC5sZW5ndGhdOwogICAgICAgIGlmIChlICE9PSB0KSB7CiAgICAgICAgICBpZiAocG93KHggLSBwb2ludHNbZSAqIDJdLCAyKSArIHBvdyh5IC0gcG9pbnRzW2UgKiAyICsgMV0sIDIpIDwgZGMpIHJldHVybiBlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgfQogICAgfSB3aGlsZSAoZSAhPT0gZTApOwogICAgcmV0dXJuIGM7CiAgfQogIHJlbmRlcihjb250ZXh0KSB7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IHsKICAgICAgcG9pbnRzLAogICAgICBoYWxmZWRnZXMsCiAgICAgIHRyaWFuZ2xlcwogICAgfSA9IHRoaXM7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IGhhbGZlZGdlcy5sZW5ndGg7IGkgPCBuOyArK2kpIHsKICAgICAgY29uc3QgaiA9IGhhbGZlZGdlc1tpXTsKICAgICAgaWYgKGogPCBpKSBjb250aW51ZTsKICAgICAgY29uc3QgdGkgPSB0cmlhbmdsZXNbaV0gKiAyOwogICAgICBjb25zdCB0aiA9IHRyaWFuZ2xlc1tqXSAqIDI7CiAgICAgIGNvbnRleHQubW92ZVRvKHBvaW50c1t0aV0sIHBvaW50c1t0aSArIDFdKTsKICAgICAgY29udGV4dC5saW5lVG8ocG9pbnRzW3RqXSwgcG9pbnRzW3RqICsgMV0pOwogICAgfQogICAgdGhpcy5yZW5kZXJIdWxsKGNvbnRleHQpOwogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgcmVuZGVyUG9pbnRzKGNvbnRleHQsIHIpIHsKICAgIGlmIChyID09PSB1bmRlZmluZWQgJiYgKCFjb250ZXh0IHx8IHR5cGVvZiBjb250ZXh0Lm1vdmVUbyAhPT0gImZ1bmN0aW9uIikpIHIgPSBjb250ZXh0LCBjb250ZXh0ID0gbnVsbDsKICAgIHIgPSByID09IHVuZGVmaW5lZCA/IDIgOiArcjsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgewogICAgICBwb2ludHMKICAgIH0gPSB0aGlzOwogICAgZm9yIChsZXQgaSA9IDAsIG4gPSBwb2ludHMubGVuZ3RoOyBpIDwgbjsgaSArPSAyKSB7CiAgICAgIGNvbnN0IHggPSBwb2ludHNbaV0sCiAgICAgICAgeSA9IHBvaW50c1tpICsgMV07CiAgICAgIGNvbnRleHQubW92ZVRvKHggKyByLCB5KTsKICAgICAgY29udGV4dC5hcmMoeCwgeSwgciwgMCwgdGF1KTsKICAgIH0KICAgIHJldHVybiBidWZmZXIgJiYgYnVmZmVyLnZhbHVlKCk7CiAgfQogIHJlbmRlckh1bGwoY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIGh1bGwsCiAgICAgIHBvaW50cwogICAgfSA9IHRoaXM7CiAgICBjb25zdCBoID0gaHVsbFswXSAqIDIsCiAgICAgIG4gPSBodWxsLmxlbmd0aDsKICAgIGNvbnRleHQubW92ZVRvKHBvaW50c1toXSwgcG9pbnRzW2ggKyAxXSk7CiAgICBmb3IgKGxldCBpID0gMTsgaSA8IG47ICsraSkgewogICAgICBjb25zdCBoID0gMiAqIGh1bGxbaV07CiAgICAgIGNvbnRleHQubGluZVRvKHBvaW50c1toXSwgcG9pbnRzW2ggKyAxXSk7CiAgICB9CiAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgaHVsbFBvbHlnb24oKSB7CiAgICBjb25zdCBwb2x5Z29uID0gbmV3IFBvbHlnb24oKTsKICAgIHRoaXMucmVuZGVySHVsbChwb2x5Z29uKTsKICAgIHJldHVybiBwb2x5Z29uLnZhbHVlKCk7CiAgfQogIHJlbmRlclRyaWFuZ2xlKGksIGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgewogICAgICBwb2ludHMsCiAgICAgIHRyaWFuZ2xlcwogICAgfSA9IHRoaXM7CiAgICBjb25zdCB0MCA9IHRyaWFuZ2xlc1tpICo9IDNdICogMjsKICAgIGNvbnN0IHQxID0gdHJpYW5nbGVzW2kgKyAxXSAqIDI7CiAgICBjb25zdCB0MiA9IHRyaWFuZ2xlc1tpICsgMl0gKiAyOwogICAgY29udGV4dC5tb3ZlVG8ocG9pbnRzW3QwXSwgcG9pbnRzW3QwICsgMV0pOwogICAgY29udGV4dC5saW5lVG8ocG9pbnRzW3QxXSwgcG9pbnRzW3QxICsgMV0pOwogICAgY29udGV4dC5saW5lVG8ocG9pbnRzW3QyXSwgcG9pbnRzW3QyICsgMV0pOwogICAgY29udGV4dC5jbG9zZVBhdGgoKTsKICAgIHJldHVybiBidWZmZXIgJiYgYnVmZmVyLnZhbHVlKCk7CiAgfQogICp0cmlhbmdsZVBvbHlnb25zKCkgewogICAgY29uc3QgewogICAgICB0cmlhbmdsZXMKICAgIH0gPSB0aGlzOwogICAgZm9yIChsZXQgaSA9IDAsIG4gPSB0cmlhbmdsZXMubGVuZ3RoIC8gMzsgaSA8IG47ICsraSkgewogICAgICB5aWVsZCB0aGlzLnRyaWFuZ2xlUG9seWdvbihpKTsKICAgIH0KICB9CiAgdHJpYW5nbGVQb2x5Z29uKGkpIHsKICAgIGNvbnN0IHBvbHlnb24gPSBuZXcgUG9seWdvbigpOwogICAgdGhpcy5yZW5kZXJUcmlhbmdsZShpLCBwb2x5Z29uKTsKICAgIHJldHVybiBwb2x5Z29uLnZhbHVlKCk7CiAgfQp9CmZ1bmN0aW9uIGZsYXRBcnJheShwb2ludHMsIGZ4LCBmeSwgdGhhdCkgewogIGNvbnN0IG4gPSBwb2ludHMubGVuZ3RoOwogIGNvbnN0IGFycmF5ID0gbmV3IEZsb2F0NjRBcnJheShuICogMik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgIGNvbnN0IHAgPSBwb2ludHNbaV07CiAgICBhcnJheVtpICogMl0gPSBmeC5jYWxsKHRoYXQsIHAsIGksIHBvaW50cyk7CiAgICBhcnJheVtpICogMiArIDFdID0gZnkuY2FsbCh0aGF0LCBwLCBpLCBwb2ludHMpOwogIH0KICByZXR1cm4gYXJyYXk7Cn0KZnVuY3Rpb24qIGZsYXRJdGVyYWJsZShwb2ludHMsIGZ4LCBmeSwgdGhhdCkgewogIGxldCBpID0gMDsKICBmb3IgKGNvbnN0IHAgb2YgcG9pbnRzKSB7CiAgICB5aWVsZCBmeC5jYWxsKHRoYXQsIHAsIGksIHBvaW50cyk7CiAgICB5aWVsZCBmeS5jYWxsKHRoYXQsIHAsIGksIHBvaW50cyk7CiAgICArK2k7CiAgfQp9CgovKioNCiAqIOiHqueEtumEsOm7nuWFp+aPkuazlShOYXR1cmFsIE5laWdoYm9yIEludGVycG9sYXRpb24p5YWn5o+S6bue5pW45YC8DQogKg0KICogQSBGYXN0IGFuZCBBY2N1cmF0ZSBBbGdvcml0aG0gZm9yIE5hdHVyYWwgTmVpZ2hib3IgSW50ZXJwb2xhdGlvbg0KICogaHR0cHM6Ly9nd2x1Y2FzdHJpZy5naXRodWIuaW8vVGluZm91ckRvY3MvTmF0dXJhbE5laWdoYm9yVGluZm91ckFsZ29yaXRobS9pbmRleC5odG1sDQogKg0KICogQW4gSW50cm9kdWN0aW9uIHRvIE5hdHVyYWwgTmVpZ2hib3IgSW50ZXJwb2xhdGlvbg0KICogaHR0cHM6Ly9nd2x1Y2FzdHJpZy5naXRodWIuaW8vVGluZm91ckRvY3MvTmF0dXJhbE5laWdoYm9ySW50cm8vaW5kZXguaHRtbA0KICoNCiAqIFt3aWtpXU5hdHVyYWwgbmVpZ2hib3IgaW50ZXJwb2xhdGlvbg0KICogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTmF0dXJhbF9uZWlnaGJvcl9pbnRlcnBvbGF0aW9uDQogKg0KICogTmF0dXJhbCBuZWlnaGJvciBpbnRlcnBvbGF0aW9uDQogKiBodHRwczovL29ic2VydmFibGVocS5jb20vQGthcmxlcnNzL25hdHVyYWwtbmVpZ2hib3ItaW50ZXJwb2xhdGlvbg0KICoNCiAqIGQzLWRlbGF1bmF5DQogKiBodHRwczovL2dpdGh1Yi5jb20vZDMvZDMtZGVsYXVuYXkNCiAqDQogKiBvbmxpbmUgdGVzdA0KICogaHR0cHM6Ly9jYXJ0b2dyYXBoeS1wbGF5Z3JvdW5kLmdpdGxhYi5pby9wbGF5Z3JvdW5kcy90cmlhbmd1bGF0aW9uLWRlbGF1bmF5LXZvcm9ub2ktZGlhZ3JhbS8NCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9pbnRlcnAyTmF0dXJhbE5laWdoYm9yLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcHNTcmMg6Ly45YWl5LqM57at5bqn5qiZ5Yqg6KeA5ris5pW45pOa6bue6Zmj5YiX77yM54K6W3t4OngxLHk6eTEsejp6MX0se3g6eDIseTp5Mix6OnoyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiXDQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gcHNUYXIg6Ly45YWl5LqM57at5bqn5qiZ6bue6Zmj5YiX5oiW6bue54mp5Lu277yM54K6W3t4OngxLHk6eTF9LHt4OngyLHk6eTJ9LC4uLl3pu57nianku7bkuYvpmaPliJfvvIzmiJZ7eDp4MSx5Onkxfem7nueJqeS7tg0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlYPSd4J10g6Ly45YWl6bue54mp5Lu25LmLeOashOS9jeWtl+S4su+8jOeCuuW6p+aome+8jOmgkOiorSd4Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neSddIOi8uOWFpem7nueJqeS7tuS5i3nmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neScNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVo9J3onXSDovLjlhaXpu57nianku7bkuYt65qyE5L2N5a2X5Liy77yM54K66KeA5ris5YC877yM6aCQ6KitJ3onDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zY2FsZT0xXSDovLjlhaXmraPopo/ljJbnr4TlnI3mlbjlgLzvvIzlm6DomZXnkIblpJrpgorlvaLmmYLmnInmlbjlgLzlrrnoqLHoqqTlt67vvIzmlYXpoIjpgJrpgY7nuK7mlL7lgLzln5/kvobmuJvlsJHllY/poYzvvIzpoJDoqK0x5piv5q2j6KaP5YyWMOiHszHkuYvplpPvvIzkvb/nlKhzY2FsZVhZ5YmH5piv5q2j6KaP5YyW54K6MOiHs3NjYWxlWFnkuYvplpPvvIzpoJDoqK0xDQogKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSDlm57lgrPpu57nianku7bpmaPliJfmiJbpu57nianku7bvvIzoi6XnmbznlJ/pjK/oqqTliYflm57lgrPpjK/oqqToqIrmga/nianku7YNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBzDQogKiBsZXQgcA0KICogbGV0IHINCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDEyNDMsDQogKiAgICAgeTogMTIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMTI0MywgeTogMTIwNywgejogbnVsbCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiBudWxsLCB5OiAyMDEsIHo6IDEyMiB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogbGV0IGZ1bkludGVycEZyYWdtZW50ID0gKG1zZykgPT4gew0KICogICAgIC8vIGNvbnNvbGUubG9nKCdmdW5JbnRlcnBGcmFnbWVudCcsIG1zZykNCiAqICAgICByZXR1cm4gbXNnLnYgLy/poJDoqK3lm57lgrNtc2cudiwg5LiJ6KeS5b2i5LiJ6KeS6bue5ZCE6buedueCunJBKnosIOaVheS4iem7nuS5i3JB5ZCI54K6MSwg5oyH5a6a5YWn5o+S5YC8eueCuuS4ieinkum7nnbkuYvnuL3lkowodjEsdjIsdjMpDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCwgeyBmdW5JbnRlcnBGcmFnbWVudCB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IG51bGwsIHk6IDIwMSwgejogMTIyIH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDEyNDMsDQogKiAgICAgeTogMTIwNywNCiAqIH0NCiAqIGxldCBmdW5JbnRlcnBGcmFnbWVudE5vVXNlID0gKG1zZykgPT4gew0KICogICAgIC8vIGNvbnNvbGUubG9nKCdmdW5JbnRlcnBGcmFnbWVudE5vVXNlJywgbXNnKQ0KICogICAgIHJldHVybiBtc2cudiAvL+mgkOioreWbnuWCs21zZy52LCDmraTomZXlm6Dlhafmj5Lpu57mlrzljp/lp4vpu57miYDlvaLmiJDmnIDlsI/lh7jlpJrpgorlvaLkuYvlpJYsIOaVheeEoeazleWFp+aPkiwg5Lqm5LiN5pyD5ZG85Y+rZnVuSW50ZXJwRnJhZ21lbnQNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwLCB7IGZ1bkludGVycEZyYWdtZW50OiBmdW5JbnRlcnBGcmFnbWVudE5vVXNlIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAxMjQzLCB5OiAxMjA3LCB6OiBudWxsIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IG51bGwsIHk6IDIwMSwgejogMTIyIH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiBsZXQgZnVuSW50ZXJwRnJhZ21lbnRzID0gKG1zZykgPT4gew0KICogICAgIC8vIGNvbnNvbGUubG9nKCdmdW5JbnRlcnBGcmFnbWVudHMnLCBtc2cpDQogKiAgICAgLy8gbGV0IHYgPSBwc1swXS52ICsgcHNbMV0udiArIHBzWzJdLnYNCiAqICAgICByZXR1cm4gbXNnLnYgLy/poJDoqK3lm57lgrNtc2cudiwg5LiJ6KeS5b2i5LiJ6KeS6bue54K6bXNnLnBzLCDlkITpu55254K6ckEqeiwg5pWF5LiJ6bue5LmLckHlkIjngroxLCDmjIflrprlhafmj5LlgLx654K65LiJ6KeS6bueduS5i+e4veWSjCh2MSx2Mix2MykNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwLCB7IGZ1bkludGVycEZyYWdtZW50cyB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyODMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyODMsIHk6IDIwNywgejogMTE0LjQzMDQwNDIxOTUxOTA4IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAxMTYwLA0KICogICAgIHk6IDM4MCwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMTE2MCwgeTogMzgwLCB6OiBudWxsIH0NCiAqDQogKiBwcyA9IFt7IGE6IDI0MywgYjogMjA2LCBjOiA5NSB9LCB7IGE6IDIzMywgYjogMjI1LCBjOiAxNDYgfSwgeyBhOiAyMSwgYjogMzI1LCBjOiAyMiB9LCB7IGE6IDk1MywgYjogMjgsIGM6IDIyMyB9LCB7IGE6IDEwOTIsIGI6IDI5MCwgYzogMzkgfSwgeyBhOiA3NDQsIGI6IDIwMCwgYzogMTkxIH0sIHsgYTogMTc0LCBiOiAzLCBjOiAyMiB9LCB7IGE6IDUzNywgYjogMzY4LCBjOiAyNDkgfSwgeyBhOiAxMTUxLCBiOiAzNzEsIGM6IDg2IH0sIHsgYTogODE0LCBiOiAyNTIsIGM6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICBhOiAyNDMsDQogKiAgICAgYjogMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsga2V5WDogJ2EnLCBrZXlZOiAnYicsIGtleVo6ICdjJyB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgYTogMjQzLCBiOiAyMDcsIGM6IDk3LjI5NDQ3NjgyNDg2ODEzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IFsNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI0MywNCiAqICAgICAgICAgeTogMjA3LA0KICogICAgIH0sDQogKiAgICAgew0KICogICAgICAgICB4OiAyODMsDQogKiAgICAgICAgIHk6IDIwNywNCiAqICAgICB9LA0KICogXQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9LA0KICogLy8gICB7IHg6IDI4MywgeTogMjA3LCB6OiAxMTQuNDMwNDA0MjE5NTE5MDggfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgeDogMC4wMDAyNDMsIHk6IDAuMDAwMjA2LCB6OiA5NSB9LCB7IHg6IDAuMDAwMjMzLCB5OiAwLjAwMDIyNSwgejogMTQ2IH0sIHsgeDogMC4wMDAwMjEsIHk6IDAuMDAwMzI1LCB6OiAyMiB9LCB7IHg6IDAuMDAwOTUzLCB5OiAwLjAwMDAyOCwgejogMjIzIH0sIHsgeDogMC4wMDEwOTIsIHk6IDAuMDAwMjksIHo6IDM5IH0sIHsgeDogMC4wMDA3NDQsIHk6IDAuMDAwMjAwLCB6OiAxOTEgfSwgeyB4OiAwLjAwMDE3NCwgeTogMC4wMDAwMDMsIHo6IDIyIH0sIHsgeDogMC4wMDA1MzcsIHk6IDAuMDAwMzY4LCB6OiAyNDkgfSwgeyB4OiAwLjAwMTE1MSwgeTogMC4wMDAzNzEsIHo6IDg2IH0sIHsgeDogMC4wMDA4MTQsIHk6IDAuMDAwMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMC4wMDAyNDMsDQogKiAgICAgeTogMC4wMDAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDAuMDAwMjQzLCB5OiAwLjAwMDIwNywgejogOTcuMjk0NDc2ODI0ODY3OCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwLCB7IHNjYWxlOiAxMDAwIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4NTUgfQ0KICoNCiAqLwpmdW5jdGlvbiBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzU3JjLCBwc1Rhciwgb3B0ID0ge30pIHsKICAvL2NoZWNrIHBzU3JjCiAgaWYgKCFpc2VhcnIocHNTcmMpKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1NyYyBpcyBub3QgYW4gZWZmZWN0aXZlIGFycmF5JwogICAgfTsKICB9CgogIC8vY2hlY2sgcHNUYXIKICBpZiAoIWlzZW9iaihwc1RhcikgJiYgIWlzZWFycihwc1RhcikpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzVGFyIGlzIG5vdCBhbiBlZmZlY3RpdmUgb2JqZWN0IG9yIGFycmF5JwogICAgfTsKICB9CgogIC8vaXNPbmUKICBsZXQgaXNPbmUgPSBpc2VvYmoocHNUYXIpOwogIGlmIChpc09uZSkgewogICAgcHNUYXIgPSBbcHNUYXJdOwogIH0KCiAgLy9rZXlYCiAgbGV0IGtleVggPSBnZXQob3B0LCAna2V5WCcpOwogIGlmICghaXNlc3RyKGtleVgpKSB7CiAgICBrZXlYID0gJ3gnOwogIH0KCiAgLy9rZXlZCiAgbGV0IGtleVkgPSBnZXQob3B0LCAna2V5WScpOwogIGlmICghaXNlc3RyKGtleVkpKSB7CiAgICBrZXlZID0gJ3knOwogIH0KCiAgLy9rZXlaCiAgbGV0IGtleVogPSBnZXQob3B0LCAna2V5WicpOwogIGlmICghaXNlc3RyKGtleVopKSB7CiAgICBrZXlaID0gJ3onOwogIH0KCiAgLy9zY2FsZQogIGxldCBzY2FsZSA9IGdldChvcHQsICdzY2FsZScpOwogIGlmICghaXNudW0oc2NhbGUpKSB7CiAgICBzY2FsZSA9IDE7CiAgfQogIHNjYWxlID0gY2RibChzY2FsZSk7CgogIC8vZnVuSW50ZXJwRnJhZ21lbnQKICBsZXQgZnVuSW50ZXJwRnJhZ21lbnQgPSBnZXQob3B0LCAnZnVuSW50ZXJwRnJhZ21lbnQnKTsKICBsZXQgdXNlRnVuSW50ZXJwRnJhZ21lbnQgPSBpc2Z1bihmdW5JbnRlcnBGcmFnbWVudCk7CgogIC8vZnVuSW50ZXJwRnJhZ21lbnRzCiAgbGV0IGZ1bkludGVycEZyYWdtZW50cyA9IGdldChvcHQsICdmdW5JbnRlcnBGcmFnbWVudHMnKTsKICBsZXQgdXNlRnVuSW50ZXJwRnJhZ21lbnRzID0gaXNmdW4oZnVuSW50ZXJwRnJhZ21lbnRzKTsKCiAgLy9rZXlJbmQKICBsZXQga2V5SW5kID0gJ2luZCc7CgogIC8vcHRzWFladG9BcnIKICBwc1NyYyA9IHB0c1hZWnRvQXJyKHBzU3JjLCB7CiAgICBrZXlYLAogICAga2V5WSwKICAgIGtleVosCiAgICBrZXlJbmQKICB9KTsKCiAgLy9jaGVjayBwc1NyYwogIGlmIChzaXplKHBzU3JjKSA9PT0gMCkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNTcmMgaGFzIG5vIGVmZmVjdGl2ZSBkYXRhJwogICAgfTsKICB9CiAgLy8gY29uc29sZS5sb2coJ3B0c1hZWnRvQXJyIHBzU3JjJywgcHNTcmMpCgogIC8vcHRzWFl0b0FycgogIHBzVGFyID0gcHRzWFl0b0Fycihwc1RhciwgewogICAga2V5WCwKICAgIGtleVksCiAgICBrZXlJbmQKICB9KTsKCiAgLy9jaGVjayBwc1RhcgogIGlmIChzaXplKHBzVGFyKSA9PT0gMCkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNUYXIgaGFzIG5vIGVmZmVjdGl2ZSBkYXRhJwogICAgfTsKICB9CiAgLy8gY29uc29sZS5sb2coJ3B0c1hZdG9BcnIgcHNUYXInLCBwc1RhcikKCiAgLy9pbnRlcnAyTm9ybWFsaXplCiAgbGV0IGl0bm0gPSBpbnRlcnAyTm9ybWFsaXplKHBzU3JjLCB7CiAgICBrZXlJbmQsCiAgICBzY2FsZQogIH0pOwogIC8vIGNvbnNvbGUubG9nKCdpdG5tLnN0JywgaXRubS5zdCkKICAvLyBjb25zb2xlLmxvZygnaXRubS5wc01pbk1heCcsIGl0bm0ucHNNaW5NYXgpCiAgcHNTcmMgPSBpdG5tLnBzOyAvL+ikh+Wvq+ato+imj+WMluaVuOaTmgogIGxldCBudiA9IGl0bm0ubnY7CiAgbGV0IGludiA9IGl0bm0uaW52OwogIC8vIGNvbnNvbGUubG9nKCdpbnRlcnAyTm9ybWFsaXplIHBzU3JjJywgcHNTcmMpCgogIC8vcHNTcmNJdHIKICBsZXQgcHNTcmNJdHIgPSBbLi4ucHNTcmNdOwoKICAvL3BzU3JjT3JpCiAgbGV0IHBzU3JjT3JpID0gWy4uLnBzU3JjXTsKCiAgLy9rcEtub3duCiAgbGV0IGtwS25vd24gPSB7fTsKICBmb3JFYWNoKHBzU3JjLCB2ID0+IHsKICAgIGxldCBrID0gYCR7di54fS0ke3YueX1gOyAvL3gseeW3sue2k+iiq+ato+imj+WMlgogICAga3BLbm93bltrXSA9IHYuejsgLy94LHkseuW3sue2k+iiq+ato+imj+WMlgogIH0pOwoKICAvL2ludERueQogIGxldCBpbnREbnkgPSBEZWxhdW5heS5mcm9tKHBzU3JjT3JpLCBkID0+IGQueCwgZCA9PiBkLnkpOyAvL3gseeW3sue2k+iiq+ato+imj+WMlgoKICAvLyAvL2hwZywg5Y6f5aeL5pW45pOa5b2i5oiQ5pyA5aSW5qGG6YKK55WMCiAgLy8gbGV0IGhwZyA9IGludERueS5odWxsUG9seWdvbigpCiAgLy8gLy8gY29uc29sZS5sb2coJ2ludERueS5odWxsUG9seWdvbicsIGhwZykKCiAgLy92Ym94CiAgbGV0IHZib3ggPSBbMCwgMCwgc2NhbGUsIHNjYWxlXTsKCiAgLy9pbmlWb3IKICBsZXQgaW5pVm9yID0gaW50RG55LnZvcm9ub2kodmJveCk7CiAgLy8gY29uc29sZS5sb2coJ2luaVZvcicsIGluaVZvcikKCiAgLy9hZGRQb2ludENvcmUKICBsZXQgYWRkUG9pbnRDb3JlID0gKGRhdGEsIHgsIHksIGluZFRhcikgPT4gewogICAgLy9wc1NyY1RlbXAKICAgIGxldCBwc1NyY1RlbXAgPSBbLi4ucHNTcmNdOwoKICAgIC8vbmV3SXRlbQogICAgbGV0IG5ld0l0ZW0gPSB7CiAgICAgIHgsCiAgICAgIHksCiAgICAgIHo6IDAKICAgIH07IC8veCx5LHrlt7LntpPooqvmraPopo/ljJYKCiAgICAvL3B1c2gKICAgIHBzU3JjVGVtcC5wdXNoKG5ld0l0ZW0pOwogICAgZGF0YS5wdXNoKG5ld0l0ZW0pOwoKICAgIC8vcG9zdFZvcgogICAgbGV0IHBvc3RWb3IgPSBEZWxhdW5heS5mcm9tKHBzU3JjVGVtcCwgZCA9PiBkLngsIGQgPT4gZC55KS52b3Jvbm9pKHZib3gpOyAvL3gseeW3sue2k+iiq+ato+imj+WMlgogICAgLy8gY29uc29sZS5sb2coJ3Bvc3RWb3InLCBwb3N0Vm9yKQoKICAgIC8vbmV3SWR4CiAgICBsZXQgbmV3SWR4ID0gcHNTcmNUZW1wLmxlbmd0aCAtIDE7CiAgICAvLyBjb25zb2xlLmxvZygnbmV3SWR4JywgbmV3SWR4KQoKICAgIC8vcGdzUXVlcnkKICAgIGxldCBwZ3NRdWVyeSA9IHBvc3RWb3IuY2VsbFBvbHlnb24obmV3SWR4KTsKICAgIC8vIGNvbnNvbGUubG9nKCdwZ3NRdWVyeScsIHBnc1F1ZXJ5KQoKICAgIC8vYXJlYVF1ZXJ5CiAgICBsZXQgYXJlYVF1ZXJ5ID0gZ2V0QXJlYVBvbHlnb24ocGdzUXVlcnkpOwogICAgLy8gY29uc29sZS5sb2coJ2FyZWFRdWVyeScsIGFyZWFRdWVyeSkKCiAgICAvL25ld1BvaW50VmFsCiAgICBsZXQgbmV3UG9pbnRWYWwgPSBudWxsOwogICAgewogICAgICAvL25laWdoYm9ySW5kaWNlcwogICAgICBsZXQgbmVpZ2hib3JJbmRpY2VzID0gW107CiAgICAgIC8vIGZvciAobGV0IGkgb2YgcG9zdFZvci5kZWxhdW5heS5uZWlnaGJvcnMobmV3SWR4KSkgeyAvL+WboOeCunBvc3RWb3IuZGVsYXVuYXkubmVpZ2hib3Jz5pivZ2VuZXJhdG9yLCDogIPmha7opoHmlK/mj7RpZTEx5b6X5L2/55Sod2hpbGXoiIduZXh06K6A5Y+WCiAgICAgIC8vICAgICBuZWlnaGJvckluZGljZXMucHVzaChpKQogICAgICAvLyB9CiAgICAgIGxldCBzcSA9IHBvc3RWb3IuZGVsYXVuYXkubmVpZ2hib3JzKG5ld0lkeCk7CiAgICAgIC8vIGNvbnNvbGUubG9nKGBzcWAsIHNxKQogICAgICBsZXQgbmV4dCA9IHNxLm5leHQoKTsKICAgICAgd2hpbGUgKCFuZXh0LmRvbmUpIHsKICAgICAgICBsZXQgdiA9IG5leHQudmFsdWU7CiAgICAgICAgbmVpZ2hib3JJbmRpY2VzLnB1c2godik7CiAgICAgICAgbmV4dCA9IHNxLm5leHQoKTsKICAgICAgfQogICAgICAvLyBjb25zb2xlLmxvZygnbmVpZ2hib3JJbmRpY2VzJywgbmVpZ2hib3JJbmRpY2VzKQoKICAgICAgLy9zdWJWYWx1ZXMKICAgICAgbGV0IHN1YlZhbHVlcyA9IG1hcChuZWlnaGJvckluZGljZXMsIGlkeCA9PiB7CiAgICAgICAgLy8gY29uc29sZS5sb2coJ2lkeCcsIGlkeCkKCiAgICAgICAgLy9wZ3MxLCBwZ3MyCiAgICAgICAgbGV0IHBnczEgPSBbcGdzUXVlcnldOwogICAgICAgIGxldCBwZ3MyID0gW2luaVZvci5jZWxsUG9seWdvbihpZHgpXTsKICAgICAgICAvLyBjb25zb2xlLmxvZygncGdzMScsIHBnczEsICdwZ3MyJywgcGdzMikKCiAgICAgICAgLy9pbnRlcnNlY3QKICAgICAgICBsZXQgcGdzSW50cyA9IFtdOwogICAgICAgIHRyeSB7CiAgICAgICAgICBwZ3NJbnRzID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyKTsKICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdwZ3NJbnRzJywgcGdzSW50cykKICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgIC8vY29uc29sZS5sb2coJ3BnczEnLCBwZ3MxKQogICAgICAgICAgLy9jb25zb2xlLmxvZygncGdzMicsIHBnczIpCiAgICAgICAgICAvL2NvbnNvbGUubG9nKGVycikKICAgICAgICB9CgogICAgICAgIC8vYXJlYUludHMKICAgICAgICBsZXQgYXJlYUludHMgPSAwOwogICAgICAgIGlmIChzaXplKHBnc0ludHMpID09PSAxKSB7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBhcmVhSW50cyA9IGdldEFyZWFQb2x5Z29uKHBnc0ludHNbMF0pOwogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdnZXRBcmVhUG9seWdvbicsZDMuZ2V0QXJlYVBvbHlnb24oaXMucmVnaW9uc1swXSksZ2V0QXJlYVBvbHlnb24oaXMucmVnaW9uc1swXSkpCiAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgY29uc29sZS5sb2coJ3Bnc0ludHMnLCBwZ3NJbnRzKTsKICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIGlhOiBhcmVhSW50cywKICAgICAgICAgIGlkeAogICAgICAgIH07CiAgICAgIH0pOwogICAgICAvLyBjb25zb2xlLmxvZygnc3ViVmFsdWVzJywgc3ViVmFsdWVzKQoKICAgICAgLy9jaGVjawogICAgICB7CiAgICAgICAgLy9uCiAgICAgICAgbGV0IG4gPSBzaXplKHN1YlZhbHVlcyk7CgogICAgICAgIC8vaWFzCiAgICAgICAgbGV0IGlhcyA9IG1hcChzdWJWYWx1ZXMsICdpYScpOwoKICAgICAgICAvL3IKICAgICAgICBsZXQgciA9IHN1bSQxKGlhcyk7CgogICAgICAgIC8vY2hlY2sKICAgICAgICBpZiAociAhPT0gYXJlYVF1ZXJ5KSB7CiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgaWHnuL3lkozmnInmmYLmnIPkuI3nrYnmlrxhcmVhUXVlcnlgKQogICAgICAgICAgLy9pYee4veWSjOacieaZguacg+S4jeetieaWvGFyZWFRdWVyeQoKICAgICAgICAgIGlmIChhcmVhUXVlcnkgPiAwICYmIHIgPiAwKSB7CiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGDoi6VpYee4veWSjOiIh2FyZWFRdWVyeemDvT4wLCDliYfoqr/mlbTlkIRpYeS9v+WFtue4veWSjOe4ruaUvuiHs2FyZWFRdWVyeWApCiAgICAgICAgICAgIC8v6IulaWHnuL3lkozoiIdhcmVhUXVlcnnpg70+MCwg5YmH6Kq/5pW05ZCEaWHkvb/lhbbnuL3lkoznuK7mlL7oh7NhcmVhUXVlcnkKICAgICAgICAgICAgbGV0IHMgPSBhcmVhUXVlcnkgLyByOwogICAgICAgICAgICBzdWJWYWx1ZXMgPSBtYXAoc3ViVmFsdWVzLCBzdiA9PiB7CiAgICAgICAgICAgICAgc3YuaWEgKj0gczsKICAgICAgICAgICAgICByZXR1cm4gc3Y7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfSBlbHNlIGlmIChhcmVhUXVlcnkgPT09IDAgJiYgciA+IDApIHsKICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYOiLpWFyZWFRdWVyeeeCujDkuJRpYee4veWSjD4wLCDliYfkvb/nlKhpYee4veWSjOeCumFyZWFRdWVyeWApCiAgICAgICAgICAgIC8v6IulYXJlYVF1ZXJ554K6MOS4lGlh57i95ZKMPjAsIOWJh+S9v+eUqGlh57i95ZKM54K6YXJlYVF1ZXJ5CiAgICAgICAgICAgIGFyZWFRdWVyeSA9IHI7CiAgICAgICAgICB9IGVsc2UgaWYgKGFyZWFRdWVyeSA+IDAgJiYgciA9PT0gMCkgewogICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhg6IulYXJlYVF1ZXJ5PjDkuJRpYee4veWSjD0wLCDliYflgYfoqK3lkIRpYeeCuuW5s+WIhmFyZWFRdWVyeWApCiAgICAgICAgICAgIC8v6IulYXJlYVF1ZXJ5PjDkuJRpYee4veWSjD0wLCDliYflgYfoqK3lkIRpYeeCuuW5s+WIhmFyZWFRdWVyeQogICAgICAgICAgICBsZXQgcyA9IGFyZWFRdWVyeSAvIG47CiAgICAgICAgICAgIHN1YlZhbHVlcyA9IG1hcChzdWJWYWx1ZXMsIHN2ID0+IHsKICAgICAgICAgICAgICBzdi5pYSA9IHM7CiAgICAgICAgICAgICAgcmV0dXJuIHN2OwogICAgICAgICAgICB9KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdhcmVhUXVlcnknLCBhcmVhUXVlcnkpOwogICAgICAgICAgICBjb25zb2xlLmxvZygnc3VtKGlhcyknLCByKTsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcmVhUXVlcnkhPT1zdW0oaWFzKSAmJiAoYXJlYVF1ZXJ5PDAgb3Igc3VtKGlhcyk8MCknKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGFyZWFRdWVyeSA9PT0gMCkgewogICAgICAgICAgLy8gY29uc29sZS5sb2coYOiLpWFyZWFRdWVyeT0w5LiUaWHnuL3lkow9MCwg5YmH5YGH6KitYXJlYVF1ZXJ554K6MSwg6ICM5ZCEaWHngrrlubPliIYxYCkKICAgICAgICAgIC8v6IulYXJlYVF1ZXJ5PWlh57i95ZKMPTAsIOWJh+WBh+iorWFyZWFRdWVyeeeCujEsIOiAjOWQhGlh54K65bmz5YiGMQogICAgICAgICAgYXJlYVF1ZXJ5ID0gMTsKICAgICAgICAgIGxldCBzID0gMSAvIG47CiAgICAgICAgICBzdWJWYWx1ZXMgPSBtYXAoc3ViVmFsdWVzLCBzdiA9PiB7CiAgICAgICAgICAgIHN2LmlhID0gczsKICAgICAgICAgICAgcmV0dXJuIHN2OwogICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIGlmIChhcmVhUXVlcnkgPCAwKSB7CiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhg6IulYXJlYVF1ZXJ5PWlh57i95ZKMPDAsIOWJh+WgsemMr2ApCiAgICAgICAgICAvL+iLpWFyZWFRdWVyeT1pYee4veWSjDwwLCDliYfloLHpjK8KICAgICAgICAgIGNvbnNvbGUubG9nKCdhcmVhUXVlcnknLCBhcmVhUXVlcnkpOwogICAgICAgICAgY29uc29sZS5sb2coJ3N1bShpYXMpJywgcik7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FyZWFRdWVyeTwwICYmIHN1bShpYXMpPDAnKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vbmV3UG9pbnRWYWxzCiAgICAgIGxldCBuZXdQb2ludFZhbHMgPSBbXTsKICAgICAgZm9yRWFjaChzdWJWYWx1ZXMsIG8gPT4gewogICAgICAgIC8vckEsIHosIHYKICAgICAgICBsZXQgckEgPSBvLmlhIC8gYXJlYVF1ZXJ5OwogICAgICAgIGxldCB6ID0gZGF0YVtvLmlkeF0uejsgLy94LHkseuW3sue2k+iiq+ato+imj+WMlgogICAgICAgIGxldCB2ID0gckEgKiB6OwogICAgICAgIC8vIGNvbnNvbGUubG9nKCdzdWJWYWx1ZScsICdyQScsIHJBLCAnby5pZHgnLCBvLmlkeCwgJ3onLCB6LCAndicsIHYpCgogICAgICAgIC8vdXNlRnVuSW50ZXJwRnJhZ21lbnQKICAgICAgICBpZiAodXNlRnVuSW50ZXJwRnJhZ21lbnQpIHsKICAgICAgICAgIHYgPSBmdW5JbnRlcnBGcmFnbWVudCh7CiAgICAgICAgICAgIHYsCiAgICAgICAgICAgIGFyZWE6IG8uaWEsCiAgICAgICAgICAgIGFyZWFUb3RhbDogYXJlYVF1ZXJ5LAogICAgICAgICAgICBhcmVhUmF0aW86IHJBLAogICAgICAgICAgICB6LAogICAgICAgICAgICBpbmRTcmM6IG8uaWR4LAogICAgICAgICAgICBpbmRUYXIKICAgICAgICAgICAgLy8gZGF0YSwKICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy9wCiAgICAgICAgbGV0IHAgPSB7CiAgICAgICAgICB2LAogICAgICAgICAgYXJlYTogby5pYSwKICAgICAgICAgIGFyZWFUb3RhbDogYXJlYVF1ZXJ5LAogICAgICAgICAgYXJlYVJhdGlvOiByQSwKICAgICAgICAgIHosCiAgICAgICAgICBpbmRTcmM6IG8uaWR4LAogICAgICAgICAgaW5kVGFyCiAgICAgICAgfTsKCiAgICAgICAgLy9wdXNoCiAgICAgICAgbmV3UG9pbnRWYWxzLnB1c2gocCk7CiAgICAgIH0pOwoKICAgICAgLy9uZXdQb2ludFZhbAogICAgICBsZXQgdnQgPSBzdW0kMShtYXAobmV3UG9pbnRWYWxzLCAndicpKTsKICAgICAgaWYgKHVzZUZ1bkludGVycEZyYWdtZW50cykgewogICAgICAgIHZ0ID0gZnVuSW50ZXJwRnJhZ21lbnRzKHsKICAgICAgICAgIHBzOiBuZXdQb2ludFZhbHMsCiAgICAgICAgICB2OiB2dCwKICAgICAgICAgIGluZFRhciwKICAgICAgICAgIGZ1bkludjogdnYgPT4gewogICAgICAgICAgICByZXR1cm4gaW52KHZ2LCAyKTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgICBuZXdQb2ludFZhbCA9IHZ0OwoKICAgICAgLy8gaWYgKGlzTmFOKG5ld1BvaW50VmFsKSkgewogICAgICAvLyAgICAgY29uc29sZS5sb2coJ2lzTmFOKG5ld1BvaW50VmFsKScsIHN1YlZhbHVlcywgJ2FyZWFRdWVyeScsIGFyZWFRdWVyeSkKICAgICAgLy8gfQogICAgICAvLyBjb25zb2xlLmxvZyhgYXJlYVF1ZXJ5WyR7YXJlYVF1ZXJ5fV0gPiAwYCwgJ25ld1BvaW50VmFsJywgbmV3UG9pbnRWYWwpCiAgICB9CgogICAgLy91cGRhdGUgbmV3UG9pbnRWYWwKICAgIGRhdGFbZGF0YS5sZW5ndGggLSAxXS56ID0gbmV3UG9pbnRWYWw7IC8veCx5LHrlt7LntpPooqvmraPopo/ljJYKCiAgICByZXR1cm4gbmV3UG9pbnRWYWw7CiAgfTsKCiAgLy9hZGRQb2ludAogIGxldCBhZGRQb2ludCA9IChkYXRhLCB4LCB5LCBpbmRUYXIpID0+IHsKICAgIC8vcgogICAgbGV0IHI7CiAgICB0cnkgewogICAgICByID0gYWRkUG9pbnRDb3JlKGRhdGEsIHgsIHksIGluZFRhcik7CiAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgY29uc29sZS5sb2coZXJyKTsKICAgICAgciA9IG51bGw7CiAgICAgIGRhdGEucG9wKCk7CiAgICB9CiAgICByZXR1cm4gcjsKICB9OwoKICAvL2dldE56CiAgbGV0IGdldE56ID0gKG54LCBueSwgaW5kVGFyKSA9PiB7CiAgICAvL2NoZWNrCiAgICBsZXQgayA9IGAke254fS0ke255fWA7IC8veCx55bey57aT6KKr5q2j6KaP5YyWCiAgICBpZiAoaGFza2V5KGtwS25vd24sIGspKSB7CiAgICAgIHJldHVybiBrcEtub3duW2tdOwogICAgfQoKICAgIC8vY2hlY2sKICAgIGlmIChueCA8IHZib3hbMF0gfHwgbnggPiB2Ym94WzJdIHx8IG55IDwgdmJveFsxXSB8fCBueSA+IHZib3hbM10pIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLy9wcmVkaWN0CiAgICBsZXQgbnogPSBhZGRQb2ludChwc1NyY0l0ciwgbngsIG55LCBpbmRUYXIpOwoKICAgIC8vc2F2ZQogICAga3BLbm93bltrXSA9IG56OwogICAgcmV0dXJuIG56OwogIH07CgogIC8vaXR2CiAgbGV0IGl0diA9IChwLCBpbmRUYXIpID0+IHsKICAgIC8veCwgbngKICAgIGxldCB4ID0gcC54OwogICAgbGV0IG54ID0gbnYoeCwgJ3gnKTsKICAgIGlmICghaXNOdW1iZXIobngpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBueFske254fV1gKTsgLy94LHnpoJDmnJ/pg73mmK/mnInlgLwKICAgIH0KCiAgICAvL3ksIG55CiAgICBsZXQgeSA9IHAueTsKICAgIGxldCBueSA9IG52KHksICd5Jyk7CiAgICBpZiAoIWlzTnVtYmVyKG55KSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgbnlbJHtueX1dYCk7IC8veCx56aCQ5pyf6YO95piv5pyJ5YC8CiAgICB9CgogICAgLy9ueiwgegogICAgbGV0IG56ID0gZ2V0TnoobngsIG55LCBpbmRUYXIpOwogICAgbGV0IHogPSBpbnYobnosICd6Jyk7CiAgICBpZiAoIWlzTnVtYmVyKHopKSB7CiAgICAgIHogPSBudWxsOyAvL3rpoIjmlK/mj7Tlj6/og73nhKHms5Xlhafmj5IKICAgIH0KCiAgICAvLyBjb25zb2xlLmxvZygneCcsIHgsICd5JywgeSwgJ3onLCB6KQogICAgLy8gY29uc29sZS5sb2coJ254JywgbngsICdueScsIG55LCAnbnonLCBueikKCiAgICAvL3IKICAgIGxldCByID0gewogICAgICBba2V5WF06IHgsCiAgICAgIFtrZXlZXTogeSwKICAgICAgW2tleVpdOiB6CiAgICB9OwogICAgcmV0dXJuIHI7CiAgfTsKCiAgLy9yCiAgbGV0IHI7CiAgaWYgKGlzT25lKSB7CiAgICBsZXQgcCA9IHBzVGFyWzBdOwogICAgciA9IGl0dihwLCAwKTsKICB9IGVsc2UgewogICAgciA9IFtdOwogICAgZm9yRWFjaChwc1RhciwgKHAsIGluZFRhcikgPT4gewogICAgICByLnB1c2goaXR2KHAsIGluZFRhcikpOwogICAgfSk7CiAgfQogIHJldHVybiByOwp9CgovL2ZvcmsgZnJvbTogaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29lbzRiL2tyaWdpbmcuanMvbWFzdGVyL2tyaWdpbmcuanMKCi8v56m66ZaT57Wx6KiI5YiG5p6Q5LmL6K6K55Ww5pW455qE55CG6KuW5qih5Z6LOiBodHRwczovL3d3dy5zdXBlcmdlb3Rlay5jb20vdHcvbWFudWFscy9TU0EvdG9waWMzMi5odG0KLy/lnKjnqbrplpPliIbmnpDnmoTlgYfoqK3kuYvkuIvvvIznm7jphLDmhIjov5HnmoTlhanpu57vvIzlnKjnm7jkvLzmiJbmmK/nm7jpl5znqIvluqbkuIrmh4nmnInovIPlvLfnmoTpl5zkv4LjgILlj43kuYvvvIzoi6Xlhanpu57nmoTot53pm6Lmi4nlpKfvvIzliYflhbbplpPnmoTnm7jpl5znqIvluqbmh4nkuZ/mnIPlsLHmraTpmY3kvY7jgIIKLy/ogIzljYrorornlbDlnJbvvIhTZW1pdmFyaW9ncmFtc++8ieiIh+WFseiuiuaVuO+8iENvdmFyaWFuY2XvvInnkIboq5bnmoTnmbzlsZXvvIzlnYfmmK/nlKjph4/muKzot53pm6LnmoTkupLnm7jpl5znqIvluqbvvIzljbPmmK/lsIfmraTop4Dlv7XpgI/pgY7mlrnnqIvlvI/nmoTovYnmj5vlsIflhbbph4/ljJbjgIIKCi8vIC8vIEV4dGVuZCB0aGUgQXJyYXkgY2xhc3MKLy8gQXJyYXkucHJvdG90eXBlLm1heCA9IGZ1bmN0aW9uKCkgewovLyAgICAgcmV0dXJuIE1hdGgubWF4LmFwcGx5KG51bGwsIHRoaXMpCi8vIH0KLy8gQXJyYXkucHJvdG90eXBlLm1pbiA9IGZ1bmN0aW9uKCkgewovLyAgICAgcmV0dXJuIE1hdGgubWluLmFwcGx5KG51bGwsIHRoaXMpCi8vIH0KLy8gQXJyYXkucHJvdG90eXBlLm1lYW4gPSBmdW5jdGlvbigpIHsKLy8gICAgIGxldCBpLCBzdW0KLy8gICAgIGZvciAoaSA9IDAsIHN1bSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7Ci8vICAgICAgICAgc3VtICs9IHRoaXNbaV0KLy8gICAgIH0KLy8gICAgIHJldHVybiBzdW0gLyB0aGlzLmxlbmd0aAovLyB9Ci8vIEFycmF5LnByb3RvdHlwZS5waXAgPSBmdW5jdGlvbih4LCB5KSB7Ci8vICAgICBsZXQgaTsgbGV0IGo7IGxldCBjID0gZmFsc2UKLy8gICAgIGZvciAoaSA9IDAsIGogPSB0aGlzLmxlbmd0aCAtIDE7IGkgPCB0aGlzLmxlbmd0aDsgaiA9IGkrKykgewovLyAgICAgICAgIGlmICgoKHRoaXNbaV1bMV0gPiB5KSAhPT0gKHRoaXNbal1bMV0gPiB5KSkgJiYKLy8gICAgICAoeCA8ICh0aGlzW2pdWzBdIC0gdGhpc1tpXVswXSkgKiAoeSAtIHRoaXNbaV1bMV0pIC8gKHRoaXNbal1bMV0gLSB0aGlzW2ldWzFdKSArIHRoaXNbaV1bMF0pKSB7Ci8vICAgICAgYyA9ICFjCi8vICAgICAgICAgfQovLyAgICAgfQovLyAgICAgcmV0dXJuIGMKLy8gfQoKbGV0IGtyaWdpbmcgPSB7fTsKCi8vIGxldCBwaXAgPSBmdW5jdGlvbihhcnIsIHgsIHkpIHsKLy8gICAgIGxldCBpCi8vICAgICBsZXQgagovLyAgICAgbGV0IGMgPSBmYWxzZQovLyAgICAgZm9yIChpID0gMCwgaiA9IGFyci5sZW5ndGggLSAxOyBpIDwgYXJyLmxlbmd0aDsgaiA9IGkrKykgewovLyAgICAgICAgIGlmICgoKGFycltpXVsxXSA+IHkpICE9PSAoYXJyW2pdWzFdID4geSkpICYmCi8vICAgICAgICAgICh4IDwgKGFycltqXVswXSAtIGFycltpXVswXSkgKiAoeSAtIGFycltpXVsxXSkgLyAoYXJyW2pdWzFdIC0gYXJyW2ldWzFdKSArIGFycltpXVswXSkpIHsKLy8gICAgICAgICAgICAgYyA9ICFjCi8vICAgICAgICAgfQovLyAgICAgfQovLyAgICAgcmV0dXJuIGMKLy8gfQoKbGV0IGNyZWF0ZUFycmF5V2l0aFZhbHVlcyA9IGZ1bmN0aW9uICh2YWx1ZSwgbikgewogIGxldCBhcnJheSA9IFtdOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBhcnJheS5wdXNoKHZhbHVlKTsKICB9CiAgcmV0dXJuIGFycmF5Owp9OwoKLy8gTWF0cml4IGFsZ2VicmEKbGV0IGtyaWdpbmdfbWF0cml4X2RpYWcgPSBmdW5jdGlvbiAoYywgbikgewogIGxldCBaID0gY3JlYXRlQXJyYXlXaXRoVmFsdWVzKDAsIG4gKiBuKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgWltpICogbiArIGldID0gYzsKICByZXR1cm4gWjsKfTsKbGV0IGtyaWdpbmdfbWF0cml4X3RyYW5zcG9zZSA9IGZ1bmN0aW9uIChYLCBuLCBtKSB7CiAgbGV0IGk7CiAgbGV0IGo7CiAgbGV0IFogPSBBcnJheShtICogbik7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IG07IGorKykgewogICAgICBaW2ogKiBuICsgaV0gPSBYW2kgKiBtICsgal07CiAgICB9CiAgfQogIHJldHVybiBaOwp9OwoKLy8gbGV0IGtyaWdpbmdfbWF0cml4X3NjYWxlID0gZnVuY3Rpb24oWCwgYywgbiwgbSkgewovLyAgICAgbGV0IGksIGoKLy8gICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKLy8gICAgICAgICBmb3IgKGogPSAwOyBqIDwgbTsgaisrKSB7Ci8vICAgICAgICAgICAgIFhbaSAqIG0gKyBqXSAqPSBjCi8vICAgICAgICAgfQovLyAgICAgfQovLyB9CgpsZXQga3JpZ2luZ19tYXRyaXhfYWRkID0gZnVuY3Rpb24gKFgsIFksIG4sIG0pIHsKICBsZXQgaTsKICBsZXQgajsKICBsZXQgWiA9IEFycmF5KG4gKiBtKTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgbTsgaisrKSB7CiAgICAgIFpbaSAqIG0gKyBqXSA9IFhbaSAqIG0gKyBqXSArIFlbaSAqIG0gKyBqXTsKICAgIH0KICB9CiAgcmV0dXJuIFo7Cn07CgovLyBOYWl2ZSBtYXRyaXggbXVsdGlwbGljYXRpb24KbGV0IGtyaWdpbmdfbWF0cml4X211bHRpcGx5ID0gZnVuY3Rpb24gKFgsIFksIG4sIG0sIHApIHsKICBsZXQgaTsKICBsZXQgajsKICBsZXQgazsKICBsZXQgWiA9IEFycmF5KG4gKiBwKTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgcDsgaisrKSB7CiAgICAgIFpbaSAqIHAgKyBqXSA9IDA7CiAgICAgIGZvciAoayA9IDA7IGsgPCBtOyBrKyspIHsKICAgICAgICBaW2kgKiBwICsgal0gKz0gWFtpICogbSArIGtdICogWVtrICogcCArIGpdOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBaOwp9OwoKLy8gQ2hvbGVza3kgZGVjb21wb3NpdGlvbgpsZXQga3JpZ2luZ19tYXRyaXhfY2hvbCA9IGZ1bmN0aW9uIChYLCBuKSB7CiAgbGV0IGk7CiAgbGV0IGo7CiAgbGV0IGs7CiAgbGV0IHAgPSBBcnJheShuKTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBwW2ldID0gWFtpICogbiArIGldOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBpOyBqKyspIHsKICAgICAgcFtpXSAtPSBYW2kgKiBuICsgal0gKiBYW2kgKiBuICsgal07CiAgICB9CiAgICBpZiAocFtpXSA8PSAwKSByZXR1cm4gZmFsc2U7CiAgICBwW2ldID0gTWF0aC5zcXJ0KHBbaV0pOwogICAgZm9yIChqID0gaSArIDE7IGogPCBuOyBqKyspIHsKICAgICAgZm9yIChrID0gMDsgayA8IGk7IGsrKykgewogICAgICAgIFhbaiAqIG4gKyBpXSAtPSBYW2ogKiBuICsga10gKiBYW2kgKiBuICsga107CiAgICAgIH0KICAgICAgWFtqICogbiArIGldIC89IHBbaV07CiAgICB9CiAgfQogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIFhbaSAqIG4gKyBpXSA9IHBbaV07CiAgcmV0dXJuIHRydWU7Cn07CgovLyBJbnZlcnNpb24gb2YgY2hvbGVza3kgZGVjb21wb3NpdGlvbgpsZXQga3JpZ2luZ19tYXRyaXhfY2hvbDJpbnYgPSBmdW5jdGlvbiAoWCwgbikgewogIGxldCBpOwogIGxldCBqOwogIGxldCBrOwogIGxldCBzdW07CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgWFtpICogbiArIGldID0gMSAvIFhbaSAqIG4gKyBpXTsKICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7CiAgICAgIHN1bSA9IDA7CiAgICAgIGZvciAoayA9IGk7IGsgPCBqOyBrKyspIHsKICAgICAgICBzdW0gLT0gWFtqICogbiArIGtdICogWFtrICogbiArIGldOwogICAgICB9CiAgICAgIFhbaiAqIG4gKyBpXSA9IHN1bSAvIFhbaiAqIG4gKyBqXTsKICAgIH0KICB9CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gaSArIDE7IGogPCBuOyBqKyspIHsKICAgICAgWFtpICogbiArIGpdID0gMDsKICAgIH0KICB9CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgWFtpICogbiArIGldICo9IFhbaSAqIG4gKyBpXTsKICAgIGZvciAoayA9IGkgKyAxOyBrIDwgbjsgaysrKSB7CiAgICAgIFhbaSAqIG4gKyBpXSArPSBYW2sgKiBuICsgaV0gKiBYW2sgKiBuICsgaV07CiAgICB9CiAgICBmb3IgKGogPSBpICsgMTsgaiA8IG47IGorKykgewogICAgICBmb3IgKGsgPSBqOyBrIDwgbjsgaysrKSB7CiAgICAgICAgWFtpICogbiArIGpdICs9IFhbayAqIG4gKyBpXSAqIFhbayAqIG4gKyBqXTsKICAgICAgfQogICAgfQogIH0KICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgaTsgaisrKSB7CiAgICAgIFhbaSAqIG4gKyBqXSA9IFhbaiAqIG4gKyBpXTsKICAgIH0KICB9Cn07CgovLyBJbnZlcnNpb24gdmlhIGdhdXNzLWpvcmRhbiBlbGltaW5hdGlvbgpsZXQga3JpZ2luZ19tYXRyaXhfc29sdmUgPSBmdW5jdGlvbiAoWCwgbikgewogIGxldCBtID0gbjsKICBsZXQgYiA9IEFycmF5KG4gKiBuKTsKICBsZXQgaW5keGMgPSBBcnJheShuKTsKICBsZXQgaW5keHIgPSBBcnJheShuKTsKICBsZXQgaXBpdiA9IEFycmF5KG4pOwogIGxldCBpOwogIGxldCBpY29sOwogIGxldCBpcm93OwogIGxldCBqOwogIGxldCBrOwogIGxldCBsOwogIGxldCBsbDsKICBsZXQgYmlnLCBkdW0sIHBpdmludiwgdGVtcDsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgIGlmIChpID09PSBqKSBiW2kgKiBuICsgal0gPSAxO2Vsc2UgYltpICogbiArIGpdID0gMDsKICAgIH0KICB9CiAgZm9yIChqID0gMDsgaiA8IG47IGorKykgaXBpdltqXSA9IDA7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgYmlnID0gMDsKICAgIGZvciAoaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgaWYgKGlwaXZbal0gIT09IDEpIHsKICAgICAgICBmb3IgKGsgPSAwOyBrIDwgbjsgaysrKSB7CiAgICAgICAgICBpZiAoaXBpdltrXSA9PT0gMCkgewogICAgICAgICAgICBpZiAoTWF0aC5hYnMoWFtqICogbiArIGtdKSA+PSBiaWcpIHsKICAgICAgICAgICAgICBiaWcgPSBNYXRoLmFicyhYW2ogKiBuICsga10pOwogICAgICAgICAgICAgIGlyb3cgPSBqOwogICAgICAgICAgICAgIGljb2wgPSBrOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICArK2lwaXZbaWNvbF07CiAgICBpZiAoaXJvdyAhPT0gaWNvbCkgewogICAgICBmb3IgKGwgPSAwOyBsIDwgbjsgbCsrKSB7CiAgICAgICAgdGVtcCA9IFhbaXJvdyAqIG4gKyBsXTsKICAgICAgICBYW2lyb3cgKiBuICsgbF0gPSBYW2ljb2wgKiBuICsgbF07CiAgICAgICAgWFtpY29sICogbiArIGxdID0gdGVtcDsKICAgICAgfQogICAgICBmb3IgKGwgPSAwOyBsIDwgbTsgbCsrKSB7CiAgICAgICAgdGVtcCA9IGJbaXJvdyAqIG4gKyBsXTsKICAgICAgICBiW2lyb3cgKiBuICsgbF0gPSBiW2ljb2wgKiBuICsgbF07CiAgICAgICAgYltpY29sICogbiArIGxdID0gdGVtcDsKICAgICAgfQogICAgfQogICAgaW5keHJbaV0gPSBpcm93OwogICAgaW5keGNbaV0gPSBpY29sOwogICAgaWYgKFhbaWNvbCAqIG4gKyBpY29sXSA9PT0gMCkgcmV0dXJuIGZhbHNlOyAvLyBTaW5ndWxhcgoKICAgIHBpdmludiA9IDEgLyBYW2ljb2wgKiBuICsgaWNvbF07CiAgICBYW2ljb2wgKiBuICsgaWNvbF0gPSAxOwogICAgZm9yIChsID0gMDsgbCA8IG47IGwrKykgWFtpY29sICogbiArIGxdICo9IHBpdmludjsKICAgIGZvciAobCA9IDA7IGwgPCBtOyBsKyspIGJbaWNvbCAqIG4gKyBsXSAqPSBwaXZpbnY7CiAgICBmb3IgKGxsID0gMDsgbGwgPCBuOyBsbCsrKSB7CiAgICAgIGlmIChsbCAhPT0gaWNvbCkgewogICAgICAgIGR1bSA9IFhbbGwgKiBuICsgaWNvbF07CiAgICAgICAgWFtsbCAqIG4gKyBpY29sXSA9IDA7CiAgICAgICAgZm9yIChsID0gMDsgbCA8IG47IGwrKykgWFtsbCAqIG4gKyBsXSAtPSBYW2ljb2wgKiBuICsgbF0gKiBkdW07CiAgICAgICAgZm9yIChsID0gMDsgbCA8IG07IGwrKykgYltsbCAqIG4gKyBsXSAtPSBiW2ljb2wgKiBuICsgbF0gKiBkdW07CiAgICAgIH0KICAgIH0KICB9CiAgZm9yIChsID0gbiAtIDE7IGwgPj0gMDsgbC0tKSB7CiAgICBpZiAoaW5keHJbbF0gIT09IGluZHhjW2xdKSB7CiAgICAgIGZvciAoayA9IDA7IGsgPCBuOyBrKyspIHsKICAgICAgICB0ZW1wID0gWFtrICogbiArIGluZHhyW2xdXTsKICAgICAgICBYW2sgKiBuICsgaW5keHJbbF1dID0gWFtrICogbiArIGluZHhjW2xdXTsKICAgICAgICBYW2sgKiBuICsgaW5keGNbbF1dID0gdGVtcDsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gdHJ1ZTsKfTsKCi8vIFZhcmlvZ3JhbSBtb2RlbHMKbGV0IGtyaWdpbmdfdmFyaW9ncmFtX2dhdXNzaWFuID0gZnVuY3Rpb24gKGgsIG51Z2dldCwgcmFuZ2UsIHNpbGwsIEEpIHsKICByZXR1cm4gbnVnZ2V0ICsgKHNpbGwgLSBudWdnZXQpIC8gcmFuZ2UgKiAoMS4wIC0gTWF0aC5leHAoLSgxLjAgLyBBKSAqIE1hdGgucG93KGggLyByYW5nZSwgMikpKTsKfTsKbGV0IGtyaWdpbmdfdmFyaW9ncmFtX2V4cG9uZW50aWFsID0gZnVuY3Rpb24gKGgsIG51Z2dldCwgcmFuZ2UsIHNpbGwsIEEpIHsKICByZXR1cm4gbnVnZ2V0ICsgKHNpbGwgLSBudWdnZXQpIC8gcmFuZ2UgKiAoMS4wIC0gTWF0aC5leHAoLSgxLjAgLyBBKSAqIChoIC8gcmFuZ2UpKSk7Cn07CmxldCBrcmlnaW5nX3ZhcmlvZ3JhbV9zcGhlcmljYWwgPSBmdW5jdGlvbiAoaCwgbnVnZ2V0LCByYW5nZSwgc2lsbCwgQSkgewogIGlmIChoID4gcmFuZ2UpIHJldHVybiBudWdnZXQgKyAoc2lsbCAtIG51Z2dldCkgLyByYW5nZTsKICByZXR1cm4gbnVnZ2V0ICsgKHNpbGwgLSBudWdnZXQpIC8gcmFuZ2UgKiAoMS41ICogKGggLyByYW5nZSkgLSAwLjUgKiBNYXRoLnBvdyhoIC8gcmFuZ2UsIDMpKTsKfTsKCi8vIFRyYWluIHVzaW5nIGdhdXNzaWFuIHByb2Nlc3NlcyB3aXRoIGJheWVzaWFuIHByaW9ycwprcmlnaW5nLnRyYWluID0gZnVuY3Rpb24gKHQsIHgsIHksIG1vZGVsLCBzaWdtYTIsIGFscGhhKSB7CiAgbGV0IHZhcmlvZ3JhbSA9IHsKICAgIHQsCiAgICB4LAogICAgeSwKICAgIG51Z2dldDogMC4wLAogICAgcmFuZ2U6IDAuMCwKICAgIHNpbGw6IDAuMCwKICAgIEE6IDEgLyAzLAogICAgbjogMAogIH07CiAgc3dpdGNoIChtb2RlbCkgewogICAgY2FzZSAnZ2F1c3NpYW4nOgogICAgICB2YXJpb2dyYW0ubW9kZWwgPSBrcmlnaW5nX3ZhcmlvZ3JhbV9nYXVzc2lhbjsKICAgICAgYnJlYWs7CiAgICBjYXNlICdleHBvbmVudGlhbCc6CiAgICAgIHZhcmlvZ3JhbS5tb2RlbCA9IGtyaWdpbmdfdmFyaW9ncmFtX2V4cG9uZW50aWFsOwogICAgICBicmVhazsKICAgIGNhc2UgJ3NwaGVyaWNhbCc6CiAgICAgIHZhcmlvZ3JhbS5tb2RlbCA9IGtyaWdpbmdfdmFyaW9ncmFtX3NwaGVyaWNhbDsKICAgICAgYnJlYWs7CiAgfQoKICAvLyBMYWcgZGlzdGFuY2Uvc2VtaXZhcmlhbmNlCiAgbGV0IGk7CiAgbGV0IGo7CiAgbGV0IGs7CiAgbGV0IGw7CiAgbGV0IG4gPSB0Lmxlbmd0aDsKICBsZXQgZGlzdGFuY2UgPSBBcnJheSgobiAqIG4gLSBuKSAvIDIpOwogIGZvciAoaSA9IDAsIGsgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgaTsgaisrLCBrKyspIHsKICAgICAgZGlzdGFuY2Vba10gPSBBcnJheSgyKTsKICAgICAgZGlzdGFuY2Vba11bMF0gPSBNYXRoLnBvdyhNYXRoLnBvdyh4W2ldIC0geFtqXSwgMikgKyBNYXRoLnBvdyh5W2ldIC0geVtqXSwgMiksIDAuNSk7CiAgICAgIGRpc3RhbmNlW2tdWzFdID0gTWF0aC5hYnModFtpXSAtIHRbal0pOwogICAgfQogIH0KICBkaXN0YW5jZS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7CiAgICByZXR1cm4gYVswXSAtIGJbMF07CiAgfSk7CiAgdmFyaW9ncmFtLnJhbmdlID0gZGlzdGFuY2VbKG4gKiBuIC0gbikgLyAyIC0gMV1bMF07CgogIC8vIEJpbiBsYWcgZGlzdGFuY2UKICBsZXQgbGFncyA9IChuICogbiAtIG4pIC8gMiA+IDMwID8gMzAgOiAobiAqIG4gLSBuKSAvIDI7CiAgLy8gY29uc29sZS5sb2coJ2xhZ3MnLCBsYWdzKQogIGxldCB0b2xlcmFuY2UgPSB2YXJpb2dyYW0ucmFuZ2UgLyBsYWdzOwogIGxldCBsYWcgPSBjcmVhdGVBcnJheVdpdGhWYWx1ZXMoMCwgbGFncyk7CiAgbGV0IHNlbWkgPSBjcmVhdGVBcnJheVdpdGhWYWx1ZXMoMCwgbGFncyk7CiAgaWYgKGxhZ3MgPCAzMCkgewogICAgZm9yIChsID0gMDsgbCA8IGxhZ3M7IGwrKykgewogICAgICBsYWdbbF0gPSBkaXN0YW5jZVtsXVswXTsKICAgICAgc2VtaVtsXSA9IGRpc3RhbmNlW2xdWzFdOwogICAgfQogIH0gZWxzZSB7CiAgICBmb3IgKGkgPSAwLCBqID0gMCwgayA9IDAsIGwgPSAwOyBpIDwgbGFncyAmJiBqIDwgKG4gKiBuIC0gbikgLyAyOyBpKyssIGsgPSAwKSB7CiAgICAgIHdoaWxlIChkaXN0YW5jZVtqXVswXSA8PSAoaSArIDEpICogdG9sZXJhbmNlKSB7CiAgICAgICAgbGFnW2xdICs9IGRpc3RhbmNlW2pdWzBdOwogICAgICAgIHNlbWlbbF0gKz0gZGlzdGFuY2Vbal1bMV07CiAgICAgICAgaisrOwogICAgICAgIGsrKzsKICAgICAgICBpZiAoaiA+PSAobiAqIG4gLSBuKSAvIDIpIGJyZWFrOwogICAgICB9CiAgICAgIGlmIChrID4gMCkgewogICAgICAgIGxhZ1tsXSAvPSBrOwogICAgICAgIHNlbWlbbF0gLz0gazsKICAgICAgICBsKys7CiAgICAgICAgLy8gY29uc29sZS5sb2coJ2wrKycsIGwpCiAgICAgIH0KICAgIH0KCiAgICBpZiAobCA8IDIpIHJldHVybiB2YXJpb2dyYW07IC8vIEVycm9yOiBOb3QgZW5vdWdoIHBvaW50cwogIH0KCiAgLy9zYXZlCiAgbGV0IGJhcnMgPSBbXTsKICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7CiAgICBsZXQgczAgPSBsYWdbaV07CiAgICBsZXQgczEgPSBzZW1pW2ldOwogICAgYmFycy5wdXNoKFtzMCwgczFdKTsKICB9CiAgbGV0IHN2cGQgPSB7CiAgICBkYXRhOiBkaXN0YW5jZSwKICAgIGJhcnMKICB9OwogIHZhcmlvZ3JhbS5zdnBkID0gc3ZwZDsKCiAgLy8gRmVhdHVyZSB0cmFuc2Zvcm1hdGlvbgogIG4gPSBsOwogIHZhcmlvZ3JhbS5yYW5nZSA9IGxhZ1tuIC0gMV0gLSBsYWdbMF07CiAgbGV0IFggPSBjcmVhdGVBcnJheVdpdGhWYWx1ZXMoMSwgMiAqIG4pOwogIGxldCBZID0gQXJyYXkobik7CiAgbGV0IEEgPSB2YXJpb2dyYW0uQTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBzd2l0Y2ggKG1vZGVsKSB7CiAgICAgIGNhc2UgJ2dhdXNzaWFuJzoKICAgICAgICBYW2kgKiAyICsgMV0gPSAxLjAgLSBNYXRoLmV4cCgtKDEuMCAvIEEpICogTWF0aC5wb3cobGFnW2ldIC8gdmFyaW9ncmFtLnJhbmdlLCAyKSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ2V4cG9uZW50aWFsJzoKICAgICAgICBYW2kgKiAyICsgMV0gPSAxLjAgLSBNYXRoLmV4cCgtKDEuMCAvIEEpICogbGFnW2ldIC8gdmFyaW9ncmFtLnJhbmdlKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnc3BoZXJpY2FsJzoKICAgICAgICBYW2kgKiAyICsgMV0gPSAxLjUgKiAobGFnW2ldIC8gdmFyaW9ncmFtLnJhbmdlKSAtIDAuNSAqIE1hdGgucG93KGxhZ1tpXSAvIHZhcmlvZ3JhbS5yYW5nZSwgMyk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBZW2ldID0gc2VtaVtpXTsKICB9CgogIC8vIExlYXN0IHNxdWFyZXMKICBsZXQgWHQgPSBrcmlnaW5nX21hdHJpeF90cmFuc3Bvc2UoWCwgbiwgMik7CiAgbGV0IFogPSBrcmlnaW5nX21hdHJpeF9tdWx0aXBseShYdCwgWCwgMiwgbiwgMik7CiAgWiA9IGtyaWdpbmdfbWF0cml4X2FkZChaLCBrcmlnaW5nX21hdHJpeF9kaWFnKDEgLyBhbHBoYSwgMiksIDIsIDIpOwogIGxldCBjbG9uZVogPSBaLnNsaWNlKDApOwogIGlmIChrcmlnaW5nX21hdHJpeF9jaG9sKFosIDIpKSB7CiAgICBrcmlnaW5nX21hdHJpeF9jaG9sMmludihaLCAyKTsKICB9IGVsc2UgewogICAga3JpZ2luZ19tYXRyaXhfc29sdmUoY2xvbmVaLCAyKTsKICAgIFogPSBjbG9uZVo7CiAgfQogIGxldCBXID0ga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoa3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoWiwgWHQsIDIsIDIsIG4pLCBZLCAyLCBuLCAxKTsKCiAgLy8gVmFyaW9ncmFtIHBhcmFtZXRlcnMKICB2YXJpb2dyYW0ubnVnZ2V0ID0gV1swXTsKICB2YXJpb2dyYW0uc2lsbCA9IFdbMV0gKiB2YXJpb2dyYW0ucmFuZ2UgKyB2YXJpb2dyYW0ubnVnZ2V0OwogIHZhcmlvZ3JhbS5uID0geC5sZW5ndGg7CgogIC8vIEdyYW0gbWF0cml4IHdpdGggcHJpb3IKICBuID0geC5sZW5ndGg7CiAgbGV0IEsgPSBBcnJheShuICogbik7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IGk7IGorKykgewogICAgICBLW2kgKiBuICsgal0gPSB2YXJpb2dyYW0ubW9kZWwoTWF0aC5wb3coTWF0aC5wb3coeFtpXSAtIHhbal0sIDIpICsgTWF0aC5wb3coeVtpXSAtIHlbal0sIDIpLCAwLjUpLCB2YXJpb2dyYW0ubnVnZ2V0LCB2YXJpb2dyYW0ucmFuZ2UsIHZhcmlvZ3JhbS5zaWxsLCB2YXJpb2dyYW0uQSk7CiAgICAgIEtbaiAqIG4gKyBpXSA9IEtbaSAqIG4gKyBqXTsKICAgIH0KICAgIEtbaSAqIG4gKyBpXSA9IHZhcmlvZ3JhbS5tb2RlbCgwLCB2YXJpb2dyYW0ubnVnZ2V0LCB2YXJpb2dyYW0ucmFuZ2UsIHZhcmlvZ3JhbS5zaWxsLCB2YXJpb2dyYW0uQSk7CiAgfQoKICAvLyBJbnZlcnNlIHBlbmFsaXplZCBHcmFtIG1hdHJpeCBwcm9qZWN0ZWQgdG8gdGFyZ2V0IHZlY3RvcgogIGxldCBDID0ga3JpZ2luZ19tYXRyaXhfYWRkKEssIGtyaWdpbmdfbWF0cml4X2RpYWcoc2lnbWEyLCBuKSwgbiwgbik7CiAgbGV0IGNsb25lQyA9IEMuc2xpY2UoMCk7CiAgaWYgKGtyaWdpbmdfbWF0cml4X2Nob2woQywgbikpIHsKICAgIGtyaWdpbmdfbWF0cml4X2Nob2wyaW52KEMsIG4pOwogIH0gZWxzZSB7CiAgICBrcmlnaW5nX21hdHJpeF9zb2x2ZShjbG9uZUMsIG4pOwogICAgQyA9IGNsb25lQzsKICB9CgogIC8vIENvcHkgdW5wcm9qZWN0ZWQgaW52ZXJ0ZWQgbWF0cml4IGFzIEsKICBsZXQgX0sgPSBDLnNsaWNlKDApOwogIGxldCBfTSA9IGtyaWdpbmdfbWF0cml4X211bHRpcGx5KEMsIHQsIG4sIG4sIDEpOwogIHZhcmlvZ3JhbS5LID0gX0s7CiAgdmFyaW9ncmFtLk0gPSBfTTsKICByZXR1cm4gdmFyaW9ncmFtOwp9OwoKLy8gTW9kZWwgcHJlZGljdGlvbgprcmlnaW5nLnByZWRpY3QgPSBmdW5jdGlvbiAoeCwgeSwgdmFyaW9ncmFtKSB7CiAgbGV0IGk7CiAgbGV0IGsgPSBBcnJheSh2YXJpb2dyYW0ubik7CiAgZm9yIChpID0gMDsgaSA8IHZhcmlvZ3JhbS5uOyBpKyspIHsKICAgIGtbaV0gPSB2YXJpb2dyYW0ubW9kZWwoTWF0aC5wb3coTWF0aC5wb3coeCAtIHZhcmlvZ3JhbS54W2ldLCAyKSArIE1hdGgucG93KHkgLSB2YXJpb2dyYW0ueVtpXSwgMiksIDAuNSksIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKTsKICB9CiAgcmV0dXJuIGtyaWdpbmdfbWF0cml4X211bHRpcGx5KGssIHZhcmlvZ3JhbS5NLCAxLCB2YXJpb2dyYW0ubiwgMSlbMF07Cn07CmtyaWdpbmcudmFyaWFuY2UgPSBmdW5jdGlvbiAoeCwgeSwgdmFyaW9ncmFtKSB7CiAgbGV0IGk7CiAgbGV0IGsgPSBBcnJheSh2YXJpb2dyYW0ubik7CiAgZm9yIChpID0gMDsgaSA8IHZhcmlvZ3JhbS5uOyBpKyspIHsKICAgIGtbaV0gPSB2YXJpb2dyYW0ubW9kZWwoTWF0aC5wb3coTWF0aC5wb3coeCAtIHZhcmlvZ3JhbS54W2ldLCAyKSArIE1hdGgucG93KHkgLSB2YXJpb2dyYW0ueVtpXSwgMiksIDAuNSksIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKTsKICB9CiAgcmV0dXJuIHZhcmlvZ3JhbS5tb2RlbCgwLCB2YXJpb2dyYW0ubnVnZ2V0LCB2YXJpb2dyYW0ucmFuZ2UsIHZhcmlvZ3JhbS5zaWxsLCB2YXJpb2dyYW0uQSkgKyBrcmlnaW5nX21hdHJpeF9tdWx0aXBseShrcmlnaW5nX21hdHJpeF9tdWx0aXBseShrLCB2YXJpb2dyYW0uSywgMSwgdmFyaW9ncmFtLm4sIHZhcmlvZ3JhbS5uKSwgaywgMSwgdmFyaW9ncmFtLm4sIDEpWzBdOwp9OwoKLy8hIExpbmVhciBhbGdlYnJhIHByaW1pdGl2ZXMgKHB1cmUgSlMsIHplcm8gZGVwZW5kZW5jaWVzKQovLyEKLy8hIFBvcnQgb2YgYGZyaWVkcmljaCAwLjYuMGA6Ci8vISAgIC0gYHNyYy9hbGdlYnJhL21vZC5yc2AgICAgICAgICAgICAgIChjb3ZhcmlhbmNlLW1hdHJpeCBoZWxwZXJzKQovLyEgICAtIGBzcmMvYWxnZWJyYS9leHRlbmRhYmxlX21hdHJpeC5yc2AgKEVNYXRyaXggLyBFVmVjdG9yIOKGkiBFeHRlbmRhYmxlTWF0cml4IC8gRXh0ZW5kYWJsZVZlY3RvcikKLy8hICAgLSB0aGUgc2xpY2Ugb2YgYG5hbGdlYnJhYCB0aGF0IGZyaWVkcmljaCBhY3R1YWxseSB1c2VzCi8vISAgICAgKG1hdHJpeCAvIHZlY3RvciBvcHMsIENob2xlc2t5IGRlY29tcG9zaXRpb24sIHRyaWFuZ3VsYXIgc29sdmVzLAovLyEgICAgICBDaG9sZXNreSBzb2x2ZSAvIGludmVyc2UsIGxlYXN0LXNxdWFyZXMpLgovLyEKLy8hIERhdGEgcmVwcmVzZW50YXRpb24gKHNlZSBQT1JUX1NQRUMgwqcyKToKLy8hICAgLSB2ZWN0b3IgPSBudW1iZXJbXQovLyEgICAtIG1hdHJpeCA9IG51bWJlcltdW10gKHJvdy1tYWpvcjsgbWF0cml4W3JdW2NdID0gcm93IHIsIGNvbCBjKQovLyEKLy8hIEFsbCBtYXRyaXggbWF0aCBoZXJlIGlzIHJvdy1tYWpvcjsgd2UgZG8gTk9UIGVtdWxhdGUgbmFsZ2VicmEncwovLyEgY29sdW1uLW1ham9yIG1lbW9yeSBsYXlvdXQsIG9ubHkgaXRzIG1hdGhlbWF0aWNhbCBzZW1hbnRpY3MuCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEJBU0lDIFZFQ1RPUiBPUEVSQVRJT05TIChpbnB1dDogbnVtYmVyW10pCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBEb3QgcHJvZHVjdCDOoyBh4bWiwrdi4bWiLgogKiBAcGFyYW0ge251bWJlcltdfSBhCiAqIEBwYXJhbSB7bnVtYmVyW119IGIKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIGRvdChhLCBiKSB7CiAgbGV0IHMgPSAwOwogIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgcyArPSBhW2ldICogYltpXTsKICByZXR1cm4gczsKfQoKLyoqCiAqIEVsZW1lbnQtd2lzZSBzdWJ0cmFjdGlvbiBhIOKIkiBiLgogKiBAcGFyYW0ge251bWJlcltdfSBhCiAqIEBwYXJhbSB7bnVtYmVyW119IGIKICogQHJldHVybnMge251bWJlcltdfQogKi8KZnVuY3Rpb24gc3ViVmVjKGEsIGIpIHsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkoYS5sZW5ndGgpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgb3V0W2ldID0gYVtpXSAtIGJbaV07CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIEV1Y2xpZGVhbiBub3JtIHNxcnQozqMgYeG1osKyKS4KICogQHBhcmFtIHtudW1iZXJbXX0gYQogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gbm9ybShhKSB7CiAgcmV0dXJuIE1hdGguc3FydChub3JtU3F1YXJlZChhKSk7Cn0KCi8qKgogKiBTcXVhcmVkIEV1Y2xpZGVhbiBub3JtIM6jIGHhtaLCsi4KICogQHBhcmFtIHtudW1iZXJbXX0gYQogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gbm9ybVNxdWFyZWQoYSkgewogIGxldCBzID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHMgKz0gYVtpXSAqIGFbaV07CiAgcmV0dXJuIHM7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gTUFUUklYIC8gTUFUUklYLVZFQ1RPUiBPUEVSQVRJT05TIChtYXRyaXggPSBudW1iZXJbXVtdLCBvbmUgcm93IHBlciByb3cpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBNYXRyaXggcHJvZHVjdCBBKG3Dl2spIMK3IEIoa8OXbikg4oaSIChtw5duKS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQgogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIG1hdE11bChBLCBCKSB7CiAgY29uc3QgbSA9IEEubGVuZ3RoOwogIGNvbnN0IGsgPSBBWzBdLmxlbmd0aDsKICBjb25zdCBuID0gQlswXS5sZW5ndGg7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG0pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICBjb25zdCBBaSA9IEFbaV07CiAgICBjb25zdCByb3cgPSBuZXcgQXJyYXkobikuZmlsbCgwKTsKICAgIGZvciAobGV0IHAgPSAwOyBwIDwgazsgcCsrKSB7CiAgICAgIGNvbnN0IGEgPSBBaVtwXTsKICAgICAgY29uc3QgQnAgPSBCW3BdOwogICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykgcm93W2pdICs9IGEgKiBCcFtqXTsKICAgIH0KICAgIG91dFtpXSA9IHJvdzsKICB9CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIE1hdHJpeC12ZWN0b3IgcHJvZHVjdCBBKG3Dl24pIMK3IHgobikg4oaSIG51bWJlcltdKG0pLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHBhcmFtIHtudW1iZXJbXX0geAogKiBAcmV0dXJucyB7bnVtYmVyW119CiAqLwpmdW5jdGlvbiBtYXRWZWMoQSwgeCkgewogIGNvbnN0IG0gPSBBLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobSk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIHsKICAgIGNvbnN0IEFpID0gQVtpXTsKICAgIGxldCBzID0gMDsKICAgIGZvciAobGV0IGogPSAwOyBqIDwgQWkubGVuZ3RoOyBqKyspIHMgKz0gQWlbal0gKiB4W2pdOwogICAgb3V0W2ldID0gczsKICB9CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIFRyYW5zcG9zZSBvZiBBLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiB0cmFuc3Bvc2UoQSkgewogIGNvbnN0IG0gPSBBLmxlbmd0aDsKICBjb25zdCBuID0gQVswXS5sZW5ndGg7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICBjb25zdCBjb2wgPSBuZXcgQXJyYXkobSk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG07IGkrKykgY29sW2ldID0gQVtpXVtqXTsKICAgIG91dFtqXSA9IGNvbDsKICB9CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIEVsZW1lbnQtd2lzZSBtYXRyaXggc3VidHJhY3Rpb24gQSDiiJIgQi4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQgogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIG1hdFN1YihBLCBCKSB7CiAgY29uc3QgbSA9IEEubGVuZ3RoOwogIGNvbnN0IG91dCA9IG5ldyBBcnJheShtKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG07IGkrKykgewogICAgY29uc3QgbiA9IEFbaV0ubGVuZ3RoOwogICAgY29uc3Qgcm93ID0gbmV3IEFycmF5KG4pOwogICAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqKyspIHJvd1tqXSA9IEFbaV1bal0gLSBCW2ldW2pdOwogICAgb3V0W2ldID0gcm93OwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogbsOXbiBpZGVudGl0eSBtYXRyaXguCiAqIEBwYXJhbSB7bnVtYmVyfSBuCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gaWRlbnRpdHkobikgewogIGNvbnN0IG91dCA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgY29uc3Qgcm93ID0gbmV3IEFycmF5KG4pLmZpbGwoMCk7CiAgICByb3dbaV0gPSAxOwogICAgb3V0W2ldID0gcm93OwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogbcOXbiB6ZXJvIG1hdHJpeC4KICogQHBhcmFtIHtudW1iZXJ9IG0KICogQHBhcmFtIHtudW1iZXJ9IG4KICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiB6ZXJvcyhtLCBuKSB7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG0pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSBvdXRbaV0gPSBuZXcgQXJyYXkobikuZmlsbCgwKTsKICByZXR1cm4gb3V0Owp9CgovKioKICogVHJhY2UgzqMgQeG1ouG1oiAoYWxzbyB1c2VkIGFzIGdlbmVyaWMgZGlhZ29uYWwgc3VtLCBlLmcuIHRyYWNlKEHigbvCuSkpLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIHRyYWNlKEEpIHsKICBjb25zdCBuID0gTWF0aC5taW4oQS5sZW5ndGgsIEFbMF0ubGVuZ3RoKTsKICBsZXQgcyA9IDA7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHMgKz0gQVtpXVtpXTsKICByZXR1cm4gczsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDSE9MRVNLWSBERUNPTVBPU0lUSU9OICYgVFJJQU5HVUxBUiBTT0xWRVMKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIENob2xlc2t5IGRlY29tcG9zaXRpb24gb2YgYSBzeW1tZXRyaWMgcG9zaXRpdmUtZGVmaW5pdGUgbWF0cml4IEEobsOXbiksCiAqIHJldHVybmluZyB0aGUgbG93ZXItdHJpYW5ndWxhciBmYWN0b3IgTCBzdWNoIHRoYXQgQSA9IEzCt0zhtYAuCiAqCiAqIEZhaWx1cmUgKG5vbi1wb3NpdGl2ZS1kZWZpbml0ZSkgYmVoYXZpb3VyOgogKiAgIC0gYGVwc2lsb24gPT09IG51bGxgIOKGkiB0aHJvdyBFcnJvciAobWF0Y2hlcyBSdXN0IGAuZXhwZWN0KClgIHBhbmljKS4KICogICAtIGBlcHNpbG9uYCBhIGZpbml0ZSBwb3NpdGl2ZSBudW1iZXIg4oaSIG1pbWljIG5hbGdlYnJhCiAqICAgICBgQ2hvbGVza3k6Om5ld193aXRoX3N1YnN0aXR1dGVgOiB3aGVuZXZlciBhIGRpYWdvbmFsIHBpdm90IGTisbwg4omkIDAsCiAqICAgICBzdWJzdGl0dXRlIGBlcHNpbG9uYCBmb3IgdGhhdCBwaXZvdCBhbmQga2VlcCBnb2luZy4gSWYgZXZlbiB0aGUKICogICAgIHN1YnN0aXR1dGUgZmFpbHMgdG8ga2VlcCB0aGluZ3MgcmVhbCAoY2Fubm90IGhhcHBlbiBmb3IgZXBzaWxvbiA+IDApLAogKiAgICAgdGhyb3cuCiAqCiAqIFJlYWRzIG9ubHkgdGhlIGxvd2VyIHRyaWFuZ2xlIG9mIEEgKHRoZSB1cHBlciB0cmlhbmdsZSBpcyBpZ25vcmVkKSwgbWF0Y2hpbmcKICogbmFsZ2VicmEncyBiZWhhdmlvdXIgb2YgdXNpbmcgb25seSB0aGUgbG93ZXItdHJpYW5ndWxhciBwYXJ0LgogKgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHBhcmFtIHtudW1iZXJ8bnVsbH0gW2Vwc2lsb249bnVsbF0KICogQHJldHVybnMge251bWJlcltdW119IGxvd2VyLXRyaWFuZ3VsYXIgTAogKi8KZnVuY3Rpb24gY2hvbGVza3koQSwgZXBzaWxvbiA9IG51bGwpIHsKICBjb25zdCBuID0gQS5sZW5ndGg7CiAgLy8gTCBzdGFydHMgYXMgYSB6ZXJvIG1hdHJpeDsgd2UgZmlsbCB0aGUgbG93ZXIgdHJpYW5nbGUgY29sdW1uIGJ5IGNvbHVtbiwKICAvLyBtaXJyb3JpbmcgbmFsZ2VicmEncyBpbi1wbGFjZSBhbGdvcml0aG0gKGxvd2VyLXRyaWFuZ3VsYXIsIGNvbHVtbi1tYWpvcikuCiAgY29uc3QgTCA9IHplcm9zKG4sIG4pOwogIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAvLyBEaWFnb25hbCBwaXZvdDogQVtqXVtqXSDiiJIgzqNfe2s8an0gTFtqXVtrXcKyCiAgICBsZXQgZGlhZyA9IEFbal1bal07CiAgICBmb3IgKGxldCBrID0gMDsgayA8IGo7IGsrKykgZGlhZyAtPSBMW2pdW2tdICogTFtqXVtrXTsKICAgIGlmIChlcHNpbG9uID09PSBudWxsKSB7CiAgICAgIGlmICghKGRpYWcgPiAwKSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiQ2hvbGVza3kgZGVjb21wb3NpdGlvbiBmYWlsZWQsIGNvbnNpZGVyIHNldHRpbmcgYGNob2xlc2t5X2Vwc2lsb25gIHZpYSBgR2F1c3NpYW5Qcm9jZXNzQnVpbGRlcmAiKTsKICAgICAgfQogICAgfSBlbHNlIGlmICghKGRpYWcgPiAwKSkgewogICAgICAvLyBuZXdfd2l0aF9zdWJzdGl0dXRlOiByZXBsYWNlIHRoZSBub24tcG9zaXRpdmUgcGl2b3Qgd2l0aCBlcHNpbG9uLgogICAgICBkaWFnID0gZXBzaWxvbjsKICAgIH0KICAgIGNvbnN0IGxqaiA9IE1hdGguc3FydChkaWFnKTsKICAgIExbal1bal0gPSBsamo7CgogICAgLy8gQmVsb3ctZGlhZ29uYWwgZW50cmllcyBvZiBjb2x1bW4gajoKICAgIC8vICAgTFtpXVtqXSA9IChBW2ldW2pdIOKIkiDOo197azxqfSBMW2ldW2tdwrdMW2pdW2tdKSAvIExbal1bal0KICAgIGZvciAobGV0IGkgPSBqICsgMTsgaSA8IG47IGkrKykgewogICAgICBsZXQgcyA9IEFbaV1bal07CiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgajsgaysrKSBzIC09IExbaV1ba10gKiBMW2pdW2tdOwogICAgICBMW2ldW2pdID0gcyAvIGxqajsKICAgIH0KICB9CiAgcmV0dXJuIEw7Cn0KCi8qKgogKiBTb2x2ZSBMwrdYID0gQiB3aGVyZSBMIGlzIGxvd2VyLXRyaWFuZ3VsYXIgKGZvcndhcmQgc3Vic3RpdHV0aW9uKS4KICogQiBtYXkgYmUgYSB2ZWN0b3IgKG51bWJlcltdKSDihpIgc29sdmVzIG9uZSBSSFMsIG9yIGEgbWF0cml4IChudW1iZXJbXVtdKQogKiDihpIgc29sdmVzIGNvbHVtbiBieSBjb2x1bW4gKGVhY2ggY29sdW1uIGlzIG9uZSBSSFMpLCByZXR1cm5pbmcgdGhlIHNhbWUgc2hhcGUuCiAqIE1hdGNoZXMgbmFsZ2VicmEgYHNvbHZlX2xvd2VyX3RyaWFuZ3VsYXJgLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IEwgbG93ZXItdHJpYW5ndWxhcgogKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IEIKICogQHJldHVybnMge251bWJlcltdfG51bWJlcltdW119CiAqLwpmdW5jdGlvbiBzb2x2ZUxvd2VyVHJpKEwsIEIpIHsKICBpZiAoQXJyYXkuaXNBcnJheShCWzBdKSkgewogICAgLy8gQiBpcyBhIG1hdHJpeDogc29sdmUgZWFjaCBjb2x1bW4uCiAgICBjb25zdCBuID0gTC5sZW5ndGg7CiAgICBjb25zdCBuY29scyA9IEJbMF0ubGVuZ3RoOwogICAgY29uc3QgWCA9IHplcm9zKG4sIG5jb2xzKTsKICAgIGZvciAobGV0IGMgPSAwOyBjIDwgbmNvbHM7IGMrKykgewogICAgICBjb25zdCBjb2wgPSBuZXcgQXJyYXkobik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBjb2xbaV0gPSBCW2ldW2NdOwogICAgICBjb25zdCBzb2wgPSBzb2x2ZUxvd2VyVHJpVmVjKEwsIGNvbCk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBYW2ldW2NdID0gc29sW2ldOwogICAgfQogICAgcmV0dXJuIFg7CiAgfQogIHJldHVybiBzb2x2ZUxvd2VyVHJpVmVjKEwsIEIpOwp9CgovKioKICogRm9yd2FyZCBzdWJzdGl0dXRpb24gZm9yIGEgc2luZ2xlIFJIUyB2ZWN0b3I6IHNvbHZlIEzCt3ggPSBiLgogKiBAcGFyYW0ge251bWJlcltdW119IEwgbG93ZXItdHJpYW5ndWxhcgogKiBAcGFyYW0ge251bWJlcltdfSBiCiAqIEByZXR1cm5zIHtudW1iZXJbXX0KICovCmZ1bmN0aW9uIHNvbHZlTG93ZXJUcmlWZWMoTCwgYikgewogIGNvbnN0IG4gPSBMLmxlbmd0aDsKICBjb25zdCB4ID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBsZXQgcyA9IGJbaV07CiAgICBjb25zdCBMaSA9IExbaV07CiAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykgcyAtPSBMaVtrXSAqIHhba107CiAgICB4W2ldID0gcyAvIExpW2ldOwogIH0KICByZXR1cm4geDsKfQoKLyoqCiAqIFNvbHZlIFXCt1ggPSBCIHdoZXJlIFUgaXMgdXBwZXItdHJpYW5ndWxhciAoYmFjayBzdWJzdGl0dXRpb24pLgogKiBJbiBmcmllZHJpY2ggdGhlIHVwcGVyLXRyaWFuZ3VsYXIgc3lzdGVtIGlzIFUgPSBM4bWALgogKiBCIG1heSBiZSBudW1iZXJbXSBvciBudW1iZXJbXVtdIChjb2x1bW4td2lzZSksIHJldHVybmluZyB0aGUgc2FtZSBzaGFwZS4KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBVIHVwcGVyLXRyaWFuZ3VsYXIKICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXXxudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gc29sdmVVcHBlclRyaShVLCBCKSB7CiAgaWYgKEFycmF5LmlzQXJyYXkoQlswXSkpIHsKICAgIGNvbnN0IG4gPSBVLmxlbmd0aDsKICAgIGNvbnN0IG5jb2xzID0gQlswXS5sZW5ndGg7CiAgICBjb25zdCBYID0gemVyb3MobiwgbmNvbHMpOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuY29sczsgYysrKSB7CiAgICAgIGNvbnN0IGNvbCA9IG5ldyBBcnJheShuKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIGNvbFtpXSA9IEJbaV1bY107CiAgICAgIGNvbnN0IHNvbCA9IHNvbHZlVXBwZXJUcmlWZWMoVSwgY29sKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIFhbaV1bY10gPSBzb2xbaV07CiAgICB9CiAgICByZXR1cm4gWDsKICB9CiAgcmV0dXJuIHNvbHZlVXBwZXJUcmlWZWMoVSwgQik7Cn0KCi8qKgogKiBCYWNrIHN1YnN0aXR1dGlvbiBmb3IgYSBzaW5nbGUgUkhTIHZlY3Rvcjogc29sdmUgVcK3eCA9IGIuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gVSB1cHBlci10cmlhbmd1bGFyCiAqIEBwYXJhbSB7bnVtYmVyW119IGIKICogQHJldHVybnMge251bWJlcltdfQogKi8KZnVuY3Rpb24gc29sdmVVcHBlclRyaVZlYyhVLCBiKSB7CiAgY29uc3QgbiA9IFUubGVuZ3RoOwogIGNvbnN0IHggPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgaSA9IG4gLSAxOyBpID49IDA7IGktLSkgewogICAgbGV0IHMgPSBiW2ldOwogICAgY29uc3QgVWkgPSBVW2ldOwogICAgZm9yIChsZXQgayA9IGkgKyAxOyBrIDwgbjsgaysrKSBzIC09IFVpW2tdICogeFtrXTsKICAgIHhbaV0gPSBzIC8gVWlbaV07CiAgfQogIHJldHVybiB4Owp9CgovKioKICogU29sdmUgQcK3WCA9IEIgZ2l2ZW4gdGhlIGxvd2VyLXRyaWFuZ3VsYXIgQ2hvbGVza3kgZmFjdG9yIEwgKEEgPSBMwrdM4bWAKToKICogZmlyc3Qgc29sdmUgTMK3WSA9IEIgKGZvcndhcmQpLCB0aGVuIEzhtYDCt1ggPSBZIChiYWNrKS4KICogTWF0Y2hlcyBuYWxnZWJyYSBgQ2hvbGVza3k6OnNvbHZlYC4KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBMIGxvd2VyLXRyaWFuZ3VsYXIgZmFjdG9yCiAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gQgogKiBAcmV0dXJucyB7bnVtYmVyW118bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIGNob2xlc2t5U29sdmUoTCwgQikgewogIGNvbnN0IHkgPSBzb2x2ZUxvd2VyVHJpKEwsIEIpOwogIGNvbnN0IEx0ID0gdHJhbnNwb3NlKEwpOwogIHJldHVybiBzb2x2ZVVwcGVyVHJpKEx0LCB5KTsKfQoKLyoqCiAqIENvbXB1dGUgQeKBu8K5ID0gKEzCt0zhtYAp4oG7wrkgZnJvbSB0aGUgbG93ZXItdHJpYW5ndWxhciBDaG9sZXNreSBmYWN0b3IgTCwKICogYnkgc29sdmluZyBBwrdYID0gSS4gTWF0Y2hlcyBuYWxnZWJyYSBgQ2hvbGVza3k6OmludmVyc2VgLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IEwgbG93ZXItdHJpYW5ndWxhciBmYWN0b3IKICogQHJldHVybnMge251bWJlcltdW119IEHigbvCuQogKi8KZnVuY3Rpb24gY2hvbGVza3lJbnZlcnNlKEwpIHsKICBjb25zdCBuID0gTC5sZW5ndGg7CiAgcmV0dXJuIGNob2xlc2t5U29sdmUoTCwgaWRlbnRpdHkobikpOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEVYVEVOREFCTEUgTUFUUklYIC8gVkVDVE9SICAoRU1hdHJpeCAvIEVWZWN0b3IpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBBIG1hdHJpeCB0aGF0IGNhbiBncm93IGJ5IGFwcGVuZGluZyByb3dzLgogKgogKiBKUyBwb3J0IG5vdGU6IHdlIHNpbXBseSBgcHVzaGAgcm93cy4gVGhlIFJ1c3QgdmVyc2lvbiBwcmUtYWxsb2NhdGVzIHdpdGggYQogKiAxLjXDlyBjYXBhY2l0eS1kb3VibGluZyBzdHJhdGVneSBwdXJlbHkgZm9yIG1lbW9yeSBlZmZpY2llbmN5OyB0aGF0IGhhcyBubwogKiBlZmZlY3Qgb24gdGhlIG51bWVyaWNhbCByZXN1bHQsIHNvIHdlIG9taXQgaXQgKFBPUlRfU1BFQyDCpzIuMykuCiAqLwpjbGFzcyBFeHRlbmRhYmxlTWF0cml4IHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdW119IGRhdGEKICAgKi8KICBjb25zdHJ1Y3RvcihkYXRhKSB7CiAgICAvKiogQHR5cGUge251bWJlcltdW119ICovCiAgICB0aGlzLmRhdGEgPSBkYXRhOwogIH0KCiAgLyoqIE51bWJlciBvZiByb3dzLiBAcmV0dXJucyB7bnVtYmVyfSAqLwogIGdldCBucm93cygpIHsKICAgIHJldHVybiB0aGlzLmRhdGEubGVuZ3RoOwogIH0KCiAgLyoqIE51bWJlciBvZiBjb2x1bW5zLiBAcmV0dXJucyB7bnVtYmVyfSAqLwogIGdldCBuY29scygpIHsKICAgIHJldHVybiB0aGlzLmRhdGEubGVuZ3RoID09PSAwID8gMCA6IHRoaXMuZGF0YVswXS5sZW5ndGg7CiAgfQoKICAvKioKICAgKiBDdXJyZW50IGRhdGEgYXMgbnVtYmVyW11bXSAoaW50ZXJuYWwgcmVmZXJlbmNlOyBjYWxsZXIgbXVzdCB0cmVhdCBhcyByZWFkLW9ubHkpLgogICAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogICAqLwogIGFzTWF0cml4KCkgewogICAgcmV0dXJuIHRoaXMuZGF0YTsKICB9CgogIC8qKgogICAqIEFwcGVuZCByb3dzIGF0IHRoZSBib3R0b20gKGluIHBsYWNlKS4KICAgKiBAcGFyYW0ge251bWJlcltdW119IHJvd3MKICAgKi8KICBhZGRSb3dzKHJvd3MpIHsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykgdGhpcy5kYXRhLnB1c2gocm93c1tpXSk7CiAgfQp9CgovKioKICogQSB2ZWN0b3IgdGhhdCBjYW4gZ3JvdyBieSBhcHBlbmRpbmcgZW50cmllcy4KICovCmNsYXNzIEV4dGVuZGFibGVWZWN0b3IgewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW119IGRhdGEKICAgKi8KICBjb25zdHJ1Y3RvcihkYXRhKSB7CiAgICAvKiogQHR5cGUge251bWJlcltdfSAqLwogICAgdGhpcy5kYXRhID0gZGF0YTsKICB9CgogIC8qKiBOdW1iZXIgb2Ygcm93cyAoZW50cmllcykuIEByZXR1cm5zIHtudW1iZXJ9ICovCiAgZ2V0IG5yb3dzKCkgewogICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGg7CiAgfQoKICAvKioKICAgKiBDdXJyZW50IGRhdGEgYXMgbnVtYmVyW10gKGludGVybmFsIHJlZmVyZW5jZTsgY2FsbGVyIG11c3QgdHJlYXQgYXMgcmVhZC1vbmx5KS4KICAgKiBAcmV0dXJucyB7bnVtYmVyW119CiAgICovCiAgYXNWZWN0b3IoKSB7CiAgICByZXR1cm4gdGhpcy5kYXRhOwogIH0KCiAgLyoqCiAgICogQXBwZW5kIGVudHJpZXMgKGluIHBsYWNlKS4KICAgKiBAcGFyYW0ge251bWJlcltdfSByb3dzCiAgICovCiAgYWRkUm93cyhyb3dzKSB7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd3MubGVuZ3RoOyBpKyspIHRoaXMuZGF0YS5wdXNoKHJvd3NbaV0pOwogIH0KCiAgLyoqCiAgICogT3ZlcndyaXRlIHRoZSB3aG9sZSBjb250ZW50OyBsZW5ndGggbXVzdCBlcXVhbCB0aGUgY3VycmVudCBsZW5ndGgKICAgKiAobWF0Y2hlcyBSdXN0IGBhc3NlcnRfZXEhYCkuCiAgICogQHBhcmFtIHtudW1iZXJbXX0gcm93cwogICAqLwogIGFzc2lnbihyb3dzKSB7CiAgICBpZiAocm93cy5sZW5ndGggIT09IHRoaXMuZGF0YS5sZW5ndGgpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHRlbmRhYmxlVmVjdG9yLmFzc2lnbjogbGVuZ3RoIG1pc21hdGNoIChnb3QgJHtyb3dzLmxlbmd0aH0sIGV4cGVjdGVkICR7dGhpcy5kYXRhLmxlbmd0aH0pYCk7CiAgICB9CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd3MubGVuZ3RoOyBpKyspIHRoaXMuZGF0YVtpXSA9IHJvd3NbaV07CiAgfQp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIENIT0xFU0tZIERFQ09NUE9TSVRJT04gQ0xBU1MgKGluY3JlbWVudGFsIE8obsKyKSB1cGRhdGUpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBBIHN0b3JlZCBDaG9sZXNreSBkZWNvbXBvc2l0aW9uIG9mIGEgc3ltbWV0cmljIHBvc2l0aXZlLWRlZmluaXRlIG1hdHJpeCwKICogc3VwcG9ydGluZyBpbmNyZW1lbnRhbCBPKG7CsikgZ3Jvd3RoIHZpYSBgaW5zZXJ0Q29sdW1uYCAodXNlZCBieQogKiBHYXVzc2lhblByb2Nlc3MuYWRkU2FtcGxlcykuIE1pcnJvcnMgbmFsZ2VicmEncyBgQ2hvbGVza3lgIG9iamVjdCB0aGF0CiAqIGZyaWVkcmljaCBrZWVwcyBpbnNpZGUgdGhlIEdQLgogKi8KY2xhc3MgQ2hvbGVza3lEZWNvbXBvc2l0aW9uIHsKICAvKioKICAgKiBCdWlsZCBmcm9tIGEgc3ltbWV0cmljIHBvc2l0aXZlLWRlZmluaXRlIG1hdHJpeC4KICAgKiBAcGFyYW0ge251bWJlcltdW119IEEKICAgKiBAcGFyYW0ge251bWJlcnxudWxsfSBbZXBzaWxvbj1udWxsXSBudWxsIOKGkiB0aHJvdyBvbiBmYWlsdXJlOyBwb3NpdGl2ZSDihpIgc3Vic3RpdHV0ZSBtb2RlLgogICAqLwogIGNvbnN0cnVjdG9yKEEsIGVwc2lsb24gPSBudWxsKSB7CiAgICAvKiogQHR5cGUge251bWJlcltdW119IGxvd2VyLXRyaWFuZ3VsYXIgZmFjdG9yIEwgKEEgPSBMwrdM4bWAKSAqLwogICAgdGhpcy5fTCA9IGNob2xlc2t5KEEsIGVwc2lsb24pOwogICAgLyoqIEB0eXBlIHtudW1iZXJ8bnVsbH0gKi8KICAgIHRoaXMuX2Vwc2lsb24gPSBlcHNpbG9uOwogIH0KCiAgLyoqCiAgICogTG93ZXItdHJpYW5ndWxhciBmYWN0b3IgTC4KICAgKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICAgKi8KICBsKCkgewogICAgcmV0dXJuIHRoaXMuX0w7CiAgfQoKICAvKioKICAgKiBTb2x2ZSBBwrdYID0gQiAoQjogbnVtYmVyW10gfCBudW1iZXJbXVtdKSwgc2FtZSBzaGFwZSBvdXQuCiAgICogRXF1aXZhbGVudCB0byBjaG9sZXNreVNvbHZlKHRoaXMubCgpLCBCKS4KICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IEIKICAgKiBAcmV0dXJucyB7bnVtYmVyW118bnVtYmVyW11bXX0KICAgKi8KICBzb2x2ZShCKSB7CiAgICByZXR1cm4gY2hvbGVza3lTb2x2ZSh0aGlzLl9MLCBCKTsKICB9CgogIC8qKgogICAqIFNvbHZlIEzCt1ggPSBCIChmb3J3YXJkIHN1YnN0aXR1dGlvbiBvbmx5KS4KICAgKiBFcXVpdmFsZW50IHRvIHNvbHZlTG93ZXJUcmkodGhpcy5sKCksIEIpLgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gQgogICAqIEByZXR1cm5zIHtudW1iZXJbXXxudW1iZXJbXVtdfQogICAqLwogIHNvbHZlTG93ZXIoQikgewogICAgcmV0dXJuIHNvbHZlTG93ZXJUcmkodGhpcy5fTCwgQik7CiAgfQoKICAvKioKICAgKiBJbnZlcnNlIEHigbvCuS4KICAgKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICAgKi8KICBpbnZlcnNlKCkgewogICAgcmV0dXJuIGNob2xlc2t5SW52ZXJzZSh0aGlzLl9MKTsKICB9CgogIC8qKgogICAqIEluc2VydCBhIHJvdy9jb2x1bW4gYXQgcG9zaXRpb24gYGNvbEluZGV4YCwgeWllbGRpbmcgdGhlCiAgICogKG4rMSnDlyhuKzEpIGRlY29tcG9zaXRpb24uIEluIGZyaWVkcmljaCBgY29sSW5kZXhgIGlzIGFsd2F5cyB0aGUgb2xkCiAgICogZGltZW5zaW9uIChpLmUuIGFwcGVuZGVkIGF0IHRoZSBlbmQpLCBzbyB0aGlzIGltcGxlbWVudHMgdGhlIHN0YW5kYXJkCiAgICogImJvcmRlcmluZyIgdXBkYXRlOgogICAqCiAgICogICBMJyA9IFsgTCAgICAgIDAgICBdICAgICAgd2l0aCAgIEwgwrcgbDIxID0gdlswLi5uXSAgIChsb3dlci10cmkgc29sdmUpCiAgICogICAgICAgIFsgbDIx4bWAICAgbDIyIF0gICAgICAgICAgICAgbDIyID0gc3FydCh2W25dIOKIkiBsMjHCt2wyMSkKICAgKgogICAqIHdoZXJlIGB2YCA9IGBuZXdDb2x1bW5gIChsZW5ndGggbisxKTogdlswLi5uXSBhcmUgY292YXJpYW5jZXMgd2l0aCB0aGUKICAgKiBleGlzdGluZyByb3dzIGFuZCB2W25dIGlzIHRoZSBuZXcgcG9pbnQncyBzZWxmLWNvdmFyaWFuY2UgKGFscmVhZHkKICAgKiBpbmNsdWRpbmcgbm9pc2XCsikuCiAgICoKICAgKiBJZiBsMjLCsiDiiaQgMCBhbmQgYW4gZXBzaWxvbiB3YXMgY29uZmlndXJlZCwgc3Vic3RpdHV0ZSBlcHNpbG9uIGZvciB0aGUKICAgKiBwaXZvdCAobWF0Y2hlcyB0aGUgc3Vic3RpdHV0ZSBiZWhhdmlvdXIgb2YgdGhlIGJhdGNoIENob2xlc2t5KS4KICAgKgogICAqIFVwZGF0ZXMgdGhpcyBvYmplY3QgaW4gcGxhY2UgYW5kIHJldHVybnMgYHRoaXNgLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJ9IGNvbEluZGV4ICBtdXN0IGVxdWFsIHRoZSBjdXJyZW50IGRpbWVuc2lvbiAoZW5kIGluc2VydGlvbikKICAgKiBAcGFyYW0ge251bWJlcltdfSBuZXdDb2x1bW4gbGVuZ3RoIGNvbEluZGV4KzEKICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBpbnNlcnRDb2x1bW4oY29sSW5kZXgsIG5ld0NvbHVtbikgewogICAgY29uc3QgbiA9IHRoaXMuX0wubGVuZ3RoOyAvLyBvbGQgZGltZW5zaW9uCiAgICAvLyBmcmllZHJpY2ggb25seSBldmVyIGluc2VydHMgYXQgdGhlIGVuZC4KICAgIGlmIChjb2xJbmRleCAhPT0gbikgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYENob2xlc2t5RGVjb21wb3NpdGlvbi5pbnNlcnRDb2x1bW46IG9ubHkgZW5kIGluc2VydGlvbiBzdXBwb3J0ZWQgKGNvbEluZGV4PSR7Y29sSW5kZXh9LCBkaW09JHtufSlgKTsKICAgIH0KICAgIGNvbnN0IEwgPSB0aGlzLl9MOwoKICAgIC8vIFNvbHZlIEwgwrcgbDIxID0gdlswLi5uXSAgKGZvcndhcmQgc3Vic3RpdHV0aW9uKS4KICAgIGNvbnN0IHYgPSBuZXdDb2x1bW47CiAgICBjb25zdCBsMjEgPSBuZXcgQXJyYXkobik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBsZXQgcyA9IHZbaV07CiAgICAgIGNvbnN0IExpID0gTFtpXTsKICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBpOyBrKyspIHMgLT0gTGlba10gKiBsMjFba107CiAgICAgIGwyMVtpXSA9IHMgLyBMaVtpXTsKICAgIH0KCiAgICAvLyBsMjIgPSBzcXJ0KHZbbl0g4oiSIGwyMcK3bDIxKQogICAgbGV0IHBpdm90ID0gdltuXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBwaXZvdCAtPSBsMjFbaV0gKiBsMjFbaV07CiAgICBpZiAodGhpcy5fZXBzaWxvbiA9PT0gbnVsbCkgewogICAgICBpZiAoIShwaXZvdCA+IDApKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJDaG9sZXNreSBkZWNvbXBvc2l0aW9uIGZhaWxlZCwgY29uc2lkZXIgc2V0dGluZyBgY2hvbGVza3lfZXBzaWxvbmAgdmlhIGBHYXVzc2lhblByb2Nlc3NCdWlsZGVyYCIpOwogICAgICB9CiAgICB9IGVsc2UgaWYgKCEocGl2b3QgPiAwKSkgewogICAgICBwaXZvdCA9IHRoaXMuX2Vwc2lsb247CiAgICB9CiAgICBjb25zdCBsMjIgPSBNYXRoLnNxcnQocGl2b3QpOwoKICAgIC8vIEJ1aWxkIHRoZSAobisxKcOXKG4rMSkgbG93ZXItdHJpYW5ndWxhciBmYWN0b3IuCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgTFtpXS5wdXNoKDApOyAvLyBwYWQgZXhpc3Rpbmcgcm93cyB3aXRoIGEgMCBpbiB0aGUgbmV3IGNvbHVtbgogICAgY29uc3QgbGFzdFJvdyA9IG5ldyBBcnJheShuICsgMSk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgbGFzdFJvd1tpXSA9IGwyMVtpXTsKICAgIGxhc3RSb3dbbl0gPSBsMjI7CiAgICBMLnB1c2gobGFzdFJvdyk7CiAgICByZXR1cm4gdGhpczsKICB9Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gQ09WQVJJQU5DRS1NQVRSSVggSEVMUEVSUyAgKGFsZ2VicmEvbW9kLnJzIGZyZWUgZnVuY3Rpb25zKQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQ292YXJpYW5jZSBtYXRyaXggYmV0d2VlbiByb3dzIG9mIG0xIGFuZCByb3dzIG9mIG0yIHVzaW5nIGBrZXJuZWxgLgogKiBvdXRbcl1bY10gPSBrZXJuZWwua2VybmVsKG0xW3JdLCBtMltjXSkuIFNoYXBlIChtMS5sZW5ndGggw5cgbTIubGVuZ3RoKS4KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBtMQogKiBAcGFyYW0ge251bWJlcltdW119IG0yCiAqIEBwYXJhbSB7e2tlcm5lbDogKHgxOm51bWJlcltdLCB4MjpudW1iZXJbXSkgPT4gbnVtYmVyfX0ga2VybmVsCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gbWFrZUNvdmFyaWFuY2VNYXRyaXgobTEsIG0yLCBrZXJuZWwpIHsKICBjb25zdCByID0gbTEubGVuZ3RoOwogIGNvbnN0IGMgPSBtMi5sZW5ndGg7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KHIpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcjsgaSsrKSB7CiAgICBjb25zdCByb3cgPSBuZXcgQXJyYXkoYyk7CiAgICBjb25zdCB4aSA9IG0xW2ldOwogICAgZm9yIChsZXQgaiA9IDA7IGogPCBjOyBqKyspIHJvd1tqXSA9IGtlcm5lbC5rZXJuZWwoeGksIG0yW2pdKTsKICAgIG91dFtpXSA9IHJvdzsKICB9CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIENvdmFyaWFuY2UgbWF0cml4IG9mIGBpbnB1dHNgIHdpdGggZGlhZ29uYWwgbm9pc2XCsiwgcmV0dXJuZWQgYXMgaXRzCiAqIENob2xlc2t5RGVjb21wb3NpdGlvbi4KICoKICogICBjb3ZbaV1bal0gPSBrZXJuZWwua2VybmVsKGlucHV0c1tpXSwgaW5wdXRzW2pdKQogKiAgIGNvdltpXVtpXSArPSBkaWFnb25hbE5vaXNlwrIgICAobm90ZTogdGhlIFNRVUFSRSBvZiB0aGUgbm9pc2UpCiAqCiAqIGBlcHNpbG9uYCBpcyBmb3J3YXJkZWQgdG8gdGhlIENob2xlc2t5IChudWxsIOKGkiB0aHJvdyBvbiBmYWlsdXJlOwogKiBwb3NpdGl2ZSDihpIgc3Vic3RpdHV0ZSBtb2RlKS4KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBpbnB1dHMKICogQHBhcmFtIHt7a2VybmVsOiAoeDE6bnVtYmVyW10sIHgyOm51bWJlcltdKSA9PiBudW1iZXJ9fSBrZXJuZWwKICogQHBhcmFtIHtudW1iZXJ9IGRpYWdvbmFsTm9pc2UgdGhlIG5vaXNlIFNUQU5EQVJEIERFVklBVElPTgogKiBAcGFyYW0ge251bWJlcnxudWxsfSBbZXBzaWxvbj1udWxsXQogKiBAcmV0dXJucyB7Q2hvbGVza3lEZWNvbXBvc2l0aW9ufQogKi8KZnVuY3Rpb24gbWFrZUNob2xlc2t5Q292TWF0cml4KGlucHV0cywga2VybmVsLCBkaWFnb25hbE5vaXNlLCBlcHNpbG9uID0gbnVsbCkgewogIGNvbnN0IG4gPSBpbnB1dHMubGVuZ3RoOwogIGNvbnN0IG5vaXNlU3EgPSBkaWFnb25hbE5vaXNlICogZGlhZ29uYWxOb2lzZTsKICBjb25zdCBjb3YgPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGNvbnN0IHJvdyA9IG5ldyBBcnJheShuKTsKICAgIGNvbnN0IHhpID0gaW5wdXRzW2ldOwogICAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqKyspIHJvd1tqXSA9IGtlcm5lbC5rZXJuZWwoeGksIGlucHV0c1tqXSk7CiAgICByb3dbaV0gKz0gbm9pc2VTcTsKICAgIGNvdltpXSA9IHJvdzsKICB9CiAgcmV0dXJuIG5ldyBDaG9sZXNreURlY29tcG9zaXRpb24oY292LCBlcHNpbG9uKTsKfQoKLyoqCiAqIEluY3JlbWVudGFsbHkgYWRkIHRoZSBsYXN0IGBuYk5ld0lucHV0c2Agcm93cyBvZiBgYWxsSW5wdXRzYCB0byBhbiBleGlzdGluZwogKiBDaG9sZXNreSBkZWNvbXBvc2l0aW9uIChpbiBwbGFjZSksIG9uZSByb3cgYXQgYSB0aW1lLiBGb3IgZWFjaCBuZXcgcm93OgogKiAgIC0gY29tcHV0ZSB0aGUgbmV3IGNvbHVtbiAoY292YXJpYW5jZXMgd2l0aCBhbGwgcm93cyB1cCB0byBhbmQgaW5jbHVkaW5nCiAqICAgICBpdHNlbGYsIGxlbmd0aCBjb2xfaW5kZXgrMSksCiAqICAgLSBhZGQgbm9pc2XCsiB0byB0aGUgZmluYWwgKHNlbGYpIGVudHJ5LAogKiAgIC0gY2FsbCBgY2hvbGVza3kuaW5zZXJ0Q29sdW1uKGNvbF9pbmRleCwgY29sdW1uKWAuCiAqCiAqIEBwYXJhbSB7Q2hvbGVza3lEZWNvbXBvc2l0aW9ufSBjaG9sZXNreSB1cGRhdGVkIGluIHBsYWNlCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gYWxsSW5wdXRzIGZ1bGwgaW5wdXQgbWF0cml4IChvbGQgcm93cyB0aGVuIG5ldyByb3dzKQogKiBAcGFyYW0ge251bWJlcn0gbmJOZXdJbnB1dHMgbnVtYmVyIG9mIHRyYWlsaW5nIHJvd3MgdG8gYWRkCiAqIEBwYXJhbSB7e2tlcm5lbDogKHgxOm51bWJlcltdLCB4MjpudW1iZXJbXSkgPT4gbnVtYmVyfX0ga2VybmVsCiAqIEBwYXJhbSB7bnVtYmVyfSBkaWFnb25hbE5vaXNlIHRoZSBub2lzZSBTVEFOREFSRCBERVZJQVRJT04KICovCmZ1bmN0aW9uIGFkZFJvd3NDaG9sZXNreUNvdk1hdHJpeChjaG9sZXNreSwgYWxsSW5wdXRzLCBuYk5ld0lucHV0cywga2VybmVsLCBkaWFnb25hbE5vaXNlKSB7CiAgY29uc3QgdG90YWwgPSBhbGxJbnB1dHMubGVuZ3RoOwogIGNvbnN0IG5iT2xkID0gdG90YWwgLSBuYk5ld0lucHV0czsKICBjb25zdCBub2lzZVNxID0gZGlhZ29uYWxOb2lzZSAqIGRpYWdvbmFsTm9pc2U7CiAgZm9yIChsZXQgcm93SW5kZXggPSAwOyByb3dJbmRleCA8IG5iTmV3SW5wdXRzOyByb3dJbmRleCsrKSB7CiAgICBjb25zdCBjb2xJbmRleCA9IG5iT2xkICsgcm93SW5kZXg7CiAgICBjb25zdCByb3cgPSBhbGxJbnB1dHNbY29sSW5kZXhdOwogICAgY29uc3QgY29sdW1uU2l6ZSA9IGNvbEluZGV4ICsgMTsKICAgIGNvbnN0IG5ld0NvbHVtbiA9IG5ldyBBcnJheShjb2x1bW5TaXplKTsKICAgIGZvciAobGV0IHRyYWluaW5nUm93SW5kZXggPSAwOyB0cmFpbmluZ1Jvd0luZGV4IDwgY29sdW1uU2l6ZTsgdHJhaW5pbmdSb3dJbmRleCsrKSB7CiAgICAgIG5ld0NvbHVtblt0cmFpbmluZ1Jvd0luZGV4XSA9IGtlcm5lbC5rZXJuZWwoYWxsSW5wdXRzW3RyYWluaW5nUm93SW5kZXhdLCByb3cpOwogICAgfQogICAgbmV3Q29sdW1uW2NvbEluZGV4XSArPSBub2lzZVNxOwogICAgY2hvbGVza3kuaW5zZXJ0Q29sdW1uKGNvbEluZGV4LCBuZXdDb2x1bW4pOwogIH0KfQoKLyoqCiAqIEZvciBlYWNoIGtlcm5lbCBoeXBlci1wYXJhbWV0ZXIsIGJ1aWxkIHRoZSAoc3ltbWV0cmljKSBncmFkaWVudCBtYXRyaXgKICog4oiCSy/iiIJwYXJhbS4gUmV0dXJucyBudW1iZXJbXVtdW10gb2YgbGVuZ3RoIGtlcm5lbC5uYlBhcmFtZXRlcnMoKS4KICoKICogICBtYXRzW3BdW3JdW2NdID0gbWF0c1twXVtjXVtyXSA9IGtlcm5lbC5ncmFkaWVudChpbnB1dHNbcl0sIGlucHV0c1tjXSlbcF0KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBpbnB1dHMKICogQHBhcmFtIHt7bmJQYXJhbWV0ZXJzOiAoKSA9PiBudW1iZXIsIGdyYWRpZW50OiAoeDE6bnVtYmVyW10sIHgyOm51bWJlcltdKSA9PiBudW1iZXJbXX19IGtlcm5lbAogKiBAcmV0dXJucyB7bnVtYmVyW11bXVtdfQogKi8KZnVuY3Rpb24gbWFrZUdyYWRpZW50Q292YXJpYW5jZU1hdHJpY2VzKGlucHV0cywga2VybmVsKSB7CiAgY29uc3QgbiA9IGlucHV0cy5sZW5ndGg7CiAgY29uc3QgbmJQYXJhbXMgPSBrZXJuZWwubmJQYXJhbWV0ZXJzKCk7CiAgY29uc3QgbWF0cyA9IG5ldyBBcnJheShuYlBhcmFtcyk7CiAgZm9yIChsZXQgcCA9IDA7IHAgPCBuYlBhcmFtczsgcCsrKSBtYXRzW3BdID0gemVyb3Mobiwgbik7CiAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIHsKICAgIGNvbnN0IHhyID0gaW5wdXRzW3JdOwogICAgLy8gU3ltbWV0cmljOiBmaWxsIChyLGMpIGFuZCAoYyxyKSB0b2dldGhlciBmb3IgYyDiiaUgci4KICAgIGZvciAobGV0IGMgPSByOyBjIDwgbjsgYysrKSB7CiAgICAgIGNvbnN0IGdyYWQgPSBrZXJuZWwuZ3JhZGllbnQoeHIsIGlucHV0c1tjXSk7CiAgICAgIGZvciAobGV0IHAgPSAwOyBwIDwgbmJQYXJhbXM7IHArKykgewogICAgICAgIG1hdHNbcF1bcl1bY10gPSBncmFkW3BdOwogICAgICAgIG1hdHNbcF1bY11bcl0gPSBncmFkW3BdOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBtYXRzOwp9CgovLyEgIyBLZXJuZWxzCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEZJVCBIRVVSSVNUSUNTIChmcmVlIGZ1bmN0aW9ucywgZXhwb3J0ZWQgZm9yIGtlcm5lbHMgJiB0ZXN0cykKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIFJvdWdoIGJhbmR3aWR0aCBlc3RpbWF0ZTogbWVhbiBFdWNsaWRlYW4gZGlzdGFuY2UgYmV0d2VlbiBkaXN0aW5jdCBzYW1wbGVzLgogKiAgIM6jX3tpPGp9IOKAlnjhtaIg4oiSIHjisbzigJYgLyAobihu4oiSMSkvMikKICogQHBhcmFtIHtudW1iZXJbXVtdfSBpbnB1dHMKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIGZpdEJhbmR3aWR0aE1lYW4oaW5wdXRzKSB7CiAgbGV0IHN1bURpc3RhbmNlcyA9IDA7CiAgY29uc3QgbmJTYW1wbGVzID0gaW5wdXRzLmxlbmd0aDsKICBmb3IgKGxldCBpID0gMDsgaSA8IG5iU2FtcGxlczsgaSsrKSB7CiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBuYlNhbXBsZXM7IGorKykgewogICAgICBzdW1EaXN0YW5jZXMgKz0gbm9ybShzdWJWZWMoaW5wdXRzW2ldLCBpbnB1dHNbal0pKTsKICAgIH0KICB9CiAgLy8gSW50ZWdlciBhcml0aG1ldGljIG1hdGNoZXMgUnVzdCBgKG4qbiAtIG4pIC8gMmAuCiAgY29uc3QgbmJEaXN0YW5jZXMgPSAobmJTYW1wbGVzICogbmJTYW1wbGVzIC0gbmJTYW1wbGVzKSAvIDI7CiAgcmV0dXJuIHN1bURpc3RhbmNlcyAvIG5iRGlzdGFuY2VzOwp9CgovKioKICogQmVzdC1ndWVzcyBhbXBsaXR1ZGUgPSB2YXJpYW5jZSBvZiB0aGUgb3V0cHV0cy4KICoKICogTWF0Y2hlcyBuYWxnZWJyYSBgdmFyaWFuY2UoKWA6IM6jKHnhtaIg4oiSIG1lYW4pwrIgLyBOIChkaXZpZGVzIGJ5IE4sIHRoZSBzYW1wbGUKICogY291bnQg4oCUIE5PVCBO4oiSMSkuIENvbmZpcm1lZCBmcm9tIG5hbGdlYnJhIDAuMzQuMiBzdGF0aXN0aWNzLnJzIChQT1JUX1NQRUMgwqc0LjEpLgogKgogKiBAcGFyYW0ge251bWJlcltdfSBvdXRwdXRzCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBmaXRBbXBsaXR1ZGVWYXIob3V0cHV0cykgewogIGNvbnN0IG4gPSBvdXRwdXRzLmxlbmd0aDsKICBsZXQgbWVhbiA9IDA7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIG1lYW4gKz0gb3V0cHV0c1tpXTsKICBtZWFuIC89IG47CiAgbGV0IGFjYyA9IDA7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGNvbnN0IGQgPSBvdXRwdXRzW2ldIC0gbWVhbjsKICAgIGFjYyArPSBkICogZDsKICB9CiAgcmV0dXJuIGFjYyAvIG47Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBTcXVhcmVkIGV4cG9uZW50aWFsIChhLmsuYS4gR2F1c3NpYW4pIGtlcm5lbDoKICogICBrKHgseSkgPSBBwrdleHAo4oiS4oCWeOKIknnigJbCsiAvICgywrdsc8KyKSksICBBID0gfGFtcGx8LgogKiBQYXJhbWV0ZXJzOiBbbHMsIGFtcGxdIChkZWZhdWx0cyBscyA9IDEsIGFtcGwgPSAxKS4gbmJQYXJhbWV0ZXJzID0gMi4gU2NhbGFibGUuCiAqLwpjbGFzcyBTcXVhcmVkRXhwIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcn0gW2xzPTFdCiAgICogQHBhcmFtIHtudW1iZXJ9IFthbXBsPTFdCiAgICovCiAgY29uc3RydWN0b3IobHMgPSAxLCBhbXBsID0gMSkgewogICAgLyoqIEB0eXBlIHtudW1iZXJ9IGxlbmd0aCBzY2FsZSAqLwogICAgdGhpcy5scyA9IGxzOwogICAgLyoqIEB0eXBlIHtudW1iZXJ9IGFtcGxpdHVkZSAqLwogICAgdGhpcy5hbXBsID0gYW1wbDsKICB9CiAgbmJQYXJhbWV0ZXJzKCkgewogICAgcmV0dXJuIDI7CiAgfQogIGlzU2NhbGFibGUoKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW119IHgxCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDIKICAgKiBAcmV0dXJucyB7bnVtYmVyfQogICAqLwogIGtlcm5lbCh4MSwgeDIpIHsKICAgIC8vIFNhbml0aXplIHBhcmFtZXRlcnMuCiAgICBjb25zdCBhbXBsID0gTWF0aC5hYnModGhpcy5hbXBsKTsKICAgIGNvbnN0IGRpc3RhbmNlU3F1YXJlZCA9IG5vcm1TcXVhcmVkKHN1YlZlYyh4MSwgeDIpKTsKICAgIGNvbnN0IHggPSAtZGlzdGFuY2VTcXVhcmVkIC8gKDIgKiB0aGlzLmxzICogdGhpcy5scyk7CiAgICByZXR1cm4gYW1wbCAqIE1hdGguZXhwKHgpOwogIH0KCiAgLyoqCiAgICogZ3JhZGllbnQgPSBbZ3JhZF9scywgZ3JhZF9hbXBsXSB3aXRoIGTCsiA9IOKAlnjiiJJ54oCWwrIsIEEgPSB8YW1wbHwsCiAgICogICBlID0gZXhwKOKIkmTCsi8oMsK3bHPCsikpOgogICAqICAgZ3JhZF9scyAgID0gKGTCsiDCtyBBIMK3IGUpIC8gbHPCswogICAqICAgZ3JhZF9hbXBsID0gc2lnbihhbXBsKSDCtyBlCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDEKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MgogICAqIEByZXR1cm5zIHtudW1iZXJbXX0KICAgKi8KICBncmFkaWVudCh4MSwgeDIpIHsKICAgIGNvbnN0IGFtcGwgPSBNYXRoLmFicyh0aGlzLmFtcGwpOwogICAgY29uc3QgZGlzdGFuY2VTcXVhcmVkID0gbm9ybVNxdWFyZWQoc3ViVmVjKHgxLCB4MikpOwogICAgY29uc3QgZXhwb25lbnRpYWwgPSBNYXRoLmV4cCgtZGlzdGFuY2VTcXVhcmVkIC8gKDIgKiB0aGlzLmxzICogdGhpcy5scykpOwogICAgY29uc3QgZ3JhZExzID0gZGlzdGFuY2VTcXVhcmVkICogYW1wbCAqIGV4cG9uZW50aWFsIC8gTWF0aC5wb3codGhpcy5scywgMyk7CiAgICBjb25zdCBncmFkQW1wbCA9IE1hdGguc2lnbih0aGlzLmFtcGwpICogZXhwb25lbnRpYWw7CiAgICByZXR1cm4gW2dyYWRMcywgZ3JhZEFtcGxdOwogIH0KCiAgLyoqIEBwYXJhbSB7bnVtYmVyfSBzY2FsZSAqLwogIHJlc2NhbGUoc2NhbGUpIHsKICAgIHRoaXMuYW1wbCAqPSBzY2FsZTsKICB9CiAgZ2V0UGFyYW1ldGVycygpIHsKICAgIHJldHVybiBbdGhpcy5scywgdGhpcy5hbXBsXTsKICB9CgogIC8qKiBAcGFyYW0ge251bWJlcltdfSBwYXJhbWV0ZXJzICovCiAgc2V0UGFyYW1ldGVycyhwYXJhbWV0ZXJzKSB7CiAgICB0aGlzLmxzID0gcGFyYW1ldGVyc1swXTsKICAgIHRoaXMuYW1wbCA9IHBhcmFtZXRlcnNbMV07CiAgfQoKICAvKioKICAgKiBoZXVyaXN0aWM6IGxzID0gbWVhbiBpbnRlci1zYW1wbGUgZGlzdGFuY2UsIGFtcGwgPSBvdXRwdXQgdmFyaWFuY2UuCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcltdfSBvdXRwdXRzCiAgICovCiAgaGV1cmlzdGljRml0KGlucHV0cywgb3V0cHV0cykgewogICAgdGhpcy5scyA9IGZpdEJhbmR3aWR0aE1lYW4oaW5wdXRzKTsKICAgIHRoaXMuYW1wbCA9IGZpdEFtcGxpdHVkZVZhcihvdXRwdXRzKTsKICB9Cn0KCi8qKiBHYXVzc2lhbiBrZXJuZWwg4oCUIGFsaWFzIG9mIFNxdWFyZWRFeHAgKFJ1c3QgYHB1YiB0eXBlIEdhdXNzaWFuID0gU3F1YXJlZEV4cGApLiAqLwpjb25zdCBHYXVzc2lhbiA9IFNxdWFyZWRFeHA7CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKICogRXhwb25lbnRpYWwga2VybmVsOgogKiAgIGsoeCx5KSA9IEHCt2V4cCjiiJLigJZ44oiSeeKAliAvICgywrdsc8KyKSksICBBID0gfGFtcGx8LgogKiBOT1RFIHRoZSBkZW5vbWluYXRvciBpcyAywrdsc8KyIChOT1QgbHMpLCBmYWl0aGZ1bCB0byBSdXN0LgogKiBQYXJhbWV0ZXJzOiBbbHMsIGFtcGxdIChkZWZhdWx0cyBscyA9IDEsIGFtcGwgPSAxKS4gbmJQYXJhbWV0ZXJzID0gMi4gU2NhbGFibGUuCiAqLwpjbGFzcyBFeHBvbmVudGlhbCB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJ9IFtscz0xXQogICAqIEBwYXJhbSB7bnVtYmVyfSBbYW1wbD0xXQogICAqLwogIGNvbnN0cnVjdG9yKGxzID0gMSwgYW1wbCA9IDEpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSBsZW5ndGggc2NhbGUgKi8KICAgIHRoaXMubHMgPSBsczsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSBhbXBsaXR1ZGUgKi8KICAgIHRoaXMuYW1wbCA9IGFtcGw7CiAgfQogIG5iUGFyYW1ldGVycygpIHsKICAgIHJldHVybiAyOwogIH0KICBpc1NjYWxhYmxlKCkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MQogICAqIEBwYXJhbSB7bnVtYmVyW119IHgyCiAgICogQHJldHVybnMge251bWJlcn0KICAgKi8KICBrZXJuZWwoeDEsIHgyKSB7CiAgICBjb25zdCBhbXBsID0gTWF0aC5hYnModGhpcy5hbXBsKTsKICAgIGNvbnN0IGRpc3RhbmNlID0gbm9ybShzdWJWZWMoeDEsIHgyKSk7CiAgICBjb25zdCB4ID0gLWRpc3RhbmNlIC8gKDIgKiB0aGlzLmxzICogdGhpcy5scyk7CiAgICByZXR1cm4gYW1wbCAqIE1hdGguZXhwKHgpOwogIH0KCiAgLyoqCiAgICogZ3JhZGllbnQgPSBbZ3JhZF9scywgZ3JhZF9hbXBsXSB3aXRoIGQgPSDigJZ44oiSeeKAliwgQSA9IHxhbXBsfCwKICAgKiAgIGUgPSBleHAo4oiSZC8oMsK3bHPCsikpOgogICAqICAgZ3JhZF9scyAgID0gKGQgwrcgQSDCtyBlKSAvIGxzwrMKICAgKiAgIGdyYWRfYW1wbCA9IHNpZ24oYW1wbCkgwrcgZQogICAqIEBwYXJhbSB7bnVtYmVyW119IHgxCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDIKICAgKiBAcmV0dXJucyB7bnVtYmVyW119CiAgICovCiAgZ3JhZGllbnQoeDEsIHgyKSB7CiAgICBjb25zdCBhbXBsID0gTWF0aC5hYnModGhpcy5hbXBsKTsKICAgIGNvbnN0IGRpc3RhbmNlID0gbm9ybShzdWJWZWMoeDEsIHgyKSk7CiAgICBjb25zdCBleHBvbmVudGlhbCA9IE1hdGguZXhwKC1kaXN0YW5jZSAvICgyICogdGhpcy5scyAqIHRoaXMubHMpKTsKICAgIGNvbnN0IGdyYWRMcyA9IGRpc3RhbmNlICogYW1wbCAqIGV4cG9uZW50aWFsIC8gTWF0aC5wb3codGhpcy5scywgMyk7CiAgICBjb25zdCBncmFkQW1wbCA9IE1hdGguc2lnbih0aGlzLmFtcGwpICogZXhwb25lbnRpYWw7CiAgICByZXR1cm4gW2dyYWRMcywgZ3JhZEFtcGxdOwogIH0KCiAgLyoqIEBwYXJhbSB7bnVtYmVyfSBzY2FsZSAqLwogIHJlc2NhbGUoc2NhbGUpIHsKICAgIHRoaXMuYW1wbCAqPSBzY2FsZTsKICB9CiAgZ2V0UGFyYW1ldGVycygpIHsKICAgIHJldHVybiBbdGhpcy5scywgdGhpcy5hbXBsXTsKICB9CgogIC8qKiBAcGFyYW0ge251bWJlcltdfSBwYXJhbWV0ZXJzICovCiAgc2V0UGFyYW1ldGVycyhwYXJhbWV0ZXJzKSB7CiAgICB0aGlzLmxzID0gcGFyYW1ldGVyc1swXTsKICAgIHRoaXMuYW1wbCA9IHBhcmFtZXRlcnNbMV07CiAgfQoKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyW119IG91dHB1dHMKICAgKi8KICBoZXVyaXN0aWNGaXQoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICB0aGlzLmxzID0gZml0QmFuZHdpZHRoTWVhbihpbnB1dHMpOwogICAgdGhpcy5hbXBsID0gZml0QW1wbGl0dWRlVmFyKG91dHB1dHMpOwogIH0KfQoKLyoqCiAqIFByaW9yIG1vZGVscyBmb3IgR2F1c3NpYW4gUHJvY2VzcyBSZWdyZXNzaW9uLgogKgogKiBQb3J0IG9mIGBmcmllZHJpY2ggMC42LjAgc3JjL3BhcmFtZXRlcnMvcHJpb3IucnNgLgogKgogKiBXaGVuIGFza2VkIHRvIHByZWRpY3QgYSB2YWx1ZSBmb3IgYW4gaW5wdXQgdGhhdCBpcyB0b28gZGlzc2ltaWxhciB0byBrbm93bgogKiBpbnB1dHMsIHRoZSBtb2RlbCByZXR1cm5zIHRoZSBwcmlvci4gVGhlIEdQIGlzIGZpdHRlZCBvbiB0aGUgKnJlc2lkdWFsKiBvZgogKiB0aGUgcHJpb3IsIHNvIGEgZ29vZCBwcmlvciBjYW4gc2lnbmlmaWNhbnRseSBpbXByb3ZlIHByZWNpc2lvbi4KICoKICogRGF0YSByZXByZXNlbnRhdGlvbiAoc2VlIFBPUlRfU1BFQyDCpzIpOgogKiAgIC0gaW5wdXRzICA6IG51bWJlcltdW10gKHJvdy1tYWpvcjsgb25lIHNhbXBsZSBwZXIgcm93KQogKiAgIC0gb3V0cHV0cyA6IG51bWJlcltdCiAqCiAqIERlcGVuZGVuY2llczogYWxnZWJyYS5tanMgKGRvdCwgbHN0c3FTb2x2ZSkKICovCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQ29uc3RhbnRQcmlvcgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBUaGUgQ29uc3RhbnQgcHJpb3IuCiAqCiAqIFJldHVybnMgYSBzaW5nbGUgY29uc3RhbnQgdmFsdWUgZm9yIGV2ZXJ5IGlucHV0IHBvaW50OiBmKHgpID0gYy4KICogQ2FuIGJlIGZpdHRlZCB0byB0aGUgbWVhbiBvZiB0aGUgdHJhaW5pbmcgb3V0cHV0cy4KICovCmNsYXNzIENvbnN0YW50UHJpb3IgewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyfSBjIHRoZSBjb25zdGFudCBwcmlvciB2YWx1ZQogICAqLwogIGNvbnN0cnVjdG9yKGMpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqLwogICAgdGhpcy5jID0gYzsKICB9CgogIC8qKgogICAqIENyZWF0ZXMgdGhlIGRlZmF1bHQgQ29uc3RhbnRQcmlvciB3aXRoIGMgPSAwLgogICAqIE1hdGNoZXMgUnVzdCBgQ29uc3RhbnRQcmlvcjo6ZGVmYXVsdChfaW5wdXRfZGltZW5zaW9uKSDihpIgU2VsZjo6bmV3KDBmNjQpYC4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyfSBfaW5wdXREaW1lbnNpb24gaWdub3JlZAogICAqIEByZXR1cm5zIHtDb25zdGFudFByaW9yfQogICAqLwogIHN0YXRpYyBkZWZhdWx0KF9pbnB1dERpbWVuc2lvbikgewogICAgcmV0dXJuIG5ldyBDb25zdGFudFByaW9yKDApOwogIH0KCiAgLyoqCiAgICogUmV0dXJucyBhIGNvbnN0YW50IHZlY3RvciBvZiBsZW5ndGggYGlucHV0cy5sZW5ndGhgLCBlYWNoIGVudHJ5ID0gdGhpcy5jLgogICAqIE1hdGNoZXMgUnVzdCBgcHJpb3IoaW5wdXQpIOKGkiBEVmVjdG9yOjpmcm9tX2VsZW1lbnQoaW5wdXQubnJvd3MoKSwgc2VsZi5jKWAuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cyBvbmUgc2FtcGxlIHBlciByb3cKICAgKiBAcmV0dXJucyB7bnVtYmVyW119IGNvbnN0YW50IGFycmF5LCBsZW5ndGggPSBpbnB1dHMubGVuZ3RoCiAgICovCiAgcHJpb3IoaW5wdXRzKSB7CiAgICByZXR1cm4gbmV3IEFycmF5KGlucHV0cy5sZW5ndGgpLmZpbGwodGhpcy5jKTsKICB9CgogIC8qKgogICAqIEZpdHMgdGhlIHByaW9yIHRvIHRoZSBhcml0aG1ldGljIG1lYW4gb2YgYG91dHB1dHNgLgogICAqIE1hdGNoZXMgUnVzdCBgZml0KF8sIHRyYWluaW5nX291dHB1dHMpIHsgc2VsZi5jID0gdHJhaW5pbmdfb3V0cHV0cy5tZWFuKCkgfWAuCiAgICogbmFsZ2VicmEncyBgbWVhbigpYCBkaXZpZGVzIGJ5IE4gKGVsZW1lbnQgY291bnQpLCBtYXRjaGluZyBKUyBhcml0aG1ldGljIG1lYW4uCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdW119IF9pbnB1dHMgaWdub3JlZAogICAqIEBwYXJhbSB7bnVtYmVyW119IG91dHB1dHMgdHJhaW5pbmcgb3V0cHV0IHZhbHVlcwogICAqLwogIGZpdChfaW5wdXRzLCBvdXRwdXRzKSB7CiAgICBjb25zdCBuID0gb3V0cHV0cy5sZW5ndGg7CiAgICBsZXQgc3VtID0gMDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBzdW0gKz0gb3V0cHV0c1tpXTsKICAgIHRoaXMuYyA9IHN1bSAvIG47CiAgfQp9CgovKioKICogY29udmVyc2lvbi5tanMg4oCUIElucHV0IGZsZXhpYmlsaXR5IGZvciB0aGUgSlMgcG9ydCBvZiBmcmllZHJpY2ggMC42LjAuCiAqCiAqIFBvcnQgb2YgYHNyYy9jb252ZXJzaW9uL21vZC5yc2AuCiAqCiAqIFJ1c3QncyBgSW5wdXRgIHRyYWl0IHVzZXMgdGhlIHR5cGUgc3lzdGVtIHRvIGRpc3Rpbmd1aXNoOgogKiAgIC0gYFZlYzxmNjQ+YCAgICAgICAoc2luZ2xlIG11bHRpZGltZW5zaW9uYWwgcG9pbnQpIOKGkiBvdXRwdXQgYGY2NGAKICogICAtIGBWZWM8VmVjPGY2ND4+YCAobXVsdGlwbGUgcG9pbnRzKSAgICAgICAgICAgICAgIOKGkiBvdXRwdXQgYFZlYzxmNjQ+YAogKiAgIC0gYERNYXRyaXg8ZjY0PmAgIChuYWxnZWJyYSBtYXRyaXgpICAgICAgICAgICAgICAg4oaSIG91dHB1dCBgRFZlY3RvcjxmNjQ+YAogKgogKiBKUyBoYXMgbm8gcGFyYW1ldHJpYyB0eXBlcywgc28gd2UgdXNlICoqcnVudGltZSBkZXRlY3Rpb24qKiBvbiB0aGUgZmlyc3QKICogZWxlbWVudCBvZiB0aGUgaW5wdXQgYXJyYXk6CiAqICAgLSBgbnVtYmVyW11gICAgd2hlcmUgYHR5cGVvZiBpbnB1dFswXSA9PT0gJ251bWJlcidgIOKGkiBzaW5nbGUgcG9pbnQKICogICAtIGBudW1iZXJbXVtdYCB3aGVyZSBgQXJyYXkuaXNBcnJheShpbnB1dFswXSlgICAgICAg4oaSIG11bHRpcGxlIHBvaW50cwogKgogKiBUaGUgImlzU2luZ2xlIiBmbGFnIGlzIHByb3BhZ2F0ZWQgaW50byBHUCByZXN1bHRzIHNvIHRoYXQ6CiAqICAgLSBzaW5nbGUtcG9pbnQgaW5wdXRzICDihpIgc2NhbGFyIG91dHB1dHMgIChgbnVtYmVyYCkKICogICAtIG11bHRpLXBvaW50IGlucHV0cyAgIOKGkiB2ZWN0b3Igb3V0cHV0cyAgKGBudW1iZXJbXWApCiAqCiAqIFRoaXMgbWF0Y2hlcyB0aGUgYE91dFZlY3RvciA9IGY2NGAgdnMgYE91dFZlY3RvciA9IFZlYzxmNjQ+YCBkaXN0aW5jdGlvbgogKiBvZiB0aGUgUnVzdCB0cmFpdCBpbXBscy4KICoKICogUE9SVF9TUEVDIMKnOSAoY29udmVyc2lvbi5tanMpLCDCpzEyIGl0ZW0gMTAgKGNvbHVtbi1tYWpvciB2cyByb3ctbWFqb3IpLgogKgogKiBObyBpbnRlcm5hbCBkZXBlbmRlbmNpZXMgKGNvbnZlcnNpb24ubWpzIGhhcyBubyBpbXBvcnRzIHBlciBQT1JUX1NQRUMgwqcxCiAqIGRlcGVuZGVuY3kgZ3JhcGgpLgogKi8KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBpc1NpbmdsZQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBEZXRlY3Qgd2hldGhlciBgaW5wdXRgIHJlcHJlc2VudHMgYSAqKnNpbmdsZSoqIG11bHRpZGltZW5zaW9uYWwgcG9pbnQuCiAqCiAqIFJ1bGVzIChtaXJyb3JzIFJ1c3QgdHJhaXQgZGlzcGF0Y2gpOgogKiAgIC0gYG51bWJlcltdYCAgIChhbGwgZWxlbWVudHMgYXJlIG51bWJlcnMpICDihpIgdHJ1ZSAgIChzaW5nbGUgcG9pbnQsIGxpa2UgYFZlYzxmNjQ+YCkKICogICAtIGBudW1iZXJbXVtdYCAoZmlyc3QgZWxlbWVudCBpcyBhbiBhcnJheSkgIOKGkiBmYWxzZSAgKG11bHRpcGxlIHBvaW50cywgbGlrZSBgVmVjPFZlYzxmNjQ+PmApCiAqCiAqIEFuIGVtcHR5IGFycmF5IGlzIHRyZWF0ZWQgYXMgbXVsdGktcG9pbnQgKGZhbHN5IHNpbmdsZSwgbWF0Y2hlcwogKiB0aGUgYGFzc2VydF9uZSEobmJfcm93cywgMClgIGd1YXJkIGluIHRoZSBSdXN0IGBWZWM8VmVjPGY2ND4+YCBpbXBsIOKAlAogKiBlbXB0eSBpbnB1dHMgYXJlIHJlamVjdGVkIHVwc3RyZWFtIGFueXdheSkuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXQKICogQHJldHVybnMge2Jvb2xlYW59CiAqLwpmdW5jdGlvbiBpc1NpbmdsZShpbnB1dCkgewogIGlmICghQXJyYXkuaXNBcnJheShpbnB1dCkgfHwgaW5wdXQubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7CiAgcmV0dXJuIHR5cGVvZiBpbnB1dFswXSA9PT0gJ251bWJlcic7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyB0b01hdHJpeAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBOb3JtYWxpc2UgYW55IHJlY29nbmlzZWQgaW5wdXQgZm9ybSB0byBgbnVtYmVyW11bXWAgKG9uZSByb3cgcGVyIHNhbXBsZSkuCiAqCiAqIHwgSlMgaW5wdXQgICAgICAgICAgICAgIHwgUnVzdCBhbmFsb2d1ZSAgICAgICAgIHwgUmVzdWx0ICAgICAgICAgICAgICAgfAogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKICogfCBgW2EsIGIsIGNdYCAgICAgICAgICAgfCBgVmVjPGY2ND5gICAgICAgICAgICAgfCBgW1thLCBiLCBjXV1gICgxw5dkKSAgfAogKiB8IGBbW2EsYl0sW2MsZF0s4oCmXWAgICAgIHwgYFZlYzxWZWM8ZjY0Pj5gICAgICAgIHwgdW5jaGFuZ2VkICAgICAgICAgICAgfAogKgogKiBNYXRjaGVzIGBJbnB1dDo6dG9fZG1hdHJpeGAgKGJvdGggaW1wbHMpOgogKiAgIC0gYFZlYzxmNjQ+YCDihpIgYERNYXRyaXg6OmZyb21fcm93X3NsaWNlKDEsIG0ubGVuKCksIG0pYCDigJQgd3JhcHMgaW4gMSByb3cuCiAqICAgLSBgVmVjPFZlYzxmNjQ+PmAg4oaSIGBETWF0cml4Ojpmcm9tX2ZuKG5iX3Jvd3MsIG5iX2NvbHMsIHxyLGN8IG1bcl1bY10pYCDigJQgZGlyZWN0LgogKgogKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0CiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gdG9NYXRyaXgoaW5wdXQpIHsKICBpZiAoaXNTaW5nbGUoaW5wdXQpKSB7CiAgICAvLyBTaW5nbGUgcG9pbnQ6IHdyYXAgaW50byBhIDEtcm93IG1hdHJpeC4KICAgIHJldHVybiBbaW5wdXQuc2xpY2UoKV07CiAgfQogIC8vIE11bHRpcGxlIHBvaW50czogcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBvdXRlciBhcnJheSBzbyBjYWxsZXJzCiAgLy8gY2Fubm90IGFjY2lkZW50YWxseSBtdXRhdGUgdGhlIG9yaWdpbmFsLCB3aGlsZSBrZWVwaW5nIGlubmVyIHJvdyByZWZzLgogIHJldHVybiBpbnB1dC5zbGljZSgpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gdG9WZWN0b3IKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKICogTm9ybWFsaXNlIGEgdHJhaW5pbmctb3V0cHV0IHZhbHVlIHRvIGBudW1iZXJbXWAuCiAqCiAqIHwgSlMgb3V0cHV0ICAgfCBSdXN0IGFuYWxvZ3VlICB8IFJlc3VsdCAgIHwKICogfC0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfAogKiB8IGBudW1iZXJgICAgIHwgYGY2NGAgICAgICAgICAgfCBgW3ZdYCAgICB8CiAqIHwgYG51bWJlcltdYCAgfCBgVmVjPGY2ND5gICAgICB8IHVuY2hhbmdlZHwKICoKICogTWF0Y2hlcyBgSW5wdXQ6OnRvX2R2ZWN0b3JgOgogKiAgIC0gYFZlYzxmNjQ+YCBpbXBsOiBgRFZlY3Rvcjo6ZnJvbV9lbGVtZW50KDEsICp2KWAg4oCUIHdyYXBzIHNjYWxhciBpbiAxLWVsZW1lbnQgdmVjdG9yLgogKiAgIC0gYFZlYzxWZWM8ZjY0Pj5gIGltcGw6IGBEVmVjdG9yOjpmcm9tX2NvbHVtbl9zbGljZSh2KWAg4oCUIGRpcmVjdCBzbGljZS4KICoKICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119IG91dHB1dAogKiBAcmV0dXJucyB7bnVtYmVyW119CiAqLwpmdW5jdGlvbiB0b1ZlY3RvcihvdXRwdXQpIHsKICBpZiAodHlwZW9mIG91dHB1dCA9PT0gJ251bWJlcicpIHsKICAgIHJldHVybiBbb3V0cHV0XTsKICB9CiAgcmV0dXJuIG91dHB1dC5zbGljZSgpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gZnJvbVZlY3RvcgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBDb252ZXJ0IGFuIGludGVybmFsIHJlc3VsdCB2ZWN0b3IgYmFjayB0byB0aGUgdXNlci1mYWNpbmcgb3V0cHV0IHR5cGUuCiAqCiAqIHwgYHNpbmdsZWAgfCBSZXN1bHQgICAgICAgICAgfCBSdXN0IGFuYWxvZ3VlIChgZnJvbV9kdmVjdG9yYCkgICAgICAgICB8CiAqIHwtLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CiAqIHwgYHRydWVgICAgfCBgdlswXWAgKG51bWJlcikgfCBgVmVjPGY2ND5gIGltcGw6IGBhc3NlcnRfZXEhKG5yb3dzLDEpOyB2WzBdYCB8CiAqIHwgYGZhbHNlYCAgfCBgdi5zbGljZSgpYCAgICAgfCBgVmVjPFZlYzxmNjQ+PmAgaW1wbDogYHYuaXRlcigpLmNsb25lZCgpLmNvbGxlY3QoKWAgfAogKgogKiBOb3RlOiBgcHJlZGljdENvdmFyaWFuY2VgICoqYWx3YXlzKiogcmV0dXJucyBgbnVtYmVyW11bXWAgYW5kIG11c3QgTk9UIGNhbGwKICogdGhpcyBmdW5jdGlvbiAoUE9SVF9TUEVDIMKnOSwgwqc2LjcpLgogKgogKiBAcGFyYW0ge251bWJlcltdfSB2ICAgICAgaW50ZXJuYWwgcmVzdWx0IHZlY3RvcgogKiBAcGFyYW0ge2Jvb2xlYW59ICBzaW5nbGUgdHJ1ZSBpZiB0aGUgb3JpZ2luYWwgaW5wdXQgd2FzIGEgc2luZ2xlIHBvaW50CiAqIEByZXR1cm5zIHtudW1iZXJ8bnVtYmVyW119CiAqLwpmdW5jdGlvbiBmcm9tVmVjdG9yKHYsIHNpbmdsZSkgewogIGlmIChzaW5nbGUpIHsKICAgIC8vIE1pcnJvcnM6IGFzc2VydF9lcSEodi5ucm93cygpLCAxKTsgdlswXQogICAgcmV0dXJuIHZbMF07CiAgfQogIHJldHVybiB2LnNsaWNlKCk7Cn0KCi8qKgogKiBNdWx0aXZhcmlhdGUgTm9ybWFsIERpc3RyaWJ1dGlvbiBzYW1wbGVyLgogKgogKiBQb3J0IG9mIGBmcmllZHJpY2ggMC42LjBgIGBzcmMvZ2F1c3NpYW5fcHJvY2Vzcy9tdWx0aXZhcmlhdGVfbm9ybWFsLnJzYC4KICoKICogRXhwb3J0czoKICogICAtIGBtdWxiZXJyeTMyKHNlZWQpYCAgICAg4oCTIHNlZWRhYmxlIFBSTkcgKFBPUlRfU1BFQyDCpzMpCiAqICAgLSBgc3RhbmRhcmROb3JtYWwocm5nKWAgIOKAkyBCb3gtTXVsbGVyIE4oMCwxKSBzYW1wbGVyIChQT1JUX1NQRUMgwqczKQogKiAgIC0gYE11bHRpdmFyaWF0ZU5vcm1hbGAgICDigJMgY2xhc3MgcHJvZHVjZWQgYnkgYEdhdXNzaWFuUHJvY2Vzcy5zYW1wbGVBdGAKICoKICogWmVybyBleHRlcm5hbCBucG0gZGVwZW5kZW5jaWVzLiBQUk5HIGNob2ljZSAobXVsYmVycnkzMiArIEJveC1NdWxsZXIpIGlzCiAqIE5PVCBiaXQtZm9yLWJpdCBpZGVudGljYWwgdG8gUnVzdCdzIHJhbmQgLyByYW5kX2Rpc3RyLCBidXQgaXMgc3RhdGlzdGljYWxseQogKiBjb3JyZWN0IGFuZCByZXByb2R1Y2libGUgZ2l2ZW4gYSBzZWVkIChQT1JUX1NQRUMgwqcxMi42KS4KICoKICogRGF0YSByZXByZXNlbnRhdGlvbiAoUE9SVF9TUEVDIMKnMik6CiAqICAgdmVjdG9yID0gbnVtYmVyW10KICogICBtYXRyaXggPSBudW1iZXJbXVtdIChyb3ctbWFqb3IpCiAqLwoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBOT1JNQUwgU0FNUExFUiDigJMgQm94LU11bGxlciAoUE9SVF9TUEVDIMKnMywgZXhhY3QgaW1wbGVtZW50YXRpb24gc3BlY2lmaWVkKQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogRHJhdyBvbmUgc3RhbmRhcmQtbm9ybWFsIHNhbXBsZSBOKDAsMSkgdXNpbmcgdGhlIEJveC1NdWxsZXIgdHJhbnNmb3JtLgogKgogKiBDb25zdW1lcyB0d28gdW5pZm9ybSBkcmF3cyBmcm9tIGBybmdgOyByZXRyaWVzIGlmIHRoZSBmaXJzdCBkcmF3IGlzIGV4YWN0bHkKICogMCAodG8gYXZvaWQgbG9nKDApIOKGkiAtSW5maW5pdHkpLgogKgogKiBOb3RlOiB0aGlzIHVzZXMgb25seSB0aGUgY29zaW5lIGJyYW5jaCBvZiBCb3gtTXVsbGVyICh0aGUgc2luZSBicmFuY2ggaXMKICogZGlzY2FyZGVkKSwgbWF0Y2hpbmcgdGhlIFBPUlRfU1BFQyDCpzMgY2Fub25pY2FsIGltcGxlbWVudGF0aW9uLiBTdGF0aXN0aWNhbAogKiBjb3JyZWN0bmVzcyBpcyBtYWludGFpbmVkOyB0aGUgc2luZSBicmFuY2ggd291bGQgZ2l2ZSBlcXVhbGx5IHZhbGlkIHNhbXBsZXMKICogYnV0IGlzIG5vdCByZXF1aXJlZC4KICoKICogQHBhcmFtIHsoKSA9PiBudW1iZXJ9IHJuZyAgdW5pZm9ybSBbMCwgMSkgZ2VuZXJhdG9yIChlLmcuIGZyb20gbXVsYmVycnkzMikKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIHN0YW5kYXJkTm9ybWFsKHJuZykgewogIGxldCB1MSA9IDAsCiAgICB1MiA9IDA7CiAgd2hpbGUgKHUxID09PSAwKSB1MSA9IHJuZygpOyAvLyBhdm9pZCBsb2coMCkKICB1MiA9IHJuZygpOwogIHJldHVybiBNYXRoLnNxcnQoLTIgKiBNYXRoLmxvZyh1MSkpICogTWF0aC5jb3MoMiAqIE1hdGguUEkgKiB1Mik7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gTXVsdGl2YXJpYXRlTm9ybWFsIENMQVNTCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBNdWx0aXZhcmlhdGUgTm9ybWFsIERpc3RyaWJ1dGlvbiBOKG1lYW4sIM6jKS4KICoKICogUHJvZHVjZWQgYnkgYEdhdXNzaWFuUHJvY2Vzcy5zYW1wbGVBdChpbnB1dHMpYC4gU3RvcmVzIHRoZSBDaG9sZXNreSBmYWN0b3IKICogTCBvZiB0aGUgcG9zdGVyaW9yIGNvdmFyaWFuY2UgzqMgKHdoZXJlIM6jID0gTMK3TOG1gCkuIFNhbXBsaW5nIHVzZXM6CiAqCiAqICAgeiB+IE4oMCwgSSkgIChkcmF3IGVhY2ggY29tcG9uZW50IHZpYSBCb3gtTXVsbGVyKQogKiAgIHggPSBtZWFuICsgTMK3eiAg4oaSICB4IH4gTihtZWFuLCDOoykKICoKICogVGhlIGBpc1NpbmdsZWAgZmxhZyBtaXJyb3JzIHRoZSBSdXN0IGBQaGFudG9tRGF0YTxUPmAgbWVjaGFuaXNtOiB3aGVuIHRoZQogKiBHUCB3YXMgcXVlcmllZCBhdCBhIHNpbmdsZSBwb2ludCAoYFQgPSBWZWM8ZjY0PmApIHRoZSBvdXRwdXQgb2YgYG1lYW4oKWAgYW5kCiAqIGBzYW1wbGUoKWAgaXMgYSBgbnVtYmVyYDsgd2hlbiBxdWVyaWVkIGF0IG11bHRpcGxlIHBvaW50cyBpdCBpcyBhIGBudW1iZXJbXWAuCiAqCiAqIFBvcnQgbm90ZXM6CiAqICAgLSBSdXN0IHN0b3JlcyBgY2hvbGVza3lfY292YXJpYW5jZWAgKGFscmVhZHkgdGhlIGxvd2VyLXRyaWFuZ3VsYXIgZmFjdG9yIEwKICogICAgIGZyb20gYG5hbGdlYnJhOjpDaG9sZXNreTo6dW5wYWNrKClgKS4gSlMgbGlrZXdpc2Ugc3RvcmVzIG9ubHkgTCBhZnRlcgogKiAgICAgZGVjb21wb3NpbmcgdGhlIGNvdmFyaWFuY2UgaW4gdGhlIGNvbnN0cnVjdG9yLgogKiAgIC0gQ2hvbGVza3kgZmFpbHVyZSDihpIgdGhyb3cgKG1hdGNoZXMgUnVzdCBgLmV4cGVjdCgiLi4uIilgKS4KICovCmNsYXNzIE11bHRpdmFyaWF0ZU5vcm1hbCB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXX0gICBtZWFuICAgICAgICBwb3N0ZXJpb3IgbWVhbiB2ZWN0b3IgKGxlbmd0aCBuKQogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gY292YXJpYW5jZSAgcG9zdGVyaW9yIGNvdmFyaWFuY2UgbWF0cml4IChuw5duKSwgc3ltbWV0cmljIHBvc2l0aXZlLWRlZmluaXRlCiAgICogQHBhcmFtIHtib29sZWFufSAgICBpc1NpbmdsZSAgICB0cnVlIHdoZW4gdGhlIEdQIGlucHV0IHdhcyBhIHNpbmdsZSBwb2ludCAobnVtYmVyW10pOwogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2Ugd2hlbiBtdWx0aXBsZSBwb2ludHMgKG51bWJlcltdW10pCiAgICovCiAgY29uc3RydWN0b3IobWVhbiwgY292YXJpYW5jZSwgaXNTaW5nbGUpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW119ICovCiAgICB0aGlzLl9tZWFuID0gbWVhbjsKICAgIC8qKgogICAgICogTG93ZXItdHJpYW5ndWxhciBDaG9sZXNreSBmYWN0b3IgTCBvZiB0aGUgY292YXJpYW5jZSAozqMgPSBMwrdM4bWAKS4KICAgICAqIEB0eXBlIHtudW1iZXJbXVtdfQogICAgICovCiAgICB0aGlzLl9MID0gY2hvbGVza3koY292YXJpYW5jZSwgbnVsbCk7IC8vIG51bGwg4oaSIHRocm93IG9uIGZhaWx1cmUgKG1hdGNoZXMgUnVzdCAuZXhwZWN0KQogICAgLyoqIEB0eXBlIHtib29sZWFufSAqLwogICAgdGhpcy5faXNTaW5nbGUgPSBpc1NpbmdsZTsKICB9CgogIC8qKgogICAqIFBvc3RlcmlvciBtZWFuLgogICAqCiAgICogUmV0dXJucyBhIGBudW1iZXJgIHdoZW4gYGlzU2luZ2xlYCBpcyB0cnVlIChzaW5nbGUtcG9pbnQgcXVlcnkpLAogICAqIG9yIGEgYG51bWJlcltdYCB3aGVuIGZhbHNlIChtdWx0aS1wb2ludCBxdWVyeSkuCiAgICoKICAgKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVtYmVyW119CiAgICovCiAgbWVhbigpIHsKICAgIHJldHVybiBmcm9tVmVjdG9yKHRoaXMuX21lYW4sIHRoaXMuX2lzU2luZ2xlKTsKICB9CgogIC8qKgogICAqIERyYXcgb25lIHNhbXBsZSBmcm9tIE4obWVhbiwgzqMpLgogICAqCiAgICogQWxnb3JpdGhtIChQT1JUX1NQRUMgwqc4KToKICAgKiAgIDEuIHogPSBbc3RhbmRhcmROb3JtYWwocm5nKSwg4oCmXSAgKG9uZSBOKDAsMSkgcGVyIGRpbWVuc2lvbikKICAgKiAgIDIuIHNhbXBsZVZlYyA9IG1lYW4gKyBMwrd6CiAgICogICAzLiByZXR1cm4gZnJvbVZlY3RvcihzYW1wbGVWZWMsIGlzU2luZ2xlKQogICAqCiAgICogYHJuZ2AgbXVzdCBiZSBhIGAoKSA9PiBudW1iZXIg4oiIIFswLCAxKWAgZnVuY3Rpb24sIGUuZy4gdGhlIGNsb3N1cmUKICAgKiByZXR1cm5lZCBieSBgbXVsYmVycnkzMihzZWVkKWAuIFRoZSBvdXRwdXQgdHlwZSBtaXJyb3JzIGBtZWFuKClgLgogICAqCiAgICogTnVtZXJpYyBub3RlOiB0aGUgUFJORyBhbmQgQm94LU11bGxlciBpbXBsZW1lbnRhdGlvbiBkaWZmZXIgZnJvbSBSdXN0J3MKICAgKiBgcmFuZGAvYHJhbmRfZGlzdHJgLCBzbyBzYW1wbGUgdmFsdWVzIHdpbGwgbm90IG1hdGNoIFJ1c3QgYml0LWZvci1iaXQuCiAgICogU3RhdGlzdGljYWwgY29ycmVjdG5lc3MgYW5kIHJlcHJvZHVjaWJpbGl0eSBnaXZlbiBhIHNlZWQgYXJlIGd1YXJhbnRlZWQuCiAgICoKICAgKiBAcGFyYW0geygpID0+IG51bWJlcn0gcm5nCiAgICogQHJldHVybnMge251bWJlciB8IG51bWJlcltdfQogICAqLwogIHNhbXBsZShybmcpIHsKICAgIGNvbnN0IG4gPSB0aGlzLl9tZWFuLmxlbmd0aDsKICAgIC8vIFN0ZXAgMTogZHJhdyB6IH4gTigwLCBJKQogICAgY29uc3QgeiA9IG5ldyBBcnJheShuKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB6W2ldID0gc3RhbmRhcmROb3JtYWwocm5nKTsKICAgIC8vIFN0ZXAgMjogc2FtcGxlVmVjID0gbWVhbiArIEzCt3oKICAgIGNvbnN0IEx6ID0gbWF0VmVjKHRoaXMuX0wsIHopOwogICAgY29uc3Qgc2FtcGxlVmVjID0gbmV3IEFycmF5KG4pOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHNhbXBsZVZlY1tpXSA9IHRoaXMuX21lYW5baV0gKyBMeltpXTsKICAgIC8vIFN0ZXAgMzogY29udmVydCB0byBzY2FsYXIgb3IgdmVjdG9yIGRlcGVuZGluZyBvbiBxdWVyeSB0eXBlCiAgICByZXR1cm4gZnJvbVZlY3RvcihzYW1wbGVWZWMsIHRoaXMuX2lzU2luZ2xlKTsKICB9Cn0KCi8vISBQYXJhbWV0ZXIgb3B0aW1pemF0aW9uIChBREFNIGdyYWRpZW50IGFzY2VudCBvbiB0aGUgbWFyZ2luYWwgbG9nLWxpa2VsaWhvb2QpLgoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBOT04tU0NBTEFCTEUgS0VSTkVMCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBDb21wdXRlcyB0aGUgZ3JhZGllbnQgb2YgdGhlIG1hcmdpbmFsIGxpa2VsaWhvb2QgZm9yIHRoZSBjdXJyZW50IHZhbHVlIG9mCiAqIGVhY2ggcGFyYW1ldGVyLiBUaGUgcHJvZHVjZWQgdmVjdG9yIGNvbnRhaW5zIHRoZSBncmFkaWVudCBwZXIga2VybmVsCiAqIHBhcmFtZXRlciBmb2xsb3dlZCBieSB0aGUgZ3JhZGllbnQgZm9yIHRoZSBub2lzZSBwYXJhbWV0ZXIuCiAqCiAqIFBlci1wYXJhbWV0ZXIgZm9ybXVsYSAoYG9wdGltaXplci5yczoyNGApOgogKiAgIMK9ICggYWxwaGHhtYAgwrcgZHAgwrcgYWxwaGEg4oiSIHRyYWNlKEvigbvCuSDCtyBkcCkgKQogKiB3aGVyZQogKiAgIEsgICAgID0gY292KHRyYWluLCB0cmFpbikKICogICBhbHBoYSA9IEvigbvCuSDCtyBvdXRwdXQKICogICBkcCAgICA9IOKIgksv4oiCcGFyYW1ldGVyCiAqCiAqIE5vaXNlIGdyYWRpZW50IChgZ3JhZGllbnQoSywgbm9pc2UpID0gMsK3bm9pc2XCt0lkYCk6CiAqICAgbm9pc2UgwrcgKCBhbHBoYcK3YWxwaGEg4oiSIHRyYWNlKEvigbvCuSkgKQogKgogKiBAcGFyYW0ge29iamVjdH0gZ3AgR2F1c3NpYW5Qcm9jZXNzIChzZWUgbW9kdWxlIG5vdGUpCiAqIEByZXR1cm5zIHtudW1iZXJbXX0gbGVuZ3RoID0ga2VybmVsLm5iUGFyYW1ldGVycygpICsgMSAobGFzdCBlbnRyeSA9IG5vaXNlKQogKi8KZnVuY3Rpb24gZ3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QoZ3ApIHsKICAvLyBOZWVkZWQgZm9yIHRoZSBwZXItcGFyYW1ldGVyIGdyYWRpZW50IGNvbXB1dGF0aW9uLgogIGNvbnN0IGNvdkludiA9IGdwLmNvdm1hdENob2xlc2t5LmludmVyc2UoKTsgLy8gS+KBu8K5CiAgY29uc3Qgb3V0cHV0ID0gZ3AudHJhaW5pbmdPdXRwdXRzLmFzVmVjdG9yKCk7CgogIC8vIGFscGhhID0gS+KBu8K5IMK3IG91dHB1dCAgKG1hdFZlYzsgY292SW52IGlzIHN5bW1ldHJpYykuCiAgY29uc3QgbiA9IG91dHB1dC5sZW5ndGg7CiAgY29uc3QgYWxwaGEgPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIHsKICAgIGxldCBzID0gMDsKICAgIGNvbnN0IHJvdyA9IGNvdkludltyXTsKICAgIGZvciAobGV0IGMgPSAwOyBjIDwgbjsgYysrKSBzICs9IHJvd1tjXSAqIG91dHB1dFtjXTsKICAgIGFscGhhW3JdID0gczsKICB9CiAgY29uc3QgaW5wdXRzID0gZ3AudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKICBjb25zdCByZXN1bHRzID0gW107CgogIC8vIExvb3Agb3ZlciB0aGUgZ3JhZGllbnQgbWF0cml4IGZvciBlYWNoIHBhcmFtZXRlci4KICBmb3IgKGNvbnN0IGNvdkdyYWRpZW50IG9mIG1ha2VHcmFkaWVudENvdmFyaWFuY2VNYXRyaWNlcyhpbnB1dHMsIGdwLmtlcm5lbCkpIHsKICAgIC8vIGRhdGFfZml0ID0gzqNfYyBhbHBoYVtjXSDCtyAoYWxwaGEgwrcgY29sX2MpICA9ICBhbHBoYeG1gCDCtyBjb3ZHcmFkaWVudCDCtyBhbHBoYQogICAgLy8gY292R3JhZGllbnQgaXMgc3ltbWV0cmljLCBzbyBpdHMgY29sdW1uIGMgZXF1YWxzIGl0cyByb3cgYy4KICAgIGxldCBkYXRhRml0ID0gMDsKICAgIGZvciAobGV0IGMgPSAwOyBjIDwgbjsgYysrKSB7CiAgICAgIC8vIGFscGhhIMK3IChjb2x1bW4gYyBvZiBjb3ZHcmFkaWVudCkKICAgICAgbGV0IGFjb2wgPSAwOwogICAgICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgYWNvbCArPSBhbHBoYVtyXSAqIGNvdkdyYWRpZW50W3JdW2NdOwogICAgICBkYXRhRml0ICs9IGFjb2wgKiBhbHBoYVtjXTsKICAgIH0KCiAgICAvLyBjb21wbGV4aXR5X3BlbmFsdHkgPSDOo19yIChyb3cgciBvZiBjb3ZJbnYpIMK3IChjb2x1bW4gciBvZiBjb3ZHcmFkaWVudCkKICAgIC8vICAgICAgICAgICAgICAgICAgICA9IHRyYWNlKGNvdkludiDCtyBjb3ZHcmFkaWVudCkKICAgIGxldCBjb21wbGV4aXR5UGVuYWx0eSA9IDA7CiAgICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgewogICAgICBjb25zdCBjUm93ID0gY292SW52W3JdOwogICAgICBsZXQgdHIgPSAwOwogICAgICBmb3IgKGxldCBrID0gMDsgayA8IG47IGsrKykgdHIgKz0gY1Jvd1trXSAqIGNvdkdyYWRpZW50W2tdW3JdOwogICAgICBjb21wbGV4aXR5UGVuYWx0eSArPSB0cjsKICAgIH0KICAgIHJlc3VsdHMucHVzaCgoZGF0YUZpdCAtIGNvbXBsZXhpdHlQZW5hbHR5KSAvIDIpOwogIH0KCiAgLy8gTm9pc2UgcGFyYW1ldGVyOiBncmFkaWVudChLLCBub2lzZSkgPSAywrdub2lzZcK3SWQuCiAgY29uc3QgZGF0YUZpdCA9IGRvdChhbHBoYSwgYWxwaGEpOwogIGNvbnN0IGNvbXBsZXhpdHlQZW5hbHR5ID0gdHJhY2UoY292SW52KTsgLy8gdHJhY2UoS+KBu8K5KQogIGNvbnN0IG5vaXNlR3JhZGllbnQgPSBncC5ub2lzZSAqIChkYXRhRml0IC0gY29tcGxleGl0eVBlbmFsdHkpOwogIHJlc3VsdHMucHVzaChub2lzZUdyYWRpZW50KTsKICByZXR1cm4gcmVzdWx0czsKfQoKLyoqCiAqIEZpdCBwYXJhbWV0ZXJzIHVzaW5nIHRoZSBBREFNIGdyYWRpZW50LWFzY2VudCBhbGdvcml0aG0uCiAqCiAqIFJ1bnMgZm9yIGF0IG1vc3QgYG1heEl0ZXJgIGl0ZXJhdGlvbnMuIFN0b3BzIGVhcmx5IGlmIGV2ZXJ5IGNvbXBvbmVudCBvZiB0aGUKICogdXBkYXRlIHN0ZXAgYGRlbHRhYCBpcyDiiaQgYGNvbnZlcmdlbmNlRnJhY3Rpb25gIGluIG1hZ25pdHVkZSAobm8gc2lnbmlmaWNhbnQKICogcHJvZ3Jlc3MpLCBvciBpZiB0aGUgcnVudGltZSBleGNlZWRzIGBtYXhUaW1lYCAobWlsbGlzZWNvbmRzKS4KICoKICogVGhlIGBub2lzZWAgcGFyYW1ldGVyIGlzIGZpdHRlZCBpbiBsb2ctc2NhbGUsIHNpbmNlIGl0cyBtYWduaXR1ZGUgbWF0dGVycwogKiBtb3JlIHRoYW4gaXRzIHByZWNpc2UgdmFsdWUuCiAqCiAqIEFEQU0gY29uc3RhbnRzIChgb3B0aW1pemVyLnJzOjc5YCk6IGJldGExPTAuOSwgYmV0YTI9MC45OTksIGVwc2lsb249MWUtOCwKICogbGVhcm5pbmdSYXRlPTAuMS4KICoKICogQHBhcmFtIHtvYmplY3R9IGdwCiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhJdGVyCiAqIEBwYXJhbSB7bnVtYmVyfSBjb252ZXJnZW5jZUZyYWN0aW9uCiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhUaW1lIG1pbGxpc2Vjb25kcwogKi8KZnVuY3Rpb24gb3B0aW1pemVQYXJhbWV0ZXJzKGdwLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKSB7CiAgY29uc3QgYmV0YTEgPSAwLjk7CiAgY29uc3QgYmV0YTIgPSAwLjk5OTsKICBjb25zdCBlcHNpbG9uID0gMWUtODsKICBjb25zdCBsZWFybmluZ1JhdGUgPSAwLjE7CgogIC8vIEluaXRpYWwgcGFyYW1ldGVyczoga2VybmVsIHBhcmFtcyB3aXRoIGFueSAwIHJlcGxhY2VkIGJ5IGVwc2lsb24gKGEgMAogIC8vIHBhcmFtZXRlciB3b3VsZCBibG9jayB0aGUgbXVsdGlwbGljYXRpdmUgQURBTSB1cGRhdGUpLCB0aGVuIG5vaXNlIGluCiAgLy8gbG9nLXNwYWNlLgogIGNvbnN0IHBhcmFtZXRlcnMgPSBncC5rZXJuZWwuZ2V0UGFyYW1ldGVycygpLm1hcChwID0+IHAgPT09IDAgPyBlcHNpbG9uIDogcCk7CiAgcGFyYW1ldGVycy5wdXNoKE1hdGgubG9nKGdwLm5vaXNlKSk7IC8vIG5vaXNlIGluIGxvZy1zcGFjZQoKICBjb25zdCBtZWFuR3JhZCA9IG5ldyBBcnJheShwYXJhbWV0ZXJzLmxlbmd0aCkuZmlsbCgwKTsKICBjb25zdCB2YXJHcmFkID0gbmV3IEFycmF5KHBhcmFtZXRlcnMubGVuZ3RoKS5maWxsKDApOwogIGNvbnN0IHRpbWVTdGFydCA9IERhdGUubm93KCk7CiAgZm9yIChsZXQgaSA9IDE7IGkgPD0gbWF4SXRlcjsgaSsrKSB7CiAgICBjb25zdCBncmFkaWVudHMgPSBncmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZChncCk7CiAgICAvLyBDb3JyZWN0IHRoZSBub2lzZSBncmFkaWVudCBmb3IgbG9nLXNwYWNlLgogICAgZ3JhZGllbnRzW2dyYWRpZW50cy5sZW5ndGggLSAxXSAqPSBncC5ub2lzZTsKICAgIGxldCBoYWRTaWduaWZpY2FudFByb2dyZXNzID0gZmFsc2U7CiAgICBmb3IgKGxldCBwID0gMDsgcCA8IHBhcmFtZXRlcnMubGVuZ3RoOyBwKyspIHsKICAgICAgbWVhbkdyYWRbcF0gPSBiZXRhMSAqIG1lYW5HcmFkW3BdICsgKDEgLSBiZXRhMSkgKiBncmFkaWVudHNbcF07CiAgICAgIHZhckdyYWRbcF0gPSBiZXRhMiAqIHZhckdyYWRbcF0gKyAoMSAtIGJldGEyKSAqIGdyYWRpZW50c1twXSAqIGdyYWRpZW50c1twXTsKICAgICAgY29uc3QgYmlhc0NvcnJlY3RlZE1lYW4gPSBtZWFuR3JhZFtwXSAvICgxIC0gTWF0aC5wb3coYmV0YTEsIGkpKTsKICAgICAgY29uc3QgYmlhc0NvcnJlY3RlZFZhcmlhbmNlID0gdmFyR3JhZFtwXSAvICgxIC0gTWF0aC5wb3coYmV0YTIsIGkpKTsKICAgICAgY29uc3QgZGVsdGEgPSBsZWFybmluZ1JhdGUgKiBiaWFzQ29ycmVjdGVkTWVhbiAvIChNYXRoLnNxcnQoYmlhc0NvcnJlY3RlZFZhcmlhbmNlKSArIGVwc2lsb24pOwogICAgICBpZiAoTWF0aC5hYnMoZGVsdGEpID4gY29udmVyZ2VuY2VGcmFjdGlvbikgaGFkU2lnbmlmaWNhbnRQcm9ncmVzcyA9IHRydWU7CiAgICAgIHBhcmFtZXRlcnNbcF0gKj0gMSArIGRlbHRhOwogICAgfQoKICAgIC8vIFNldCBrZXJuZWwgcGFyYW1ldGVycyAodGhlIGtlcm5lbCByZWFkcyBvbmx5IGl0cyBvd24gbGVhZGluZyBwcmVmaXgKICAgIC8vIG9mIGBwYXJhbWV0ZXJzYDsgdGhlIHRyYWlsaW5nIG5vaXNlIGxvZy12YWx1ZSBpcyBpZ25vcmVkIGJ5IGl0KS4KICAgIGdwLmtlcm5lbC5zZXRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpOwogICAgLy8gR2V0IHRoZSBub2lzZSBvdXQgb2YgbG9nLXNwYWNlIGJlZm9yZSBzZXR0aW5nIGl0LgogICAgZ3Aubm9pc2UgPSBNYXRoLmV4cChwYXJhbWV0ZXJzW3BhcmFtZXRlcnMubGVuZ3RoIC0gMV0pOwoKICAgIC8vIFJlZml0IHRoZSBtb2RlbCAocmVidWlsZCB0aGUgQ2hvbGVza3kgZmFjdG9yIG9mIHRoZSBjb3ZhcmlhbmNlIG1hdHJpeCkuCiAgICBncC5jb3ZtYXRDaG9sZXNreSA9IG1ha2VDaG9sZXNreUNvdk1hdHJpeChncC50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpLCBncC5rZXJuZWwsIGdwLm5vaXNlLCBncC5jaG9sZXNreUVwc2lsb24pOwogICAgaWYgKCFoYWRTaWduaWZpY2FudFByb2dyZXNzIHx8IERhdGUubm93KCkgLSB0aW1lU3RhcnQgPiBtYXhUaW1lKSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBTQ0FMQUJMRSBLRVJORUwKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIFJldHVybnMgYFtzY2FsZSwgZ3JhZGllbnRzXWA6IHRoZSBvcHRpbWFsIHNjYWxlIGZvciB0aGUga2VybmVsK25vaXNlICh1c2VkIHRvCiAqIG9wdGltaXplIHRoZSBub2lzZSkgcGx1cyB0aGUgZ3JhZGllbnQgcGVyIGtlcm5lbCBwYXJhbWV0ZXIgKE5PVCBpbmNsdWRpbmcgdGhlCiAqIG5vaXNlIGdyYWRpZW50KS4KICoKICogUGVyLXBhcmFtZXRlciBmb3JtdWxhIChgb3B0aW1pemVyLnJzOjE1MGApOgogKiAgIMK9ICggYWxwaGHhtYAgwrcgZHAgwrcgYWxwaGEgLyBzY2FsZSDiiJIgdHJhY2UoS+KBu8K5IMK3IGRwKSApCiAqICAgc2NhbGUgPSBvdXRwdXThtYAgwrcgS+KBu8K5IMK3IG91dHB1dCAvIG4KICogTk9URTogdGhlIGRhdGEtZml0IHRlcm0gaXMgZGl2aWRlZCBieSBgc2NhbGVgLCB1bmxpa2UgdGhlIHVuc2NhbGVkIGdyYWRpZW50LgogKgogKiBAcGFyYW0ge29iamVjdH0gZ3AKICogQHJldHVybnMge1tudW1iZXIsIG51bWJlcltdXX0gW3NjYWxlLCByZXN1bHRzXSAocmVzdWx0cyBsZW5ndGggPSBuYlBhcmFtZXRlcnMpCiAqLwpmdW5jdGlvbiBzY2FsZWRHcmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZChncCkgewogIGNvbnN0IGNvdkludiA9IGdwLmNvdm1hdENob2xlc2t5LmludmVyc2UoKTsgLy8gS+KBu8K5CiAgY29uc3Qgb3V0cHV0ID0gZ3AudHJhaW5pbmdPdXRwdXRzLmFzVmVjdG9yKCk7CiAgY29uc3QgbiA9IG91dHB1dC5sZW5ndGg7CgogIC8vIGFscGhhID0gS+KBu8K5IMK3IG91dHB1dAogIGNvbnN0IGFscGhhID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSB7CiAgICBsZXQgcyA9IDA7CiAgICBjb25zdCByb3cgPSBjb3ZJbnZbcl07CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG47IGMrKykgcyArPSByb3dbY10gKiBvdXRwdXRbY107CiAgICBhbHBoYVtyXSA9IHM7CiAgfQoKICAvLyBTY2FsaW5nIGZvciB0aGUga2VybmVsOiBvdXRwdXThtYAgwrcgS+KBu8K5IMK3IG91dHB1dCAvIG4gPSBvdXRwdXTCt2FscGhhIC8gbi4KICBjb25zdCBzY2FsZSA9IGRvdChvdXRwdXQsIGFscGhhKSAvIG47CiAgY29uc3QgaW5wdXRzID0gZ3AudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKICBjb25zdCByZXN1bHRzID0gW107CiAgZm9yIChjb25zdCBjb3ZHcmFkaWVudCBvZiBtYWtlR3JhZGllbnRDb3ZhcmlhbmNlTWF0cmljZXMoaW5wdXRzLCBncC5rZXJuZWwpKSB7CiAgICAvLyBkYXRhX2ZpdCA9IChhbHBoYeG1gCDCtyBjb3ZHcmFkaWVudCDCtyBhbHBoYSkgLyBzY2FsZQogICAgbGV0IGRhdGFGaXQgPSAwOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuOyBjKyspIHsKICAgICAgbGV0IGFjb2wgPSAwOwogICAgICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgYWNvbCArPSBhbHBoYVtyXSAqIGNvdkdyYWRpZW50W3JdW2NdOwogICAgICBkYXRhRml0ICs9IGFjb2wgKiBhbHBoYVtjXTsKICAgIH0KICAgIGRhdGFGaXQgLz0gc2NhbGU7CgogICAgLy8gY29tcGxleGl0eV9wZW5hbHR5ID0gdHJhY2UoY292SW52IMK3IGNvdkdyYWRpZW50KQogICAgbGV0IGNvbXBsZXhpdHlQZW5hbHR5ID0gMDsKICAgIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSB7CiAgICAgIGNvbnN0IGNSb3cgPSBjb3ZJbnZbcl07CiAgICAgIGxldCB0ciA9IDA7CiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgbjsgaysrKSB0ciArPSBjUm93W2tdICogY292R3JhZGllbnRba11bcl07CiAgICAgIGNvbXBsZXhpdHlQZW5hbHR5ICs9IHRyOwogICAgfQogICAgcmVzdWx0cy5wdXNoKChkYXRhRml0IC0gY29tcGxleGl0eVBlbmFsdHkpIC8gMik7CiAgfQoKICAvLyBOT1RFOiBmYWl0aGZ1bCB0byBSdXN0IHNvdXJjZSDigJQgdGhlIG5vaXNlIGdyYWRpZW50IGlzIGludGVudGlvbmFsbHkgTk9UCiAgLy8gcHVzaGVkIGhlcmUgKGl0IGlzIGNvbW1lbnRlZCBvdXQgaW4gb3B0aW1pemVyLnJzOjE4OC0xOTEpOyB0aGUgbm9pc2UgaXMKICAvLyBpbnN0ZWFkIGZpdHRlZCB2aWEgYGtlcm5lbC5yZXNjYWxlKHNjYWxlKWAgKyBgZ3Aubm9pc2UgKj0gc2NhbGVgLgoKICByZXR1cm4gW3NjYWxlLCByZXN1bHRzXTsKfQoKLyoqCiAqIEZpdCBwYXJhbWV0ZXJzIHVzaW5nIEFEQU0gZ3JhZGllbnQgYXNjZW50OyBhZGRpdGlvbmFsbHksIGF0IGVhY2ggc3RlcCB0aGUKICoga2VybmVsIGFuZCBub2lzZSBhcmUgcmVzY2FsZWQgYnkgdGhlIG9wdGltYWwgbWFnbml0dWRlIGBzY2FsZWAuCiAqCiAqIFJ1bnMgZm9yIGF0IG1vc3QgYG1heEl0ZXJgIGl0ZXJhdGlvbnMuIFN0b3BzIGVhcmx5IG9uIG5vIHNpZ25pZmljYW50IHByb2dyZXNzCiAqIChhbGwgYGRlbHRhYCDiiaQgYGNvbnZlcmdlbmNlRnJhY3Rpb25gKSBvciBpZiB0aGUgcnVudGltZSBleGNlZWRzIGBtYXhUaW1lYAogKiAobWlsbGlzZWNvbmRzKS4KICoKICogQURBTSBjb25zdGFudHMgaWRlbnRpY2FsIHRvIHtAbGluayBvcHRpbWl6ZVBhcmFtZXRlcnN9LgogKgogKiBAcGFyYW0ge29iamVjdH0gZ3AKICogQHBhcmFtIHtudW1iZXJ9IG1heEl0ZXIKICogQHBhcmFtIHtudW1iZXJ9IGNvbnZlcmdlbmNlRnJhY3Rpb24KICogQHBhcmFtIHtudW1iZXJ9IG1heFRpbWUgbWlsbGlzZWNvbmRzCiAqLwpmdW5jdGlvbiBzY2FsZWRPcHRpbWl6ZVBhcmFtZXRlcnMoZ3AsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpIHsKICBjb25zdCBiZXRhMSA9IDAuOTsKICBjb25zdCBiZXRhMiA9IDAuOTk5OwogIGNvbnN0IGVwc2lsb24gPSAxZS04OwogIGNvbnN0IGxlYXJuaW5nUmF0ZSA9IDAuMTsKCiAgLy8gSW5pdGlhbCBwYXJhbWV0ZXJzOiBrZXJuZWwgcGFyYW1zIHdpdGggMCByZXBsYWNlZCBieSBlcHNpbG9uLgogIC8vIChObyBub2lzZSBwdXNoZWQ6IHRoZSBub2lzZSBpcyBmaXR0ZWQgYnkgcmVzY2FsaW5nLCBub3QgYnkgZ3JhZGllbnQuKQogIGxldCBwYXJhbWV0ZXJzID0gZ3Aua2VybmVsLmdldFBhcmFtZXRlcnMoKS5tYXAocCA9PiBwID09PSAwID8gZXBzaWxvbiA6IHApOwogIGNvbnN0IG1lYW5HcmFkID0gbmV3IEFycmF5KHBhcmFtZXRlcnMubGVuZ3RoKS5maWxsKDApOwogIGNvbnN0IHZhckdyYWQgPSBuZXcgQXJyYXkocGFyYW1ldGVycy5sZW5ndGgpLmZpbGwoMCk7CiAgY29uc3QgdGltZVN0YXJ0ID0gRGF0ZS5ub3coKTsKICBmb3IgKGxldCBpID0gMTsgaSA8PSBtYXhJdGVyOyBpKyspIHsKICAgIGNvbnN0IFtzY2FsZSwgZ3JhZGllbnRzXSA9IHNjYWxlZEdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKGdwKTsKICAgIGxldCBoYWRTaWduaWZpY2FudFByb2dyZXNzID0gZmFsc2U7CiAgICBmb3IgKGxldCBwID0gMDsgcCA8IHBhcmFtZXRlcnMubGVuZ3RoOyBwKyspIHsKICAgICAgbWVhbkdyYWRbcF0gPSBiZXRhMSAqIG1lYW5HcmFkW3BdICsgKDEgLSBiZXRhMSkgKiBncmFkaWVudHNbcF07CiAgICAgIHZhckdyYWRbcF0gPSBiZXRhMiAqIHZhckdyYWRbcF0gKyAoMSAtIGJldGEyKSAqIGdyYWRpZW50c1twXSAqIGdyYWRpZW50c1twXTsKICAgICAgY29uc3QgYmlhc0NvcnJlY3RlZE1lYW4gPSBtZWFuR3JhZFtwXSAvICgxIC0gTWF0aC5wb3coYmV0YTEsIGkpKTsKICAgICAgY29uc3QgYmlhc0NvcnJlY3RlZFZhcmlhbmNlID0gdmFyR3JhZFtwXSAvICgxIC0gTWF0aC5wb3coYmV0YTIsIGkpKTsKICAgICAgY29uc3QgZGVsdGEgPSBsZWFybmluZ1JhdGUgKiBiaWFzQ29ycmVjdGVkTWVhbiAvIChNYXRoLnNxcnQoYmlhc0NvcnJlY3RlZFZhcmlhbmNlKSArIGVwc2lsb24pOwogICAgICBpZiAoTWF0aC5hYnMoZGVsdGEpID4gY29udmVyZ2VuY2VGcmFjdGlvbikgaGFkU2lnbmlmaWNhbnRQcm9ncmVzcyA9IHRydWU7CiAgICAgIHBhcmFtZXRlcnNbcF0gKj0gMSArIGRlbHRhOwogICAgfQoKICAgIC8vIFNldCBwYXJhbWV0ZXJzLCB0aGVuIHJlc2NhbGUgdGhlIGtlcm5lbCBhbmQgbm9pc2UgYnkgdGhlIG9wdGltYWwgc2NhbGUuCiAgICBncC5rZXJuZWwuc2V0UGFyYW1ldGVycyhwYXJhbWV0ZXJzKTsKICAgIGdwLmtlcm5lbC5yZXNjYWxlKHNjYWxlKTsKICAgIGdwLm5vaXNlICo9IHNjYWxlOwogICAgLy8gR2V0IHBhcmFtZXRlcnMgYmFjayBhcyB0aGV5IGhhdmUgYmVlbiByZXNjYWxlZCAocmVzY2FsZSBjaGFuZ2VzIHRoZQogICAgLy8gYW1wbGl0dWRlLCBzbyB0aGUgbG9jYWwgYHBhcmFtZXRlcnNgIG11c3QgYmUgcmVmcmVzaGVkIGZyb20gdGhlIGtlcm5lbCkuCiAgICBwYXJhbWV0ZXJzID0gZ3Aua2VybmVsLmdldFBhcmFtZXRlcnMoKTsKCiAgICAvLyBSZWZpdCB0aGUgbW9kZWwuCiAgICBncC5jb3ZtYXRDaG9sZXNreSA9IG1ha2VDaG9sZXNreUNvdk1hdHJpeChncC50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpLCBncC5rZXJuZWwsIGdwLm5vaXNlLCBncC5jaG9sZXNreUVwc2lsb24pOwogICAgaWYgKCFoYWRTaWduaWZpY2FudFByb2dyZXNzIHx8IERhdGUubm93KCkgLSB0aW1lU3RhcnQgPiBtYXhUaW1lKSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKLy8hIEdhdXNzaWFuIHByb2Nlc3MuCgovKiogRGVmYXVsdCBtYXhpbXVtIGZpdHRpbmcgdGltZTogb25lIGhvdXIsIGV4cHJlc3NlZCBpbiBtaWxsaXNlY29uZHMgKFJ1c3QgdXNlcyBjaHJvbm86OkR1cmF0aW9uOjpzZWNvbmRzKDM2MDApKS4gKi8KY29uc3QgREVGQVVMVF9NQVhfVElNRV9NUyA9IDM2MDAgKiAxMDAwOwoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBHYXVzc2lhblByb2Nlc3MKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIEEgR2F1c3NpYW4gcHJvY2VzcyB0aGF0IGNhbiBiZSB1c2VkIHRvIG1ha2UgcHJlZGljdGlvbnMgYmFzZWQgb24gaXRzIHRyYWluaW5nCiAqIGRhdGEuCiAqCiAqIEludGVybmFsIHN0YXRlIChtaXJyb3JzIHRoZSBSdXN0IGBHYXVzc2lhblByb2Nlc3NgIHN0cnVjdCwgYG1vZC5yczo1OWApOgogKiAgIC0gYHByaW9yYCAgICAgICAgICAgUHJpb3IgaW5zdGFuY2UuCiAqICAgLSBga2VybmVsYCAgICAgICAgICBLZXJuZWwgaW5zdGFuY2UuCiAqICAgLSBgbm9pc2VgICAgICAgICAgICBudW1iZXIg4oCUIG5vaXNlIFNUQU5EQVJEIERFVklBVElPTiAobm90IHZhcmlhbmNlKS4KICogICAtIGBjaG9sZXNreUVwc2lsb25gIG51bWJlciB8IG51bGwg4oCUIHN1YnN0aXR1dGUgcGl2b3QgZm9yIENob2xlc2t5IChvciBudWxsKS4KICogICAtIGB0cmFpbmluZ0lucHV0c2AgIEV4dGVuZGFibGVNYXRyaXguCiAqICAgLSBgdHJhaW5pbmdPdXRwdXRzYCBFeHRlbmRhYmxlVmVjdG9yIOKAlCBzdG9yZXMgYG91dHB1dHMg4oiSIHByaW9yKGlucHV0cylgICh0aGUgcmVzaWR1YWwhKS4KICogICAtIGBjb3ZtYXRDaG9sZXNreWAgIENob2xlc2t5RGVjb21wb3NpdGlvbiBvZiBLID0ga2VybmVsKFgsWCkgKyBub2lzZcKywrdJLgogKi8KY2xhc3MgR2F1c3NpYW5Qcm9jZXNzIHsKICAvKioKICAgKiBSYXcgY29uc3RydWN0b3IgKGBtb2QucnM6MTQyYCkuIFByZWZlciB7QGxpbmsgR2F1c3NpYW5Qcm9jZXNzLmRlZmF1bHR9IG9yCiAgICoge0BsaW5rIEdhdXNzaWFuUHJvY2Vzcy5idWlsZGVyfS4KICAgKgogICAqIEBwYXJhbSB7b2JqZWN0fSAgICAgICBwcmlvciAgICAgICAgICAgIFByaW9yIGluc3RhbmNlLgogICAqIEBwYXJhbSB7b2JqZWN0fSAgICAgICBrZXJuZWwgICAgICAgICAgIEtlcm5lbCBpbnN0YW5jZS4KICAgKiBAcGFyYW0ge251bWJlcn0gICAgICAgbm9pc2UgICAgICAgICAgICBub2lzZSBzdGFuZGFyZCBkZXZpYXRpb24gKOKJpSAwKS4KICAgKiBAcGFyYW0ge251bWJlcnxudWxsfSAgY2hvbGVza3lFcHNpbG9uICBzdWJzdGl0dXRlIHBpdm90IChvciBudWxsIHRvIHRocm93IG9uIGZhaWx1cmUpLgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gdHJhaW5pbmdJbnB1dHMgIHJhdyBpbnB1dHMuCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICB0cmFpbmluZ091dHB1dHMgcmF3IG91dHB1dHMgKE5PVCB5ZXQgcmVzaWR1YWxpc2VkKS4KICAgKi8KICBjb25zdHJ1Y3Rvcihwcmlvciwga2VybmVsLCBub2lzZSwgY2hvbGVza3lFcHNpbG9uLCB0cmFpbmluZ0lucHV0cywgdHJhaW5pbmdPdXRwdXRzKSB7CiAgICBpZiAoIShub2lzZSA+PSAwKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBub2lzZSBwYXJhbWV0ZXIgc2hvdWxkIGJlIG5vbi1uZWdhdGl2ZSBidXQgd2UgdHJpZWQgdG8gc2V0IGl0IHRvICR7bm9pc2V9YCk7CiAgICB9CgogICAgLy8gTm9ybWFsaXNlIGlucHV0cy9vdXRwdXRzIGludG8gbWF0cml4IC8gdmVjdG9yIGZvcm0gKG1hdGNoZXMgVDo6aW50b19kbWF0cml4IC8gaW50b19kdmVjdG9yKS4KICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KHRyYWluaW5nSW5wdXRzKTsKICAgIGNvbnN0IG91dHB1dHNWZWN0b3IgPSB0b1ZlY3Rvcih0cmFpbmluZ091dHB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeC5sZW5ndGggIT09IG91dHB1dHNWZWN0b3IubGVuZ3RoKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgdHJhaW5pbmdfaW5wdXRzLm5yb3dzKCkgKCR7aW5wdXRzTWF0cml4Lmxlbmd0aH0pICE9PSB0cmFpbmluZ19vdXRwdXRzLm5yb3dzKCkgKCR7b3V0cHV0c1ZlY3Rvci5sZW5ndGh9KWApOwogICAgfQoKICAgIC8qKiBAdHlwZSB7b2JqZWN0fSAqLwogICAgdGhpcy5wcmlvciA9IHByaW9yOwogICAgLyoqIEB0eXBlIHtvYmplY3R9ICovCiAgICB0aGlzLmtlcm5lbCA9IGtlcm5lbDsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSBub2lzZSBzdGFuZGFyZCBkZXZpYXRpb24gKi8KICAgIHRoaXMubm9pc2UgPSBub2lzZTsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfG51bGx9ICovCiAgICB0aGlzLmNob2xlc2t5RXBzaWxvbiA9IGNob2xlc2t5RXBzaWxvbjsKCiAgICAvLyBFeHRlbmRhYmxlIHRyYWluaW5nIGRhdGEuIHRyYWluaW5nT3V0cHV0cyBob2xkcyB0aGUgUFJJT1IgUkVTSURVQUwuCiAgICAvKiogQHR5cGUge0V4dGVuZGFibGVNYXRyaXh9ICovCiAgICB0aGlzLnRyYWluaW5nSW5wdXRzID0gbmV3IEV4dGVuZGFibGVNYXRyaXgoaW5wdXRzTWF0cml4KTsKICAgIGNvbnN0IHByaW9yVmFsdWVzID0gcHJpb3IucHJpb3IoaW5wdXRzTWF0cml4KTsKICAgIGNvbnN0IHJlc2lkdWFsID0gbmV3IEFycmF5KG91dHB1dHNWZWN0b3IubGVuZ3RoKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0c1ZlY3Rvci5sZW5ndGg7IGkrKykgewogICAgICByZXNpZHVhbFtpXSA9IG91dHB1dHNWZWN0b3JbaV0gLSBwcmlvclZhbHVlc1tpXTsKICAgIH0KICAgIC8qKiBAdHlwZSB7RXh0ZW5kYWJsZVZlY3Rvcn0gKi8KICAgIHRoaXMudHJhaW5pbmdPdXRwdXRzID0gbmV3IEV4dGVuZGFibGVWZWN0b3IocmVzaWR1YWwpOwoKICAgIC8vIENob2xlc2t5IG9mIHRoZSBjb3ZhcmlhbmNlIG1hdHJpeCBLID0ga2VybmVsKFgsWCkgKyBub2lzZcKywrdJLgogICAgLyoqIEB0eXBlIHtpbXBvcnQoJy4vYWxnZWJyYS5tanMnKS5DaG9sZXNreURlY29tcG9zaXRpb259ICovCiAgICB0aGlzLmNvdm1hdENob2xlc2t5ID0gbWFrZUNob2xlc2t5Q292TWF0cml4KGlucHV0c01hdHJpeCwga2VybmVsLCBub2lzZSwgY2hvbGVza3lFcHNpbG9uKTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBTVEFUSUMgQ09OU1RSVUNUT1JTCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBSZXR1cm5zIGEgR2F1c3NpYW4gcHJvY2VzcyB3aXRoIGEgR2F1c3NpYW4ga2VybmVsIGFuZCBhIGNvbnN0YW50IHByaW9yLAogICAqIGJvdGggZml0dGVkIHRvIHRoZSBkYXRhIChgbW9kLnJzOjk2YCkuCiAgICoKICAgKiBFcXVpdmFsZW50IHRvIGBidWlsZGVyKGlucHV0cywgb3V0cHV0cykuZml0X2tlcm5lbCgpLmZpdF9wcmlvcigpLnRyYWluKClgLgogICAqCiAgICogTm90ZTogYGRlZmF1bHRgIGlzIGEgdmFsaWQgc3RhdGljLW1ldGhvZCBuYW1lIGluIEpTIGNsYXNzZXM7IHNlZQogICAqIHtAbGluayBHYXVzc2lhblByb2Nlc3MuZnJvbURhdGF9IGZvciBhIHNhZmUgYWxpYXMuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSAgICAgb3V0cHV0cwogICAqIEByZXR1cm5zIHtHYXVzc2lhblByb2Nlc3N9CiAgICovCiAgc3RhdGljIGRlZmF1bHQoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICByZXR1cm4gR2F1c3NpYW5Qcm9jZXNzLmJ1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKS5maXRLZXJuZWwoKS5maXRQcmlvcigpLnRyYWluKCk7CiAgfQoKICAvKioKICAgKiBTYWZlIGFsaWFzIG9mIHtAbGluayBHYXVzc2lhblByb2Nlc3MuZGVmYXVsdH0gKGluIGNhc2UgYSB0b29sY2hhaW4gZGlzbGlrZXMKICAgKiB0aGUgYGRlZmF1bHRgIG1ldGhvZCBuYW1lKS4gSWRlbnRpY2FsIGJlaGF2aW91ci4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICBvdXRwdXRzCiAgICogQHJldHVybnMge0dhdXNzaWFuUHJvY2Vzc30KICAgKi8KICBzdGF0aWMgZnJvbURhdGEoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICByZXR1cm4gR2F1c3NpYW5Qcm9jZXNzLmRlZmF1bHQoaW5wdXRzLCBvdXRwdXRzKTsKICB9CgogIC8qKgogICAqIFJldHVybnMgYSBidWlsZGVyIHRvIGRlZmluZSBzcGVjaWZpYyBwYXJhbWV0ZXJzIG9mIHRoZSBHYXVzc2lhbiBwcm9jZXNzCiAgICogKGBtb2QucnM6MTI5YCkuIERlZmF1bHRzIHRvIGEgR2F1c3NpYW4ga2VybmVsICsgY29uc3RhbnQgcHJpb3IuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSAgICAgb3V0cHV0cwogICAqIEByZXR1cm5zIHtHYXVzc2lhblByb2Nlc3NCdWlsZGVyfQogICAqLwogIHN0YXRpYyBidWlsZGVyKGlucHV0cywgb3V0cHV0cykgewogICAgcmV0dXJuIG5ldyBHYXVzc2lhblByb2Nlc3NCdWlsZGVyKGlucHV0cywgb3V0cHV0cyk7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gQUREIFNBTVBMRVMKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIEFkZHMgbmV3IHNhbXBsZXMgdG8gdGhlIG1vZGVsIChgbW9kLnJzOjE3M2ApLgogICAqCiAgICogVXBkYXRlcyB0aGUgbW9kZWwgaW4gTyhuwrIpIChmYXN0ZXIgdGhhbiByZXRyYWluaW5nIGZyb20gc2NyYXRjaCkgYnV0IGRvZXMKICAgKiBOT1QgcmVmaXQgdGhlIHBhcmFtZXRlcnMuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSAgICAgb3V0cHV0cwogICAqLwogIGFkZF9zYW1wbGVzKGlucHV0cywgb3V0cHV0cykgewogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGNvbnN0IG91dHB1dHNWZWN0b3IgPSB0b1ZlY3RvcihvdXRwdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXgubGVuZ3RoICE9PSBvdXRwdXRzVmVjdG9yLmxlbmd0aCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5ucm93cygpICgke2lucHV0c01hdHJpeC5sZW5ndGh9KSAhPT0gb3V0cHV0cy5ucm93cygpICgke291dHB1dHNWZWN0b3IubGVuZ3RofSlgKTsKICAgIH0KICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KCiAgICAvLyBSZXNpZHVhbGlzZSB0aGUgbmV3IG91dHB1dHMgYWdhaW5zdCB0aGUgY3VycmVudCBwcmlvci4KICAgIGNvbnN0IHByaW9yVmFsdWVzID0gdGhpcy5wcmlvci5wcmlvcihpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgcmVzaWR1YWwgPSBuZXcgQXJyYXkob3V0cHV0c1ZlY3Rvci5sZW5ndGgpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRzVmVjdG9yLmxlbmd0aDsgaSsrKSB7CiAgICAgIHJlc2lkdWFsW2ldID0gb3V0cHV0c1ZlY3RvcltpXSAtIHByaW9yVmFsdWVzW2ldOwogICAgfQoKICAgIC8vIEdyb3cgdGhlIHRyYWluaW5nIGRhdGEuCiAgICB0aGlzLnRyYWluaW5nSW5wdXRzLmFkZFJvd3MoaW5wdXRzTWF0cml4KTsKICAgIHRoaXMudHJhaW5pbmdPdXRwdXRzLmFkZFJvd3MocmVzaWR1YWwpOwoKICAgIC8vIEluY3JlbWVudGFsbHkgZXh0ZW5kIHRoZSBDaG9sZXNreSBkZWNvbXBvc2l0aW9uIHdpdGggdGhlIG5ldyByb3dzLgogICAgY29uc3QgbmJOZXdJbnB1dHMgPSBpbnB1dHNNYXRyaXgubGVuZ3RoOwogICAgYWRkUm93c0Nob2xlc2t5Q292TWF0cml4KHRoaXMuY292bWF0Q2hvbGVza3ksIHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKSwgbmJOZXdJbnB1dHMsIHRoaXMua2VybmVsLCB0aGlzLm5vaXNlKTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBMSUtFTElIT09ECiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBMb2cgbGlrZWxpaG9vZCBvZiB0aGUgY3VycmVudCBtb2RlbCBnaXZlbiB0aGUgdHJhaW5pbmcgZGF0YSAoYG1vZC5yczoxOTZgKS4KICAgKgogICAqIEZvcm11bGE6CiAgICogICDiiJLCvSAoIG91dHB1dOG1gMK3S+KBu8K5wrdvdXRwdXQgKyDOo19yIGxufGtlcm5lbCh44bWjLHjhtaMpICsgbm9pc2XCsnwgKyBuwrdsbigyz4ApICkKICAgKgogICAqIHdoZXJlIGBvdXRwdXRgIGlzIHRoZSBwcmlvciByZXNpZHVhbC4KICAgKgogICAqIEByZXR1cm5zIHtudW1iZXJ9CiAgICovCiAgbGlrZWxpaG9vZCgpIHsKICAgIGNvbnN0IG91dHB1dCA9IHRoaXMudHJhaW5pbmdPdXRwdXRzLmFzVmVjdG9yKCk7IC8vIHJlc2lkdWFsCiAgICBjb25zdCBMID0gdGhpcy5jb3ZtYXRDaG9sZXNreS5sKCk7CgogICAgLy8gdHJhbnNwb3NlKG9sKcK3b2wgPSBvdXRwdXThtYDCt0vigbvCucK3b3V0cHV0LCB3aGVyZSBMwrdvbCA9IG91dHB1dC4KICAgIGNvbnN0IG9sID0gc29sdmVMb3dlclRyaShMLCBvdXRwdXQpOwogICAgY29uc3QgZGF0YUZpdCA9IG5vcm1TcXVhcmVkKG9sKTsKCiAgICAvLyBDb21wbGV4aXR5IHBlbmFsdHk6IM6jIGxufCBzZWxmLWNvdmFyaWFuY2UgKyBub2lzZcKyIHwuCiAgICBjb25zdCBpbnB1dHMgPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CiAgICBjb25zdCBub2lzZVNxID0gdGhpcy5ub2lzZSAqIHRoaXMubm9pc2U7CiAgICBsZXQgY29tcGxleGl0eVBlbmFsdHkgPSAwOwogICAgZm9yIChsZXQgciA9IDA7IHIgPCBpbnB1dHMubGVuZ3RoOyByKyspIHsKICAgICAgY29uc3Qgc2VsZkNvdiA9IHRoaXMua2VybmVsLmtlcm5lbChpbnB1dHNbcl0sIGlucHV0c1tyXSkgKyBub2lzZVNxOwogICAgICBjb21wbGV4aXR5UGVuYWx0eSArPSBNYXRoLmxvZyhNYXRoLmFicyhzZWxmQ292KSk7CiAgICB9CiAgICBjb25zdCBuID0gaW5wdXRzLmxlbmd0aDsKICAgIGNvbnN0IG5vcm1hbGl6YXRpb25Db25zdGFudCA9IG4gKiBNYXRoLmxvZygyICogTWF0aC5QSSk7CiAgICByZXR1cm4gLShkYXRhRml0ICsgY29tcGxleGl0eVBlbmFsdHkgKyBub3JtYWxpemF0aW9uQ29uc3RhbnQpIC8gMjsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBQUkVESUNUCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBQcmVkaWN0cyB0aGUgbWVhbiBvZiB0aGUgR2F1c3NpYW4gcHJvY2VzcyBmb3IgZWFjaCByb3cgb2YgYGlucHV0c2AKICAgKiAoYG1vZC5yczoyMjZgKS4KICAgKgogICAqIEZvcm11bGE6IGBwcmlvciArIGNvdihpbnB1dCx0cmFpbinCt0vigbvCucK3b3V0cHV0YC4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge251bWJlcnxudW1iZXJbXX0gbnVtYmVyIGZvciBhIHNpbmdsZS1wb2ludCBpbnB1dCwgbnVtYmVyW10gb3RoZXJ3aXNlLgogICAqLwogIHByZWRpY3QoaW5wdXRzKSB7CiAgICBjb25zdCBzaW5nbGUgPSBpc1NpbmdsZShpbnB1dHMpOwogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgIC8vIHdlaWdodHMgKG5UcmFpbiDDlyBuSW5wdXQpID0gS+KBu8K5IMK3IGNvdih0cmFpbiwgaW5wdXRzKS4KICAgIGxldCB3ZWlnaHRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgodHJhaW5NYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwogICAgd2VpZ2h0cyA9IHRoaXMuY292bWF0Q2hvbGVza3kuc29sdmUod2VpZ2h0cyk7CiAgICBjb25zdCBtZWFuID0gdGhpcy5fbWVhbkZyb21XZWlnaHRzKHdlaWdodHMsIGlucHV0c01hdHJpeCk7CiAgICByZXR1cm4gZnJvbVZlY3RvcihtZWFuLCBzaW5nbGUpOwogIH0KCiAgLyoqCiAgICogUHJlZGljdHMgdGhlIHZhcmlhbmNlIG9mIHRoZSBHYXVzc2lhbiBwcm9jZXNzIGZvciBlYWNoIHJvdyBvZiBgaW5wdXRzYAogICAqIChgbW9kLnJzOjI0OGApLgogICAqCiAgICogRm9ybXVsYSAoZGlhZ29uYWwgb2YpOgogICAqICAgY292KGlucHV0LGlucHV0KSDiiJIgY292KGlucHV0LHRyYWluKcK3S+KBu8K5wrdjb3YodHJhaW4saW5wdXQpCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEByZXR1cm5zIHtudW1iZXJ8bnVtYmVyW119CiAgICovCiAgcHJlZGljdF92YXJpYW5jZShpbnB1dHMpIHsKICAgIGNvbnN0IHNpbmdsZSA9IGlzU2luZ2xlKGlucHV0cyk7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQogICAgY29uc3QgdHJhaW5NYXRyaXggPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CgogICAgLy8gY292X3RyYWluX2lucHV0cyAoblRyYWluIMOXIG5JbnB1dCkuCiAgICBjb25zdCBjb3ZUcmFpbklucHV0cyA9IG1ha2VDb3ZhcmlhbmNlTWF0cml4KHRyYWluTWF0cml4LCBpbnB1dHNNYXRyaXgsIHRoaXMua2VybmVsKTsKCiAgICAvLyBrbCA9IEzigbvCuSDCtyBjb3ZfdHJhaW5faW5wdXRzICAoc29sdmUgTMK3a2wgPSBjb3ZfdHJhaW5faW5wdXRzKS4KICAgIGNvbnN0IGtsID0gc29sdmVMb3dlclRyaSh0aGlzLmNvdm1hdENob2xlc2t5LmwoKSwgY292VHJhaW5JbnB1dHMpOwoKICAgIC8vIHZhcmlhbmNlW2ldID0ga2VybmVsKGlucHV04bWiLGlucHV04bWiKSDiiJIg4oCWY29sdW1uIGkgb2Yga2zigJbCsi4KICAgIGNvbnN0IG5JbnB1dCA9IGlucHV0c01hdHJpeC5sZW5ndGg7CiAgICBjb25zdCB2YXJpYW5jZXMgPSBuZXcgQXJyYXkobklucHV0KTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbklucHV0OyBpKyspIHsKICAgICAgY29uc3QgYmFzZUNvdiA9IHRoaXMua2VybmVsLmtlcm5lbChpbnB1dHNNYXRyaXhbaV0sIGlucHV0c01hdHJpeFtpXSk7CiAgICAgIGNvbnN0IHByZWRpY3RlZENvdiA9IGNvbHVtbk5vcm1TcXVhcmVkKGtsLCBpKTsKICAgICAgdmFyaWFuY2VzW2ldID0gYmFzZUNvdiAtIHByZWRpY3RlZENvdjsKICAgIH0KICAgIHJldHVybiBmcm9tVmVjdG9yKHZhcmlhbmNlcywgc2luZ2xlKTsKICB9CgogIC8qKgogICAqIFByZWRpY3RzIGJvdGggdGhlIG1lYW4gYW5kIHRoZSB2YXJpYW5jZSBmb3IgZWFjaCByb3cgb2YgYGlucHV0c2AKICAgKiAoYG1vZC5yczoyOTBgKS4gRmFzdGVyIHRoYW4gY2FsbGluZyBgcHJlZGljdGAgYW5kIGBwcmVkaWN0X3ZhcmlhbmNlYAogICAqIHNlcGFyYXRlbHkuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEByZXR1cm5zIHtbbnVtYmVyfG51bWJlcltdLCBudW1iZXJ8bnVtYmVyW11dfSBgW21lYW4sIHZhcmlhbmNlXWAuCiAgICovCiAgcHJlZGljdF9tZWFuX3ZhcmlhbmNlKGlucHV0cykgewogICAgY29uc3Qgc2luZ2xlID0gaXNTaW5nbGUoaW5wdXRzKTsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KGlucHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4WzBdLmxlbmd0aCAhPT0gdGhpcy50cmFpbmluZ0lucHV0cy5uY29scykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5uY29scygpICgke2lucHV0c01hdHJpeFswXS5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfaW5wdXRzLm5jb2xzKCkgKCR7dGhpcy50cmFpbmluZ0lucHV0cy5uY29sc30pYCk7CiAgICB9CiAgICBjb25zdCB0cmFpbk1hdHJpeCA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKCiAgICAvLyBjb3ZfdHJhaW5faW5wdXRzIChuVHJhaW4gw5cgbklucHV0KTsgIHdlaWdodHMgPSBL4oG7wrkgwrcgY292X3RyYWluX2lucHV0cy4KICAgIGNvbnN0IGNvdlRyYWluSW5wdXRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgodHJhaW5NYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwogICAgY29uc3Qgd2VpZ2h0cyA9IHRoaXMuY292bWF0Q2hvbGVza3kuc29sdmUoY292VHJhaW5JbnB1dHMpOwoKICAgIC8vIC0tLS0tIG1lYW4gLS0tLS0KICAgIGNvbnN0IG1lYW5WZWMgPSB0aGlzLl9tZWFuRnJvbVdlaWdodHMod2VpZ2h0cywgaW5wdXRzTWF0cml4KTsKICAgIGNvbnN0IG1lYW4gPSBmcm9tVmVjdG9yKG1lYW5WZWMsIHNpbmdsZSk7CgogICAgLy8gLS0tLS0gdmFyaWFuY2UgLS0tLS0KICAgIC8vIHZhcmlhbmNlW2ldID0ga2VybmVsKGlucHV04bWiLGlucHV04bWiKSDiiJIgKGNvbHVtbiBpIG9mIGNvdl90cmFpbl9pbnB1dHMpwrcoY29sdW1uIGkgb2Ygd2VpZ2h0cykuCiAgICBjb25zdCBuSW5wdXQgPSBpbnB1dHNNYXRyaXgubGVuZ3RoOwogICAgY29uc3QgdmFyaWFuY2VzID0gbmV3IEFycmF5KG5JbnB1dCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5JbnB1dDsgaSsrKSB7CiAgICAgIGNvbnN0IGJhc2VDb3YgPSB0aGlzLmtlcm5lbC5rZXJuZWwoaW5wdXRzTWF0cml4W2ldLCBpbnB1dHNNYXRyaXhbaV0pOwogICAgICBjb25zdCBwcmVkaWN0ZWRDb3YgPSBjb2x1bW5Eb3QoY292VHJhaW5JbnB1dHMsIHdlaWdodHMsIGkpOwogICAgICB2YXJpYW5jZXNbaV0gPSBiYXNlQ292IC0gcHJlZGljdGVkQ292OwogICAgfQogICAgY29uc3QgdmFyaWFuY2UgPSBmcm9tVmVjdG9yKHZhcmlhbmNlcywgc2luZ2xlKTsKICAgIHJldHVybiBbbWVhbiwgdmFyaWFuY2VdOwogIH0KCiAgLyoqCiAgICogUmV0dXJucyB0aGUgZnVsbCBjb3ZhcmlhbmNlIG1hdHJpeCBmb3IgdGhlIHJvd3Mgb2YgYGlucHV0c2AgKGBtb2QucnM6MzI5YCkuCiAgICoKICAgKiBGb3JtdWxhOgogICAqICAgY292KGlucHV0LGlucHV0KSDiiJIgY292KGlucHV0LHRyYWluKcK3S+KBu8K5wrdjb3YodHJhaW4saW5wdXQpCiAgICoKICAgKiBBTFdBWVMgcmV0dXJucyBhIGBudW1iZXJbXVtdYCBtYXRyaXggKG5ldmVyIHNjYWxhcmlzZWQg4oCUIG1hdGNoZXMgUnVzdCB3aGljaAogICAqIGFsd2F5cyByZXR1cm5zIGEgYERNYXRyaXhgKS4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge251bWJlcltdW119IChuSW5wdXQgw5cgbklucHV0KQogICAqLwogIHByZWRpY3RfY292YXJpYW5jZShpbnB1dHMpIHsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KGlucHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4WzBdLmxlbmd0aCAhPT0gdGhpcy50cmFpbmluZ0lucHV0cy5uY29scykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5uY29scygpICgke2lucHV0c01hdHJpeFswXS5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfaW5wdXRzLm5jb2xzKCkgKCR7dGhpcy50cmFpbmluZ0lucHV0cy5uY29sc30pYCk7CiAgICB9CiAgICBjb25zdCB0cmFpbk1hdHJpeCA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKICAgIGNvbnN0IGNvdlRyYWluSW5wdXRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgodHJhaW5NYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwogICAgY29uc3QgY292SW5wdXRzSW5wdXRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgoaW5wdXRzTWF0cml4LCBpbnB1dHNNYXRyaXgsIHRoaXMua2VybmVsKTsKCiAgICAvLyBrbCA9IEzigbvCuSDCtyBjb3ZfdHJhaW5faW5wdXRzLgogICAgY29uc3Qga2wgPSBzb2x2ZUxvd2VyVHJpKHRoaXMuY292bWF0Q2hvbGVza3kubCgpLCBjb3ZUcmFpbklucHV0cyk7CgogICAgLy8gcmVzdWx0ID0gY292X2lucHV0c19pbnB1dHMg4oiSIGts4bWAwrdrbCAgIChtYXRjaGVzIGdlbW1fdHIoLTEsIGtsLCBrbCwgMSkpLgogICAgY29uc3Qga2x0X2tsID0gbWF0TXVsKHRyYW5zcG9zZShrbCksIGtsKTsKICAgIHJldHVybiBtYXRTdWIoY292SW5wdXRzSW5wdXRzLCBrbHRfa2wpOwogIH0KCiAgLyoqCiAgICogUHJvZHVjZXMgYSBtdWx0aXZhcmlhdGUgR2F1c3NpYW4gdGhhdCBjYW4gYmUgc2FtcGxlZCBhdCB0aGUgaW5wdXQgcG9pbnRzCiAgICogKGBtb2QucnM6MzcxYCkuCiAgICoKICAgKiBDb3ZhcmlhbmNlOgogICAqICAgY292KGlucHV0LGlucHV0KSDiiJIgY292KGlucHV0LHRyYWluKcK3S+KBu8K5wrdjb3YodHJhaW4saW5wdXQpCiAgICogTWVhbjoKICAgKiAgIHByaW9yICsgY292KGlucHV0LHRyYWluKcK3S+KBu8K5wrdvdXRwdXQKICAgKgogICAqIFRoZSByZXR1cm5lZCB7QGxpbmsgTXVsdGl2YXJpYXRlTm9ybWFsfSBoYXMgYSBgLnNhbXBsZShybmcpYCBtZXRob2Qgd2hlcmUKICAgKiBgcm5nYCBpcyBhIGAoKSA9PiBudW1iZXIg4oiIIFswLDEpYCAoZS5nLiBmcm9tIGBtdWxiZXJyeTMyYCkuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEByZXR1cm5zIHtNdWx0aXZhcmlhdGVOb3JtYWx9CiAgICovCiAgc2FtcGxlX2F0KGlucHV0cykgewogICAgY29uc3Qgc2luZ2xlID0gaXNTaW5nbGUoaW5wdXRzKTsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KGlucHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4WzBdLmxlbmd0aCAhPT0gdGhpcy50cmFpbmluZ0lucHV0cy5uY29scykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5uY29scygpICgke2lucHV0c01hdHJpeFswXS5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfaW5wdXRzLm5jb2xzKCkgKCR7dGhpcy50cmFpbmluZ0lucHV0cy5uY29sc30pYCk7CiAgICB9CiAgICBjb25zdCB0cmFpbk1hdHJpeCA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKCiAgICAvLyB3ZWlnaHRzID0gS+KBu8K5IMK3IGNvdih0cmFpbiwgaW5wdXRzKS4KICAgIGNvbnN0IGNvdlRyYWluSW5wdXRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgodHJhaW5NYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwogICAgY29uc3Qgd2VpZ2h0cyA9IHRoaXMuY292bWF0Q2hvbGVza3kuc29sdmUoY292VHJhaW5JbnB1dHMpOwoKICAgIC8vIGNvdiA9IGNvdihpbnB1dCxpbnB1dCkg4oiSIGNvdl90cmFpbl9pbnB1dHPhtYDCt3dlaWdodHMgIChnZW1tX3RyKC0xLCBjb3ZUcmFpbklucHV0cywgd2VpZ2h0cywgMSkpLgogICAgY29uc3QgY292SW5wdXRzSW5wdXRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgoaW5wdXRzTWF0cml4LCBpbnB1dHNNYXRyaXgsIHRoaXMua2VybmVsKTsKICAgIGNvbnN0IGN0X3cgPSBtYXRNdWwodHJhbnNwb3NlKGNvdlRyYWluSW5wdXRzKSwgd2VpZ2h0cyk7CiAgICBjb25zdCBjb3YgPSBtYXRTdWIoY292SW5wdXRzSW5wdXRzLCBjdF93KTsKCiAgICAvLyBtZWFuID0gcHJpb3IgKyB3ZWlnaHRz4bWAwrd0cmFpbmluZ091dHB1dHMuCiAgICBjb25zdCBtZWFuID0gdGhpcy5fbWVhbkZyb21XZWlnaHRzKHdlaWdodHMsIGlucHV0c01hdHJpeCk7CiAgICByZXR1cm4gbmV3IE11bHRpdmFyaWF0ZU5vcm1hbChtZWFuLCBjb3YsIHNpbmdsZSk7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gRklUCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBGaXRzIHRoZSByZXF1ZXN0ZWQgcGFyYW1ldGVycyBhbmQgcmV0cmFpbnMgdGhlIG1vZGVsIChgbW9kLnJzOjQwNmApLgogICAqCiAgICogTm9pc2UgYW5kIGtlcm5lbCBwYXJhbWV0ZXJzIGFyZSBmaXR0ZWQgYnkgZ3JhZGllbnQgYXNjZW50IChBREFNKSBvbiB0aGUKICAgKiBtYXJnaW5hbCBsb2ctbGlrZWxpaG9vZC4gUnVucyBmb3IgYXQgbW9zdCBgbWF4SXRlcmAgaXRlcmF0aW9ucywgc3RvcHBpbmcKICAgKiBlYXJseSB3aGVuIGFsbCBncmFkaWVudHMgYXJlIGJlbG93IGBjb252ZXJnZW5jZUZyYWN0aW9uYMK3cGFyYW0gb3IgYWZ0ZXIKICAgKiBgbWF4VGltZWAuCiAgICoKICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZpdFByaW9yICAgICAgICAgICAgICBmaXQgdGhlIHByaW9yIHRvIHRoZSBkYXRhLgogICAqIEBwYXJhbSB7Ym9vbGVhbn0gZml0S2VybmVsICAgICAgICAgICAgIGZpdCB0aGUga2VybmVsIChhbmQgbm9pc2UpIHBhcmFtZXRlcnMuCiAgICogQHBhcmFtIHtudW1iZXJ9ICBtYXhJdGVyICAgICAgICAgICAgICAgbWF4IGdyYWRpZW50LWFzY2VudCBpdGVyYXRpb25zLgogICAqIEBwYXJhbSB7bnVtYmVyfSAgY29udmVyZ2VuY2VGcmFjdGlvbiAgIHJlbGF0aXZlIGNvbnZlcmdlbmNlIHRocmVzaG9sZC4KICAgKiBAcGFyYW0ge251bWJlcn0gW21heFRpbWU9MzYwMDAwMF0gICAgICBtYXggZml0dGluZyB0aW1lIGluIE1JTExJU0VDT05EUwogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChSdXN0IHVzZXMgY2hyb25vOjpEdXJhdGlvbiBzZWNvbmRzKS4KICAgKi8KICBmaXRfcGFyYW1ldGVycyhmaXRQcmlvciwgZml0S2VybmVsLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lID0gREVGQVVMVF9NQVhfVElNRV9NUykgewogICAgaWYgKGZpdFByaW9yKSB7CiAgICAgIGNvbnN0IGlucHV0cyA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKCiAgICAgIC8vIFJlY292ZXIgdGhlIG9yaWdpbmFsIChyYXcpIG91dHB1dHM6IHJlc2lkdWFsICsgcHJpb3Jfb2xkKGlucHV0cykuCiAgICAgIGNvbnN0IHJlc2lkdWFsT2xkID0gdGhpcy50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsKICAgICAgY29uc3QgcHJpb3JPbGQgPSB0aGlzLnByaW9yLnByaW9yKGlucHV0cyk7CiAgICAgIGNvbnN0IG9yaWdpbmFsT3V0cHV0cyA9IG5ldyBBcnJheShyZXNpZHVhbE9sZC5sZW5ndGgpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc2lkdWFsT2xkLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgb3JpZ2luYWxPdXRwdXRzW2ldID0gcmVzaWR1YWxPbGRbaV0gKyBwcmlvck9sZFtpXTsKICAgICAgfQoKICAgICAgLy8gUmVmaXQgdGhlIHByaW9yIG9uIHRoZSByYXcgb3V0cHV0cy4KICAgICAgdGhpcy5wcmlvci5maXQoaW5wdXRzLCBvcmlnaW5hbE91dHB1dHMpOwoKICAgICAgLy8gUmUtcmVzaWR1YWxpc2UgYWdhaW5zdCB0aGUgbmV3IHByaW9yIGFuZCBzdG9yZSBiYWNrLgogICAgICBjb25zdCBwcmlvck5ldyA9IHRoaXMucHJpb3IucHJpb3IoaW5wdXRzKTsKICAgICAgY29uc3QgcmVzaWR1YWxOZXcgPSBuZXcgQXJyYXkob3JpZ2luYWxPdXRwdXRzLmxlbmd0aCk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JpZ2luYWxPdXRwdXRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgcmVzaWR1YWxOZXdbaV0gPSBvcmlnaW5hbE91dHB1dHNbaV0gLSBwcmlvck5ld1tpXTsKICAgICAgfQogICAgICB0aGlzLnRyYWluaW5nT3V0cHV0cy5hc3NpZ24ocmVzaWR1YWxOZXcpOwoKICAgICAgLy8gSWYgdGhlIGtlcm5lbCBpcyBOT1QgYmVpbmcgZml0dGVkLCByZXRyYWluIHRoZSBjb3ZhcmlhbmNlIENob2xlc2t5CiAgICAgIC8vIGZyb20gc2NyYXRjaCAodGhlIHJlc2lkdWFscyBjaGFuZ2VkKS4gV2hlbiBmaXRLZXJuZWwgaXMgdHJ1ZSB0aGUKICAgICAgLy8gb3B0aW1pemVyIHJlYnVpbGRzIGl0IGFueXdheS4KICAgICAgaWYgKCFmaXRLZXJuZWwpIHsKICAgICAgICB0aGlzLmNvdm1hdENob2xlc2t5ID0gbWFrZUNob2xlc2t5Q292TWF0cml4KGlucHV0cywgdGhpcy5rZXJuZWwsIHRoaXMubm9pc2UsIHRoaXMuY2hvbGVza3lFcHNpbG9uKTsKICAgICAgfQogICAgfQogICAgaWYgKGZpdEtlcm5lbCkgewogICAgICBpZiAodGhpcy5rZXJuZWwuaXNTY2FsYWJsZSgpKSB7CiAgICAgICAgc2NhbGVkT3B0aW1pemVQYXJhbWV0ZXJzKHRoaXMsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpOwogICAgICB9IGVsc2UgewogICAgICAgIG9wdGltaXplUGFyYW1ldGVycyh0aGlzLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKTsKICAgICAgfQogICAgfQogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIElOVEVSTkFMIEhFTFBFUlMKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIENvbXB1dGVzIHRoZSBwb3N0ZXJpb3IgbWVhbiBgcHJpb3IgKyB3ZWlnaHRz4bWAwrd0cmFpbmluZ091dHB1dHNgLCBpLmUuCiAgICogYG1lYW5baV0gPSBwcmlvcihpbnB1dHMpW2ldICsgzqNfdCB3ZWlnaHRzW3RdW2ldwrd0cmFpbmluZ091dHB1dHNbdF1gLgogICAqCiAgICogVGhpcyByZXByb2R1Y2VzIG5hbGdlYnJhIGBwcmlvci5nZW1tX3RyKDEsIHdlaWdodHMsIHRyYWluaW5nT3V0cHV0cywgMSlgLAogICAqIHdoZXJlIGB3ZWlnaHRzYCBpcyAoblRyYWluIMOXIG5JbnB1dCksIGB0cmFpbmluZ091dHB1dHNgIGlzIHRoZSByZXNpZHVhbAogICAqIHZlY3RvciAobGVuZ3RoIG5UcmFpbiksIGFuZCB0aGUgcmVzdWx0IGhhcyBsZW5ndGggbklucHV0LgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSB3ZWlnaHRzICAgICAgKG5UcmFpbiDDlyBuSW5wdXQpCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBpbnB1dHNNYXRyaXggKG5JbnB1dCDDlyBkKQogICAqIEByZXR1cm5zIHtudW1iZXJbXX0gcG9zdGVyaW9yIG1lYW4gKGxlbmd0aCBuSW5wdXQpLCBwcmlvciBhbHJlYWR5IGFkZGVkLgogICAqIEBwcml2YXRlCiAgICovCiAgX21lYW5Gcm9tV2VpZ2h0cyh3ZWlnaHRzLCBpbnB1dHNNYXRyaXgpIHsKICAgIGNvbnN0IG5JbnB1dCA9IGlucHV0c01hdHJpeC5sZW5ndGg7CiAgICBjb25zdCBuVHJhaW4gPSB3ZWlnaHRzLmxlbmd0aDsKICAgIGNvbnN0IG91dHB1dHMgPSB0aGlzLnRyYWluaW5nT3V0cHV0cy5hc1ZlY3RvcigpOyAvLyByZXNpZHVhbAogICAgY29uc3QgcHJpb3JWZWMgPSB0aGlzLnByaW9yLnByaW9yKGlucHV0c01hdHJpeCk7CiAgICBjb25zdCBtZWFuID0gbmV3IEFycmF5KG5JbnB1dCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5JbnB1dDsgaSsrKSB7CiAgICAgIGxldCBzID0gcHJpb3JWZWNbaV07CiAgICAgIGZvciAobGV0IHQgPSAwOyB0IDwgblRyYWluOyB0KyspIHsKICAgICAgICBzICs9IHdlaWdodHNbdF1baV0gKiBvdXRwdXRzW3RdOwogICAgICB9CiAgICAgIG1lYW5baV0gPSBzOwogICAgfQogICAgcmV0dXJuIG1lYW47CiAgfQp9CgovLyBNaXhpbiB0aGUgb3B0aW1pemVyIGZyZWUtZnVuY3Rpb25zIG9udG8gdGhlIHByb3RvdHlwZSBzbyB0aGV5IGFyZSBhbHNvCi8vIHJlYWNoYWJsZSBhcyBtZXRob2RzIChlLmcuIGBncC5vcHRpbWl6ZVBhcmFtZXRlcnMoLi4uKWApLiBgZml0X3BhcmFtZXRlcnNgCi8vIGFib3ZlIGNhbGxzIHRoZSBpbXBvcnRlZCBmcmVlIGZ1bmN0aW9ucyBkaXJlY3RseTsgdGhlc2UgYWxpYXNlcyBqdXN0IGtlZXAgdGhlCi8vIHN1cmZhY2UgY29uc2lzdGVudCB3aXRoIFBPUlRfU1BFQyDCpzcgKCJpbXBvcnQgdGhlbiBjYWxsIGFzIG1ldGhvZHMiKS4KR2F1c3NpYW5Qcm9jZXNzLnByb3RvdHlwZS5vcHRpbWl6ZVBhcmFtZXRlcnMgPSBmdW5jdGlvbiAobWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSkgewogIHJldHVybiBvcHRpbWl6ZVBhcmFtZXRlcnModGhpcywgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSk7Cn07CkdhdXNzaWFuUHJvY2Vzcy5wcm90b3R5cGUuc2NhbGVkT3B0aW1pemVQYXJhbWV0ZXJzID0gZnVuY3Rpb24gKG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpIHsKICByZXR1cm4gc2NhbGVkT3B0aW1pemVQYXJhbWV0ZXJzKHRoaXMsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpOwp9OwpHYXVzc2lhblByb2Nlc3MucHJvdG90eXBlLmdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kID0gZnVuY3Rpb24gKCkgewogIHJldHVybiBncmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZCh0aGlzKTsKfTsKR2F1c3NpYW5Qcm9jZXNzLnByb3RvdHlwZS5zY2FsZWRHcmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZCA9IGZ1bmN0aW9uICgpIHsKICByZXR1cm4gc2NhbGVkR3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QodGhpcyk7Cn07CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEdhdXNzaWFuUHJvY2Vzc0J1aWxkZXIKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIEJ1aWxkZXIgdG8gc2V0IHRoZSBwYXJhbWV0ZXJzIG9mIGEgR2F1c3NpYW4gcHJvY2VzcyAoYGJ1aWxkZXIucnNgKS4KICoKICogQ2hhaW5hYmxlIHNldHRlcnMgY3VsbWluYXRpbmcgaW4gYHRyYWluKClgLiBQcm9kdWNlZCBieQogKiBgR2F1c3NpYW5Qcm9jZXNzLmJ1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKWAuCiAqCiAqIERlZmF1bHRzIChgYnVpbGRlci5yczo2NmApOgogKiAgIC0gY29uc3RhbnQgcHJpb3IgKDAgdW5sZXNzIGZpdHRlZCkKICogICAtIGEgR2F1c3NpYW4ga2VybmVsCiAqICAgLSBub2lzZSA9IDEwJSBvZiB0aGUgb3V0cHV0IHN0YW5kYXJkIGRldmlhdGlvbgogKiAgIC0gZG9lcyBub3QgZml0IGFueSBwYXJhbWV0ZXJzCiAqICAgLSBmaXQgcnVucyBmb3Ig4omkIDEwMCBpdGVyYXRpb25zIC8gMSBob3VyIHVubGVzcyBhbGwgZ3JhZGllbnRzIGFyZSBiZWxvdyA1JS4KICoKICogU2V0dGVycyBtdXRhdGUgYW5kIHJldHVybiBgdGhpc2AgKFJ1c3QgcmV0dXJucyBhIG5ldyB0eXBlZCBidWlsZGVyOyBmb3IgSlMgd2UKICoga2VlcCBhIHNpbmdsZSBtdXRhYmxlIGJ1aWxkZXIg4oCUIGJlaGF2aW91ciBpcyBpZGVudGljYWwgZm9yIHRoZSBmbHVlbnQgQVBJKS4KICovCmNsYXNzIEdhdXNzaWFuUHJvY2Vzc0J1aWxkZXIgewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gdHJhaW5pbmdJbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIHRyYWluaW5nT3V0cHV0cwogICAqLwogIGNvbnN0cnVjdG9yKHRyYWluaW5nSW5wdXRzLCB0cmFpbmluZ091dHB1dHMpIHsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KHRyYWluaW5nSW5wdXRzKTsKICAgIGNvbnN0IG91dHB1dHNWZWN0b3IgPSB0b1ZlY3Rvcih0cmFpbmluZ091dHB1dHMpOwoKICAgIC8qKiBAdHlwZSB7bnVtYmVyW11bXX0gKi8KICAgIHRoaXMudHJhaW5pbmdJbnB1dHMgPSBpbnB1dHNNYXRyaXg7CiAgICAvKiogQHR5cGUge251bWJlcltdfSAqLwogICAgdGhpcy50cmFpbmluZ091dHB1dHMgPSBvdXRwdXRzVmVjdG9yOwoKICAgIC8vIERlZmF1bHQgcHJpb3I6IENvbnN0YW50UHJpb3IoMCkgKGRpbSBpcyBpZ25vcmVkIGJ5IENvbnN0YW50UHJpb3IpLgogICAgLyoqIEB0eXBlIHtvYmplY3R9ICovCiAgICB0aGlzLnByaW9yID0gQ29uc3RhbnRQcmlvci5kZWZhdWx0KGlucHV0c01hdHJpeC5sZW5ndGggPT09IDAgPyAwIDogaW5wdXRzTWF0cml4WzBdLmxlbmd0aCk7CiAgICAvLyBEZWZhdWx0IGtlcm5lbDogR2F1c3NpYW4gLyBTcXVhcmVkRXhwIHdpdGggZGVmYXVsdCBwYXJhbWV0ZXJzLgogICAgLyoqIEB0eXBlIHtvYmplY3R9ICovCiAgICB0aGlzLmtlcm5lbCA9IG5ldyBHYXVzc2lhbigpOwogICAgLy8gRGVmYXVsdCBub2lzZTogMTAlIG9mIHRoZSBvdXRwdXQgc3RhbmRhcmQgZGV2aWF0aW9uLgogICAgLy8gICByb3dfdmFyaWFuY2Uob3V0cHV0cylbMF0gPSDOoyh54bWi4oiSyLMpwrIvTiAgKGRpdmlkZSBieSBOIOKAlCBzZWUgZml0QW1wbGl0dWRlVmFyKS4KICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqLwogICAgdGhpcy5ub2lzZSA9IDAuMSAqIE1hdGguc3FydChmaXRBbXBsaXR1ZGVWYXIob3V0cHV0c1ZlY3RvcikpOwogICAgLyoqIEB0eXBlIHtudW1iZXJ8bnVsbH0gKi8KICAgIHRoaXMuY2hvbGVza3lFcHNpbG9uID0gbnVsbDsKCiAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovCiAgICB0aGlzLnNob3VsZEZpdEtlcm5lbCA9IGZhbHNlOwogICAgLyoqIEB0eXBlIHtib29sZWFufSAqLwogICAgdGhpcy5zaG91bGRGaXRQcmlvciA9IGZhbHNlOwoKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqLwogICAgdGhpcy5tYXhJdGVyID0gMTAwOwogICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovCiAgICB0aGlzLmNvbnZlcmdlbmNlRnJhY3Rpb24gPSAwLjA1OwogICAgLyoqIEB0eXBlIHtudW1iZXJ9IG1heCBmaXR0aW5nIHRpbWUgaW4gbWlsbGlzZWNvbmRzICovCiAgICB0aGlzLm1heFRpbWUgPSBERUZBVUxUX01BWF9USU1FX01TOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFNFVFRFUlMgKGNoYWluYWJsZSkKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFNldHMgYSBuZXcgcHJpb3IuCiAgICogQHBhcmFtIHtvYmplY3R9IHByaW9yCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgc2V0UHJpb3IocHJpb3IpIHsKICAgIHRoaXMucHJpb3IgPSBwcmlvcjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogU2V0cyB0aGUgbm9pc2UgcGFyYW1ldGVyIChzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIG91dHB1dCBub2lzZSkuCiAgICogQHBhcmFtIHtudW1iZXJ9IG5vaXNlICjiiaUgMCkKICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBzZXROb2lzZShub2lzZSkgewogICAgaWYgKCEobm9pc2UgPj0gMCkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgbm9pc2UgcGFyYW1ldGVyIHNob3VsZCBiZSBub24tbmVnYXRpdmUgYnV0IHdlIHRyaWVkIHRvIHNldCBpdCB0byAke25vaXNlfWApOwogICAgfQogICAgdGhpcy5ub2lzZSA9IG5vaXNlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBDaGFuZ2VzIHRoZSBrZXJuZWwgb2YgdGhlIEdhdXNzaWFuIHByb2Nlc3MuCiAgICogQHBhcmFtIHtvYmplY3R9IGtlcm5lbAogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIHNldEtlcm5lbChrZXJuZWwpIHsKICAgIHRoaXMua2VybmVsID0ga2VybmVsOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBTZXRzIHRoZSBDaG9sZXNreSBlcHNpbG9uLiBXaGVuIGEgc3RyaWN0bHkgcG9zaXRpdmUgdmFsdWUgaXMgZ2l2ZW4sIHRoZQogICAqIENob2xlc2t5IGRlY29tcG9zaXRpb24gaXMgZ3VhcmFudGVlZCB0byBzdWNjZWVkICh0aGUgdmFsdWUgaXMgdXNlZCBpbgogICAqIHBsYWNlIG9mIGEgbm9uLXBvc2l0aXZlIGRpYWdvbmFsIHBpdm90KS4gYG51bGxgIGlnbm9yZXMgaXQuCiAgICogQHBhcmFtIHtudW1iZXJ8bnVsbH0gY2hvbGVza3lFcHNpbG9uCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgc2V0Q2hvbGVza3lFcHNpbG9uKGNob2xlc2t5RXBzaWxvbikgewogICAgdGhpcy5jaG9sZXNreUVwc2lsb24gPSBjaG9sZXNreUVwc2lsb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE1vZGlmaWVzIHRoZSBzdG9wcGluZyBjcml0ZXJpYSBvZiB0aGUgZ3JhZGllbnQgZGVzY2VudCB1c2VkIHRvIGZpdCB0aGUKICAgKiBub2lzZSBhbmQga2VybmVsIHBhcmFtZXRlcnMuCiAgICogQHBhcmFtIHtudW1iZXJ9IG1heEl0ZXIKICAgKiBAcGFyYW0ge251bWJlcn0gY29udmVyZ2VuY2VGcmFjdGlvbgogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIHNldEZpdFBhcmFtZXRlcnMobWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbikgewogICAgdGhpcy5tYXhJdGVyID0gbWF4SXRlcjsKICAgIHRoaXMuY29udmVyZ2VuY2VGcmFjdGlvbiA9IGNvbnZlcmdlbmNlRnJhY3Rpb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEFza3MgZm9yIHRoZSBrZXJuZWwgcGFyYW1ldGVycyB0byBiZSBmaXR0ZWQgb24gdGhlIHRyYWluaW5nIGRhdGEgKGFwcGxpZWQKICAgKiB3aGVuIGB0cmFpbigpYCBpcyBjYWxsZWQpLgogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIGZpdEtlcm5lbCgpIHsKICAgIHRoaXMuc2hvdWxkRml0S2VybmVsID0gdHJ1ZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQXNrcyBmb3IgdGhlIHByaW9yIHRvIGJlIGZpdHRlZCBvbiB0aGUgdHJhaW5pbmcgZGF0YSAoYXBwbGllZCB3aGVuCiAgICogYHRyYWluKClgIGlzIGNhbGxlZCkuCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgZml0UHJpb3IoKSB7CiAgICB0aGlzLnNob3VsZEZpdFByaW9yID0gdHJ1ZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFRSQUlOCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBUcmFpbnMgdGhlIEdhdXNzaWFuIHByb2Nlc3MsIGZpdHRpbmcgdGhlIHBhcmFtZXRlcnMgaWYgcmVxdWVzdGVkCiAgICogKGBidWlsZGVyLnJzOjE4OWApLgogICAqCiAgICogU3RlcHM6CiAgICogICAxLiBpZiBgc2hvdWxkRml0S2VybmVsYCDihpIgYGtlcm5lbC5oZXVyaXN0aWNGaXQoaW5wdXRzLCBvdXRwdXRzKWAgdXNpbmcgdGhlCiAgICogICAgICBSQVcgb3V0cHV0cyAodGhlIGJ1aWxkZXIgaGFzIG5vdCBzdWJ0cmFjdGVkIHRoZSBwcmlvciB5ZXQpLgogICAqICAgMi4gY29uc3RydWN0IHRoZSBHYXVzc2lhblByb2Nlc3MuCiAgICogICAzLiBgZ3AuZml0X3BhcmFtZXRlcnMoc2hvdWxkRml0UHJpb3IsIHNob3VsZEZpdEtlcm5lbCwg4oCmKWAuCiAgICoKICAgKiBAcmV0dXJucyB7R2F1c3NpYW5Qcm9jZXNzfQogICAqLwogIHRyYWluKCkgewogICAgLy8gMS4gS2VybmVsIGhldXJpc3RpYyBmaXQgKHVzZXMgcmF3IG91dHB1dHMpLgogICAgaWYgKHRoaXMuc2hvdWxkRml0S2VybmVsKSB7CiAgICAgIHRoaXMua2VybmVsLmhldXJpc3RpY0ZpdCh0aGlzLnRyYWluaW5nSW5wdXRzLCB0aGlzLnRyYWluaW5nT3V0cHV0cyk7CiAgICB9CgogICAgLy8gMi4gQnVpbGQgdGhlIEdQICh0aGlzIHJlc2lkdWFsaXNlcyB0aGUgb3V0cHV0cyBhbmQgYnVpbGRzIHRoZSBDaG9sZXNreSkuCiAgICBjb25zdCBncCA9IG5ldyBHYXVzc2lhblByb2Nlc3ModGhpcy5wcmlvciwgdGhpcy5rZXJuZWwsIHRoaXMubm9pc2UsIHRoaXMuY2hvbGVza3lFcHNpbG9uLCB0aGlzLnRyYWluaW5nSW5wdXRzLCB0aGlzLnRyYWluaW5nT3V0cHV0cyk7CgogICAgLy8gMy4gRml0IG9uIHRoZSB0cmFpbmluZyBkYXRhLCBpZiByZXF1ZXN0ZWQuCiAgICBncC5maXRfcGFyYW1ldGVycyh0aGlzLnNob3VsZEZpdFByaW9yLCB0aGlzLnNob3VsZEZpdEtlcm5lbCwgdGhpcy5tYXhJdGVyLCB0aGlzLmNvbnZlcmdlbmNlRnJhY3Rpb24sIHRoaXMubWF4VGltZSk7CiAgICByZXR1cm4gZ3A7CiAgfQp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIExPQ0FMIENPTFVNTiBIRUxQRVJTCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBTcXVhcmVkIEV1Y2xpZGVhbiBub3JtIG9mIGNvbHVtbiBgY2Agb2YgbWF0cml4IGBNYCAobnVtYmVyW11bXSkuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTQogKiBAcGFyYW0ge251bWJlcn0gYwogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gY29sdW1uTm9ybVNxdWFyZWQoTSwgYykgewogIGxldCBzID0gMDsKICBmb3IgKGxldCByID0gMDsgciA8IE0ubGVuZ3RoOyByKyspIHsKICAgIGNvbnN0IHYgPSBNW3JdW2NdOwogICAgcyArPSB2ICogdjsKICB9CiAgcmV0dXJuIHM7Cn0KCi8qKgogKiBEb3QgcHJvZHVjdCBvZiBjb2x1bW4gYGNgIG9mIEEgd2l0aCBjb2x1bW4gYGNgIG9mIEIgKGJvdGggbnVtYmVyW11bXSkuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcGFyYW0ge251bWJlcltdW119IEIKICogQHBhcmFtIHtudW1iZXJ9IGMKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIGNvbHVtbkRvdChBLCBCLCBjKSB7CiAgbGV0IHMgPSAwOwogIGZvciAobGV0IHIgPSAwOyByIDwgQS5sZW5ndGg7IHIrKykgewogICAgcyArPSBBW3JdW2NdICogQltyXVtjXTsKICB9CiAgcmV0dXJuIHM7Cn0KCi8qKg0KICog5YWL5Yip6YeR5rOVKEtyaWdpbmcp5YWn5aSW5o+S6bue5pW45YC8DQogKg0KICog5YWL5Yip6YeR5rOV6KiI566X6IiH5a+m6Zqb6YGL566X55O26aC45ZWP6aGM5Y+v6Kmz6KaLOiBodHRwczovL2dpdGh1Yi5jb20vbHZpc2VpL3dlYi1kZXZlbG9wZXItcmVzb3VyY2VzL2Jsb2IvbWFzdGVyL3dlYmFzc2VtYmx5L2tyaWdpbmcubWQNCiAqDQogKiDoi6XmmK9Ob2RlLmpz56uv5L2/55So6aCI5pu06auY6KiI566X6YCf5bqm77yM5Y+v5L2/55Sody1rcmlnaW5nOiBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1rcmlnaW5nDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvaW50ZXJwMktyaWdpbmcudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwc1NyYyDovLjlhaXkuozntq3luqfmqJnliqDop4DmuKzmlbjmk5rpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MSx6OnoxfSx7eDp4Mix5OnkyLHo6ejJ9LC4uLl3pu57nianku7bkuYvpmaPliJcNCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBwc1RhciDovLjlhaXkuozntq3luqfmqJnpu57pmaPliJfmiJbpu57nianku7bvvIzngrpbe3g6eDEseTp5MX0se3g6eDIseTp5Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIl++8jOaIlnt4OngxLHk6eTF96bue54mp5Lu2DQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7bkuYt45qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu25LmLeeashOS9jeWtl+S4su+8jOeCuuW6p+aome+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5Wj0neiddIOi8uOWFpem7nueJqeS7tuS5i3rmrITkvY3lrZfkuLLvvIzngrrop4DmuKzlgLzvvIzpoJDoqK0neicNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LnNjYWxlPTFdIOi8uOWFpeato+imj+WMluevhOWcjeaVuOWAvO+8jOWboOiZleeQhuWkmumCiuW9ouaZguacieaVuOWAvOWuueioseiqpOW3ru+8jOaVhemgiOmAmumBjue4ruaUvuWAvOWfn+S+hua4m+WwkeWVj+mhjO+8jOmgkOiorTHmmK/mraPopo/ljJYw6IezMeS5i+mWk++8jOS9v+eUqHNjYWxlWFnliYfmmK/mraPopo/ljJbngrow6Iezc2NhbGVYWeS5i+mWk++8jOmgkOiorTENCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0Lm1ldGhvZD0nZnJpZWRyaWNoJ10g6Ly45YWl5b6M56uv5byV5pOO5a2X5Liy77yM5Y+v6YG4J2ZyaWVkcmljaCcoR2F1c3NpYW4gUHJvY2VzcyBSZWdyZXNzaW9u77yM5qC45Ye95pW477yMa3JpZ2luZy1mcmllZHJpY2gp44CBJ2ludmFsbCco57aT5YW4T3JkaW5hcnkgS3JpZ2luZ++8jOWNiuiuiueVsOWcluaTrOWQiO+8jGtyaWdpbmctaW52YWxsL2tyaWdpbmcubWpzKe+8jOmgkOiorSdmcmllZHJpY2gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5tb2RlbD0nZXhwb25lbnRpYWwnXSDovLjlhaXmk6zlkIjmqKHlvI/lrZfkuLLvvIxtZXRob2Q9J2ludmFsbCfmmYLlj6/pgbgnZXhwb25lbnRpYWwn44CBJ2dhdXNzaWFuJ+OAgSdzcGhlcmljYWwn77ybbWV0aG9kPSdmcmllZHJpY2gn5pmCJ2dhdXNzaWFuJ+WwjeaHiVNxdWFyZWRFeHDjgIHlhbbppJgo5ZCrc3BoZXJpY2FsKeWwjeaHiUV4cG9uZW50aWFs77yM6aCQ6KitJ2V4cG9uZW50aWFsJw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2lnbWEyPTBdIOi8uOWFpeiHquWLleaTrOWQiOWPg+aVuHNpZ21hMuaVuOWAvO+8jOWDhW1ldGhvZD0naW52YWxsJ+aZguacieaViO+8jOmgkOiorTANCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LmFscGhhPTEwMF0g6Ly45YWl6Ieq5YuV5pOs5ZCI5Y+D5pW4YWxwaGHmlbjlgLzvvIzlg4VtZXRob2Q9J2ludmFsbCfmmYLmnInmlYjvvIzpoJDoqK0xMDANCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LmxzPTAuNV0g6Ly45YWlZnJpZWRyaWNo5qC45Ye95pW4bGVuZ3Roc2NhbGXmlbjlgLwo5bCN5oeJ5q2j6KaP5YyW5b6M5YC85Z+fKe+8jOWDhW1ldGhvZD0nZnJpZWRyaWNoJ+aZguacieaViO+8jOmgkOiorTAuNQ0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQubm9pc2U9MC4wMV0g6Ly45YWlZnJpZWRyaWNo6KeA5ris5Zmq6Z+z5qiZ5rqW5beuKOWwjeaHieato+imj+WMluW+jOWAvOWfnynvvIzlg4VtZXRob2Q9J2ZyaWVkcmljaCfmmYLmnInmlYjvvIzpoJDoqK0wLjAxDQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQucmV0dXJuV2l0aFZhcmlvZ3JhbT1mYWxzZV0g6Ly45YWl5piv5ZCm5Zue5YKz5pOs5ZCI5Y2K6K6K55Ww5pW457WQ5p6c5biD5p6X5YC877yMbWV0aG9kPSdmcmllZHJpY2gn5pmCdmFyaW9ncmFt5Zue5YKzbnVsbO+8jOmgkOiorWZhbHNlDQogKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSDlm57lgrPpu57nianku7bpmaPliJfmiJbpu57nianku7bvvIzoi6Xkvb/nlKhyZXR1cm5XaXRoVmFyaW9ncmFtPXRydWXliYflm57lgrPnianku7bos4foqIrvvIzoi6XnmbznlJ/pjK/oqqTliYflm57lgrPpjK/oqqToqIrmga/nianku7YNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBzDQogKiBsZXQgcA0KICogbGV0IHINCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDUsIHo6IDk0Ljk0OTI1ODk4Nzg0NTI3IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyODMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjgzLCB5OiAyMDUsIHo6IDExNy4xNDg5NjMxMDY5NTE0NyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTE2MCwNCiAqICAgICB5OiAzODAsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAxMTYwLCB5OiAzODAsIHo6IDg0Ljk4MzE0NjcyMDA1MzM0IH0NCiAqDQogKiBwcyA9IFt7IGE6IDI0MywgYjogMjA2LCBjOiA5NSB9LCB7IGE6IDIzMywgYjogMjI1LCBjOiAxNDYgfSwgeyBhOiAyMSwgYjogMzI1LCBjOiAyMiB9LCB7IGE6IDk1MywgYjogMjgsIGM6IDIyMyB9LCB7IGE6IDEwOTIsIGI6IDI5MCwgYzogMzkgfSwgeyBhOiA3NDQsIGI6IDIwMCwgYzogMTkxIH0sIHsgYTogMTc0LCBiOiAzLCBjOiAyMiB9LCB7IGE6IDUzNywgYjogMzY4LCBjOiAyNDkgfSwgeyBhOiAxMTUxLCBiOiAzNzEsIGM6IDg2IH0sIHsgYTogODE0LCBiOiAyNTIsIGM6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICBhOiAyNDMsDQogKiAgICAgYjogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwLCB7IGtleVg6ICdhJywga2V5WTogJ2InLCBrZXlaOiAnYycgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IGE6IDI0MywgYjogMjA1LCBjOiA5NC45NDkyNTg5ODc4NDUyNyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSBbDQogKiAgICAgew0KICogICAgICAgICB4OiAyNDMsDQogKiAgICAgICAgIHk6IDIwNSwNCiAqICAgICB9LA0KICogICAgIHsNCiAqICAgICAgICAgeDogMjgzLA0KICogICAgICAgICB5OiAyMDUsDQogKiAgICAgfSwNCiAqIF0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDUsIHo6IDk0Ljk0OTI1ODk4Nzg0NTI3IH0sDQogKiAvLyAgIHsgeDogMjgzLCB5OiAyMDUsIHo6IDExNy4xNDg5NjMxMDY5NTE0NyB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCwgeyBzY2FsZTogMTAwMCwgbWV0aG9kOiAnaW52YWxsJyB9KSAvL3NjYWxlLXJvYnVzdOeCumludmFsbOWwiOWxrCwgZnJpZWRyaWNo5Zu65a6aa2VybmVs6Z2ec2NhbGUtcm9idXN0DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNSwgejogOTQuODg0Nzk5NDg0MTg4NzggfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHAsIHsgbW9kZWw6ICdnYXVzc2lhbicgfSkgLy9mcmllZHJpY2jpu5joqo0sIGdhdXNzaWFu5bCN5oeJU3F1YXJlZEV4cOaguA0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDUsIHo6IDExOC45MDU4MjUwMDc0Nzk4MyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCwgeyBzaWdtYTI6IDAuMDAxLCBhbHBoYTogNzAsIG1ldGhvZDogJ2ludmFsbCcgfSkgLy9zaWdtYTIvYWxwaGHngrppbnZhbGzljYrorornlbDlnJbmk6zlkIjlj4PmlbgsIGZyaWVkcmljaOS4jemBqeeUqA0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDUsIHo6IDkwLjg4NzAyOTQ5Mjc2MzQzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwLCB7IHJldHVybldpdGhWYXJpb2dyYW06IHRydWUsIG1ldGhvZDogJ2ludmFsbCcgfSkgLy92YXJpb2dyYW3ngrppbnZhbGzlsIjlsawsIGZyaWVkcmljaOWbnuWCs251bGwNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7DQogKiAvLyAgIHJlc3VsdDogeyB4OiAyNDMsIHk6IDIwNSwgejogOTQuODg0Nzk5NDg0MTg3MjEgfSwNCiAqIC8vICAgdmFyaW9ncmFtOiB7DQogKiAvLyAgICAgdDogWw0KICogLy8gICAgICAgMC4zMjE1ODU5MDMwODM3MDA0NCwNCiAqIC8vICAgICAgIDAuNTQ2MjU1NTA2NjA3OTI5NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjg4NTQ2MjU1NTA2NjA3OTMsDQogKiAvLyAgICAgICAwLjA3NDg4OTg2Nzg0MTQwOTY5LA0KICogLy8gICAgICAgMC43NDQ0OTMzOTIwNzA0ODQ2LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjI4MTkzODMyNTk5MTE4OTQ1LA0KICogLy8gICAgICAgMC40NTM3NDQ0OTMzOTIwNzA0Ng0KICogLy8gICAgIF0sDQogKiAvLyAgICAgeDogWw0KICogLy8gICAgICAgMC4xOTY0NjAxNzY5OTExNTA0NSwNCiAqIC8vICAgICAgIDAuMTg3NjEwNjE5NDY5MDI2NTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44MjQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgICAgMC45NDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjYzOTgyMzAwODg0OTU1NzYsDQogKiAvLyAgICAgICAwLjEzNTM5ODIzMDA4ODQ5NTU4LA0KICogLy8gICAgICAgMC40NTY2MzcxNjgxNDE1OTI5NCwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjcwMTc2OTkxMTUwNDQyNDgNCiAqIC8vICAgICBdLA0KICogLy8gICAgIHk6IFsNCiAqIC8vICAgICAgIDAuNTE2ODE0MTU5MjkyMDM1NCwNCiAqIC8vICAgICAgIDAuNTMzNjI4MzE4NTg0MDcwOCwNCiAqIC8vICAgICAgIDAuNjIyMTIzODkzODA1MzA5NywNCiAqIC8vICAgICAgIDAuMzU5MjkyMDM1Mzk4MjMwMDcsDQogKiAvLyAgICAgICAwLjU5MTE1MDQ0MjQ3Nzg3NjEsDQogKiAvLyAgICAgICAwLjUxMTUwNDQyNDc3ODc2MSwNCiAqIC8vICAgICAgIDAuMzM3MTY4MTQxNTkyOTIwMzYsDQogKiAvLyAgICAgICAwLjY2MDE3Njk5MTE1MDQ0MjUsDQogKiAvLyAgICAgICAwLjY2MjgzMTg1ODQwNzA3OTcsDQogKiAvLyAgICAgICAwLjU1NzUyMjEyMzg5MzgwNTMNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG51Z2dldDogMC4zMzUyODUzNDkyMzQyODE0NCwNCiAqIC8vICAgICByYW5nZTogMC45ODE4Mjc0MjA0MTIwNDg4LA0KICogLy8gICAgIHNpbGw6IDAuNDU4NDU4MDMzMzQ0MzA3NSwNCiAqIC8vICAgICBBOiAwLjMzMzMzMzMzMzMzMzMzMzMsDQogKiAvLyAgICAgbjogMTAsDQogKiAvLyAgICAgbW9kZWw6IFtGdW5jdGlvbjoga3JpZ2luZ192YXJpb2dyYW1fZXhwb25lbnRpYWxdLA0KICogLy8gICAgIHN2cGQ6IHsgZGF0YTogW0FycmF5XSwgYmFyczogW0FycmF5XSB9LA0KICogLy8gICAgIEs6IFsNCiAqIC8vICAgICAgICAgIC03NS44NTE3MDA0MTc1MjQ1LCAgICAgICA2Ny45MjU3MjI5MjM0ODQsIC0wLjE2MzM1ODQxMDM2OTY0Njc3LA0KICogLy8gICAgICAgIDAuMjQxMzE1MTg5NzgyNzA4NzcsICAtMC4wNDIzNDI0Njg2NTA0ODczMiwgICAwLjg3NzA1MTgzOTYzMjg5MTIsDQogKiAvLyAgICAgICAgICA1LjYxNjk2MDM2MjE3MDI3OSwgICAgIDEuNjIxNjU5NjM3NDQwMjI3LCAwLjAyNzg4ODAwMTY1MTg5NDYzNSwNCiAqIC8vICAgICAgIC0wLjIxNDE1ODUzNDE2NjUyODAzLCAgICAgNjcuOTI1NzIyOTIzNDg0MDIsICAgLTc1LjYxNzg2NDc4ODI0ODY4LA0KICogLy8gICAgICAgICAgNS40MTMyMzIwNzk3MjcwNjQsICAgMC4wNDkwNjk0MzQzODM4NTk1OCwgIDAuMDM2NzkxMTMyMjkzNDg0NjUsDQogKiAvLyAgICAgICAtMC4xMTg0NzEzOTM1MjY5ODY3NywgICAgMC4zMTQyMDEyNzY3Mjk3OTE3LCAgIDEuOTUzMTA3ODg1NDQzMDAyNCwNCiAqIC8vICAgICAgICAwLjE0MjE2Mzc3ODU0MDU1MzQzLCAtMC4wMjY1MDMxMDQ2NzI1MjUxNzQsICAgLTAuMTYzMzU4NDEwMzY5NjUxLA0KICogLy8gICAgICAgICAgNS40MTMyMzIwNzk3MjcwNjcsICAgLTEwLjM0MTA4ODc0MTYwMjQ3NSwgICAgMC43MDc2OTAyNTY0MTUyMDUsDQogKiAvLyAgICAgICAgIDAuMjcxNzI1OTQ3NzQ4MTM3NSwgICAgLTAuMDMyNzUxMzM4MzI3ODE4LCAgIDIuNDAyMTUxMDQ2NzczNDQwNiwNCiAqIC8vICAgICAgICAgMS4xMDM5NTI5MzAzMjA0OTU4LCAgICAwLjkzNDMyNDExOTk2MjY3MTEsICAwLjE3NTkzOTEwNjc3MTk5NTUzLA0KICogLy8gICAgICAgIDAuMjQxMzE1MTg5NzgyNjg4MjMsICAgMC4wNDkwNjk0MzQzODM4ODQ1MywgICAwLjcwNzY5MDI1NjQxNTIwMDYsDQogKiAvLyAgICAgICAgLTExLjE5NTg5NTgwOTMzMjgxOCwgICAgMy42MzE4MzI2NzY3MTY4MjY3LCAgIDMuMDkzNTM4NjUwODg4NzAzNSwNCiAqIC8vICAgICAgICAgMS4wNDUxNTUzNDk5NTY4MTM2LCAgIDAuMDc2ODExMTUxNTkwMjUxOTgsICAgMC41NTAwNTIwOTgxMjUzNDE2LA0KICogLy8gICAgICAgICAgMi4xNzY5MjgyMDc3MTAwNDgsICAtMC4wNDIzNDI0Njg2NTA0OTA1NSwgIDAuMDM2NzkxMTMyMjkzNDg1NzgsDQogKiAvLyAgICAgICAgMC4yNzE3MjU5NDc3NDgxMzgxMywgICAgMy42MzE4MzI2NzY3MTY4MTg4LCAgLTIxLjgzMzk5MTgzMzM5NzUyNiwNCiAqIC8vICAgICAgICAtMC4zNzAzNTQ0NTY3MDMxNzg0LCAgICAwLjE2MzE5NDA3OTcwODY4MTQsICAgMC4xNDc4NDg1Mjg1MzAyMTIxLA0KICogLy8gICAgICAgICAxNC41OTI2NjExNTM2NDYzNDksICAgICAzLjUyOTY0MDc1OTY2MDk0OSwgICAgMC44NzcwNTE4Mzk2MzI4ODQsDQogKiAvLyAgICAgICAtMC4xMTg0NzEzOTM1MjY5NzExMSwgLTAuMDMyNzUxMzM4MzI3ODE5Njg2LCAgIDMuMDkzNTM4NjUwODg4Njk4NiwNCiAqIC8vICAgICAgIC0wLjM3MDM1NDQ1NjcwMzE4MDczLCAgIC0yMy40MjgzODUwNTc4MDM2OTUsICAgMC44MzQ2OTA5MDc1OTg0OTUyLA0KICogLy8gICAgICAgICAgMy42ODM4MDA0MTU0ODU3NzgsICAtMC4wNzA5NDUyODY1OTk2ODE1MiwgICAxNS42MzA4MzQ3ODI3MzU3MjIsDQogKiAvLyAgICAgICAgICA1LjYxNjk2MDM2MjE3MDIzOCwgICAwLjMxNDIwMTI3NjcyOTgzMjU2LCAgIDIuNDAyMTUxMDQ2NzczNDM5NywNCiAqIC8vICAgICAgICAgIDEuMDQ1MTU1MzQ5OTU2ODE1LCAgIDAuMTYzMTk0MDc5NzA4Njg1MjcsICAgMC44MzQ2OTA5MDc1OTg0OTIzLA0KICogLy8gICAgICAgICAtMTEuMTU5Njc2NDM1NzQ3MjgsICAgMC40Nzk4MDUwNTcyNzYyMzkwNywgICAwLjc1MjUxMTk2Mzk4Njk0NzMsDQogKiAvLyAgICAgICAgLTAuMDM5OTAyMDIxNjI2MTM4NCwgICAgMS42MjE2NTk2Mzc0NDAyNzM5LCAgIDEuOTUzMTA3ODg1NDQyOTUzMywNCiAqIC8vICAgICAgICAgMS4xMDM5NTI5MzAzMjA0OTYyLCAgIDAuMDc2ODExMTUxNTkwMjQ5NjIsICAgMC4xNDc4NDg1Mjg1MzAyMDEzLA0KICogLy8gICAgICAgICAzLjY4MzgwMDQxNTQ4NTc5MzUsICAgICAgMC40Nzk4MDUwNTcyNzYyNCwgIC0xMS41OTQ1NTU5MzA3NTM4MzUsDQogKiAvLyAgICAgICAgIDAuOTIzNzI4NDIxNDE0MDIyNiwgICAgMS44OTQ3ODU5NzcyMjIzMzA4LCAwLjAyNzg4ODAwMTY1MTkxNzM3NywNCiAqIC8vICAgICAgICAwLjE0MjE2Mzc3ODU0MDUzNDcyLCAgICAwLjkzNDMyNDExOTk2MjY3MzIsICAgMC41NTAwNTIwOTgxMjUzNDc2LA0KICogLy8gICAgICAgICAxNC41OTI2NjExNTM2NDYzNDcsICAgLTAuMDcwOTQ1Mjg2NTk5NjczNSwgICAwLjc1MjUxMTk2Mzk4Njk0ODYsDQogKiAvLyAgICAgICAgIDAuOTIzNzI4NDIxNDE0MDExMSwgICAtMTguMjUxMjMwMjQ1NjUzMzE4LCAgICAwLjgzNzk1OTY5MzM5MTgwOSwNCiAqIC8vICAgICAgIC0wLjIxNDE1ODUzNDE2NjU0NjkzLCAtMC4wMjY1MDMxMDQ2NzI1MTc4NzQsICAgMC4xNzU5MzkxMDY3NzE5OTg5LA0KICogLy8gICAgICAgICAgMi4xNzY5MjgyMDc3MTAwNTMsICAgICAzLjUyOTY0MDc1OTY2MDk1MiwgICAxNS42MzA4MzQ3ODI3MzU3MDQsDQogKiAvLyAgICAgICAtMC4wMzk5MDIwMjE2MjYxMzc0NCwgICAgIDEuODk0Nzg1OTc3MjIyMzQzLCAgIDAuODM3OTU5NjkzMzkxODE0OCwNCiAqIC8vICAgICAgICAgLTIzLjg5MjA0MDE3MTQ1MjgxDQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBNOiBbDQogKiAvLyAgICAgICAxNS4xMDc3NzU1MjgxNzM4MDIsDQogKiAvLyAgICAgICAtMTcuNTIzNTUzMTY0MDI0MzcsDQogKiAvLyAgICAgICA0Ljk3NDI3OTc2NzY2ODgyOSwNCiAqIC8vICAgICAgIC02LjAxNDM3MDgzODYyODM1OSwNCiAqIC8vICAgICAgIDcuMTc1MDk1Mjk0Nzg5NDAyLA0KICogLy8gICAgICAgLTMuNzU3MjY1NzMzOTgwNzE4MywNCiAqIC8vICAgICAgIDQuMjEwOTIwNTIxMTU3Nzg4LA0KICogLy8gICAgICAgLTYuMDY0MzIzMTQzODYzMDEzLA0KICogLy8gICAgICAgLTIuMjI4MDcyNDQ1Mjk1MjQ4NywNCiAqIC8vICAgICAgIDUuMDM1Nzg1Mzg1NTQ5MTE3DQogKiAvLyAgICAgXQ0KICogLy8gICB9DQogKiAvLyB9DQogKg0KICovCmZ1bmN0aW9uIGludGVycDJLcmlnaW5nKHBzU3JjLCBwc1Rhciwgb3B0ID0ge30pIHsKICAvL2NoZWNrIHBzU3JjCiAgaWYgKCFpc2VhcnIocHNTcmMpKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1NyYyBpcyBub3QgYW4gZWZmZWN0aXZlIGFycmF5JwogICAgfTsKICB9CgogIC8vY2hlY2sgcHNUYXIKICBpZiAoIWlzZW9iaihwc1RhcikgJiYgIWlzZWFycihwc1RhcikpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzVGFyIGlzIG5vdCBhbiBlZmZlY3RpdmUgb2JqZWN0IG9yIGFycmF5JwogICAgfTsKICB9CgogIC8vaXNPbmUKICBsZXQgaXNPbmUgPSBpc2VvYmoocHNUYXIpOwogIGlmIChpc09uZSkgewogICAgcHNUYXIgPSBbcHNUYXJdOwogIH0KCiAgLy9rZXlYCiAgbGV0IGtleVggPSBnZXQob3B0LCAna2V5WCcpOwogIGlmICghaXNlc3RyKGtleVgpKSB7CiAgICBrZXlYID0gJ3gnOwogIH0KCiAgLy9rZXlZCiAgbGV0IGtleVkgPSBnZXQob3B0LCAna2V5WScpOwogIGlmICghaXNlc3RyKGtleVkpKSB7CiAgICBrZXlZID0gJ3knOwogIH0KCiAgLy9rZXlaCiAgbGV0IGtleVogPSBnZXQob3B0LCAna2V5WicpOwogIGlmICghaXNlc3RyKGtleVopKSB7CiAgICBrZXlaID0gJ3onOwogIH0KCiAgLy9zY2FsZQogIGxldCBzY2FsZSA9IGdldChvcHQsICdzY2FsZScpOwogIGlmICghaXNudW0oc2NhbGUpKSB7CiAgICBzY2FsZSA9IDE7CiAgfQogIHNjYWxlID0gY2RibChzY2FsZSk7CgogIC8vbWV0aG9kCiAgbGV0IG1ldGhvZCA9IGdldChvcHQsICdtZXRob2QnKTsKICBpZiAobWV0aG9kICE9PSAnZnJpZWRyaWNoJyAmJiBtZXRob2QgIT09ICdpbnZhbGwnKSB7CiAgICBtZXRob2QgPSAnZnJpZWRyaWNoJzsKICB9CgogIC8va3JpZ2luZ01vZGVsCiAgbGV0IGtyaWdpbmdNb2RlbCA9IGdldChvcHQsICdtb2RlbCcpOwogIGlmIChrcmlnaW5nTW9kZWwgIT09ICdleHBvbmVudGlhbCcgJiYga3JpZ2luZ01vZGVsICE9PSAnZ2F1c3NpYW4nICYmIGtyaWdpbmdNb2RlbCAhPT0gJ3NwaGVyaWNhbCcpIHsKICAgIGtyaWdpbmdNb2RlbCA9ICdleHBvbmVudGlhbCc7CiAgfQoKICAvL2tyaWdpbmdTaWdtYTIKICBsZXQga3JpZ2luZ1NpZ21hMiA9IGdldChvcHQsICdzaWdtYTInKTsKICBpZiAoIWlzbnVtKGtyaWdpbmdTaWdtYTIpKSB7CiAgICBrcmlnaW5nU2lnbWEyID0gMDsKICB9CiAga3JpZ2luZ1NpZ21hMiA9IGNkYmwoa3JpZ2luZ1NpZ21hMik7CgogIC8va3JpZ2luZ0FscGhhCiAgbGV0IGtyaWdpbmdBbHBoYSA9IGdldChvcHQsICdhbHBoYScpOwogIGlmICghaXNudW0oa3JpZ2luZ0FscGhhKSkgewogICAga3JpZ2luZ0FscGhhID0gMTAwOwogIH0KICBrcmlnaW5nQWxwaGEgPSBjZGJsKGtyaWdpbmdBbHBoYSk7CgogIC8vbHMsIGZyaWVkcmljaOaguOWHveaVuGxlbmd0aHNjYWxlCiAgbGV0IGxzID0gZ2V0KG9wdCwgJ2xzJyk7CiAgaWYgKCFpc251bShscykpIHsKICAgIGxzID0gMC41OwogIH0KICBscyA9IGNkYmwobHMpOwoKICAvL25vaXNlLCBmcmllZHJpY2jop4DmuKzlmarpn7PmqJnmupblt64KICBsZXQgbm9pc2UgPSBnZXQob3B0LCAnbm9pc2UnKTsKICBpZiAoIWlzbnVtKG5vaXNlKSkgewogICAgbm9pc2UgPSAwLjAxOwogIH0KICBub2lzZSA9IGNkYmwobm9pc2UpOwoKICAvL3JldHVybldpdGhWYXJpb2dyYW0KICBsZXQgcmV0dXJuV2l0aFZhcmlvZ3JhbSA9IGdldChvcHQsICdyZXR1cm5XaXRoVmFyaW9ncmFtJyk7CiAgaWYgKCFpc2JvbChyZXR1cm5XaXRoVmFyaW9ncmFtKSkgewogICAgcmV0dXJuV2l0aFZhcmlvZ3JhbSA9IGZhbHNlOwogIH0KICAvLyBjb25zb2xlLmxvZygncmV0dXJuV2l0aFZhcmlvZ3JhbScsIHJldHVybldpdGhWYXJpb2dyYW0pCgogIC8vcHRzWFladG9BcnIKICBwc1NyYyA9IHB0c1hZWnRvQXJyKHBzU3JjLCBvcHQpOwoKICAvL2NoZWNrIHBzU3JjCiAgaWYgKHNpemUocHNTcmMpID09PSAwKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1NyYyBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KICAvLyBjb25zb2xlLmxvZygncHRzWFladG9BcnIgcHNTcmMnLCBwc1NyYykKCiAgLy9wdHNYWXRvQXJyCiAgcHNUYXIgPSBwdHNYWXRvQXJyKHBzVGFyLCBvcHQpOwoKICAvL2NoZWNrIHBzVGFyCiAgaWYgKHNpemUocHNUYXIpID09PSAwKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1RhciBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KICAvLyBjb25zb2xlLmxvZygncHRzWFl0b0FyciBwc1RhcicsIHBzVGFyKQoKICAvL2ludGVycDJOb3JtYWxpemUKICBsZXQgaXRubSA9IGludGVycDJOb3JtYWxpemUocHNTcmMsIHsKICAgIHNjYWxlCiAgfSk7CiAgcHNTcmMgPSBpdG5tLnBzOyAvL+ikh+Wvq+ato+imj+WMluaVuOaTmgogIGxldCBudiA9IGl0bm0ubnY7CiAgbGV0IGludiA9IGl0bm0uaW52OwoKICAvL2twS25vd24KICBsZXQga3BLbm93biA9IHt9OwogIGZvckVhY2gocHNTcmMsIHYgPT4gewogICAgbGV0IGsgPSBgJHt2Lnh9LSR7di55fWA7IC8v5bey57aT6KKr5q2j6KaP5YyW6IezeCx5CiAgICBrcEtub3duW2tdID0gdi56OyAvL+W3sue2k+iiq+ato+imj+WMluiHs3gseSx6CiAgfSk7CgogIC8vdmFyaW9ncmFtLCBwcmVkaWN0OiDkvp1tZXRob2TliIfmj5vlvoznq6/lvJXmk44KICBsZXQgdmFyaW9ncmFtID0gbnVsbDsgLy9mcmllZHJpY2jnhKHljYrorornlbDlnJbmpoLlv7UsIOWbnuWCs+aZgue2reaMgW51bGwKICBsZXQgcHJlZGljdDsgLy8obngsIG55KSA9PiBuegogIGlmIChtZXRob2QgPT09ICdmcmllZHJpY2gnKSB7CiAgICAvL2lucHV0cywgb3V0cHV0cyAo5bey5q2j6KaP5YyWKQogICAgbGV0IGlucHV0cyA9IFtdOwogICAgbGV0IG91dHB1dHMgPSBbXTsKICAgIGZvckVhY2gocHNTcmMsIHYgPT4gewogICAgICBpbnB1dHMucHVzaChbdi54LCB2LnldKTsKICAgICAgb3V0cHV0cy5wdXNoKHYueik7CiAgICB9KTsKCiAgICAvL2tlcm5lbCwgbW9kZWzlsI3mh4nmoLjlh73mlbg6IGdhdXNzaWFuLT5TcXVhcmVkRXhwLCDlhbbppJgo5ZCrc3BoZXJpY2FsKS0+RXhwb25lbnRpYWwKICAgIGxldCBrZXJuZWw7CiAgICBpZiAoa3JpZ2luZ01vZGVsID09PSAnZ2F1c3NpYW4nKSB7CiAgICAgIGtlcm5lbCA9IG5ldyBTcXVhcmVkRXhwKGxzLCAxKTsKICAgIH0gZWxzZSB7CiAgICAgIGtlcm5lbCA9IG5ldyBFeHBvbmVudGlhbChscywgMSk7CiAgICB9CgogICAgLy9ncCwg5Zu65a6aa2VybmVs5LiN5YGaQURBTeWEquWMlijos4fmlpnlt7LmraPopo/ljJYsIOWbuuWummxlbmd0aHNjYWxl5Y2z5ZCI55CGKQogICAgbGV0IGdwID0gR2F1c3NpYW5Qcm9jZXNzLmJ1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKS5zZXRLZXJuZWwoa2VybmVsKS5zZXROb2lzZShub2lzZSkudHJhaW4oKTsKCiAgICAvL3ByZWRpY3QKICAgIHByZWRpY3QgPSAobngsIG55KSA9PiBncC5wcmVkaWN0KFtueCwgbnldKTsKICB9IGVsc2UgewogICAgLy94LCB5LCB0CiAgICBsZXQgeCA9IFtdOwogICAgbGV0IHkgPSBbXTsKICAgIGxldCB0ID0gW107CiAgICBmb3JFYWNoKHBzU3JjLCB2ID0+IHsKICAgICAgeC5wdXNoKHYueCk7CiAgICAgIHkucHVzaCh2LnkpOwogICAgICB0LnB1c2godi56KTsKICAgIH0pOwoKICAgIC8vdmFyaW9ncmFtCiAgICB2YXJpb2dyYW0gPSBrcmlnaW5nLnRyYWluKHQsIHgsIHksIGtyaWdpbmdNb2RlbCwga3JpZ2luZ1NpZ21hMiwga3JpZ2luZ0FscGhhKTsKICAgIC8vIGNvbnNvbGUubG9nKCd2YXJpb2dyYW0nLCB2YXJpb2dyYW0pCgogICAgLy9wcmVkaWN0CiAgICBwcmVkaWN0ID0gKG54LCBueSkgPT4ga3JpZ2luZy5wcmVkaWN0KG54LCBueSwgdmFyaW9ncmFtKTsKICB9CgogIC8va3BkdAogIGxldCBrcGR0ID0gKG54LCBueSkgPT4gewogICAgLy9jaGVjawogICAgbGV0IGsgPSBgJHtueH0tJHtueX1gOyAvL+W3sue2k+iiq+ato+imj+WMluiHs3gseQogICAgaWYgKGhhc2tleShrcEtub3duLCBrKSkgewogICAgICByZXR1cm4ga3BLbm93bltrXTsKICAgIH0KCiAgICAvL3ByZWRpY3QKICAgIGxldCBueiA9IHByZWRpY3QobngsIG55KTsKCiAgICAvL3NhdmUKICAgIGtwS25vd25ba10gPSBuejsKICAgIHJldHVybiBuejsKICB9OwoKICAvL2l0dgogIGxldCBpdHYgPSBwID0+IHsKICAgIC8veCwgbngKICAgIGxldCB4ID0gcC54OwogICAgbGV0IG54ID0gbnYoeCwgJ3gnKTsKICAgIGlmICghaXNOdW1iZXIobngpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBueFske254fV1gKTsgLy94LHnpoJDmnJ/pg73mmK/mnInlgLwKICAgIH0KCiAgICAvL3ksIG55CiAgICBsZXQgeSA9IHAueTsKICAgIGxldCBueSA9IG52KHksICd5Jyk7CiAgICBpZiAoIWlzTnVtYmVyKG55KSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgbnlbJHtueX1dYCk7IC8veCx56aCQ5pyf6YO95piv5pyJ5YC8CiAgICB9CgogICAgLy9ueiwgegogICAgbGV0IG56ID0ga3BkdChueCwgbnkpOwogICAgbGV0IHogPSBpbnYobnosICd6Jyk7CiAgICBpZiAoIWlzTnVtYmVyKHopKSB7CiAgICAgIHogPSBudWxsOyAvL3rpoIjmlK/mj7Tlj6/og73nhKHms5Xlhafmj5IKICAgIH0KCiAgICAvLyBjb25zb2xlLmxvZygneCcsIHgsICd5JywgeSwgJ3onLCB6KQogICAgLy8gY29uc29sZS5sb2coJ254JywgbngsICdueScsIG55LCAnbnonLCBueikKCiAgICAvL3IKICAgIGxldCByID0gewogICAgICBba2V5WF06IHgsCiAgICAgIFtrZXlZXTogeSwKICAgICAgW2tleVpdOiB6CiAgICB9OwogICAgcmV0dXJuIHI7CiAgfTsKCiAgLy9yCiAgbGV0IHI7CiAgaWYgKGlzT25lKSB7CiAgICBsZXQgcCA9IHBzVGFyWzBdOwogICAgciA9IGl0dihwKTsKICB9IGVsc2UgewogICAgciA9IFtdOwogICAgZm9yRWFjaChwc1RhciwgcCA9PiB7CiAgICAgIHIucHVzaChpdHYocCkpOwogICAgfSk7CiAgfQoKICAvL3JldHVybldpdGhWYXJpb2dyYW0KICBpZiAocmV0dXJuV2l0aFZhcmlvZ3JhbSkgewogICAgciA9IHsKICAgICAgcmVzdWx0OiByLAogICAgICB2YXJpb2dyYW0KICAgIH07CiAgfQogIHJldHVybiByOwp9CgovKioNCiAqIOmHneWwjeS4jeimj+WJh+S6jOe2reaVuOaTmumAsuihjOaMh+WumuWFp+aPkum7nuaVuOWAvA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ludGVycDIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwc1NyYyDovLjlhaXpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MX0se3g6eDIseTp5Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIlw0KICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHBzVGFyIOi8uOWFpem7numZo+WIl+aIlum7nueJqeS7tu+8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiX77yM5oiWe3g6eDEseTp5MX3pu57nianku7YNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tuS5i3jluqfmqJnmrITkvY3lrZfkuLLvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7bkuYt55bqn5qiZ5qyE5L2N5a2X5Liy77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlaPSd6J10g6Ly45YWl6bue54mp5Lu25LmLeuW6p+aomeaIluWAvOashOS9jeWtl+S4su+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2NhbGU9MV0g6Ly45YWl5q2j6KaP5YyW56+E5ZyN5pW45YC877yM5Zug6JmV55CG5aSa6YKK5b2i5pmC5pyJ5pW45YC85a656Kix6Kqk5beu77yM5pWF6aCI6YCa6YGO57iu5pS+5YC85Z+f5L6G5rib5bCR5ZWP6aGM77yM6aCQ6KitMeaYr+ato+imj+WMljDoh7Mx5LmL6ZaT77yM5L2/55Soc2NhbGVYWeWJh+aYr+ato+imj+WMlueCujDoh7NzY2FsZVhZ5LmL6ZaT77yM6aCQ6KitMQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQubWV0aG9kPSduYXR1cmFsTmVpZ2hib3InXSDovLjlhaXlhafmj5Lmlrnms5XlrZfkuLLvvIzlj6/pgbgnbmF0dXJhbE5laWdoYm9yJ+OAgSdrcmlnaW5nJ++8jOmgkOiorSduYXR1cmFsTmVpZ2hib3In77ybbWV0aG9kPSdrcmlnaW5nJ+aZguWRvOWPq2ludGVycDJLcmlnaW5n5Lim5Zu65a6a5L2/55So5YW2ZnJpZWRyaWNo5byV5pOOKOe2k2ludGVycDLnhKHms5XpgbjnlKhpbnZhbGzlvJXmk44pDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5tb2RlbD0nZXhwb25lbnRpYWwnXSDovLjlhaXoi6VtZXRob2Q9J2tyaWdpbmcn5pmC5LmL5qC45Ye95pW45bCN5oeJ5qih5byP5a2X5Liy77yMJ2dhdXNzaWFuJ+WwjeaHiVNxdWFyZWRFeHDjgIHlhbbppJgo5ZCrJ2V4cG9uZW50aWFsJ+OAgSdzcGhlcmljYWwnKeWwjeaHiUV4cG9uZW50aWFs77yM6aCQ6KitJ2V4cG9uZW50aWFsJw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQubHM9MC41XSDovLjlhaXoi6VtZXRob2Q9J2tyaWdpbmcn5pmC5LmLZnJpZWRyaWNo5qC45Ye95pW4bGVuZ3Roc2NhbGXmlbjlgLwo5bCN5oeJ5q2j6KaP5YyW5b6M5YC85Z+fKe+8jOmgkOiorTAuNQ0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQubm9pc2U9MC4wMV0g6Ly45YWl6IulbWV0aG9kPSdrcmlnaW5nJ+aZguS5i2ZyaWVkcmljaOingOa4rOWZqumfs+aomea6luW3rijlsI3mh4nmraPopo/ljJblvozlgLzln58p77yM6aCQ6KitMC4wMQ0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2lnbWEyPTBdICjlg4XoiIppbnZhbGzlvJXmk47kuYvljYrorornlbDlnJbmk6zlkIjlj4PmlbjvvIzlm6BpbnRlcnAy5LmLa3JpZ2luZ+WbuuWumui1sGZyaWVkcmljaOaVheS4jeeUn+aViCkg6Ly45YWl6Ieq5YuV5pOs5ZCI5Y+D5pW4c2lnbWEy5pW45YC877yM6aCQ6KitMA0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuYWxwaGE9MTAwXSAo5YOF6IiKaW52YWxs5byV5pOO5LmL5Y2K6K6K55Ww5ZyW5pOs5ZCI5Y+D5pW477yM5ZugaW50ZXJwMuS5i2tyaWdpbmflm7rlrprotbBmcmllZHJpY2jmlYXkuI3nlJ/mlYgpIOi8uOWFpeiHquWLleaTrOWQiOWPg+aVuGFscGhh5pW45YC877yM6aCQ6KitMTAwDQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQucmV0dXJuV2l0aFZhcmlvZ3JhbT1mYWxzZV0gKOWDheiIimludmFsbOW8leaTjuWPg+aVuO+8jOWboGludGVycDLkuYtrcmlnaW5n5Zu65a6a6LWwZnJpZWRyaWNo5pWF5LiN55Sf5pWI77yMZnJpZWRyaWNo54Sh5Y2K6K6K55Ww5ZyWKSDovLjlhaXmmK/lkKblm57lgrPmk6zlkIjljYrorornlbDmlbjntZDmnpzluIPmnpflgLzvvIzpoJDoqK1mYWxzZQ0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnVzZVN5bmM9ZmFsc2VdIOi8uOWFpeaYr+WQpuS9v+eUqOWQjOatpeWHveaVuOW4g+ael+WAvO+8jOmgkOiorWZhbHNlDQogKiBAcmV0dXJucyB7UHJvbWlzZXxBcnJheXxPYmplY3R9IOWbnuWCs1Byb21pc2XmiJbpu57nianku7bpmaPliJfmiJbpu57nianku7bvvIzoi6V1c2VTeW5jPWZhbHNl5YmH5Zue5YKzUHJvbWlzZe+8jHJlc29sdmXngrrlm57lgrPpu57nianku7bpmaPliJfmiJbpu57nianku7bvvIxyZWplY3TngrrlpLHmlZfoqIrmga/vvIzoi6V1c2VTeW5jPXRydWXliYflm57lgrPpu57nianku7bpmaPliJfmiJbpu57nianku7bvvIzoi6XnmbznlJ/pjK/oqqTliYflm57lgrPpjK/oqqToqIrmga/nianku7YNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBzDQogKiBsZXQgcA0KICogbGV0IHINCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI4MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI4MywgeTogMjA3LCB6OiAxMTQuNDMwNDA0MjE5NTE5MDggfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDExNjAsDQogKiAgICAgeTogMzgwLA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAxMTYwLCB5OiAzODAsIHo6IG51bGwgfQ0KICoNCiAqIHBzID0gW3sgYTogMjQzLCBiOiAyMDYsIGM6IDk1IH0sIHsgYTogMjMzLCBiOiAyMjUsIGM6IDE0NiB9LCB7IGE6IDIxLCBiOiAzMjUsIGM6IDIyIH0sIHsgYTogOTUzLCBiOiAyOCwgYzogMjIzIH0sIHsgYTogMTA5MiwgYjogMjkwLCBjOiAzOSB9LCB7IGE6IDc0NCwgYjogMjAwLCBjOiAxOTEgfSwgeyBhOiAxNzQsIGI6IDMsIGM6IDIyIH0sIHsgYTogNTM3LCBiOiAzNjgsIGM6IDI0OSB9LCB7IGE6IDExNTEsIGI6IDM3MSwgYzogODYgfSwgeyBhOiA4MTQsIGI6IDI1MiwgYzogMTI1IH1dDQogKiBwID0gew0KICogICAgIGE6IDI0MywNCiAqICAgICBiOiAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCwgeyBrZXlYOiAnYScsIGtleVk6ICdiJywga2V5WjogJ2MnIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyBhOiAyNDMsIGI6IDIwNywgYzogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gWw0KICogICAgIHsNCiAqICAgICAgICAgeDogMjQzLA0KICogICAgICAgICB5OiAyMDcsDQogKiAgICAgfSwNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI4MywNCiAqICAgICAgICAgeTogMjA3LA0KICogICAgIH0sDQogKiBdDQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0sDQogKiAvLyAgIHsgeDogMjgzLCB5OiAyMDcsIHo6IDExNC40MzA0MDQyMTk1MTkwOCB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwLCB7IG1ldGhvZDogJ2tyaWdpbmcnIH0pIC8vbWV0aG9kPSdrcmlnaW5nJ+i1sGludGVycDJLcmlnaW5nLCDpu5joqo1mcmllZHJpY2jlvJXmk44NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny40OTg0NjIzNTEwODEyMyB9DQogKg0KICogcHMgPSBbeyB4OiAwLjAwMDI0MywgeTogMC4wMDAyMDYsIHo6IDk1IH0sIHsgeDogMC4wMDAyMzMsIHk6IDAuMDAwMjI1LCB6OiAxNDYgfSwgeyB4OiAwLjAwMDAyMSwgeTogMC4wMDAzMjUsIHo6IDIyIH0sIHsgeDogMC4wMDA5NTMsIHk6IDAuMDAwMDI4LCB6OiAyMjMgfSwgeyB4OiAwLjAwMTA5MiwgeTogMC4wMDAyOSwgejogMzkgfSwgeyB4OiAwLjAwMDc0NCwgeTogMC4wMDAyMDAsIHo6IDE5MSB9LCB7IHg6IDAuMDAwMTc0LCB5OiAwLjAwMDAwMywgejogMjIgfSwgeyB4OiAwLjAwMDUzNywgeTogMC4wMDAzNjgsIHo6IDI0OSB9LCB7IHg6IDAuMDAxMTUxLCB5OiAwLjAwMDM3MSwgejogODYgfSwgeyB4OiAwLjAwMDgxNCwgeTogMC4wMDAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAwLjAwMDI0MywNCiAqICAgICB5OiAwLjAwMDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMC4wMDAyNDMsIHk6IDAuMDAwMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4Njc4IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHAsIHsgc2NhbGU6IDEwMDAgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4Njg1NSB9DQogKg0KICogLy9mb3IgaW50ZXJwMi53ay51bWQuanMNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMihwcywgcCwgeyB1c2VTeW5jOiB0cnVlIH0pIC8v5L2/55SoaW50ZXJwMi53ay51bWQuanPliYfkuI3mlK/mj7RzeW5j5qih5byPDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqLwpmdW5jdGlvbiBpbnRlcnAyKHBzU3JjLCBwc1Rhciwgb3B0ID0ge30pIHsKICAvL21ldGhvZAogIGxldCBtZXRob2QgPSBnZXQob3B0LCAnbWV0aG9kJyk7CiAgaWYgKG1ldGhvZCAhPT0gJ25hdHVyYWxOZWlnaGJvcicgJiYgbWV0aG9kICE9PSAna3JpZ2luZycpIHsKICAgIG1ldGhvZCA9ICduYXR1cmFsTmVpZ2hib3InOwogIH0KCiAgLy91c2VTeW5jCiAgbGV0IHVzZVN5bmMgPSBnZXQob3B0LCAndXNlU3luYycpOwogIGlmICghaXNib2wodXNlU3luYykpIHsKICAgIHVzZVN5bmMgPSBmYWxzZTsKICB9CgogIC8vX3N5bmMKICBsZXQgX3N5bmMgPSAoKSA9PiB7CiAgICBsZXQgciA9IG51bGw7CiAgICB0cnkgewogICAgICBpZiAobWV0aG9kID09PSAnbmF0dXJhbE5laWdoYm9yJykgewogICAgICAgIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzU3JjLCBwc1Rhciwgb3B0KTsKICAgICAgfSBlbHNlIGlmIChtZXRob2QgPT09ICdrcmlnaW5nJykgewogICAgICAgIHIgPSBpbnRlcnAyS3JpZ2luZyhwc1NyYywgcHNUYXIsIG9wdCk7CiAgICAgIH0KICAgIH0gY2F0Y2ggKGVycikgewogICAgICByID0gewogICAgICAgIGVycjogZXJyLnRvU3RyaW5nKCkKICAgICAgfTsKICAgIH0KICAgIHJldHVybiByOwogIH07CgogIC8vX2FzeW5jCiAgbGV0IF9hc3luYyA9IGFzeW5jICgpID0+IHsKICAgIGxldCByID0gbnVsbDsKICAgIHRyeSB7CiAgICAgIHIgPSBfc3luYygpOwogICAgICBsZXQgZXJyID0gZ2V0KHIsICdlcnInKTsKICAgICAgaWYgKGlzZXN0cihlcnIpKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHI7CiAgICAgIH0KICAgIH0gY2F0Y2ggKGVycikgewogICAgICBjb25zb2xlLmxvZyhlcnIpOwogICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyLnRvU3RyaW5nKCkpOwogICAgfQogIH07CiAgaWYgKHVzZVN5bmMpIHsKICAgIHJldHVybiBfc3luYygpOwogIH0gZWxzZSB7CiAgICByZXR1cm4gX2FzeW5jKCk7CiAgfQp9CgoKCmxldCBpbnN0YW5jZSA9IG51bGwKZnVuY3Rpb24gaW5pdChpbnB1dCl7CgogICAgLy9pbml0CiAgICBsZXQgcgogICAgCiAgICAgICAgciA9IHsKICAgICAgICAgICAgbWFpbjogaW50ZXJwMgogICAgICAgIH0KICAgICAgICAKCiAgICAvL29uCiAgICAKCiAgICAvL3NhdmUKICAgIGluc3RhbmNlID0gcgoKfQoKZnVuY3Rpb24gc2VuZE1lc3NhZ2UoZGF0YSkgewogICAgCiAgICAgICAgcGFyZW50UG9ydC5wb3N0TWVzc2FnZShkYXRhKQogICAgICAgIAp9Cgphc3luYyBmdW5jdGlvbiBydW4oZGF0YSkgewogICAgLy8gY29uc29sZS5sb2coJ2lubmVyIHdvcmtlciBydW4nLGRhdGEpCgogICAgLy9tb2RlCiAgICBsZXQgbW9kZSA9IGRhdGEubW9kZQoKICAgIC8vY2hlY2sKICAgIGlmKG1vZGUgIT09ICdpbml0JyAmJiBtb2RlICE9PSAnY2FsbCcpewogICAgICAgIHJldHVybgogICAgfQoKICAgIC8vaW5pdAogICAgaWYobW9kZSA9PT0gJ2luaXQnKXsKICAgICAgICAKICAgICAgICB0cnl7CgogICAgICAgICAgICAvL3R5cGUKICAgICAgICAgICAgbGV0IHR5cGUgPSBkYXRhLnR5cGUKCiAgICAgICAgICAgIC8vaW5wdXQKICAgICAgICAgICAgbGV0IGlucHV0ID0gZGF0YS5pbnB1dAogICAgCiAgICAgICAgICAgIC8vaW5zdGFuY2UKICAgICAgICAgICAgaWYodHlwZSA9PT0gJ2Z1bmN0aW9uJyl7CiAgICAgICAgICAgICAgICBpbml0KC4uLmlucHV0KQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYodHlwZSA9PT0gJ29iamVjdCcpewogICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBpbnRlcnAyCiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIGNhdGNoKGVycil7CiAgICAgICAgCiAgICAgICAgICAgIC8vc2VuZE1lc3NhZ2UKICAgICAgICAgICAgbGV0IHJlcyA9IHsKICAgICAgICAgICAgICAgIG1vZGU6ICdlbWl0JywKICAgICAgICAgICAgICAgIGV2TmFtZTogJ2Vycm9yJywKICAgICAgICAgICAgICAgIG1zZzogZXJyLAogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbmRNZXNzYWdlKHJlcykKCiAgICAgICAgfQogICAgICAgICAgICAKICAgIH0KCiAgICAvL2NoZWNrCiAgICBpZihtb2RlID09PSAnY2FsbCcpewogICAgICAgIGxldCBzdGF0ZSA9ICcnCiAgICAgICAgbGV0IG1zZyA9IG51bGwKCiAgICAgICAgdHJ5ewoKICAgICAgICAgICAgLy9mdW4KICAgICAgICAgICAgbGV0IGZ1biA9IGluc3RhbmNlW2RhdGEuZnVuXQoKICAgICAgICAgICAgLy9pbnB1dAogICAgICAgICAgICBsZXQgaW5wdXQgPSBkYXRhLmlucHV0CgogICAgICAgICAgICAvL2V4ZWMKICAgICAgICAgICAgYXdhaXQgZnVuKC4uLmlucHV0KQogICAgICAgICAgICAgICAgLnRoZW4oKHN1YykgPT4gewogICAgICAgICAgICAgICAgICAgIHN0YXRlPSdzdWNjZXNzJwogICAgICAgICAgICAgICAgICAgIG1zZz1zdWMKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycikgPT4gewogICAgICAgICAgICAgICAgICAgIHN0YXRlPSdlcnJvcicKICAgICAgICAgICAgICAgICAgICBtc2c9ZXJyCiAgICAgICAgICAgICAgICB9KQoKICAgICAgICB9CiAgICAgICAgY2F0Y2goZXJyKXsKICAgICAgICAgICAgc3RhdGUgPSAnZXJyb3InCiAgICAgICAgICAgIG1zZyA9IGVycgogICAgICAgIH0KICAgICAgICAKICAgICAgICAvL3NlbmRNZXNzYWdlCiAgICAgICAgbGV0IHJlcyA9IHsKICAgICAgICAgICAgbW9kZTogJ3JldHVybicsCiAgICAgICAgICAgIGlkOiBkYXRhLmlkLAogICAgICAgICAgICBmdW46IGRhdGEuZnVuLAogICAgICAgICAgICBzdGF0ZSwKICAgICAgICAgICAgbXNnLAogICAgICAgIH0KICAgICAgICBzZW5kTWVzc2FnZShyZXMpCgogICAgfQoKfQoKZnVuY3Rpb24gcmVjdk1lc3NhZ2UoZGF0YSkgewogICAgLy8gY29uc29sZS5sb2coJ2lubmVyIHdvcmtlciByZWN2OicsIGRhdGEpCgogICAgLy9kYXRhUmVjdgogICAgbGV0IGRhdGFSZWN2ID0gZGF0YQoKICAgIC8vcnVuCiAgICBydW4oZGF0YVJlY3YpCgp9CgoKICAgICAgICBwYXJlbnRQb3J0Lm9uKCdtZXNzYWdlJywgcmVjdk1lc3NhZ2UpCiAgICAgICAgCgp0cnl7CgogICAgLy/lg4Xku6V1bmNhdWdodEV4Y2VwdGlvbk1vbml0b3LoqJjpjIQsIOS4jeWPr+iou+WGinVuY2F1Z2h0RXhjZXB0aW9u6IiHdW5oYW5kbGVkUmVqZWN0aW9u55uj6IG9OgogICAgLy/mlrx3b3JrZXLlhafoqLvlhormraTkuoznm6Pogb3mnIPpmLvmraJOb2Rl6aCQ6Kit55qEd29ya2Vy57WC5q2i6KGM54K6LCDkvb93b3JrZXLltKnmvbDlvozku43lrZjmtLvnqbrovYksCiAgICAvL+WkluWxpOaUtuS4jeWIsGVycm9yL2V4aXTkuovku7YsIHBlbmRpbmcgcHJvbWlzZeawuOS5heaHuOe9riwg5LiU5a2Y5rS75q6t5bGNd29ya2Vy5pyD5Luk5a6/5Li756iL5bqP54Sh5rOV6YCA5Ye6OwogICAgLy/np7vpmaTlvox3b3JrZXLkvp3poJDoqK3ooYzngrrmrbvkuqEsIGVycm9y5LqL5Lu25YKz6Iez5aSW5bGkLCDnlLHlpJblsaTmlbTmiblyZWplY3QgcGVuZGluZwogICAgLy8gcHJvY2Vzcy5vbigndW5oYW5kbGVkUmVqZWN0aW9uJywgKGVycikgPT4gewogICAgLy8gICAgIGNvbnNvbGUubG9nKCdpbm5lcjp1bmhhbmRsZWRSZWplY3Rpb24nLCBlcnIpCiAgICAvLyB9KQogICAgLy8gcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCAoZXJyKSA9PiB7CiAgICAvLyAgICAgY29uc29sZS5sb2coJ2lubmVyOnVuY2F1Z2h0RXhjZXB0aW9uJywgZXJyKQogICAgLy8gfSkKICAgIHByb2Nlc3Mub24oJ3VuY2F1Z2h0RXhjZXB0aW9uTW9uaXRvcicsIChlcnIpID0+IHsKICAgICAgICBjb25zb2xlLmxvZygnaW5uZXI6dW5jYXVnaHRFeGNlcHRpb25Nb25pdG9yJywgZXJyKQogICAgfSkKCn0KY2F0Y2goZXJyKXt9Cgo=`;//code
|
|
139
|
+
let codeB64=`CgogICAgICAgIC8vaW1wb3J0IHsgcGFyZW50UG9ydCB9IGZyb20gJ3dvcmtlcl90aHJlYWRzJwogICAgICAgIGxldCB7IHBhcmVudFBvcnQgfSA9IHJlcXVpcmUoJ3dvcmtlcl90aHJlYWRzJykgLy/lm6BwYWNrYWdlLmpzb27kuI3ntaZ0eXBlPW1vZHVsZeaVheeEoeazleaUr+aPtGVzNiBpbXBvcnQsIOW+l+S9v+eUqHJlcXVpcmUKICAgICAgICAvL+iLpeimgeaWvG5vZGVqcyB3b3JrZXLlhafkvb/nlKjnhKHms5XovYnora/nmoTljp/nlJ/lpZfku7bkvovlpoJmcywg6YG/5YWN5L2/55So6aCC5bGkaW1wb3J05Yqg6LyJ5L2/55SoLCDlm6DnhKHms5XovYnora/mnIPnm7TmjqXkv53nlZkKICAgICAgICAvL+S4puWboGltcG9ydOS9jeaWvHdvcmtlcuWkluWxpOmZkOWumueCunJlcXVpcmXljYAocGFja2FnZS5qc29u5LiN57WmdHlwZT1tb2R1bGUpLCDmlYXlh7rnj77pjK/oqqTnhKHms5XovYnora8KICAgICAgICAKCid1c2Ugc3RyaWN0JzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0FycmF5KFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzQXJyYXkoJ2FiYycpOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzQXJyYXkoXy5ub29wKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTsKdmFyIGlzQXJyYXkkMSA9IGlzQXJyYXk7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqLwp2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7CnZhciBmcmVlR2xvYmFsJDEgPSBmcmVlR2xvYmFsOwoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi8KdmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7CgovKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi8KdmFyIHJvb3QgPSBmcmVlR2xvYmFsJDEgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTsKdmFyIHJvb3QkMSA9IHJvb3Q7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIFN5bWJvbCA9IHJvb3QkMS5TeW1ib2w7CnZhciBTeW1ib2wkMSA9IFN5bWJvbDsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJGIgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQ4ID0gb2JqZWN0UHJvdG8kYi5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBVc2VkIHRvIHJlc29sdmUgdGhlCiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKQogKiBvZiB2YWx1ZXMuCiAqLwp2YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmckMSA9IG9iamVjdFByb3RvJGIudG9TdHJpbmc7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHN5bVRvU3RyaW5nVGFnJDEgPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnRvU3RyaW5nVGFnIDogdW5kZWZpbmVkOwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUdldFRhZ2Agd2hpY2ggaWdub3JlcyBgU3ltYm9sLnRvU3RyaW5nVGFnYCB2YWx1ZXMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByYXcgYHRvU3RyaW5nVGFnYC4KICovCmZ1bmN0aW9uIGdldFJhd1RhZyh2YWx1ZSkgewogIHZhciBpc093biA9IGhhc093blByb3BlcnR5JDguY2FsbCh2YWx1ZSwgc3ltVG9TdHJpbmdUYWckMSksCiAgICB0YWcgPSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXTsKICB0cnkgewogICAgdmFsdWVbc3ltVG9TdHJpbmdUYWckMV0gPSB1bmRlZmluZWQ7CiAgICB2YXIgdW5tYXNrZWQgPSB0cnVlOwogIH0gY2F0Y2ggKGUpIHt9CiAgdmFyIHJlc3VsdCA9IG5hdGl2ZU9iamVjdFRvU3RyaW5nJDEuY2FsbCh2YWx1ZSk7CiAgaWYgKHVubWFza2VkKSB7CiAgICBpZiAoaXNPd24pIHsKICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWckMV0gPSB0YWc7CiAgICB9IGVsc2UgewogICAgICBkZWxldGUgdmFsdWVbc3ltVG9TdHJpbmdUYWckMV07CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJGEgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqCiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUKICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpCiAqIG9mIHZhbHVlcy4KICovCnZhciBuYXRpdmVPYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvJGEudG9TdHJpbmc7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyB1c2luZyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuCiAqLwpmdW5jdGlvbiBvYmplY3RUb1N0cmluZyh2YWx1ZSkgewogIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgbnVsbFRhZyA9ICdbb2JqZWN0IE51bGxdJywKICB1bmRlZmluZWRUYWcgPSAnW29iamVjdCBVbmRlZmluZWRdJzsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnRvU3RyaW5nVGFnIDogdW5kZWZpbmVkOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRUYWdgIHdpdGhvdXQgZmFsbGJhY2tzIGZvciBidWdneSBlbnZpcm9ubWVudHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLgogKi8KZnVuY3Rpb24gYmFzZUdldFRhZyh2YWx1ZSkgewogIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZFRhZyA6IG51bGxUYWc7CiAgfQogIHJldHVybiBzeW1Ub1N0cmluZ1RhZyAmJiBzeW1Ub1N0cmluZ1RhZyBpbiBPYmplY3QodmFsdWUpID8gZ2V0UmF3VGFnKHZhbHVlKSA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYAogKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mICJvYmplY3QiLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc09iamVjdExpa2Uoe30pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdExpa2UoXy5ub29wKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5pc09iamVjdExpa2UobnVsbCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHsKICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIHN5bWJvbFRhZyQxID0gJ1tvYmplY3QgU3ltYm9sXSc7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTeW1ib2xgIHByaW1pdGl2ZSBvciBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHN5bWJvbCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7CiAqIC8vID0+IHRydWUKICoKICogXy5pc1N5bWJvbCgnYWJjJyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHwgaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBzeW1ib2xUYWckMTsKfQoKLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqLwp2YXIgcmVJc0RlZXBQcm9wID0gL1wufFxbKD86W15bXF1dKnwoWyInXSkoPzooPyFcMSlbXlxcXXxcXC4pKj9cMSlcXS8sCiAgcmVJc1BsYWluUHJvcCA9IC9eXHcqJC87CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc0tleSh2YWx1ZSwgb2JqZWN0KSB7CiAgaWYgKGlzQXJyYXkkMSh2YWx1ZSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgaWYgKHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnc3ltYm9sJyB8fCB0eXBlID09ICdib29sZWFuJyB8fCB2YWx1ZSA9PSBudWxsIHx8IGlzU3ltYm9sKHZhbHVlKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpIHx8ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSkgfHwgb2JqZWN0ICE9IG51bGwgJiYgdmFsdWUgaW4gT2JqZWN0KG9iamVjdCk7Cn0KCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUKICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKQogKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc09iamVjdCh7fSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdChbMSwgMiwgM10pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNPYmplY3QoXy5ub29wKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzT2JqZWN0KG51bGwpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHsKICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJywKICBmdW5jVGFnJDEgPSAnW29iamVjdCBGdW5jdGlvbl0nLAogIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsCiAgcHJveHlUYWcgPSAnW29iamVjdCBQcm94eV0nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0Z1bmN0aW9uKF8pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7CiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yCiAgLy8gaW4gU2FmYXJpIDkgd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXlzIGFuZCBvdGhlciBjb25zdHJ1Y3RvcnMuCiAgdmFyIHRhZyA9IGJhc2VHZXRUYWcodmFsdWUpOwogIHJldHVybiB0YWcgPT0gZnVuY1RhZyQxIHx8IHRhZyA9PSBnZW5UYWcgfHwgdGFnID09IGFzeW5jVGFnIHx8IHRhZyA9PSBwcm94eVRhZzsKfQoKLyoqIFVzZWQgdG8gZGV0ZWN0IG92ZXJyZWFjaGluZyBjb3JlLWpzIHNoaW1zLiAqLwp2YXIgY29yZUpzRGF0YSA9IHJvb3QkMVsnX19jb3JlLWpzX3NoYXJlZF9fJ107CnZhciBjb3JlSnNEYXRhJDEgPSBjb3JlSnNEYXRhOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi8KdmFyIG1hc2tTcmNLZXkgPSBmdW5jdGlvbiAoKSB7CiAgdmFyIHVpZCA9IC9bXi5dKyQvLmV4ZWMoY29yZUpzRGF0YSQxICYmIGNvcmVKc0RhdGEkMS5rZXlzICYmIGNvcmVKc0RhdGEkMS5rZXlzLklFX1BST1RPIHx8ICcnKTsKICByZXR1cm4gdWlkID8gJ1N5bWJvbChzcmMpXzEuJyArIHVpZCA6ICcnOwp9KCk7CgovKioKICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgaXRzIHNvdXJjZSBtYXNrZWQuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGZ1bmNgIGlzIG1hc2tlZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNNYXNrZWQoZnVuYykgewogIHJldHVybiAhIW1hc2tTcmNLZXkgJiYgbWFza1NyY0tleSBpbiBmdW5jOwp9CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBmdW5jUHJvdG8kMSA9IEZ1bmN0aW9uLnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi8KdmFyIGZ1bmNUb1N0cmluZyQxID0gZnVuY1Byb3RvJDEudG9TdHJpbmc7CgovKioKICogQ29udmVydHMgYGZ1bmNgIHRvIGl0cyBzb3VyY2UgY29kZS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY29udmVydC4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc291cmNlIGNvZGUuCiAqLwpmdW5jdGlvbiB0b1NvdXJjZShmdW5jKSB7CiAgaWYgKGZ1bmMgIT0gbnVsbCkgewogICAgdHJ5IHsKICAgICAgcmV0dXJuIGZ1bmNUb1N0cmluZyQxLmNhbGwoZnVuYyk7CiAgICB9IGNhdGNoIChlKSB7fQogICAgdHJ5IHsKICAgICAgcmV0dXJuIGZ1bmMgKyAnJzsKICAgIH0gY2F0Y2ggKGUpIHt9CiAgfQogIHJldHVybiAnJzsKfQoKLyoqCiAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAKICogW3N5bnRheCBjaGFyYWN0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wYXR0ZXJucykuCiAqLwp2YXIgcmVSZWdFeHBDaGFyID0gL1tcXF4kLiorPygpW1xde318XS9nOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkpLiAqLwp2YXIgcmVJc0hvc3RDdG9yID0gL15cW29iamVjdCAuKz9Db25zdHJ1Y3RvclxdJC87CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBmdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGUsCiAgb2JqZWN0UHJvdG8kOSA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovCnZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDcgPSBvYmplY3RQcm90byQ5Lmhhc093blByb3BlcnR5OwoKLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi8KdmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICsgZnVuY1RvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkkNykucmVwbGFjZShyZVJlZ0V4cENoYXIsICdcXCQmJykucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXCgpfCBmb3IgLis/KD89XFxcXSkvZywgJyQxLio/JykgKyAnJCcpOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmF0aXZlYCB3aXRob3V0IGJhZCBzaGltIGNoZWNrcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzTmF0aXZlKHZhbHVlKSB7CiAgaWYgKCFpc09iamVjdCh2YWx1ZSkgfHwgaXNNYXNrZWQodmFsdWUpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHZhciBwYXR0ZXJuID0gaXNGdW5jdGlvbih2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yOwogIHJldHVybiBwYXR0ZXJuLnRlc3QodG9Tb3VyY2UodmFsdWUpKTsKfQoKLyoqCiAqIEdldHMgdGhlIHZhbHVlIGF0IGBrZXlgIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS4KICovCmZ1bmN0aW9uIGdldFZhbHVlKG9iamVjdCwga2V5KSB7CiAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07Cn0KCi8qKgogKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZnVuY3Rpb24gaWYgaXQncyBuYXRpdmUsIGVsc2UgYHVuZGVmaW5lZGAuCiAqLwpmdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHsKICB2YXIgdmFsdWUgPSBnZXRWYWx1ZShvYmplY3QsIGtleSk7CiAgcmV0dXJuIGJhc2VJc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDsKfQoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpOwp2YXIgbmF0aXZlQ3JlYXRlJDEgPSBuYXRpdmVDcmVhdGU7CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgaGFzaC4KICoKICogQHByaXZhdGUKICogQG5hbWUgY2xlYXIKICogQG1lbWJlck9mIEhhc2gKICovCmZ1bmN0aW9uIGhhc2hDbGVhcigpIHsKICB0aGlzLl9fZGF0YV9fID0gbmF0aXZlQ3JlYXRlJDEgPyBuYXRpdmVDcmVhdGUkMShudWxsKSA6IHt9OwogIHRoaXMuc2l6ZSA9IDA7Cn0KCi8qKgogKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZGVsZXRlCiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoIFRoZSBoYXNoIHRvIG1vZGlmeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGhhc2hEZWxldGUoa2V5KSB7CiAgdmFyIHJlc3VsdCA9IHRoaXMuaGFzKGtleSkgJiYgZGVsZXRlIHRoaXMuX19kYXRhX19ba2V5XTsKICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqLwp2YXIgSEFTSF9VTkRFRklORUQkMiA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJzsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDggPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQ2ID0gb2JqZWN0UHJvdG8kOC5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBHZXRzIHRoZSBoYXNoIHZhbHVlIGZvciBga2V5YC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZ2V0CiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuCiAqLwpmdW5jdGlvbiBoYXNoR2V0KGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXzsKICBpZiAobmF0aXZlQ3JlYXRlJDEpIHsKICAgIHZhciByZXN1bHQgPSBkYXRhW2tleV07CiAgICByZXR1cm4gcmVzdWx0ID09PSBIQVNIX1VOREVGSU5FRCQyID8gdW5kZWZpbmVkIDogcmVzdWx0OwogIH0KICByZXR1cm4gaGFzT3duUHJvcGVydHkkNi5jYWxsKGRhdGEsIGtleSkgPyBkYXRhW2tleV0gOiB1bmRlZmluZWQ7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDcgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQ1ID0gb2JqZWN0UHJvdG8kNy5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBDaGVja3MgaWYgYSBoYXNoIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGhhcwogKiBAbWVtYmVyT2YgSGFzaAogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187CiAgcmV0dXJuIG5hdGl2ZUNyZWF0ZSQxID8gZGF0YVtrZXldICE9PSB1bmRlZmluZWQgOiBoYXNPd25Qcm9wZXJ0eSQ1LmNhbGwoZGF0YSwga2V5KTsKfQoKLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqLwp2YXIgSEFTSF9VTkRFRklORUQkMSA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJzsKCi8qKgogKiBTZXRzIHRoZSBoYXNoIGBrZXlgIHRvIGB2YWx1ZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIHNldAogKiBAbWVtYmVyT2YgSGFzaAogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBoYXNoIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gaGFzaFNldChrZXksIHZhbHVlKSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fOwogIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7CiAgZGF0YVtrZXldID0gbmF0aXZlQ3JlYXRlJDEgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCA/IEhBU0hfVU5ERUZJTkVEJDEgOiB2YWx1ZTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYSBoYXNoIG9iamVjdC4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gSGFzaChlbnRyaWVzKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CiAgdGhpcy5jbGVhcigpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTsKICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7CiAgfQp9CgovLyBBZGQgbWV0aG9kcyB0byBgSGFzaGAuCkhhc2gucHJvdG90eXBlLmNsZWFyID0gaGFzaENsZWFyOwpIYXNoLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBoYXNoRGVsZXRlOwpIYXNoLnByb3RvdHlwZS5nZXQgPSBoYXNoR2V0OwpIYXNoLnByb3RvdHlwZS5oYXMgPSBoYXNoSGFzOwpIYXNoLnByb3RvdHlwZS5zZXQgPSBoYXNoU2V0OwoKLyoqCiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIGxpc3QgY2FjaGUuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGNsZWFyCiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICovCmZ1bmN0aW9uIGxpc3RDYWNoZUNsZWFyKCkgewogIHRoaXMuX19kYXRhX18gPSBbXTsKICB0aGlzLnNpemUgPSAwOwp9CgovKioKICogUGVyZm9ybXMgYQogKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKQogKiBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXF1aXZhbGVudC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07CiAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07CiAqCiAqIF8uZXEob2JqZWN0LCBvYmplY3QpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uZXEob2JqZWN0LCBvdGhlcik7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uZXEoJ2EnLCAnYScpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uZXEoTmFOLCBOYU4pOwogKiAvLyA9PiB0cnVlCiAqLwpmdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHsKICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8IHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7Cn0KCi8qKgogKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgYGtleWAgaXMgZm91bmQgaW4gYGFycmF5YCBvZiBrZXktdmFsdWUgcGFpcnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LgogKiBAcGFyYW0geyp9IGtleSBUaGUga2V5IHRvIHNlYXJjaCBmb3IuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuCiAqLwpmdW5jdGlvbiBhc3NvY0luZGV4T2YoYXJyYXksIGtleSkgewogIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKGxlbmd0aC0tKSB7CiAgICBpZiAoZXEoYXJyYXlbbGVuZ3RoXVswXSwga2V5KSkgewogICAgICByZXR1cm4gbGVuZ3RoOwogICAgfQogIH0KICByZXR1cm4gLTE7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlOwoKLyoqCiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlRGVsZXRlKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7CiAgaWYgKGluZGV4IDwgMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxOwogIGlmIChpbmRleCA9PSBsYXN0SW5kZXgpIHsKICAgIGRhdGEucG9wKCk7CiAgfSBlbHNlIHsKICAgIHNwbGljZS5jYWxsKGRhdGEsIGluZGV4LCAxKTsKICB9CiAgLS10aGlzLnNpemU7CiAgcmV0dXJuIHRydWU7Cn0KCi8qKgogKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZ2V0CiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS4KICovCmZ1bmN0aW9uIGxpc3RDYWNoZUdldChrZXkpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sCiAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpOwogIHJldHVybiBpbmRleCA8IDAgPyB1bmRlZmluZWQgOiBkYXRhW2luZGV4XVsxXTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGxpc3RDYWNoZUhhcyhrZXkpIHsKICByZXR1cm4gYXNzb2NJbmRleE9mKHRoaXMuX19kYXRhX18sIGtleSkgPiAtMTsKfQoKLyoqCiAqIFNldHMgdGhlIGxpc3QgY2FjaGUgYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbGlzdCBjYWNoZSBpbnN0YW5jZS4KICovCmZ1bmN0aW9uIGxpc3RDYWNoZVNldChrZXksIHZhbHVlKSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLAogICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTsKICBpZiAoaW5kZXggPCAwKSB7CiAgICArK3RoaXMuc2l6ZTsKICAgIGRhdGEucHVzaChba2V5LCB2YWx1ZV0pOwogIH0gZWxzZSB7CiAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlOwogIH0KICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gbGlzdCBjYWNoZSBvYmplY3QuCiAqCiAqIEBwcml2YXRlCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS4KICovCmZ1bmN0aW9uIExpc3RDYWNoZShlbnRyaWVzKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CiAgdGhpcy5jbGVhcigpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTsKICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7CiAgfQp9CgovLyBBZGQgbWV0aG9kcyB0byBgTGlzdENhY2hlYC4KTGlzdENhY2hlLnByb3RvdHlwZS5jbGVhciA9IGxpc3RDYWNoZUNsZWFyOwpMaXN0Q2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IGxpc3RDYWNoZURlbGV0ZTsKTGlzdENhY2hlLnByb3RvdHlwZS5nZXQgPSBsaXN0Q2FjaGVHZXQ7Ckxpc3RDYWNoZS5wcm90b3R5cGUuaGFzID0gbGlzdENhY2hlSGFzOwpMaXN0Q2FjaGUucHJvdG90eXBlLnNldCA9IGxpc3RDYWNoZVNldDsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi8KdmFyIE1hcCA9IGdldE5hdGl2ZShyb290JDEsICdNYXAnKTsKdmFyIE1hcCQxID0gTWFwOwoKLyoqCiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC4KICoKICogQHByaXZhdGUKICogQG5hbWUgY2xlYXIKICogQG1lbWJlck9mIE1hcENhY2hlCiAqLwpmdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkgewogIHRoaXMuc2l6ZSA9IDA7CiAgdGhpcy5fX2RhdGFfXyA9IHsKICAgICdoYXNoJzogbmV3IEhhc2goKSwKICAgICdtYXAnOiBuZXcgKE1hcCQxIHx8IExpc3RDYWNoZSkoKSwKICAgICdzdHJpbmcnOiBuZXcgSGFzaCgpCiAgfTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciB1c2UgYXMgdW5pcXVlIG9iamVjdCBrZXkuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7CiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgcmV0dXJuIHR5cGUgPT0gJ3N0cmluZycgfHwgdHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nID8gdmFsdWUgIT09ICdfX3Byb3RvX18nIDogdmFsdWUgPT09IG51bGw7Cn0KCi8qKgogKiBHZXRzIHRoZSBkYXRhIGZvciBgbWFwYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIHF1ZXJ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSByZWZlcmVuY2Uga2V5LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWFwIGRhdGEuCiAqLwpmdW5jdGlvbiBnZXRNYXBEYXRhKG1hcCwga2V5KSB7CiAgdmFyIGRhdGEgPSBtYXAuX19kYXRhX187CiAgcmV0dXJuIGlzS2V5YWJsZShrZXkpID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddIDogZGF0YS5tYXA7Cn0KCi8qKgogKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgbWFwLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIE1hcENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZURlbGV0ZShrZXkpIHsKICB2YXIgcmVzdWx0ID0gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpWydkZWxldGUnXShrZXkpOwogIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogR2V0cyB0aGUgbWFwIHZhbHVlIGZvciBga2V5YC4KICoKICogQHByaXZhdGUKICogQG5hbWUgZ2V0CiAqIEBtZW1iZXJPZiBNYXBDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLgogKi8KZnVuY3Rpb24gbWFwQ2FjaGVHZXQoa2V5KSB7CiAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5nZXQoa2V5KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIG1hcCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBoYXMKICogQG1lbWJlck9mIE1hcENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHsKICByZXR1cm4gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLmhhcyhrZXkpOwp9CgovKioKICogU2V0cyB0aGUgbWFwIGBrZXlgIHRvIGB2YWx1ZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIHNldAogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbWFwIGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gbWFwQ2FjaGVTZXQoa2V5LCB2YWx1ZSkgewogIHZhciBkYXRhID0gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLAogICAgc2l6ZSA9IGRhdGEuc2l6ZTsKICBkYXRhLnNldChrZXksIHZhbHVlKTsKICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYSBtYXAgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gTWFwQ2FjaGUoZW50cmllcykgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoOwogIHRoaXMuY2xlYXIoKTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07CiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pOwogIH0KfQoKLy8gQWRkIG1ldGhvZHMgdG8gYE1hcENhY2hlYC4KTWFwQ2FjaGUucHJvdG90eXBlLmNsZWFyID0gbWFwQ2FjaGVDbGVhcjsKTWFwQ2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IG1hcENhY2hlRGVsZXRlOwpNYXBDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbWFwQ2FjaGVHZXQ7Ck1hcENhY2hlLnByb3RvdHlwZS5oYXMgPSBtYXBDYWNoZUhhczsKTWFwQ2FjaGUucHJvdG90eXBlLnNldCA9IG1hcENhY2hlU2V0OwoKLyoqIEVycm9yIG1lc3NhZ2UgY29uc3RhbnRzLiAqLwp2YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nOwoKLyoqCiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IG1lbW9pemVzIHRoZSByZXN1bHQgb2YgYGZ1bmNgLiBJZiBgcmVzb2x2ZXJgIGlzCiAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGUKICogYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBtZW1vaXplZCBmdW5jdGlvbi4gQnkgZGVmYXVsdCwgdGhlIGZpcnN0IGFyZ3VtZW50CiAqIHByb3ZpZGVkIHRvIHRoZSBtZW1vaXplZCBmdW5jdGlvbiBpcyB1c2VkIGFzIHRoZSBtYXAgY2FjaGUga2V5LiBUaGUgYGZ1bmNgCiAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLgogKgogKiAqKk5vdGU6KiogVGhlIGNhY2hlIGlzIGV4cG9zZWQgYXMgdGhlIGBjYWNoZWAgcHJvcGVydHkgb24gdGhlIG1lbW9pemVkCiAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYAogKiBjb25zdHJ1Y3RvciB3aXRoIG9uZSB3aG9zZSBpbnN0YW5jZXMgaW1wbGVtZW50IHRoZQogKiBbYE1hcGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXByb3BlcnRpZXMtb2YtdGhlLW1hcC1wcm90b3R5cGUtb2JqZWN0KQogKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IEZ1bmN0aW9uCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC4KICogQHBhcmFtIHtGdW5jdGlvbn0gW3Jlc29sdmVyXSBUaGUgZnVuY3Rpb24gdG8gcmVzb2x2ZSB0aGUgY2FjaGUga2V5LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIgfTsKICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9OwogKgogKiB2YXIgdmFsdWVzID0gXy5tZW1vaXplKF8udmFsdWVzKTsKICogdmFsdWVzKG9iamVjdCk7CiAqIC8vID0+IFsxLCAyXQogKgogKiB2YWx1ZXMob3RoZXIpOwogKiAvLyA9PiBbMywgNF0KICoKICogb2JqZWN0LmEgPSAyOwogKiB2YWx1ZXMob2JqZWN0KTsKICogLy8gPT4gWzEsIDJdCiAqCiAqIC8vIE1vZGlmeSB0aGUgcmVzdWx0IGNhY2hlLgogKiB2YWx1ZXMuY2FjaGUuc2V0KG9iamVjdCwgWydhJywgJ2InXSk7CiAqIHZhbHVlcyhvYmplY3QpOwogKiAvLyA9PiBbJ2EnLCAnYiddCiAqCiAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuCiAqIF8ubWVtb2l6ZS5DYWNoZSA9IFdlYWtNYXA7CiAqLwpmdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7CiAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicgfHwgcmVzb2x2ZXIgIT0gbnVsbCAmJiB0eXBlb2YgcmVzb2x2ZXIgIT0gJ2Z1bmN0aW9uJykgewogICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpOwogIH0KICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbiAoKSB7CiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cywKICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sCiAgICAgIGNhY2hlID0gbWVtb2l6ZWQuY2FjaGU7CiAgICBpZiAoY2FjaGUuaGFzKGtleSkpIHsKICAgICAgcmV0dXJuIGNhY2hlLmdldChrZXkpOwogICAgfQogICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7CiAgICBtZW1vaXplZC5jYWNoZSA9IGNhY2hlLnNldChrZXksIHJlc3VsdCkgfHwgY2FjaGU7CiAgICByZXR1cm4gcmVzdWx0OwogIH07CiAgbWVtb2l6ZWQuY2FjaGUgPSBuZXcgKG1lbW9pemUuQ2FjaGUgfHwgTWFwQ2FjaGUpKCk7CiAgcmV0dXJuIG1lbW9pemVkOwp9CgovLyBFeHBvc2UgYE1hcENhY2hlYC4KbWVtb2l6ZS5DYWNoZSA9IE1hcENhY2hlOwoKLyoqIFVzZWQgYXMgdGhlIG1heGltdW0gbWVtb2l6ZSBjYWNoZSBzaXplLiAqLwp2YXIgTUFYX01FTU9JWkVfU0laRSA9IDUwMDsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWVtb2l6ZWAgd2hpY2ggY2xlYXJzIHRoZSBtZW1vaXplZCBmdW5jdGlvbidzCiAqIGNhY2hlIHdoZW4gaXQgZXhjZWVkcyBgTUFYX01FTU9JWkVfU0laRWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBtZW1vaXplQ2FwcGVkKGZ1bmMpIHsKICB2YXIgcmVzdWx0ID0gbWVtb2l6ZShmdW5jLCBmdW5jdGlvbiAoa2V5KSB7CiAgICBpZiAoY2FjaGUuc2l6ZSA9PT0gTUFYX01FTU9JWkVfU0laRSkgewogICAgICBjYWNoZS5jbGVhcigpOwogICAgfQogICAgcmV0dXJuIGtleTsKICB9KTsKICB2YXIgY2FjaGUgPSByZXN1bHQuY2FjaGU7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqLwp2YXIgcmVQcm9wTmFtZSA9IC9bXi5bXF1dK3xcWyg/OigtP1xkKyg/OlwuXGQrKT8pfChbIiddKSgoPzooPyFcMilbXlxcXXxcXC4pKj8pXDIpXF18KD89KD86XC58XFtcXSkoPzpcLnxcW1xdfCQpKS9nOwoKLyoqIFVzZWQgdG8gbWF0Y2ggYmFja3NsYXNoZXMgaW4gcHJvcGVydHkgcGF0aHMuICovCnZhciByZUVzY2FwZUNoYXIgPSAvXFwoXFwpPy9nOwoKLyoqCiAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcHJvcGVydHkgcGF0aCBhcnJheS4KICovCnZhciBzdHJpbmdUb1BhdGggPSBtZW1vaXplQ2FwcGVkKGZ1bmN0aW9uIChzdHJpbmcpIHsKICB2YXIgcmVzdWx0ID0gW107CiAgaWYgKHN0cmluZy5jaGFyQ29kZUF0KDApID09PSA0NiAvKiAuICovKSB7CiAgICByZXN1bHQucHVzaCgnJyk7CiAgfQogIHN0cmluZy5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7CiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN1YlN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2gpOwogIH0pOwogIHJldHVybiByZXN1bHQ7Cn0pOwp2YXIgc3RyaW5nVG9QYXRoJDEgPSBzdHJpbmdUb1BhdGg7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlCiAqIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LgogKi8KZnVuY3Rpb24gYXJyYXlNYXAoYXJyYXksIGl0ZXJhdGVlKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCwKICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSk7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgSU5GSU5JVFkkMiA9IDEgLyAwOwoKLyoqIFVzZWQgdG8gY29udmVydCBzeW1ib2xzIHRvIHByaW1pdGl2ZXMgYW5kIHN0cmluZ3MuICovCnZhciBzeW1ib2xQcm90byQxID0gU3ltYm9sJDEgPyBTeW1ib2wkMS5wcm90b3R5cGUgOiB1bmRlZmluZWQsCiAgc3ltYm9sVG9TdHJpbmcgPSBzeW1ib2xQcm90byQxID8gc3ltYm9sUHJvdG8kMS50b1N0cmluZyA6IHVuZGVmaW5lZDsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b1N0cmluZ2Agd2hpY2ggZG9lc24ndCBjb252ZXJ0IG51bGxpc2gKICogdmFsdWVzIHRvIGVtcHR5IHN0cmluZ3MuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy4KICovCmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkgewogIC8vIEV4aXQgZWFybHkgZm9yIHN0cmluZ3MgdG8gYXZvaWQgYSBwZXJmb3JtYW5jZSBoaXQgaW4gc29tZSBlbnZpcm9ubWVudHMuCiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICBpZiAoaXNBcnJheSQxKHZhbHVlKSkgewogICAgLy8gUmVjdXJzaXZlbHkgY29udmVydCB2YWx1ZXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS4KICAgIHJldHVybiBhcnJheU1hcCh2YWx1ZSwgYmFzZVRvU3RyaW5nKSArICcnOwogIH0KICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7CiAgICByZXR1cm4gc3ltYm9sVG9TdHJpbmcgPyBzeW1ib2xUb1N0cmluZy5jYWxsKHZhbHVlKSA6ICcnOwogIH0KICB2YXIgcmVzdWx0ID0gdmFsdWUgKyAnJzsKICByZXR1cm4gcmVzdWx0ID09ICcwJyAmJiAxIC8gdmFsdWUgPT0gLUlORklOSVRZJDIgPyAnLTAnIDogcmVzdWx0Owp9CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZy4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkIGZvciBgbnVsbGAKICogYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuCiAqIEBleGFtcGxlCiAqCiAqIF8udG9TdHJpbmcobnVsbCk7CiAqIC8vID0+ICcnCiAqCiAqIF8udG9TdHJpbmcoLTApOwogKiAvLyA9PiAnLTAnCiAqCiAqIF8udG9TdHJpbmcoWzEsIDIsIDNdKTsKICogLy8gPT4gJzEsMiwzJwogKi8KZnVuY3Rpb24gdG9TdHJpbmcodmFsdWUpIHsKICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogYmFzZVRvU3RyaW5nKHZhbHVlKTsKfQoKLyoqCiAqIENhc3RzIGB2YWx1ZWAgdG8gYSBwYXRoIGFycmF5IGlmIGl0J3Mgbm90IG9uZS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC4KICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjYXN0IHByb3BlcnR5IHBhdGggYXJyYXkuCiAqLwpmdW5jdGlvbiBjYXN0UGF0aCh2YWx1ZSwgb2JqZWN0KSB7CiAgaWYgKGlzQXJyYXkkMSh2YWx1ZSkpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CiAgcmV0dXJuIGlzS2V5KHZhbHVlLCBvYmplY3QpID8gW3ZhbHVlXSA6IHN0cmluZ1RvUGF0aCQxKHRvU3RyaW5nKHZhbHVlKSk7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgSU5GSU5JVFkkMSA9IDEgLyAwOwoKLyoqCiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzdHJpbmcga2V5IGlmIGl0J3Mgbm90IGEgc3RyaW5nIG9yIHN5bWJvbC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC4KICogQHJldHVybnMge3N0cmluZ3xzeW1ib2x9IFJldHVybnMgdGhlIGtleS4KICovCmZ1bmN0aW9uIHRvS2V5KHZhbHVlKSB7CiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCBpc1N5bWJvbCh2YWx1ZSkpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CiAgdmFyIHJlc3VsdCA9IHZhbHVlICsgJyc7CiAgcmV0dXJuIHJlc3VsdCA9PSAnMCcgJiYgMSAvIHZhbHVlID09IC1JTkZJTklUWSQxID8gJy0wJyA6IHJlc3VsdDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWZhdWx0IHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuCiAqLwpmdW5jdGlvbiBiYXNlR2V0KG9iamVjdCwgcGF0aCkgewogIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpOwogIHZhciBpbmRleCA9IDAsCiAgICBsZW5ndGggPSBwYXRoLmxlbmd0aDsKICB3aGlsZSAob2JqZWN0ICE9IG51bGwgJiYgaW5kZXggPCBsZW5ndGgpIHsKICAgIG9iamVjdCA9IG9iamVjdFt0b0tleShwYXRoW2luZGV4KytdKV07CiAgfQogIHJldHVybiBpbmRleCAmJiBpbmRleCA9PSBsZW5ndGggPyBvYmplY3QgOiB1bmRlZmluZWQ7Cn0KCi8qKgogKiBHZXRzIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuIElmIHRoZSByZXNvbHZlZCB2YWx1ZSBpcwogKiBgdW5kZWZpbmVkYCwgdGhlIGBkZWZhdWx0VmFsdWVgIGlzIHJldHVybmVkIGluIGl0cyBwbGFjZS4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMy43LjAKICogQGNhdGVnb3J5IE9iamVjdAogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfV0gfTsKICoKICogXy5nZXQob2JqZWN0LCAnYVswXS5iLmMnKTsKICogLy8gPT4gMwogKgogKiBfLmdldChvYmplY3QsIFsnYScsICcwJywgJ2InLCAnYyddKTsKICogLy8gPT4gMwogKgogKiBfLmdldChvYmplY3QsICdhLmIuYycsICdkZWZhdWx0Jyk7CiAqIC8vID0+ICdkZWZhdWx0JwogKi8KZnVuY3Rpb24gZ2V0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7CiAgdmFyIHJlc3VsdCA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogYmFzZUdldChvYmplY3QsIHBhdGgpOwogIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWx1ZSA6IHJlc3VsdDsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgYm9vbFRhZyQyID0gJ1tvYmplY3QgQm9vbGVhbl0nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBib29sZWFuIHByaW1pdGl2ZSBvciBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJvb2xlYW4sIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0Jvb2xlYW4oZmFsc2UpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNCb29sZWFuKG51bGwpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNCb29sZWFuKHZhbHVlKSB7CiAgcmV0dXJuIHZhbHVlID09PSB0cnVlIHx8IHZhbHVlID09PSBmYWxzZSB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGJvb2xUYWckMjsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrpib29sZWFuDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNib2wudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzYm9sKGZhbHNlKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNib2wodikgewogIHJldHVybiBpc0Jvb2xlYW4odik7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65a2X5LiyDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNzdHIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyKDApKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc3N0cignMCcpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyKCcnKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNzdHIodikgewogIGxldCBjID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpOwogIHJldHVybiBjID09PSAnW29iamVjdCBTdHJpbmddJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrmnInmlYjlrZfkuLINCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2VzdHIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXN0cignMS4yNScpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXN0cigxMjUpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VzdHIoJycpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKi8KZnVuY3Rpb24gaXNlc3RyKHYpIHsKICAvL2NoZWNrCiAgaWYgKGlzc3RyKHYpKSB7CiAgICBpZiAodiAhPT0gJycpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IKICogaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC4KICovCmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkgewogICAgICBicmVhazsKICAgIH0KICB9CiAgcmV0dXJuIGFycmF5Owp9CgovKioKICogQ3JlYXRlcyBhIGJhc2UgZnVuY3Rpb24gZm9yIG1ldGhvZHMgbGlrZSBgXy5mb3JJbmAgYW5kIGBfLmZvck93bmAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gY3JlYXRlQmFzZUZvcihmcm9tUmlnaHQpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwgaXRlcmF0ZWUsIGtleXNGdW5jKSB7CiAgICB2YXIgaW5kZXggPSAtMSwKICAgICAgaXRlcmFibGUgPSBPYmplY3Qob2JqZWN0KSwKICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLAogICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7CiAgICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgICAgdmFyIGtleSA9IHByb3BzW2Zyb21SaWdodCA/IGxlbmd0aCA6ICsraW5kZXhdOwogICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBvYmplY3Q7CiAgfTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlcyBvdmVyIGBvYmplY3RgCiAqIHByb3BlcnRpZXMgcmV0dXJuZWQgYnkgYGtleXNGdW5jYCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIHByb3BlcnR5LgogKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuCiAqLwp2YXIgYmFzZUZvciA9IGNyZWF0ZUJhc2VGb3IoKTsKdmFyIGJhc2VGb3IkMSA9IGJhc2VGb3I7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udGltZXNgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcwogKiBvciBtYXggYXJyYXkgbGVuZ3RoIGNoZWNrcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byBpbnZva2UgYGl0ZXJhdGVlYC4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLgogKi8KZnVuY3Rpb24gYmFzZVRpbWVzKG4sIGl0ZXJhdGVlKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSBBcnJheShuKTsKICB3aGlsZSAoKytpbmRleCA8IG4pIHsKICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShpbmRleCk7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGFyZ3NUYWckMiA9ICdbb2JqZWN0IEFyZ3VtZW50c10nOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzQXJndW1lbnRzYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCwKICovCmZ1bmN0aW9uIGJhc2VJc0FyZ3VtZW50cyh2YWx1ZSkgewogIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGFyZ3NUYWckMjsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNiA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDQgPSBvYmplY3RQcm90byQ2Lmhhc093blByb3BlcnR5OwoKLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovCnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSQxID0gb2JqZWN0UHJvdG8kNi5wcm9wZXJ0eUlzRW51bWVyYWJsZTsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LAogKiAgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc0FyZ3VtZW50cyA9IGJhc2VJc0FyZ3VtZW50cyhmdW5jdGlvbiAoKSB7CiAgcmV0dXJuIGFyZ3VtZW50czsKfSgpKSA/IGJhc2VJc0FyZ3VtZW50cyA6IGZ1bmN0aW9uICh2YWx1ZSkgewogIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGhhc093blByb3BlcnR5JDQuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmICFwcm9wZXJ0eUlzRW51bWVyYWJsZSQxLmNhbGwodmFsdWUsICdjYWxsZWUnKTsKfTsKdmFyIGlzQXJndW1lbnRzJDEgPSBpc0FyZ3VtZW50czsKCi8qKgogKiBUaGlzIG1ldGhvZCByZXR1cm5zIGBmYWxzZWAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMTMuMAogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLnRpbWVzKDIsIF8uc3R1YkZhbHNlKTsKICogLy8gPT4gW2ZhbHNlLCBmYWxzZV0KICovCmZ1bmN0aW9uIHN0dWJGYWxzZSgpIHsKICByZXR1cm4gZmFsc2U7Cn0KCi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovCnZhciBmcmVlRXhwb3J0cyQxID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzOwoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqLwp2YXIgZnJlZU1vZHVsZSQxID0gZnJlZUV4cG9ydHMkMSAmJiB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTsKCi8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovCnZhciBtb2R1bGVFeHBvcnRzJDEgPSBmcmVlTW9kdWxlJDEgJiYgZnJlZU1vZHVsZSQxLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzJDE7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIEJ1ZmZlciA9IG1vZHVsZUV4cG9ydHMkMSA/IHJvb3QkMS5CdWZmZXIgOiB1bmRlZmluZWQ7CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovCnZhciBuYXRpdmVJc0J1ZmZlciA9IEJ1ZmZlciA/IEJ1ZmZlci5pc0J1ZmZlciA6IHVuZGVmaW5lZDsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGJ1ZmZlci4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4zLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNCdWZmZXIobmV3IEJ1ZmZlcigyKSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0J1ZmZlcihuZXcgVWludDhBcnJheSgyKSk7CiAqIC8vID0+IGZhbHNlCiAqLwp2YXIgaXNCdWZmZXIgPSBuYXRpdmVJc0J1ZmZlciB8fCBzdHViRmFsc2U7CnZhciBpc0J1ZmZlciQxID0gaXNCdWZmZXI7CgovKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi8KdmFyIE1BWF9TQUZFX0lOVEVHRVIkMSA9IDkwMDcxOTkyNTQ3NDA5OTE7CgovKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovCnZhciByZUlzVWludCA9IC9eKD86MHxbMS05XVxkKikkLzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgaW5kZXgsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkgewogIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlOwogIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiQxIDogbGVuZ3RoOwogIHJldHVybiAhIWxlbmd0aCAmJiAodHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlICE9ICdzeW1ib2wnICYmIHJlSXNVaW50LnRlc3QodmFsdWUpKSAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoOwp9CgovKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi8KdmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguCiAqCiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uCiAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzTGVuZ3RoKDMpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNMZW5ndGgoSW5maW5pdHkpOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzTGVuZ3RoKCczJyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8PSBNQVhfU0FGRV9JTlRFR0VSOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBhcmdzVGFnJDEgPSAnW29iamVjdCBBcmd1bWVudHNdJywKICBhcnJheVRhZyQxID0gJ1tvYmplY3QgQXJyYXldJywKICBib29sVGFnJDEgPSAnW29iamVjdCBCb29sZWFuXScsCiAgZGF0ZVRhZyQxID0gJ1tvYmplY3QgRGF0ZV0nLAogIGVycm9yVGFnJDEgPSAnW29iamVjdCBFcnJvcl0nLAogIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLAogIG1hcFRhZyQzID0gJ1tvYmplY3QgTWFwXScsCiAgbnVtYmVyVGFnJDIgPSAnW29iamVjdCBOdW1iZXJdJywKICBvYmplY3RUYWckMiA9ICdbb2JqZWN0IE9iamVjdF0nLAogIHJlZ2V4cFRhZyQxID0gJ1tvYmplY3QgUmVnRXhwXScsCiAgc2V0VGFnJDMgPSAnW29iamVjdCBTZXRdJywKICBzdHJpbmdUYWckMiA9ICdbb2JqZWN0IFN0cmluZ10nLAogIHdlYWtNYXBUYWckMSA9ICdbb2JqZWN0IFdlYWtNYXBdJzsKdmFyIGFycmF5QnVmZmVyVGFnJDEgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLAogIGRhdGFWaWV3VGFnJDIgPSAnW29iamVjdCBEYXRhVmlld10nLAogIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJywKICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsCiAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLAogIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLAogIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLAogIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLAogIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsCiAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJywKICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nOwoKLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqLwp2YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTsKdHlwZWRBcnJheVRhZ3NbZmxvYXQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1tmbG9hdDY0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQxNlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTsKdHlwZWRBcnJheVRhZ3NbYXJnc1RhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW2FycmF5VGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tib29sVGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWckMl0gPSB0eXBlZEFycmF5VGFnc1tkYXRlVGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tmdW5jVGFnXSA9IHR5cGVkQXJyYXlUYWdzW21hcFRhZyQzXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW29iamVjdFRhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW3NldFRhZyQzXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW3dlYWtNYXBUYWckMV0gPSBmYWxzZTsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkgewogIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bmFyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBzdG9yaW5nIG1ldGFkYXRhLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gYmFzZVVuYXJ5KGZ1bmMpIHsKICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICByZXR1cm4gZnVuYyh2YWx1ZSk7CiAgfTsKfQoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi8KdmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzOwoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqLwp2YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlOwoKLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi8KdmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHByb2Nlc3NgIGZyb20gTm9kZS5qcy4gKi8KdmFyIGZyZWVQcm9jZXNzID0gbW9kdWxlRXhwb3J0cyAmJiBmcmVlR2xvYmFsJDEucHJvY2VzczsKCi8qKiBVc2VkIHRvIGFjY2VzcyBmYXN0ZXIgTm9kZS5qcyBoZWxwZXJzLiAqLwp2YXIgbm9kZVV0aWwgPSBmdW5jdGlvbiAoKSB7CiAgdHJ5IHsKICAgIC8vIFVzZSBgdXRpbC50eXBlc2AgZm9yIE5vZGUuanMgMTArLgogICAgdmFyIHR5cGVzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlKCd1dGlsJykudHlwZXM7CiAgICBpZiAodHlwZXMpIHsKICAgICAgcmV0dXJuIHR5cGVzOwogICAgfQoKICAgIC8vIExlZ2FjeSBgcHJvY2Vzcy5iaW5kaW5nKCd1dGlsJylgIGZvciBOb2RlLmpzIDwgMTAuCiAgICByZXR1cm4gZnJlZVByb2Nlc3MgJiYgZnJlZVByb2Nlc3MuYmluZGluZyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nKCd1dGlsJyk7CiAgfSBjYXRjaCAoZSkge30KfSgpOwp2YXIgbm9kZVV0aWwkMSA9IG5vZGVVdGlsOwoKLyogTm9kZS5qcyBoZWxwZXIgcmVmZXJlbmNlcy4gKi8KdmFyIG5vZGVJc1R5cGVkQXJyYXkgPSBub2RlVXRpbCQxICYmIG5vZGVVdGlsJDEuaXNUeXBlZEFycmF5OwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSB0eXBlZCBhcnJheS4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMy4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc1R5cGVkQXJyYXkobmV3IFVpbnQ4QXJyYXkpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNUeXBlZEFycmF5KFtdKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc1R5cGVkQXJyYXkgPSBub2RlSXNUeXBlZEFycmF5ID8gYmFzZVVuYXJ5KG5vZGVJc1R5cGVkQXJyYXkpIDogYmFzZUlzVHlwZWRBcnJheTsKdmFyIGlzVHlwZWRBcnJheSQxID0gaXNUeXBlZEFycmF5OwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNSA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDMgPSBvYmplY3RQcm90byQ1Lmhhc093blByb3BlcnR5OwoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5oZXJpdGVkIFNwZWNpZnkgcmV0dXJuaW5nIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lcy4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy4KICovCmZ1bmN0aW9uIGFycmF5TGlrZUtleXModmFsdWUsIGluaGVyaXRlZCkgewogIHZhciBpc0FyciA9IGlzQXJyYXkkMSh2YWx1ZSksCiAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyQxKHZhbHVlKSwKICAgIGlzQnVmZiA9ICFpc0FyciAmJiAhaXNBcmcgJiYgaXNCdWZmZXIkMSh2YWx1ZSksCiAgICBpc1R5cGUgPSAhaXNBcnIgJiYgIWlzQXJnICYmICFpc0J1ZmYgJiYgaXNUeXBlZEFycmF5JDEodmFsdWUpLAogICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLAogICAgcmVzdWx0ID0gc2tpcEluZGV4ZXMgPyBiYXNlVGltZXModmFsdWUubGVuZ3RoLCBTdHJpbmcpIDogW10sCiAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoOwogIGZvciAodmFyIGtleSBpbiB2YWx1ZSkgewogICAgaWYgKChpbmhlcml0ZWQgfHwgaGFzT3duUHJvcGVydHkkMy5jYWxsKHZhbHVlLCBrZXkpKSAmJiAhKHNraXBJbmRleGVzICYmICgKICAgIC8vIFNhZmFyaSA5IGhhcyBlbnVtZXJhYmxlIGBhcmd1bWVudHMubGVuZ3RoYCBpbiBzdHJpY3QgbW9kZS4KICAgIGtleSA9PSAnbGVuZ3RoJyB8fAogICAgLy8gTm9kZS5qcyAwLjEwIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIGJ1ZmZlcnMuCiAgICBpc0J1ZmYgJiYgKGtleSA9PSAnb2Zmc2V0JyB8fCBrZXkgPT0gJ3BhcmVudCcpIHx8CiAgICAvLyBQaGFudG9tSlMgMiBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiB0eXBlZCBhcnJheXMuCiAgICBpc1R5cGUgJiYgKGtleSA9PSAnYnVmZmVyJyB8fCBrZXkgPT0gJ2J5dGVMZW5ndGgnIHx8IGtleSA9PSAnYnl0ZU9mZnNldCcpIHx8CiAgICAvLyBTa2lwIGluZGV4IHByb3BlcnRpZXMuCiAgICBpc0luZGV4KGtleSwgbGVuZ3RoKSkpKSB7CiAgICAgIHJlc3VsdC5wdXNoKGtleSk7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDQgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxpa2VseSBhIHByb3RvdHlwZSBvYmplY3QuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNQcm90b3R5cGUodmFsdWUpIHsKICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLAogICAgcHJvdG8gPSB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlIHx8IG9iamVjdFByb3RvJDQ7CiAgcmV0dXJuIHZhbHVlID09PSBwcm90bzsKfQoKLyoqCiAqIENyZWF0ZXMgYSB1bmFyeSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50IHRyYW5zZm9ybWVkLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIGFyZ3VtZW50IHRyYW5zZm9ybS4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkgewogIHJldHVybiBmdW5jdGlvbiAoYXJnKSB7CiAgICByZXR1cm4gZnVuYyh0cmFuc2Zvcm0oYXJnKSk7CiAgfTsKfQoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqLwp2YXIgbmF0aXZlS2V5cyA9IG92ZXJBcmcoT2JqZWN0LmtleXMsIE9iamVjdCk7CnZhciBuYXRpdmVLZXlzJDEgPSBuYXRpdmVLZXlzOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kMyA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDIgPSBvYmplY3RQcm90byQzLmhhc093blByb3BlcnR5OwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmtleXNgIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLgogKi8KZnVuY3Rpb24gYmFzZUtleXMob2JqZWN0KSB7CiAgaWYgKCFpc1Byb3RvdHlwZShvYmplY3QpKSB7CiAgICByZXR1cm4gbmF0aXZlS2V5cyQxKG9iamVjdCk7CiAgfQogIHZhciByZXN1bHQgPSBbXTsKICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHsKICAgIGlmIChoYXNPd25Qcm9wZXJ0eSQyLmNhbGwob2JqZWN0LCBrZXkpICYmIGtleSAhPSAnY29uc3RydWN0b3InKSB7CiAgICAgIHJlc3VsdC5wdXNoKGtleSk7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgYXJyYXktbGlrZSBpZiBpdCdzCiAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3IKICogZXF1YWwgdG8gYDBgIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYE51bWJlci5NQVhfU0FGRV9JTlRFR0VSYC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0FycmF5TGlrZShbMSwgMiwgM10pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNBcnJheUxpa2UoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5TGlrZSgnYWJjJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5TGlrZShfLm5vb3ApOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHsKICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLgogKgogKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZQogKiBbRVMgc3BlY10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LmtleXMpCiAqIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIEBzdGF0aWMKICogQHNpbmNlIDAuMS4wCiAqIEBtZW1iZXJPZiBfCiAqIEBjYXRlZ29yeSBPYmplY3QKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLgogKiBAZXhhbXBsZQogKgogKiBmdW5jdGlvbiBGb28oKSB7CiAqICAgdGhpcy5hID0gMTsKICogICB0aGlzLmIgPSAyOwogKiB9CiAqCiAqIEZvby5wcm90b3R5cGUuYyA9IDM7CiAqCiAqIF8ua2V5cyhuZXcgRm9vKTsKICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKQogKgogKiBfLmtleXMoJ2hpJyk7CiAqIC8vID0+IFsnMCcsICcxJ10KICovCmZ1bmN0aW9uIGtleXMob2JqZWN0KSB7CiAgcmV0dXJuIGlzQXJyYXlMaWtlKG9iamVjdCkgPyBhcnJheUxpa2VLZXlzKG9iamVjdCkgOiBiYXNlS2V5cyhvYmplY3QpOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuCiAqLwpmdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHsKICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3IkMShvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTsKfQoKLyoqCiAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gY3JlYXRlQmFzZUVhY2goZWFjaEZ1bmMsIGZyb21SaWdodCkgewogIHJldHVybiBmdW5jdGlvbiAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHsKICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHsKICAgICAgcmV0dXJuIGNvbGxlY3Rpb247CiAgICB9CiAgICBpZiAoIWlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7CiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7CiAgICB9CiAgICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGgsCiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTEsCiAgICAgIGl0ZXJhYmxlID0gT2JqZWN0KGNvbGxlY3Rpb24pOwogICAgd2hpbGUgKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSB7CiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBjb2xsZWN0aW9uOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuCiAqLwp2YXIgYmFzZUVhY2ggPSBjcmVhdGVCYXNlRWFjaChiYXNlRm9yT3duKTsKdmFyIGJhc2VFYWNoJDEgPSBiYXNlRWFjaDsKCi8qKgogKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBpdCByZWNlaXZlcy4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IFV0aWwKICogQHBhcmFtIHsqfSB2YWx1ZSBBbnkgdmFsdWUuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9OwogKgogKiBjb25zb2xlLmxvZyhfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdCk7CiAqIC8vID0+IHRydWUKICovCmZ1bmN0aW9uIGlkZW50aXR5JDEodmFsdWUpIHsKICByZXR1cm4gdmFsdWU7Cn0KCi8qKgogKiBDYXN0cyBgdmFsdWVgIHRvIGBpZGVudGl0eWAgaWYgaXQncyBub3QgYSBmdW5jdGlvbi4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGNhc3QgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBjYXN0RnVuY3Rpb24odmFsdWUpIHsKICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IGlkZW50aXR5JDE7Cn0KCi8qKgogKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIGVsZW1lbnQuCiAqIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuCiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC4KICoKICogKipOb3RlOioqIEFzIHdpdGggb3RoZXIgIkNvbGxlY3Rpb25zIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSAibGVuZ3RoIgogKiBwcm9wZXJ0eSBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgdXNlIGBfLmZvckluYAogKiBvciBgXy5mb3JPd25gIGZvciBvYmplY3QgaXRlcmF0aW9uLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAYWxpYXMgZWFjaAogKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbgogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC4KICogQHNlZSBfLmZvckVhY2hSaWdodAogKiBAZXhhbXBsZQogKgogKiBfLmZvckVhY2goWzEsIDJdLCBmdW5jdGlvbih2YWx1ZSkgewogKiAgIGNvbnNvbGUubG9nKHZhbHVlKTsKICogfSk7CiAqIC8vID0+IExvZ3MgYDFgIHRoZW4gYDJgLgogKgogKiBfLmZvckVhY2goeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7CiAqICAgY29uc29sZS5sb2coa2V5KTsKICogfSk7CiAqIC8vID0+IExvZ3MgJ2EnIHRoZW4gJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLgogKi8KZnVuY3Rpb24gZm9yRWFjaChjb2xsZWN0aW9uLCBpdGVyYXRlZSkgewogIHZhciBmdW5jID0gaXNBcnJheSQxKGNvbGxlY3Rpb24pID8gYXJyYXlFYWNoIDogYmFzZUVhY2gkMTsKICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBjYXN0RnVuY3Rpb24oaXRlcmF0ZWUpKTsKfQoKLyoqCiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIHN0YWNrLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBjbGVhcgogKiBAbWVtYmVyT2YgU3RhY2sKICovCmZ1bmN0aW9uIHN0YWNrQ2xlYXIoKSB7CiAgdGhpcy5fX2RhdGFfXyA9IG5ldyBMaXN0Q2FjaGUoKTsKICB0aGlzLnNpemUgPSAwOwp9CgovKioKICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIHN0YWNrLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIFN0YWNrCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBzdGFja0RlbGV0ZShrZXkpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sCiAgICByZXN1bHQgPSBkYXRhWydkZWxldGUnXShrZXkpOwogIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogR2V0cyB0aGUgc3RhY2sgdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIFN0YWNrCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuCiAqLwpmdW5jdGlvbiBzdGFja0dldChrZXkpIHsKICByZXR1cm4gdGhpcy5fX2RhdGFfXy5nZXQoa2V5KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIHN0YWNrIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGhhcwogKiBAbWVtYmVyT2YgU3RhY2sKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIHN0YWNrSGFzKGtleSkgewogIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyhrZXkpOwp9CgovKiogVXNlZCBhcyB0aGUgc2l6ZSB0byBlbmFibGUgbGFyZ2UgYXJyYXkgb3B0aW1pemF0aW9ucy4gKi8KdmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7CgovKioKICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBTdGFjawogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBzdGFjayBjYWNoZSBpbnN0YW5jZS4KICovCmZ1bmN0aW9uIHN0YWNrU2V0KGtleSwgdmFsdWUpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187CiAgaWYgKGRhdGEgaW5zdGFuY2VvZiBMaXN0Q2FjaGUpIHsKICAgIHZhciBwYWlycyA9IGRhdGEuX19kYXRhX187CiAgICBpZiAoIU1hcCQxIHx8IHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSB7CiAgICAgIHBhaXJzLnB1c2goW2tleSwgdmFsdWVdKTsKICAgICAgdGhpcy5zaXplID0gKytkYXRhLnNpemU7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGUocGFpcnMpOwogIH0KICBkYXRhLnNldChrZXksIHZhbHVlKTsKICB0aGlzLnNpemUgPSBkYXRhLnNpemU7CiAgcmV0dXJuIHRoaXM7Cn0KCi8qKgogKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gU3RhY2soZW50cmllcykgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyA9IG5ldyBMaXN0Q2FjaGUoZW50cmllcyk7CiAgdGhpcy5zaXplID0gZGF0YS5zaXplOwp9CgovLyBBZGQgbWV0aG9kcyB0byBgU3RhY2tgLgpTdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyOwpTdGFjay5wcm90b3R5cGVbJ2RlbGV0ZSddID0gc3RhY2tEZWxldGU7ClN0YWNrLnByb3RvdHlwZS5nZXQgPSBzdGFja0dldDsKU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzOwpTdGFjay5wcm90b3R5cGUuc2V0ID0gc3RhY2tTZXQ7CgovKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovCnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJzsKCi8qKgogKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGFycmF5IGNhY2hlLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBhZGQKICogQG1lbWJlck9mIFNldENhY2hlCiAqIEBhbGlhcyBwdXNoCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNhY2hlLgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjYWNoZSBpbnN0YW5jZS4KICovCmZ1bmN0aW9uIHNldENhY2hlQWRkKHZhbHVlKSB7CiAgdGhpcy5fX2RhdGFfXy5zZXQodmFsdWUsIEhBU0hfVU5ERUZJTkVEKTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGluIHRoZSBhcnJheSBjYWNoZS4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBTZXRDYWNoZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gc2V0Q2FjaGVIYXModmFsdWUpIHsKICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXModmFsdWUpOwp9CgovKioKICoKICogQ3JlYXRlcyBhbiBhcnJheSBjYWNoZSBvYmplY3QgdG8gc3RvcmUgdW5pcXVlIHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBTZXRDYWNoZSh2YWx1ZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IHZhbHVlcyA9PSBudWxsID8gMCA6IHZhbHVlcy5sZW5ndGg7CiAgdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZSgpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB0aGlzLmFkZCh2YWx1ZXNbaW5kZXhdKTsKICB9Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBTZXRDYWNoZWAuClNldENhY2hlLnByb3RvdHlwZS5hZGQgPSBTZXRDYWNoZS5wcm90b3R5cGUucHVzaCA9IHNldENhY2hlQWRkOwpTZXRDYWNoZS5wcm90b3R5cGUuaGFzID0gc2V0Q2FjaGVIYXM7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNvbWVgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZQogKiBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssCiAqICBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBhcnJheVNvbWUoYXJyYXksIHByZWRpY2F0ZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBjYWNoZUhhcyhjYWNoZSwga2V5KSB7CiAgcmV0dXJuIGNhY2hlLmhhcyhrZXkpOwp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDUgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMyA9IDI7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBhcnJheXMgd2l0aCBzdXBwb3J0IGZvcgogKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYXJlLgogKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgYXJyYXlgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBlcXVhbEFycmF5cyhhcnJheSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHsKICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHJDUsCiAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsCiAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7CiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc1BhcnRpYWwgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICAvLyBDaGVjayB0aGF0IGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLgogIHZhciBhcnJTdGFja2VkID0gc3RhY2suZ2V0KGFycmF5KTsKICB2YXIgb3RoU3RhY2tlZCA9IHN0YWNrLmdldChvdGhlcik7CiAgaWYgKGFyclN0YWNrZWQgJiYgb3RoU3RhY2tlZCkgewogICAgcmV0dXJuIGFyclN0YWNrZWQgPT0gb3RoZXIgJiYgb3RoU3RhY2tlZCA9PSBhcnJheTsKICB9CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSB0cnVlLAogICAgc2VlbiA9IGJpdG1hc2sgJiBDT01QQVJFX1VOT1JERVJFRF9GTEFHJDMgPyBuZXcgU2V0Q2FjaGUoKSA6IHVuZGVmaW5lZDsKICBzdGFjay5zZXQoYXJyYXksIG90aGVyKTsKICBzdGFjay5zZXQob3RoZXIsIGFycmF5KTsKCiAgLy8gSWdub3JlIG5vbi1pbmRleCBwcm9wZXJ0aWVzLgogIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7CiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sCiAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdOwogICAgaWYgKGN1c3RvbWl6ZXIpIHsKICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsID8gY3VzdG9taXplcihvdGhWYWx1ZSwgYXJyVmFsdWUsIGluZGV4LCBvdGhlciwgYXJyYXksIHN0YWNrKSA6IGN1c3RvbWl6ZXIoYXJyVmFsdWUsIG90aFZhbHVlLCBpbmRleCwgYXJyYXksIG90aGVyLCBzdGFjayk7CiAgICB9CiAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkgewogICAgICBpZiAoY29tcGFyZWQpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgYnJlYWs7CiAgICB9CiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLgogICAgaWYgKHNlZW4pIHsKICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uIChvdGhWYWx1ZSwgb3RoSW5kZXgpIHsKICAgICAgICBpZiAoIWNhY2hlSGFzKHNlZW4sIG90aEluZGV4KSAmJiAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHsKICAgICAgICAgIHJldHVybiBzZWVuLnB1c2gob3RoSW5kZXgpOwogICAgICAgIH0KICAgICAgfSkpIHsKICAgICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfSBlbHNlIGlmICghKGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykpKSB7CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICB9CiAgc3RhY2tbJ2RlbGV0ZSddKGFycmF5KTsKICBzdGFja1snZGVsZXRlJ10ob3RoZXIpOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgVWludDhBcnJheSA9IHJvb3QkMS5VaW50OEFycmF5Owp2YXIgVWludDhBcnJheSQxID0gVWludDhBcnJheTsKCi8qKgogKiBDb252ZXJ0cyBgbWFwYCB0byBpdHMga2V5LXZhbHVlIHBhaXJzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gbWFwIFRoZSBtYXAgdG8gY29udmVydC4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuCiAqLwpmdW5jdGlvbiBtYXBUb0FycmF5KG1hcCkgewogIHZhciBpbmRleCA9IC0xLAogICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpOwogIG1hcC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7CiAgICByZXN1bHRbKytpbmRleF0gPSBba2V5LCB2YWx1ZV07CiAgfSk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENvbnZlcnRzIGBzZXRgIHRvIGFuIGFycmF5IG9mIGl0cyB2YWx1ZXMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBzZXQgVGhlIHNldCB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlcy4KICovCmZ1bmN0aW9uIHNldFRvQXJyYXkoc2V0KSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7CiAgc2V0LmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7CiAgICByZXN1bHRbKytpbmRleF0gPSB2YWx1ZTsKICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDQgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMiA9IDI7CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLAogIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsCiAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLAogIG1hcFRhZyQyID0gJ1tvYmplY3QgTWFwXScsCiAgbnVtYmVyVGFnJDEgPSAnW29iamVjdCBOdW1iZXJdJywKICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJywKICBzZXRUYWckMiA9ICdbb2JqZWN0IFNldF0nLAogIHN0cmluZ1RhZyQxID0gJ1tvYmplY3QgU3RyaW5nXScsCiAgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7CnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsCiAgZGF0YVZpZXdUYWckMSA9ICdbb2JqZWN0IERhdGFWaWV3XSc7CgovKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi8KdmFyIHN5bWJvbFByb3RvID0gU3ltYm9sJDEgPyBTeW1ib2wkMS5wcm90b3R5cGUgOiB1bmRlZmluZWQsCiAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZDsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGNvbXBhcmluZyBvYmplY3RzIG9mCiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuCiAqCiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY29tcGFyaW5nIHZhbHVlcyB3aXRoIHRhZ3Mgb2YKICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3RzIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy4KICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykgewogIHN3aXRjaCAodGFnKSB7CiAgICBjYXNlIGRhdGFWaWV3VGFnJDE6CiAgICAgIGlmIChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoIHx8IG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgb2JqZWN0ID0gb2JqZWN0LmJ1ZmZlcjsKICAgICAgb3RoZXIgPSBvdGhlci5idWZmZXI7CiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOgogICAgICBpZiAob2JqZWN0LmJ5dGVMZW5ndGggIT0gb3RoZXIuYnl0ZUxlbmd0aCB8fCAhZXF1YWxGdW5jKG5ldyBVaW50OEFycmF5JDEob2JqZWN0KSwgbmV3IFVpbnQ4QXJyYXkkMShvdGhlcikpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogICAgY2FzZSBib29sVGFnOgogICAgY2FzZSBkYXRlVGFnOgogICAgY2FzZSBudW1iZXJUYWckMToKICAgICAgLy8gQ29lcmNlIGJvb2xlYW5zIHRvIGAxYCBvciBgMGAgYW5kIGRhdGVzIHRvIG1pbGxpc2Vjb25kcy4KICAgICAgLy8gSW52YWxpZCBkYXRlcyBhcmUgY29lcmNlZCB0byBgTmFOYC4KICAgICAgcmV0dXJuIGVxKCtvYmplY3QsICtvdGhlcik7CiAgICBjYXNlIGVycm9yVGFnOgogICAgICByZXR1cm4gb2JqZWN0Lm5hbWUgPT0gb3RoZXIubmFtZSAmJiBvYmplY3QubWVzc2FnZSA9PSBvdGhlci5tZXNzYWdlOwogICAgY2FzZSByZWdleHBUYWc6CiAgICBjYXNlIHN0cmluZ1RhZyQxOgogICAgICAvLyBDb2VyY2UgcmVnZXhlcyB0byBzdHJpbmdzIGFuZCB0cmVhdCBzdHJpbmdzLCBwcmltaXRpdmVzIGFuZCBvYmplY3RzLAogICAgICAvLyBhcyBlcXVhbC4gU2VlIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1yZWdleHAucHJvdG90eXBlLnRvc3RyaW5nCiAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuCiAgICAgIHJldHVybiBvYmplY3QgPT0gb3RoZXIgKyAnJzsKICAgIGNhc2UgbWFwVGFnJDI6CiAgICAgIHZhciBjb252ZXJ0ID0gbWFwVG9BcnJheTsKICAgIGNhc2Ugc2V0VGFnJDI6CiAgICAgIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNDsKICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpOwogICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC4KICAgICAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTsKICAgICAgaWYgKHN0YWNrZWQpIHsKICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjsKICAgICAgfQogICAgICBiaXRtYXNrIHw9IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMjsKCiAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLgogICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7CiAgICAgIHZhciByZXN1bHQgPSBlcXVhbEFycmF5cyhjb252ZXJ0KG9iamVjdCksIGNvbnZlcnQob3RoZXIpLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTsKICAgICAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICBjYXNlIHN5bWJvbFRhZzoKICAgICAgaWYgKHN5bWJvbFZhbHVlT2YpIHsKICAgICAgICByZXR1cm4gc3ltYm9sVmFsdWVPZi5jYWxsKG9iamVjdCkgPT0gc3ltYm9sVmFsdWVPZi5jYWxsKG90aGVyKTsKICAgICAgfQogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBBcHBlbmRzIHRoZSBlbGVtZW50cyBvZiBgdmFsdWVzYCB0byBgYXJyYXlgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LgogKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcHBlbmQuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLgogKi8KZnVuY3Rpb24gYXJyYXlQdXNoKGFycmF5LCB2YWx1ZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsCiAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGFycmF5W29mZnNldCArIGluZGV4XSA9IHZhbHVlc1tpbmRleF07CiAgfQogIHJldHVybiBhcnJheTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRBbGxLZXlzYCBhbmQgYGdldEFsbEtleXNJbmAgd2hpY2ggdXNlcwogKiBga2V5c0Z1bmNgIGFuZCBgc3ltYm9sc0Z1bmNgIHRvIGdldCB0aGUgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQKICogc3ltYm9scyBvZiBgb2JqZWN0YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBzeW1ib2xzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBzeW1ib2xzIG9mIGBvYmplY3RgLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLgogKi8KZnVuY3Rpb24gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzRnVuYywgc3ltYm9sc0Z1bmMpIHsKICB2YXIgcmVzdWx0ID0ga2V5c0Z1bmMob2JqZWN0KTsKICByZXR1cm4gaXNBcnJheSQxKG9iamVjdCkgPyByZXN1bHQgOiBhcnJheVB1c2gocmVzdWx0LCBzeW1ib2xzRnVuYyhvYmplY3QpKTsKfQoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5maWx0ZXJgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS4KICovCmZ1bmN0aW9uIGFycmF5RmlsdGVyKGFycmF5LCBwcmVkaWNhdGUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLAogICAgcmVzSW5kZXggPSAwLAogICAgcmVzdWx0ID0gW107CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTsKICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHsKICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWU7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBUaGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGVtcHR5IGFycmF5LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjEzLjAKICogQGNhdGVnb3J5IFV0aWwKICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZW1wdHkgYXJyYXkuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBhcnJheXMgPSBfLnRpbWVzKDIsIF8uc3R1YkFycmF5KTsKICoKICogY29uc29sZS5sb2coYXJyYXlzKTsKICogLy8gPT4gW1tdLCBbXV0KICoKICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gc3R1YkFycmF5KCkgewogIHJldHVybiBbXTsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kMiA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8kMi5wcm9wZXJ0eUlzRW51bWVyYWJsZTsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi8KdmFyIG5hdGl2ZUdldFN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzOwoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBzeW1ib2xzLgogKi8KdmFyIGdldFN5bWJvbHMgPSAhbmF0aXZlR2V0U3ltYm9scyA/IHN0dWJBcnJheSA6IGZ1bmN0aW9uIChvYmplY3QpIHsKICBpZiAob2JqZWN0ID09IG51bGwpIHsKICAgIHJldHVybiBbXTsKICB9CiAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7CiAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24gKHN5bWJvbCkgewogICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpOwogIH0pOwp9Owp2YXIgZ2V0U3ltYm9scyQxID0gZ2V0U3ltYm9sczsKCi8qKgogKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuCiAqLwpmdW5jdGlvbiBnZXRBbGxLZXlzKG9iamVjdCkgewogIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXMsIGdldFN5bWJvbHMkMSk7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckMyA9IDE7CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQxID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkMSA9IG9iamVjdFByb3RvJDEuaGFzT3duUHJvcGVydHk7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3IKICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7CiAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyQzLAogICAgb2JqUHJvcHMgPSBnZXRBbGxLZXlzKG9iamVjdCksCiAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsCiAgICBvdGhQcm9wcyA9IGdldEFsbEtleXMob3RoZXIpLAogICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoOwogIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc1BhcnRpYWwpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoOwogIHdoaWxlIChpbmRleC0tKSB7CiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdOwogICAgaWYgKCEoaXNQYXJ0aWFsID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkkMS5jYWxsKG90aGVyLCBrZXkpKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQogIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuCiAgdmFyIG9ialN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTsKICB2YXIgb3RoU3RhY2tlZCA9IHN0YWNrLmdldChvdGhlcik7CiAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkgewogICAgcmV0dXJuIG9ialN0YWNrZWQgPT0gb3RoZXIgJiYgb3RoU3RhY2tlZCA9PSBvYmplY3Q7CiAgfQogIHZhciByZXN1bHQgPSB0cnVlOwogIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTsKICBzdGFjay5zZXQob3RoZXIsIG9iamVjdCk7CiAgdmFyIHNraXBDdG9yID0gaXNQYXJ0aWFsOwogIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7CiAgICBrZXkgPSBvYmpQcm9wc1tpbmRleF07CiAgICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSwKICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldOwogICAgaWYgKGN1c3RvbWl6ZXIpIHsKICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spIDogY3VzdG9taXplcihvYmpWYWx1ZSwgb3RoVmFsdWUsIGtleSwgb2JqZWN0LCBvdGhlciwgc3RhY2spOwogICAgfQogICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICBpZiAoIShjb21wYXJlZCA9PT0gdW5kZWZpbmVkID8gb2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSA6IGNvbXBhcmVkKSkgewogICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgYnJlYWs7CiAgICB9CiAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7CiAgfQogIGlmIChyZXN1bHQgJiYgIXNraXBDdG9yKSB7CiAgICB2YXIgb2JqQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvciwKICAgICAgb3RoQ3RvciA9IG90aGVyLmNvbnN0cnVjdG9yOwoKICAgIC8vIE5vbiBgT2JqZWN0YCBvYmplY3QgaW5zdGFuY2VzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWFsLgogICAgaWYgKG9iakN0b3IgIT0gb3RoQ3RvciAmJiAnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyICYmICEodHlwZW9mIG9iakN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvYmpDdG9yIGluc3RhbmNlb2Ygb2JqQ3RvciAmJiB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkgewogICAgICByZXN1bHQgPSBmYWxzZTsKICAgIH0KICB9CiAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7CiAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTsKICByZXR1cm4gcmVzdWx0Owp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBEYXRhVmlldyA9IGdldE5hdGl2ZShyb290JDEsICdEYXRhVmlldycpOwp2YXIgRGF0YVZpZXckMSA9IERhdGFWaWV3OwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgUHJvbWlzZSQxID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ1Byb21pc2UnKTsKdmFyIFByb21pc2UkMiA9IFByb21pc2UkMTsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi8KdmFyIFNldCA9IGdldE5hdGl2ZShyb290JDEsICdTZXQnKTsKdmFyIFNldCQxID0gU2V0OwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgV2Vha01hcCA9IGdldE5hdGl2ZShyb290JDEsICdXZWFrTWFwJyk7CnZhciBXZWFrTWFwJDEgPSBXZWFrTWFwOwoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgbWFwVGFnJDEgPSAnW29iamVjdCBNYXBdJywKICBvYmplY3RUYWckMSA9ICdbb2JqZWN0IE9iamVjdF0nLAogIHByb21pc2VUYWcgPSAnW29iamVjdCBQcm9taXNlXScsCiAgc2V0VGFnJDEgPSAnW29iamVjdCBTZXRdJywKICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nOwp2YXIgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IG1hcHMsIHNldHMsIGFuZCB3ZWFrbWFwcy4gKi8KdmFyIGRhdGFWaWV3Q3RvclN0cmluZyA9IHRvU291cmNlKERhdGFWaWV3JDEpLAogIG1hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShNYXAkMSksCiAgcHJvbWlzZUN0b3JTdHJpbmcgPSB0b1NvdXJjZShQcm9taXNlJDIpLAogIHNldEN0b3JTdHJpbmcgPSB0b1NvdXJjZShTZXQkMSksCiAgd2Vha01hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShXZWFrTWFwJDEpOwoKLyoqCiAqIEdldHMgdGhlIGB0b1N0cmluZ1RhZ2Agb2YgYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuCiAqLwp2YXIgZ2V0VGFnID0gYmFzZUdldFRhZzsKCi8vIEZhbGxiYWNrIGZvciBkYXRhIHZpZXdzLCBtYXBzLCBzZXRzLCBhbmQgd2VhayBtYXBzIGluIElFIDExIGFuZCBwcm9taXNlcyBpbiBOb2RlLmpzIDwgNi4KaWYgKERhdGFWaWV3JDEgJiYgZ2V0VGFnKG5ldyBEYXRhVmlldyQxKG5ldyBBcnJheUJ1ZmZlcigxKSkpICE9IGRhdGFWaWV3VGFnIHx8IE1hcCQxICYmIGdldFRhZyhuZXcgTWFwJDEoKSkgIT0gbWFwVGFnJDEgfHwgUHJvbWlzZSQyICYmIGdldFRhZyhQcm9taXNlJDIucmVzb2x2ZSgpKSAhPSBwcm9taXNlVGFnIHx8IFNldCQxICYmIGdldFRhZyhuZXcgU2V0JDEoKSkgIT0gc2V0VGFnJDEgfHwgV2Vha01hcCQxICYmIGdldFRhZyhuZXcgV2Vha01hcCQxKCkpICE9IHdlYWtNYXBUYWcpIHsKICBnZXRUYWcgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgIHZhciByZXN1bHQgPSBiYXNlR2V0VGFnKHZhbHVlKSwKICAgICAgQ3RvciA9IHJlc3VsdCA9PSBvYmplY3RUYWckMSA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLAogICAgICBjdG9yU3RyaW5nID0gQ3RvciA/IHRvU291cmNlKEN0b3IpIDogJyc7CiAgICBpZiAoY3RvclN0cmluZykgewogICAgICBzd2l0Y2ggKGN0b3JTdHJpbmcpIHsKICAgICAgICBjYXNlIGRhdGFWaWV3Q3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBkYXRhVmlld1RhZzsKICAgICAgICBjYXNlIG1hcEN0b3JTdHJpbmc6CiAgICAgICAgICByZXR1cm4gbWFwVGFnJDE7CiAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBwcm9taXNlVGFnOwogICAgICAgIGNhc2Ugc2V0Q3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBzZXRUYWckMTsKICAgICAgICBjYXNlIHdlYWtNYXBDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIHdlYWtNYXBUYWc7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKfQp2YXIgZ2V0VGFnJDEgPSBnZXRUYWc7CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDIgPSAxOwoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLAogIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJywKICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJzsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zCiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXIKICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy4KICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7CiAgdmFyIG9iaklzQXJyID0gaXNBcnJheSQxKG9iamVjdCksCiAgICBvdGhJc0FyciA9IGlzQXJyYXkkMShvdGhlciksCiAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnJDEob2JqZWN0KSwKICAgIG90aFRhZyA9IG90aElzQXJyID8gYXJyYXlUYWcgOiBnZXRUYWckMShvdGhlcik7CiAgb2JqVGFnID0gb2JqVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvYmpUYWc7CiAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7CiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZywKICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZywKICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7CiAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlciQxKG9iamVjdCkpIHsKICAgIGlmICghaXNCdWZmZXIkMShvdGhlcikpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgb2JqSXNBcnIgPSB0cnVlOwogICAgb2JqSXNPYmogPSBmYWxzZTsKICB9CiAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHsKICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjaygpKTsKICAgIHJldHVybiBvYmpJc0FyciB8fCBpc1R5cGVkQXJyYXkkMShvYmplY3QpID8gZXF1YWxBcnJheXMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykgOiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIG9ialRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7CiAgfQogIGlmICghKGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyQyKSkgewogICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSwKICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7CiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkgewogICAgICB2YXIgb2JqVW53cmFwcGVkID0gb2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsCiAgICAgICAgb3RoVW53cmFwcGVkID0gb3RoSXNXcmFwcGVkID8gb3RoZXIudmFsdWUoKSA6IG90aGVyOwogICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2soKSk7CiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTsKICAgIH0KICB9CiAgaWYgKCFpc1NhbWVUYWcpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKCkpOwogIHJldHVybiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zCiAqIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4KICogIDEgLSBVbm9yZGVyZWQgY29tcGFyaXNvbgogKiAgMiAtIFBhcnRpYWwgY29tcGFyaXNvbgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSB7CiAgaWYgKHZhbHVlID09PSBvdGhlcikgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmICh2YWx1ZSA9PSBudWxsIHx8IG90aGVyID09IG51bGwgfHwgIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpIHsKICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyOwogIH0KICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgYmFzZUlzRXF1YWwsIHN0YWNrKTsKfQoKLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovCnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyQxID0gMSwKICBDT01QQVJFX1VOT1JERVJFRF9GTEFHJDEgPSAyOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWF0Y2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuCiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guCiAqIEBwYXJhbSB7QXJyYXl9IG1hdGNoRGF0YSBUaGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3MgdG8gbWF0Y2guCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIG1hdGNoRGF0YSwgY3VzdG9taXplcikgewogIHZhciBpbmRleCA9IG1hdGNoRGF0YS5sZW5ndGgsCiAgICBsZW5ndGggPSBpbmRleCwKICAgIG5vQ3VzdG9taXplciA9ICFjdXN0b21pemVyOwogIGlmIChvYmplY3QgPT0gbnVsbCkgewogICAgcmV0dXJuICFsZW5ndGg7CiAgfQogIG9iamVjdCA9IE9iamVjdChvYmplY3QpOwogIHdoaWxlIChpbmRleC0tKSB7CiAgICB2YXIgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07CiAgICBpZiAobm9DdXN0b21pemVyICYmIGRhdGFbMl0gPyBkYXRhWzFdICE9PSBvYmplY3RbZGF0YVswXV0gOiAhKGRhdGFbMF0gaW4gb2JqZWN0KSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTsKICAgIHZhciBrZXkgPSBkYXRhWzBdLAogICAgICBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLAogICAgICBzcmNWYWx1ZSA9IGRhdGFbMV07CiAgICBpZiAobm9DdXN0b21pemVyICYmIGRhdGFbMl0pIHsKICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgdmFyIHN0YWNrID0gbmV3IFN0YWNrKCk7CiAgICAgIGlmIChjdXN0b21pemVyKSB7CiAgICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjayk7CiAgICAgIH0KICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWQgPyBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIENPTVBBUkVfUEFSVElBTF9GTEFHJDEgfCBDT01QQVJFX1VOT1JERVJFRF9GTEFHJDEsIGN1c3RvbWl6ZXIsIHN0YWNrKSA6IHJlc3VsdCkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn0KCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdAogKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTsKfQoKLyoqCiAqIEdldHMgdGhlIHByb3BlcnR5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC4KICovCmZ1bmN0aW9uIGdldE1hdGNoRGF0YShvYmplY3QpIHsKICB2YXIgcmVzdWx0ID0ga2V5cyhvYmplY3QpLAogICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDsKICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgIHZhciBrZXkgPSByZXN1bHRbbGVuZ3RoXSwKICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTsKICAgIHJlc3VsdFtsZW5ndGhdID0gW2tleSwgdmFsdWUsIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSldOwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBtYXRjaGVzUHJvcGVydHlgIGZvciBzb3VyY2UgdmFsdWVzIHN1aXRhYmxlCiAqIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKGtleSwgc3JjVmFsdWUpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgaWYgKG9iamVjdCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiBvYmplY3Rba2V5XSA9PT0gc3JjVmFsdWUgJiYgKHNyY1ZhbHVlICE9PSB1bmRlZmluZWQgfHwga2V5IGluIE9iamVjdChvYmplY3QpKTsKICB9Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lc24ndCBjbG9uZSBgc291cmNlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VNYXRjaGVzKHNvdXJjZSkgewogIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTsKICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkgewogICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKG1hdGNoRGF0YVswXVswXSwgbWF0Y2hEYXRhWzBdWzFdKTsKICB9CiAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QpIHsKICAgIHJldHVybiBvYmplY3QgPT09IHNvdXJjZSB8fCBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhKTsKICB9Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaGFzSW5gIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBrZXkgVGhlIGtleSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUhhc0luKG9iamVjdCwga2V5KSB7CiAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGtleSBpbiBPYmplY3Qob2JqZWN0KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgcGF0aGAgZXhpc3RzIG9uIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNGdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjayBwcm9wZXJ0aWVzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHBhdGhgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzUGF0aChvYmplY3QsIHBhdGgsIGhhc0Z1bmMpIHsKICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoLAogICAgcmVzdWx0ID0gZmFsc2U7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBrZXkgPSB0b0tleShwYXRoW2luZGV4XSk7CiAgICBpZiAoIShyZXN1bHQgPSBvYmplY3QgIT0gbnVsbCAmJiBoYXNGdW5jKG9iamVjdCwga2V5KSkpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgICBvYmplY3QgPSBvYmplY3Rba2V5XTsKICB9CiAgaWYgKHJlc3VsdCB8fCArK2luZGV4ICE9IGxlbmd0aCkgewogICAgcmV0dXJuIHJlc3VsdDsKICB9CiAgbGVuZ3RoID0gb2JqZWN0ID09IG51bGwgPyAwIDogb2JqZWN0Lmxlbmd0aDsKICByZXR1cm4gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSAmJiAoaXNBcnJheSQxKG9iamVjdCkgfHwgaXNBcmd1bWVudHMkMShvYmplY3QpKTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgcGF0aGAgaXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG9mIGBvYmplY3RgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgT2JqZWN0CiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBvYmplY3QgPSBfLmNyZWF0ZSh7ICdhJzogXy5jcmVhdGUoeyAnYic6IDIgfSkgfSk7CiAqCiAqIF8uaGFzSW4ob2JqZWN0LCAnYScpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaGFzSW4ob2JqZWN0LCAnYS5iJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5oYXNJbihvYmplY3QsIFsnYScsICdiJ10pOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaGFzSW4ob2JqZWN0LCAnYicpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaGFzSW4ob2JqZWN0LCBwYXRoKSB7CiAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGhhc1BhdGgob2JqZWN0LCBwYXRoLCBiYXNlSGFzSW4pOwp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMSwKICBDT01QQVJFX1VOT1JERVJFRF9GTEFHID0gMjsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzUHJvcGVydHlgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNyY1ZhbHVlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7CiAgaWYgKGlzS2V5KHBhdGgpICYmIGlzU3RyaWN0Q29tcGFyYWJsZShzcmNWYWx1ZSkpIHsKICAgIHJldHVybiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZSh0b0tleShwYXRoKSwgc3JjVmFsdWUpOwogIH0KICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgdmFyIG9ialZhbHVlID0gZ2V0KG9iamVjdCwgcGF0aCk7CiAgICByZXR1cm4gb2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvYmpWYWx1ZSA9PT0gc3JjVmFsdWUgPyBoYXNJbihvYmplY3QsIHBhdGgpIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eWAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlUHJvcGVydHkoa2V5KSB7CiAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QpIHsKICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldOwogIH07Cn0KCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VQcm9wZXJ0eWAgd2hpY2ggc3VwcG9ydHMgZGVlcCBwYXRocy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgcmV0dXJuIGJhc2VHZXQob2JqZWN0LCBwYXRoKTsKICB9Owp9CgovKioKICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgdmFsdWUgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAyLjQuMAogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdHMgPSBbCiAqICAgeyAnYSc6IHsgJ2InOiAyIH0gfSwKICogICB7ICdhJzogeyAnYic6IDEgfSB9CiAqIF07CiAqCiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYicpKTsKICogLy8gPT4gWzIsIDFdCiAqCiAqIF8ubWFwKF8uc29ydEJ5KG9iamVjdHMsIF8ucHJvcGVydHkoWydhJywgJ2InXSkpLCAnYS5iJyk7CiAqIC8vID0+IFsxLCAyXQogKi8KZnVuY3Rpb24gcHJvcGVydHkocGF0aCkgewogIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eSh0b0tleShwYXRoKSkgOiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXRlcmF0ZWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IFt2YWx1ZT1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhbiBpdGVyYXRlZS4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBpdGVyYXRlZS4KICovCmZ1bmN0aW9uIGJhc2VJdGVyYXRlZSh2YWx1ZSkgewogIC8vIERvbid0IHN0b3JlIHRoZSBgdHlwZW9mYCByZXN1bHQgaW4gYSB2YXJpYWJsZSB0byBhdm9pZCBhIEpJVCBidWcgaW4gU2FmYXJpIDkuCiAgLy8gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNTYwMzQgZm9yIG1vcmUgZGV0YWlscy4KICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpIHsKICAgIHJldHVybiB2YWx1ZTsKICB9CiAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgIHJldHVybiBpZGVudGl0eSQxOwogIH0KICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7CiAgICByZXR1cm4gaXNBcnJheSQxKHZhbHVlKSA/IGJhc2VNYXRjaGVzUHJvcGVydHkodmFsdWVbMF0sIHZhbHVlWzFdKSA6IGJhc2VNYXRjaGVzKHZhbHVlKTsKICB9CiAgcmV0dXJuIHByb3BlcnR5KHZhbHVlKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hcGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS4KICovCmZ1bmN0aW9uIGJhc2VNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107CiAgYmFzZUVhY2gkMShjb2xsZWN0aW9uLCBmdW5jdGlvbiAodmFsdWUsIGtleSwgY29sbGVjdGlvbikgewogICAgcmVzdWx0WysraW5kZXhdID0gaXRlcmF0ZWUodmFsdWUsIGtleSwgY29sbGVjdGlvbik7CiAgfSk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJ1CiAqIGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOgogKiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuCiAqCiAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZQogKiBgXy5ldmVyeWAsIGBfLmZpbHRlcmAsIGBfLm1hcGAsIGBfLm1hcFZhbHVlc2AsIGBfLnJlamVjdGAsIGFuZCBgXy5zb21lYC4KICoKICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6CiAqIGBhcnlgLCBgY2h1bmtgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBldmVyeWAsCiAqIGBmaWxsYCwgYGludmVydGAsIGBwYXJzZUludGAsIGByYW5kb21gLCBgcmFuZ2VgLCBgcmFuZ2VSaWdodGAsIGByZXBlYXRgLAogKiBgc2FtcGxlU2l6ZWAsIGBzbGljZWAsIGBzb21lYCwgYHNvcnRCeWAsIGBzcGxpdGAsIGB0YWtlYCwgYHRha2VSaWdodGAsCiAqIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1FbmRgLCBgdHJpbVN0YXJ0YCwgYW5kIGB3b3Jkc2AKICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IENvbGxlY3Rpb24KICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LgogKiBAZXhhbXBsZQogKgogKiBmdW5jdGlvbiBzcXVhcmUobikgewogKiAgIHJldHVybiBuICogbjsKICogfQogKgogKiBfLm1hcChbNCwgOF0sIHNxdWFyZSk7CiAqIC8vID0+IFsxNiwgNjRdCiAqCiAqIF8ubWFwKHsgJ2EnOiA0LCAnYic6IDggfSwgc3F1YXJlKTsKICogLy8gPT4gWzE2LCA2NF0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkKICoKICogdmFyIHVzZXJzID0gWwogKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LAogKiAgIHsgJ3VzZXInOiAnZnJlZCcgfQogKiBdOwogKgogKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC4KICogXy5tYXAodXNlcnMsICd1c2VyJyk7CiAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXQogKi8KZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7CiAgdmFyIGZ1bmMgPSBpc0FycmF5JDEoY29sbGVjdGlvbikgPyBhcnJheU1hcCA6IGJhc2VNYXA7CiAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgYmFzZUl0ZXJhdGVlKGl0ZXJhdGVlKSk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zdW1gIGFuZCBgXy5zdW1CeWAgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uCiAqLwpmdW5jdGlvbiBiYXNlU3VtKGFycmF5LCBpdGVyYXRlZSkgewogIHZhciByZXN1bHQsCiAgICBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgY3VycmVudCA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSk7CiAgICBpZiAoY3VycmVudCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gY3VycmVudCA6IHJlc3VsdCArIGN1cnJlbnQ7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBDb21wdXRlcyB0aGUgc3VtIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMy40LjAKICogQGNhdGVnb3J5IE1hdGgKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLgogKiBAZXhhbXBsZQogKgogKiBfLnN1bShbNCwgMiwgOCwgNl0pOwogKiAvLyA9PiAyMAogKi8KZnVuY3Rpb24gc3VtJDEoYXJyYXkpIHsKICByZXR1cm4gYXJyYXkgJiYgYXJyYXkubGVuZ3RoID8gYmFzZVN1bShhcnJheSwgaWRlbnRpdHkkMSkgOiAwOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3RyaW5nLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNTdHJpbmcoJ2FiYycpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNTdHJpbmcoMSk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgIWlzQXJyYXkkMSh2YWx1ZSkgJiYgaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBzdHJpbmdUYWc7Cn0KCi8qKgogKiBHZXRzIHRoZSBzaXplIG9mIGFuIEFTQ0lJIGBzdHJpbmdgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuCiAqLwp2YXIgYXNjaWlTaXplID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTsKdmFyIGFzY2lpU2l6ZSQxID0gYXNjaWlTaXplOwoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNoYXJhY3RlciBjbGFzc2VzLiAqLwp2YXIgcnNBc3RyYWxSYW5nZSQxID0gJ1xcdWQ4MDAtXFx1ZGZmZicsCiAgcnNDb21ib01hcmtzUmFuZ2UkMSA9ICdcXHUwMzAwLVxcdTAzNmYnLAogIHJlQ29tYm9IYWxmTWFya3NSYW5nZSQxID0gJ1xcdWZlMjAtXFx1ZmUyZicsCiAgcnNDb21ib1N5bWJvbHNSYW5nZSQxID0gJ1xcdTIwZDAtXFx1MjBmZicsCiAgcnNDb21ib1JhbmdlJDEgPSByc0NvbWJvTWFya3NSYW5nZSQxICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlJDEgKyByc0NvbWJvU3ltYm9sc1JhbmdlJDEsCiAgcnNWYXJSYW5nZSQxID0gJ1xcdWZlMGVcXHVmZTBmJzsKCi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi8KdmFyIHJzWldKJDEgPSAnXFx1MjAwZCc7CgovKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB3aXRoIFt6ZXJvLXdpZHRoIGpvaW5lcnMgb3IgY29kZSBwb2ludHMgZnJvbSB0aGUgYXN0cmFsIHBsYW5lc10oaHR0cDovL2Vldi5lZS9ibG9nLzIwMTUvMDkvMTIvZGFyay1jb3JuZXJzLW9mLXVuaWNvZGUvKS4gKi8KdmFyIHJlSGFzVW5pY29kZSA9IFJlZ0V4cCgnWycgKyByc1pXSiQxICsgcnNBc3RyYWxSYW5nZSQxICsgcnNDb21ib1JhbmdlJDEgKyByc1ZhclJhbmdlJDEgKyAnXScpOwoKLyoqCiAqIENoZWNrcyBpZiBgc3RyaW5nYCBjb250YWlucyBVbmljb2RlIHN5bWJvbHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYSBzeW1ib2wgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGhhc1VuaWNvZGUoc3RyaW5nKSB7CiAgcmV0dXJuIHJlSGFzVW5pY29kZS50ZXN0KHN0cmluZyk7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi8KdmFyIHJzQXN0cmFsUmFuZ2UgPSAnXFx1ZDgwMC1cXHVkZmZmJywKICByc0NvbWJvTWFya3NSYW5nZSA9ICdcXHUwMzAwLVxcdTAzNmYnLAogIHJlQ29tYm9IYWxmTWFya3NSYW5nZSA9ICdcXHVmZTIwLVxcdWZlMmYnLAogIHJzQ29tYm9TeW1ib2xzUmFuZ2UgPSAnXFx1MjBkMC1cXHUyMGZmJywKICByc0NvbWJvUmFuZ2UgPSByc0NvbWJvTWFya3NSYW5nZSArIHJlQ29tYm9IYWxmTWFya3NSYW5nZSArIHJzQ29tYm9TeW1ib2xzUmFuZ2UsCiAgcnNWYXJSYW5nZSA9ICdcXHVmZTBlXFx1ZmUwZic7CgovKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2FwdHVyZSBncm91cHMuICovCnZhciByc0FzdHJhbCA9ICdbJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsCiAgcnNDb21ibyA9ICdbJyArIHJzQ29tYm9SYW5nZSArICddJywKICByc0ZpdHogPSAnXFx1ZDgzY1tcXHVkZmZiLVxcdWRmZmZdJywKICByc01vZGlmaWVyID0gJyg/OicgKyByc0NvbWJvICsgJ3wnICsgcnNGaXR6ICsgJyknLAogIHJzTm9uQXN0cmFsID0gJ1teJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsCiAgcnNSZWdpb25hbCA9ICcoPzpcXHVkODNjW1xcdWRkZTYtXFx1ZGRmZl0pezJ9JywKICByc1N1cnJQYWlyID0gJ1tcXHVkODAwLVxcdWRiZmZdW1xcdWRjMDAtXFx1ZGZmZl0nLAogIHJzWldKID0gJ1xcdTIwMGQnOwoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIHJlZ2V4ZXMuICovCnZhciByZU9wdE1vZCA9IHJzTW9kaWZpZXIgKyAnPycsCiAgcnNPcHRWYXIgPSAnWycgKyByc1ZhclJhbmdlICsgJ10/JywKICByc09wdEpvaW4gPSAnKD86JyArIHJzWldKICsgJyg/OicgKyBbcnNOb25Bc3RyYWwsIHJzUmVnaW9uYWwsIHJzU3VyclBhaXJdLmpvaW4oJ3wnKSArICcpJyArIHJzT3B0VmFyICsgcmVPcHRNb2QgKyAnKSonLAogIHJzU2VxID0gcnNPcHRWYXIgKyByZU9wdE1vZCArIHJzT3B0Sm9pbiwKICByc1N5bWJvbCA9ICcoPzonICsgW3JzTm9uQXN0cmFsICsgcnNDb21ibyArICc/JywgcnNDb21ibywgcnNSZWdpb25hbCwgcnNTdXJyUGFpciwgcnNBc3RyYWxdLmpvaW4oJ3wnKSArICcpJzsKCi8qKiBVc2VkIHRvIG1hdGNoIFtzdHJpbmcgc3ltYm9sc10oaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtdW5pY29kZSkuICovCnZhciByZVVuaWNvZGUgPSBSZWdFeHAocnNGaXR6ICsgJyg/PScgKyByc0ZpdHogKyAnKXwnICsgcnNTeW1ib2wgKyByc1NlcSwgJ2cnKTsKCi8qKgogKiBHZXRzIHRoZSBzaXplIG9mIGEgVW5pY29kZSBgc3RyaW5nYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIGluc3BlY3QuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN0cmluZyBzaXplLgogKi8KZnVuY3Rpb24gdW5pY29kZVNpemUoc3RyaW5nKSB7CiAgdmFyIHJlc3VsdCA9IHJlVW5pY29kZS5sYXN0SW5kZXggPSAwOwogIHdoaWxlIChyZVVuaWNvZGUudGVzdChzdHJpbmcpKSB7CiAgICArK3Jlc3VsdDsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIEdldHMgdGhlIG51bWJlciBvZiBzeW1ib2xzIGluIGBzdHJpbmdgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuCiAqLwpmdW5jdGlvbiBzdHJpbmdTaXplKHN0cmluZykgewogIHJldHVybiBoYXNVbmljb2RlKHN0cmluZykgPyB1bmljb2RlU2l6ZShzdHJpbmcpIDogYXNjaWlTaXplJDEoc3RyaW5nKTsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsCiAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XSc7CgovKioKICogR2V0cyB0aGUgc2l6ZSBvZiBgY29sbGVjdGlvbmAgYnkgcmV0dXJuaW5nIGl0cyBsZW5ndGggZm9yIGFycmF5LWxpa2UKICogdmFsdWVzIG9yIHRoZSBudW1iZXIgb2Ygb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgZm9yIG9iamVjdHMuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIHNpemUuCiAqIEBleGFtcGxlCiAqCiAqIF8uc2l6ZShbMSwgMiwgM10pOwogKiAvLyA9PiAzCiAqCiAqIF8uc2l6ZSh7ICdhJzogMSwgJ2InOiAyIH0pOwogKiAvLyA9PiAyCiAqCiAqIF8uc2l6ZSgncGViYmxlcycpOwogKiAvLyA9PiA3CiAqLwpmdW5jdGlvbiBzaXplKGNvbGxlY3Rpb24pIHsKICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7CiAgICByZXR1cm4gMDsKICB9CiAgaWYgKGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7CiAgICByZXR1cm4gaXNTdHJpbmcoY29sbGVjdGlvbikgPyBzdHJpbmdTaXplKGNvbGxlY3Rpb24pIDogY29sbGVjdGlvbi5sZW5ndGg7CiAgfQogIHZhciB0YWcgPSBnZXRUYWckMShjb2xsZWN0aW9uKTsKICBpZiAodGFnID09IG1hcFRhZyB8fCB0YWcgPT0gc2V0VGFnKSB7CiAgICByZXR1cm4gY29sbGVjdGlvbi5zaXplOwogIH0KICByZXR1cm4gYmFzZUtleXMoY29sbGVjdGlvbikubGVuZ3RoOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYE51bWJlcmAgcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogKipOb3RlOioqIFRvIGV4Y2x1ZGUgYEluZmluaXR5YCwgYC1JbmZpbml0eWAsIGFuZCBgTmFOYCwgd2hpY2ggYXJlCiAqIGNsYXNzaWZpZWQgYXMgbnVtYmVycywgdXNlIHRoZSBgXy5pc0Zpbml0ZWAgbWV0aG9kLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBudW1iZXIsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc051bWJlcigzKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNOdW1iZXIoSW5maW5pdHkpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNOdW1iZXIoJzMnKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzTnVtYmVyKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IG51bWJlclRhZzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnianku7YNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc29iai50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNvYmooe30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzb2JqKHsgYTogMTIzIH0pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc29iaih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IE9iamVjdF0nOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuacieaViOeJqeS7tg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzb2JqLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VvYmooe30pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VvYmooeyBhOiAxMjMgfSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzZW9iaih2KSB7CiAgaWYgKGlzb2JqKHYpKSB7CiAgICBmb3IgKGxldCBrIGluIHYpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrpmaPliJcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2Fyci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNhcnIoW10pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzYXJyKFt7fV0pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2Fycih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IEFycmF5XSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K6dW5kZWZpbmVkDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXN1bmRlZmluZWQudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzdW5kZWZpbmVkKHVuZGVmaW5lZCkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzdW5kZWZpbmVkKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgVW5kZWZpbmVkXSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K6bnVsbA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzbnVsbC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNudWxsKG51bGwpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc251bGwodikgewogIGxldCBjID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpOwogIHJldHVybiBjID09PSAnW29iamVjdCBOdWxsXSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K656m654mp5Lu2DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNvYmowLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc29iajAoe30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzb2JqMCh7IGE6IDEyMyB9KSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzb2JqMCh2KSB7CiAgaWYgKGlzb2JqKHYpKSB7CiAgICBmb3IgKGxldCBrIGluIHYpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnqbrlrZfkuLINCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc3N0cjAudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyMCgnJykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIwKCcwJykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyMCgnYWJjMTI1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc3N0cjAodikgewogIGlmIChpc3N0cih2KSkgewogICAgaWYgKHYgPT09ICcnKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K654Sh5YWn5a656Zmj5YiXDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNhcnIwLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2FycihbXSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNhcnIoW3t9XSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2FycjAodikgewogIGlmIChpc2Fycih2KSkgewogICAgaWYgKHYubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8vIGltcG9ydCBpc05hTiBmcm9tICdsb2Rhc2gtZXMvaXNOYU4uanMnCgovKioNCiAqIOWIpOaWt+aYr+WQpueCuk5hTg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzbmFuLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc25hbihOYU4pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc25hbih2KSB7CiAgLy8gcmV0dXJuIGlzTmFOKHYpCiAgcmV0dXJuIHYgIT09IHY7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65buj576p54Sh5pWIDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNlci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNlcignMTJhNScpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKCcnKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKFtdKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKFt7fV0pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKFsnJ10pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKHt9KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKG51bGwpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIodW5kZWZpbmVkKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKE5hTikpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzZXIodikgewogIGlmIChpc3VuZGVmaW5lZCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc251bGwodikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICBpZiAoaXNvYmowKHYpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKGlzc3RyMCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc2FycjAodikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICBpZiAoaXNuYW4odikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICByZXR1cm4gZmFsc2U7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pyJ5pWI6Zmj5YiX77yM6ZW35bqm6Iez5bCR5aSn5pa8562J5pa8Me+8jOWQhOWFg+e0oOiHs+WwkeeahueCuuacieaViA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzZWFyci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNlYXJyKFt7fV0pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VhcnIoW3sgYTogMTIzIH1dKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNlYXJyKHYpIHsKICAvL2NoZWNrCiAgaWYgKCFpc2Fycih2KSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy9jaGVjayBsZW5ndGgKICBpZiAodi5sZW5ndGggPT09IDApIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIC8vY2hlY2sgbGVuZ3RoPTEKICBpZiAodi5sZW5ndGggPT09IDEpIHsKICAgIGlmIChpc2VyKHZbMF0pKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pW45a2XDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNuYnIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbmJyKDEuMjUpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbmJyKCcxLjI1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc25icih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IE51bWJlcl0nOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuaVuOWtlw0KICoNCiAqIOazqOaEj++8muacrOWHveW8j+S4jeaUr+aPtEJpZ0ludO+8jHR5cGVvZiBCaWdJbnTlgLzngronYmlnaW50J+iAjOmdnidudW1iZXIn5pWFaXNuYnLliKTlrprngrpmYWxzZeOAgg0KICogQmlnSW506IiHTnVtYmVy5ZyoSlPngrrkupLkuI3nm7jlrrnnmoTnrpfooZPln58oYDFuICsgMWDjgIFgTWF0aC5mbG9vcigxbilgIOeahuaTslR5cGVFcnJvcinvvIwNCiAqIOiAjGlzbnVt55qE6Zqx5ZCr5aWR57SE5piv44CM6YCa6YGO5b6M5Y+v5YGaTnVtYmVy566X6KGT6YGL566X44CN77yMd3NlbWnlhafpgL42MOiZlWNhbGxzaXRl5L6d6LO05q2k5aWR57SEDQogKiAo5aaCYXJyTWF4L2Fyck1pbi9yb3VuZC9yYW5kb21SYW5nZeetiSnvvIzoi6XmlL7lr6xpc251beiqjUJpZ0ludOWwh+WwjuiHtOmAmeS6m2NhbGxzaXRl5Z+36KGM5pyf6Yyv6Kqk44CCDQogKiDmraToqK3oqIjoiIdsb2Rhc2ggYF8uaXNOdW1iZXJgIOWwh0JpZ0ludOaOkumZpOeahOiZleeQhuS4gOiHtOOAgkJpZ0ludOiri+WPpuS9nOeNqOeri+WIpOaWt+OAgg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzbnVtLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bSgwKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bSgxLjI1KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bSgnLTEyNScpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKDEyM24pKQ0KICogLy8gPT4gZmFsc2UgKEJpZ0ludOS4jeiiq+imlueCuuaVuOWtlywg6Kmz6KaL5LiK5pa56Kqq5piOKQ0KICoNCiAqLwpmdW5jdGlvbiBpc251bSh2KSB7CiAgbGV0IGIgPSBmYWxzZTsKICBpZiAoaXNlc3RyKHYpKSB7CiAgICBiID0gIWlzTmFOKE51bWJlcih2KSk7CiAgfSBlbHNlIGlmIChpc25icih2KSkgewogICAgLy/ms6jmhI9OYU7ngrpOdW1iZXIsIOaVhWlzbmJy5Zue5YKzdHJ1ZQogICAgaWYgKGlzbmFuKHYpKSB7CiAgICAgIHJldHVybiBmYWxzZTsgLy/mraTomZXliKTlrprngrrmnInmlYjmlbjlrZcsIOaVhU5hTumgiOWJlOmZpAogICAgfSBlbHNlIHsKICAgICAgYiA9IHRydWU7CiAgICB9CiAgfQogIHJldHVybiBiOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuWHveaVuA0KICoNCiAqIOWnlOa0vmxvZGFzaOS5i2lzRnVuY3Rpb27vvIzkuIDoiKzlh73mlbjjgIHnrq3poK3lh73mlbjjgIFhc3luY+WHveaVuOOAgWdlbmVyYXRvcuWHveaVuOiIh2NsYXNz55qG54K6dHJ1Ze+8m2FzeW5jIGdlbmVyYXRvcuWHveaVuChhc3luYyBmdW5jdGlvbiop5pa8bG9kYXNoIDTliKTngrpmYWxzZe+8jOWxrOWFtuW3suefpemZkOWItg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzZnVuLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2Z1bignMS4yNScpKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKiBjb25zb2xlLmxvZyhpc2Z1bihmdW5jdGlvbigpIHt9KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNmdW4odikgewogIHJldHVybiBpc0Z1bmN0aW9uKHYpOwp9CgovKiogVXNlZCB0byBtYXRjaCBhIHNpbmdsZSB3aGl0ZXNwYWNlIGNoYXJhY3Rlci4gKi8KdmFyIHJlV2hpdGVzcGFjZSA9IC9ccy87CgovKioKICogVXNlZCBieSBgXy50cmltYCBhbmQgYF8udHJpbUVuZGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZQogKiBjaGFyYWN0ZXIgb2YgYHN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIuCiAqLwpmdW5jdGlvbiB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSB7CiAgdmFyIGluZGV4ID0gc3RyaW5nLmxlbmd0aDsKICB3aGlsZSAoaW5kZXgtLSAmJiByZVdoaXRlc3BhY2UudGVzdChzdHJpbmcuY2hhckF0KGluZGV4KSkpIHt9CiAgcmV0dXJuIGluZGV4Owp9CgovKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIHdoaXRlc3BhY2UuICovCnZhciByZVRyaW1TdGFydCA9IC9eXHMrLzsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50cmltYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHRyaW0uCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHRyaW1tZWQgc3RyaW5nLgogKi8KZnVuY3Rpb24gYmFzZVRyaW0oc3RyaW5nKSB7CiAgcmV0dXJuIHN0cmluZyA/IHN0cmluZy5zbGljZSgwLCB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSArIDEpLnJlcGxhY2UocmVUcmltU3RhcnQsICcnKSA6IHN0cmluZzsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBOQU4kMSA9IDAgLyAwOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi8KdmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTsKCi8qKiBVc2VkIHRvIGRldGVjdCBiaW5hcnkgc3RyaW5nIHZhbHVlcy4gKi8KdmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7CgovKiogVXNlZCB0byBkZXRlY3Qgb2N0YWwgc3RyaW5nIHZhbHVlcy4gKi8KdmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7CgovKiogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgd2l0aG91dCBhIGRlcGVuZGVuY3kgb24gYHJvb3RgLiAqLwp2YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLgogKiBAZXhhbXBsZQogKgogKiBfLnRvTnVtYmVyKDMuMik7CiAqIC8vID0+IDMuMgogKgogKiBfLnRvTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpOwogKiAvLyA9PiA1ZS0zMjQKICoKICogXy50b051bWJlcihJbmZpbml0eSk7CiAqIC8vID0+IEluZmluaXR5CiAqCiAqIF8udG9OdW1iZXIoJzMuMicpOwogKiAvLyA9PiAzLjIKICovCmZ1bmN0aW9uIHRvTnVtYmVyKHZhbHVlKSB7CiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7CiAgICByZXR1cm4gTkFOJDE7CiAgfQogIGlmIChpc09iamVjdCh2YWx1ZSkpIHsKICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTsKICAgIHZhbHVlID0gaXNPYmplY3Qob3RoZXIpID8gb3RoZXIgKyAnJyA6IG90aGVyOwogIH0KICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7CiAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6ICt2YWx1ZTsKICB9CiAgdmFsdWUgPSBiYXNlVHJpbSh2YWx1ZSk7CiAgdmFyIGlzQmluYXJ5ID0gcmVJc0JpbmFyeS50ZXN0KHZhbHVlKTsKICByZXR1cm4gaXNCaW5hcnkgfHwgcmVJc09jdGFsLnRlc3QodmFsdWUpID8gZnJlZVBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCBpc0JpbmFyeSA/IDIgOiA4KSA6IHJlSXNCYWRIZXgudGVzdCh2YWx1ZSkgPyBOQU4kMSA6ICt2YWx1ZTsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBJTkZJTklUWSA9IDEgLyAwLAogIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDg7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMTIuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgbnVtYmVyLgogKiBAZXhhbXBsZQogKgogKiBfLnRvRmluaXRlKDMuMik7CiAqIC8vID0+IDMuMgogKgogKiBfLnRvRmluaXRlKE51bWJlci5NSU5fVkFMVUUpOwogKiAvLyA9PiA1ZS0zMjQKICoKICogXy50b0Zpbml0ZShJbmZpbml0eSk7CiAqIC8vID0+IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4CiAqCiAqIF8udG9GaW5pdGUoJzMuMicpOwogKiAvLyA9PiAzLjIKICovCmZ1bmN0aW9uIHRvRmluaXRlKHZhbHVlKSB7CiAgaWYgKCF2YWx1ZSkgewogICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwOwogIH0KICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTsKICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHsKICAgIHZhciBzaWduID0gdmFsdWUgPCAwID8gLTEgOiAxOwogICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjsKICB9CiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDsKfQoKLyoqDQogKiDmlbjlrZfmiJblrZfkuLLovYnmta7pu57mlbgNCiAqIOiLpei8uOWFpemdnuaVuOWtl+WJh+WbnuWCszANCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9jZGJsLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHtOdW1iZXJ8U3RyaW5nfSB2IOi8uOWFpeaVuOWtl+aIluWtl+S4sg0KICogQHJldHVybnMge051bWJlcn0g5Zue5YKz5pW45a2XDQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGNkYmwoJzI1JykpDQogKiAvLyA9PiAyNQ0KICoNCiAqLwpmdW5jdGlvbiBjZGJsKHYpIHsKICAvL2NoZWNrCiAgaWYgKCFpc251bSh2KSkgewogICAgcmV0dXJuIDA7CiAgfQogIGxldCByID0gdG9GaW5pdGUodik7CiAgcmV0dXJuIHI7Cn0KCi8qKg0KICog5Yik5pa354mp5Lu25piv5ZCm5pyJa2V55bGs5oCnDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaGFza2V5LnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHtPYmplY3R9IG9iaiDovLjlhaXnianku7YNCiAqIEBwYXJhbSB7U3RyaW5nfSBrZXkg6Ly45YWl6KaB5p+l5om+55qEa2V55a2X5LiyDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGhhc2tleSh7IGE6IDEyMywgYjogJ3h5eicsIGM6ICc0NW9wJywgZDogbnVsbCB9LCAnYScpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBoYXNrZXkob2JqLCBrZXkpIHsKICAvL2NoZWNrCiAgaWYgKCFpc29iaihvYmopKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIGlmICghaXNlc3RyKGtleSkgJiYgIWlzbnVtKGtleSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgcmV0dXJuIGtleSBpbiBvYmo7Cn0KCi8qKg0KICog5o+Q5Y+W6bue6Zmj5YiX5YWn5LmL6bueWzAsMV3miJZ7eCx5feaIluaMh+WumumNteWAvOaIkOeCuum7nnt4LHl954mp5Lu26Zmj5YiXDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvcHRzWFl0b0Fyci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzIOi8uOWFpem7numZo+WIl++8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiX77yM5oiWW1t4MSx5MV0sW3gyLHkyXSwuLi5d6bue5bqn5qiZ6Zmj5YiX5LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7Z45bqn5qiZ6Y215a2X5Liy77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu2eeW6p+aomemNteWtl+S4su+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5SW5kPSdpbmQnXSDovLjlhaXpu57nianku7bmjIfmqJnpjbXlrZfkuLLvvIzpoJDoqK0naW5kJw0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnJldHVybk9iakFycmF5PXRydWVdIOi8uOWFpeaYr+WQpuWbnuWCs+eJqeS7tumZo+WIl++8jOiLpXRydWXku6Pooajlm57lgrPpu57ngrrnianku7Z7eCx5feS5i+mZo+WIl++8jOiLpWZhbHNl5Zue5YKz6bue6Zmj5YiXW3gseV3kuYvpmaPliJfvvIzpoJDoqK10cnVlDQogKiBAcmV0dXJucyB7QXJyYXl9IOWbnuWCs+m7numZo+WIlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCByDQogKg0KICogcHMgPSBbWzI0MywgMjA2XSwgWzIzMywgMjI1XSwgWzIxLCAzMjVdXQ0KICogciA9IHB0c1hZdG9BcnIocHMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7ICd4JzogMjQzLCAneSc6IDIwNiB9LCB7ICd4JzogMjMzLCAneSc6IDIyNSB9LCB7ICd4JzogMjEsICd5JzogMzI1IH1dDQogKiByID0gcHRzWFl0b0FycihwcykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDYsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCBpbmQ6IDEgfSwNCiAqIC8vICAgeyB4OiAyMSwgeTogMzI1LCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgJ2EnOiAyNDMsICdiJzogMjA2IH0sIHsgJ2EnOiAyMzMsICdiJzogMjI1IH0sIHsgJ2EnOiAyMSwgJ2InOiAzMjUgfV0NCiAqIHIgPSBwdHNYWXRvQXJyKHBzLCB7IGtleVg6ICdhJywga2V5WTogJ2InIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKi8KZnVuY3Rpb24gcHRzWFl0b0Fycihwcywgb3B0ID0ge30pIHsKICAvL+iLpeeEoeaVuOaTmuWbnuWCs+epuumZo+WIlwogIGlmIChzaXplKHBzKSA8PSAwKSB7CiAgICByZXR1cm4gW107CiAgfQoKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleUluZAogIGxldCBrZXlJbmQgPSBnZXQob3B0LCAna2V5SW5kJywgJycpOwogIGlmICghaXNlc3RyKGtleUluZCkpIHsKICAgIGtleUluZCA9ICdpbmQnOwogIH0KCiAgLy9yZXR1cm5PYmpBcnJheQogIGxldCByZXR1cm5PYmpBcnJheSA9IGdldChvcHQsICdyZXR1cm5PYmpBcnJheScpOwogIGlmICghaXNib2wocmV0dXJuT2JqQXJyYXkpKSB7CiAgICByZXR1cm5PYmpBcnJheSA9IHRydWU7CiAgfQoKICAvL3JzCiAgbGV0IHJzID0gW107CiAgZm9yRWFjaChwcywgKHYsIGspID0+IHsKICAgIGxldCB4ID0gbnVsbDsKICAgIGxldCB5ID0gbnVsbDsKICAgIGlmIChpc2Fycih2KSAmJiBzaXplKHYpID49IDIpIHsKICAgICAgeCA9IGdldCh2LCAwKTsKICAgICAgeSA9IGdldCh2LCAxKTsKICAgIH0gZWxzZSB7CiAgICAgIHggPSBnZXQodiwga2V5WCwgbnVsbCk7CiAgICAgIHkgPSBnZXQodiwga2V5WSwgbnVsbCk7CiAgICB9CiAgICBpZiAoaXNudW0oeCkgJiYgaXNudW0oeSkpIHsKICAgICAgeCA9IHRvTnVtYmVyKHgpOwogICAgICB5ID0gdG9OdW1iZXIoeSk7CiAgICAgIHJzLnB1c2goewogICAgICAgIHgsCiAgICAgICAgeSwKICAgICAgICBba2V5SW5kXTogawogICAgICB9KTsKICAgIH0KICB9KTsKCiAgLy9yZXR1cm5PYmpBcnJheQogIGlmICghcmV0dXJuT2JqQXJyYXkpIHsKICAgIHJzID0gbWFwKHJzLCB2ID0+IHsKICAgICAgcmV0dXJuIFt2LngsIHYueSwgdltrZXlJbmRdXTsKICAgIH0pOwogIH0KICByZXR1cm4gcnM7Cn0KCi8qKg0KICog5o+Q5Y+W6bue6Zmj5YiX5YWn5LmL6bueWzAsMSwyXeaIlnt4LHksen3miJbmjIflrprpjbXlgLzmiJDngrrpu557eCx5LHp954mp5Lu26Zmj5YiXDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvcHRzWFladG9BcnIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwcyDovLjlhaXpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MSx6OnoxfSx7eDp4Mix5OnkyLHo6ejJ9LC4uLl3pu57nianku7bkuYvpmaPliJfvvIzmiJZbW3gxLHkxLHoxXSxbeDIseTIsejJdLC4uLl3pu57luqfmqJnpmaPliJfkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tnjluqfmqJnpjbXlrZfkuLLvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7Z55bqn5qiZ6Y215a2X5Liy77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd6J10g6Ly45YWl6bue54mp5Lu2euW6p+aomemNteWtl+S4su+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5SW5kPSdpbmQnXSDovLjlhaXpu57nianku7bmjIfmqJnpjbXlrZfkuLLvvIzpoJDoqK0naW5kJw0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnJldHVybk9iakFycmF5PXRydWVdIOi8uOWFpeaYr+WQpuWbnuWCs+eJqeS7tumZo+WIl++8jOiLpXRydWXku6Pooajlm57lgrPpu57ngrrnianku7Z7eCx5LHp95LmL6Zmj5YiX77yM6IulZmFsc2Xlm57lgrPpu57pmaPliJdbeCx5LHpd5LmL6Zmj5YiX77yM6aCQ6KitdHJ1ZQ0KICogQHJldHVybnMge0FycmF5fSDlm57lgrPpu557eCx5LHp96Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHINCiAqDQogKiBwcyA9IFtbMjQzLCAyMDYsIDk1XSwgWzIzMywgMjI1LCAxNDZdLCBbMjEsIDMyNSwgMjJdXQ0KICogciA9IHB0c1hZWnRvQXJyKHBzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNiwgejogOTUsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYsIGluZDogMSB9LA0KICogLy8gICB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyLCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgJ3gnOiAyNDMsICd5JzogMjA2LCAneic6IDk1IH0sIHsgJ3gnOiAyMzMsICd5JzogMjI1LCAneic6IDE0NiB9LCB7ICd4JzogMjEsICd5JzogMzI1LCAneic6IDIyIH1dDQogKiByID0gcHRzWFladG9BcnIocHMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCB6OiA5NSwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgejogMjIsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyAnYSc6IDI0MywgJ2InOiAyMDYsICdjJzogOTUgfSwgeyAnYSc6IDIzMywgJ2InOiAyMjUsICdjJzogMTQ2IH0sIHsgJ2EnOiAyMSwgJ2InOiAzMjUsICdjJzogMjIgfV0NCiAqIHIgPSBwdHNYWVp0b0FycihwcywgeyBrZXlYOiAnYScsIGtleVk6ICdiJywga2V5WjogJ2MnIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCB6OiA5NSwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgejogMjIsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICovCmZ1bmN0aW9uIHB0c1hZWnRvQXJyKHBzLCBvcHQgPSB7fSkgewogIC8v6Iul54Sh5pW45pOa5Zue5YKz56m66Zmj5YiXCiAgaWYgKHNpemUocHMpIDw9IDApIHsKICAgIHJldHVybiBbXTsKICB9CgogIC8va2V5WAogIGxldCBrZXlYID0gZ2V0KG9wdCwgJ2tleVgnKTsKICBpZiAoIWlzZXN0cihrZXlYKSkgewogICAga2V5WCA9ICd4JzsKICB9CgogIC8va2V5WQogIGxldCBrZXlZID0gZ2V0KG9wdCwgJ2tleVknKTsKICBpZiAoIWlzZXN0cihrZXlZKSkgewogICAga2V5WSA9ICd5JzsKICB9CgogIC8va2V5WgogIGxldCBrZXlaID0gZ2V0KG9wdCwgJ2tleVonLCAnJyk7CiAgaWYgKCFpc2VzdHIoa2V5WikpIHsKICAgIGtleVogPSAneic7CiAgfQoKICAvL2tleUluZAogIGxldCBrZXlJbmQgPSBnZXQob3B0LCAna2V5SW5kJywgJycpOwogIGlmICghaXNlc3RyKGtleUluZCkpIHsKICAgIGtleUluZCA9ICdpbmQnOwogIH0KCiAgLy9yZXR1cm5PYmpBcnJheQogIGxldCByZXR1cm5PYmpBcnJheSA9IGdldChvcHQsICdyZXR1cm5PYmpBcnJheScpOwogIGlmICghaXNib2wocmV0dXJuT2JqQXJyYXkpKSB7CiAgICByZXR1cm5PYmpBcnJheSA9IHRydWU7CiAgfQoKICAvL3JzCiAgbGV0IHJzID0gW107CiAgZm9yRWFjaChwcywgKHYsIGspID0+IHsKICAgIGxldCB4ID0gbnVsbDsKICAgIGxldCB5ID0gbnVsbDsKICAgIGxldCB6ID0gbnVsbDsKICAgIGlmIChpc2Fycih2KSAmJiBzaXplKHYpID49IDMpIHsKICAgICAgeCA9IGdldCh2LCAwKTsKICAgICAgeSA9IGdldCh2LCAxKTsKICAgICAgeiA9IGdldCh2LCAyKTsKICAgIH0gZWxzZSB7CiAgICAgIHggPSBnZXQodiwga2V5WCwgbnVsbCk7CiAgICAgIHkgPSBnZXQodiwga2V5WSwgbnVsbCk7CiAgICAgIHogPSBnZXQodiwga2V5WiwgbnVsbCk7CiAgICB9CiAgICBpZiAoaXNudW0oeCkgJiYgaXNudW0oeSkgJiYgaXNudW0oeikpIHsKICAgICAgeCA9IHRvTnVtYmVyKHgpOwogICAgICB5ID0gdG9OdW1iZXIoeSk7CiAgICAgIHogPSB0b051bWJlcih6KTsKICAgICAgcnMucHVzaCh7CiAgICAgICAgeCwKICAgICAgICB5LAogICAgICAgIHosCiAgICAgICAgW2tleUluZF06IGsKICAgICAgfSk7CiAgICB9CiAgfSk7CgogIC8vcmV0dXJuT2JqQXJyYXkKICBpZiAoIXJldHVybk9iakFycmF5KSB7CiAgICBycyA9IG1hcChycywgdiA9PiB7CiAgICAgIHJldHVybiBbdi54LCB2LnksIHYueiwgdltrZXlJbmRdXTsKICAgIH0pOwogIH0KICByZXR1cm4gcnM7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8ubWF4YCBhbmQgYF8ubWluYCB3aGljaCBhY2NlcHRzIGEKICogYGNvbXBhcmF0b3JgIHRvIGRldGVybWluZSB0aGUgZXh0cmVtdW0gdmFsdWUuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGNvbXBhcmF0b3IgdXNlZCB0byBjb21wYXJlIHZhbHVlcy4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGV4dHJlbXVtIHZhbHVlLgogKi8KZnVuY3Rpb24gYmFzZUV4dHJlbXVtKGFycmF5LCBpdGVyYXRlZSwgY29tcGFyYXRvcikgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sCiAgICAgIGN1cnJlbnQgPSBpdGVyYXRlZSh2YWx1ZSk7CiAgICBpZiAoY3VycmVudCAhPSBudWxsICYmIChjb21wdXRlZCA9PT0gdW5kZWZpbmVkID8gY3VycmVudCA9PT0gY3VycmVudCAmJiAhaXNTeW1ib2woY3VycmVudCkgOiBjb21wYXJhdG9yKGN1cnJlbnQsIGNvbXB1dGVkKSkpIHsKICAgICAgdmFyIGNvbXB1dGVkID0gY3VycmVudCwKICAgICAgICByZXN1bHQgPSB2YWx1ZTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmx0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBgb3RoZXJgLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUx0KHZhbHVlLCBvdGhlcikgewogIHJldHVybiB2YWx1ZSA8IG90aGVyOwp9CgovKioKICogQ29tcHV0ZXMgdGhlIG1pbmltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksCiAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgTWF0aAogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZS4KICogQGV4YW1wbGUKICoKICogXy5taW4oWzQsIDIsIDgsIDZdKTsKICogLy8gPT4gMgogKgogKiBfLm1pbihbXSk7CiAqIC8vID0+IHVuZGVmaW5lZAogKi8KZnVuY3Rpb24gbWluKGFycmF5KSB7CiAgcmV0dXJuIGFycmF5ICYmIGFycmF5Lmxlbmd0aCA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHkkMSwgYmFzZUx0KSA6IHVuZGVmaW5lZDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmd0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUd0KHZhbHVlLCBvdGhlcikgewogIHJldHVybiB2YWx1ZSA+IG90aGVyOwp9CgovKioKICogQ29tcHV0ZXMgdGhlIG1heGltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksCiAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgTWF0aAogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZS4KICogQGV4YW1wbGUKICoKICogXy5tYXgoWzQsIDIsIDgsIDZdKTsKICogLy8gPT4gOAogKgogKiBfLm1heChbXSk7CiAqIC8vID0+IHVuZGVmaW5lZAogKi8KZnVuY3Rpb24gbWF4KGFycmF5KSB7CiAgcmV0dXJuIGFycmF5ICYmIGFycmF5Lmxlbmd0aCA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHkkMSwgYmFzZUd0KSA6IHVuZGVmaW5lZDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbHRlcmAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS4KICovCmZ1bmN0aW9uIGJhc2VGaWx0ZXIoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7CiAgdmFyIHJlc3VsdCA9IFtdOwogIGJhc2VFYWNoJDEoY29sbGVjdGlvbiwgZnVuY3Rpb24gKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikgewogICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pKSB7CiAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTsKICAgIH0KICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyBhbiBhcnJheSBvZiBhbGwgZWxlbWVudHMKICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0aHJlZQogKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS4KICoKICogKipOb3RlOioqIFVubGlrZSBgXy5yZW1vdmVgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbgogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuCiAqIEBzZWUgXy5yZWplY3QKICogQGV4YW1wbGUKICoKICogdmFyIHVzZXJzID0gWwogKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LAogKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfQogKiBdOwogKgogKiBfLmZpbHRlcih1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ10KICoKICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC4KICogXy5maWx0ZXIodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXQogKgogKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuCiAqIF8uZmlsdGVyKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7CiAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddCiAqCiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLgogKiBfLmZpbHRlcih1c2VycywgJ2FjdGl2ZScpOwogKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddCiAqCiAqIC8vIENvbWJpbmluZyBzZXZlcmFsIHByZWRpY2F0ZXMgdXNpbmcgYF8ub3ZlckV2ZXJ5YCBvciBgXy5vdmVyU29tZWAuCiAqIF8uZmlsdGVyKHVzZXJzLCBfLm92ZXJTb21lKFt7ICdhZ2UnOiAzNiB9LCBbJ2FnZScsIDQwXV0pKTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ2Jhcm5leSddCiAqLwpmdW5jdGlvbiBmaWx0ZXIoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7CiAgdmFyIGZ1bmMgPSBpc0FycmF5JDEoY29sbGVjdGlvbikgPyBhcnJheUZpbHRlciA6IGJhc2VGaWx0ZXI7CiAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgYmFzZUl0ZXJhdGVlKHByZWRpY2F0ZSkpOwp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovCnZhciBuYXRpdmVDZWlsID0gTWF0aC5jZWlsLAogIG5hdGl2ZU1heCA9IE1hdGgubWF4OwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJhbmdlYCBhbmQgYF8ucmFuZ2VSaWdodGAgd2hpY2ggZG9lc24ndAogKiBjb2VyY2UgYXJndW1lbnRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS4KICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS4KICogQHBhcmFtIHtudW1iZXJ9IHN0ZXAgVGhlIHZhbHVlIHRvIGluY3JlbWVudCBvciBkZWNyZW1lbnQgYnkuCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuCiAqLwpmdW5jdGlvbiBiYXNlUmFuZ2Uoc3RhcnQsIGVuZCwgc3RlcCwgZnJvbVJpZ2h0KSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBuYXRpdmVNYXgobmF0aXZlQ2VpbCgoZW5kIC0gc3RhcnQpIC8gKHN0ZXAgfHwgMSkpLCAwKSwKICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7CiAgd2hpbGUgKGxlbmd0aC0tKSB7CiAgICByZXN1bHRbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF0gPSBzdGFydDsKICAgIHN0YXJ0ICs9IHN0ZXA7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBDaGVja3MgaWYgdGhlIGdpdmVuIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgdmFsdWUgYXJndW1lbnQuCiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuCiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHsKICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7CiAgaWYgKHR5cGUgPT0gJ251bWJlcicgPyBpc0FycmF5TGlrZShvYmplY3QpICYmIGlzSW5kZXgoaW5kZXgsIG9iamVjdC5sZW5ndGgpIDogdHlwZSA9PSAnc3RyaW5nJyAmJiBpbmRleCBpbiBvYmplY3QpIHsKICAgIHJldHVybiBlcShvYmplY3RbaW5kZXhdLCB2YWx1ZSk7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIENyZWF0ZXMgYSBgXy5yYW5nZWAgb3IgYF8ucmFuZ2VSaWdodGAgZnVuY3Rpb24uCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByYW5nZSBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGNyZWF0ZVJhbmdlKGZyb21SaWdodCkgewogIHJldHVybiBmdW5jdGlvbiAoc3RhcnQsIGVuZCwgc3RlcCkgewogICAgaWYgKHN0ZXAgJiYgdHlwZW9mIHN0ZXAgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoc3RhcnQsIGVuZCwgc3RlcCkpIHsKICAgICAgZW5kID0gc3RlcCA9IHVuZGVmaW5lZDsKICAgIH0KICAgIC8vIEVuc3VyZSB0aGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC4KICAgIHN0YXJ0ID0gdG9GaW5pdGUoc3RhcnQpOwogICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIGVuZCA9IHN0YXJ0OwogICAgICBzdGFydCA9IDA7CiAgICB9IGVsc2UgewogICAgICBlbmQgPSB0b0Zpbml0ZShlbmQpOwogICAgfQogICAgc3RlcCA9IHN0ZXAgPT09IHVuZGVmaW5lZCA/IHN0YXJ0IDwgZW5kID8gMSA6IC0xIDogdG9GaW5pdGUoc3RlcCk7CiAgICByZXR1cm4gYmFzZVJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXAsIGZyb21SaWdodCk7CiAgfTsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbnVtYmVycyAocG9zaXRpdmUgYW5kL29yIG5lZ2F0aXZlKSBwcm9ncmVzc2luZyBmcm9tCiAqIGBzdGFydGAgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC4gQSBzdGVwIG9mIGAtMWAgaXMgdXNlZCBpZiBhIG5lZ2F0aXZlCiAqIGBzdGFydGAgaXMgc3BlY2lmaWVkIHdpdGhvdXQgYW4gYGVuZGAgb3IgYHN0ZXBgLiBJZiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkLAogKiBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuCiAqCiAqICoqTm90ZToqKiBKYXZhU2NyaXB0IGZvbGxvd3MgdGhlIElFRUUtNzU0IHN0YW5kYXJkIGZvciByZXNvbHZpbmcKICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IFV0aWwKICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLgogKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLgogKiBAcGFyYW0ge251bWJlcn0gW3N0ZXA9MV0gVGhlIHZhbHVlIHRvIGluY3JlbWVudCBvciBkZWNyZW1lbnQgYnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy4KICogQHNlZSBfLmluUmFuZ2UsIF8ucmFuZ2VSaWdodAogKiBAZXhhbXBsZQogKgogKiBfLnJhbmdlKDQpOwogKiAvLyA9PiBbMCwgMSwgMiwgM10KICoKICogXy5yYW5nZSgtNCk7CiAqIC8vID0+IFswLCAtMSwgLTIsIC0zXQogKgogKiBfLnJhbmdlKDEsIDUpOwogKiAvLyA9PiBbMSwgMiwgMywgNF0KICoKICogXy5yYW5nZSgwLCAyMCwgNSk7CiAqIC8vID0+IFswLCA1LCAxMCwgMTVdCiAqCiAqIF8ucmFuZ2UoMCwgLTQsIC0xKTsKICogLy8gPT4gWzAsIC0xLCAtMiwgLTNdCiAqCiAqIF8ucmFuZ2UoMSwgNCwgMCk7CiAqIC8vID0+IFsxLCAxLCAxXQogKgogKiBfLnJhbmdlKDApOwogKiAvLyA9PiBbXQogKi8KdmFyIHJhbmdlID0gY3JlYXRlUmFuZ2UoKTsKdmFyIHJhbmdlJDEgPSByYW5nZTsKCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgTkFOID0gMCAvIDA7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWVhbmAgYW5kIGBfLm1lYW5CeWAgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLgogKi8KZnVuY3Rpb24gYmFzZU1lYW4oYXJyYXksIGl0ZXJhdGVlKSB7CiAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoOwogIHJldHVybiBsZW5ndGggPyBiYXNlU3VtKGFycmF5LCBpdGVyYXRlZSkgLyBsZW5ndGggOiBOQU47Cn0KCi8qKgogKiBDb21wdXRlcyB0aGUgbWVhbiBvZiB0aGUgdmFsdWVzIGluIGBhcnJheWAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBNYXRoCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG1lYW4uCiAqIEBleGFtcGxlCiAqCiAqIF8ubWVhbihbNCwgMiwgOCwgNl0pOwogKiAvLyA9PiA1CiAqLwpmdW5jdGlvbiBtZWFuKGFycmF5KSB7CiAgcmV0dXJuIGJhc2VNZWFuKGFycmF5LCBpZGVudGl0eSQxKTsKfQoKZnVuY3Rpb24gbm9ybWFsaXplQXJyYXlDb3JlKGFycikgewogIC8vY2hlY2sgcHNTcmMKICBpZiAoIWlzZWFycihhcnIpKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdhcnIgaXMgbm90IGFuIGVmZmVjdGl2ZSBhcnJheScKICAgIH07CiAgfQoKICAvL3YwCiAgbGV0IHYwID0gZ2V0KGFyciwgMCk7CgogIC8vbgogIGxldCBuID0gMDsgLy8xZCBhcnJheQogIGlmIChpc2VhcnIodjApKSB7CiAgICBuID0gc2l6ZSh2MCk7IC8vbmQgYXJyYXkKICB9CgogIC8vZWFycgogIGxldCBlYXJyID0gW107CiAgaWYgKG4gPT09IDApIHsKICAgIGVhcnIgPSBmaWx0ZXIoYXJyLCBpc251bSk7CiAgICBlYXJyID0gbWFwKGVhcnIsIGNkYmwpOwogIH0gZWxzZSB7CiAgICBmb3JFYWNoKGFyciwgdnMgPT4gewogICAgICAvL2IKICAgICAgbGV0IGIgPSB0cnVlOwogICAgICBsZXQgY3MgPSBbXTsKICAgICAgZm9yRWFjaChyYW5nZSQxKG4pLCBpID0+IHsKICAgICAgICAvL3YKICAgICAgICBsZXQgdiA9IGdldCh2cywgaSk7CgogICAgICAgIC8vY2hlY2sKICAgICAgICBpZiAoIWlzbnVtKHYpKSB7CiAgICAgICAgICBiID0gZmFsc2U7CiAgICAgICAgICAvL+i3s+WHuuaPm+S4i+S4gOWAiwogICAgICAgIH0KCiAgICAgICAgLy9wdXNoCiAgICAgICAgY3MucHVzaChjZGJsKHYpKTsKICAgICAgfSk7CgogICAgICAvL2NoZWNrCiAgICAgIGlmIChiKSB7CiAgICAgICAgZWFyci5wdXNoKGNzKTsKICAgICAgfQogICAgfSk7CiAgfQoKICAvL2NoZWNrCiAgaWYgKHNpemUoZWFycikgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ2FyciBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KCiAgLy9zdGEKICBsZXQgc3RhID0gYXJyID0+IHsKICAgIGxldCBybWluID0gbWluKGFycik7CiAgICBsZXQgcm1heCA9IG1heChhcnIpOwogICAgcmV0dXJuIHsKICAgICAgbWluOiBybWluLAogICAgICBtYXg6IHJtYXgsCiAgICAgIHJhbmdlOiBybWF4IC0gcm1pbiwKICAgICAgbWlkOiAocm1heCArIHJtaW4pIC8gMiwKICAgICAgYXZnOiBtZWFuKGFycikKICAgIH07CiAgfTsKCiAgLy9ubWFycgogIGxldCBubWFyciA9IChhcnIsIHJtaW4sIHJtYXgsIHJybmcpID0+IHsKICAgIHJldHVybiBtYXAoYXJyLCB2ID0+IHsKICAgICAgcmV0dXJuICh2IC0gcm1pbikgLyBycm5nOwogICAgfSk7CiAgfTsKCiAgLy9ubQogIGxldCBubSA9IGFyciA9PiB7CiAgICBsZXQgcyA9IHN0YShhcnIpOwogICAgbGV0IGFycnQgPSBubWFycihhcnIsIHMubWluLCBzLm1heCwgcy5yYW5nZSk7CiAgICByZXR1cm4gewogICAgICBhcnI6IGFycnQsCiAgICAgIC4uLnMKICAgIH07CiAgfTsKCiAgLy9yCiAgbGV0IHIgPSBudWxsOwogIGlmIChuID09PSAwKSB7CiAgICByID0gbm0oZWFycik7CiAgfSBlbHNlIHsKICAgIHIgPSBtYXAocmFuZ2UkMShuKSwgaSA9PiB7CiAgICAgIGxldCBlYXJydCA9IG1hcChlYXJyLCBpKTsKICAgICAgcmV0dXJuIG5tKGVhcnJ0KTsKICAgIH0pOwogIH0KICByZXR1cm4gcjsKfQoKLyoqDQogKiDph53lsI3kuIDntq3miJbkuozntq3pmaPliJfmraPopo/ljJYNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9ub3JtYWxpemVBcnJheS50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IGFyciDovLjlhaXos4fmlpnpmaPliJfvvIzngrpbeDEseDIsLi4uXeS5i+S4gOe2remZo+WIl++8jOaIlltbeDEseTFdLFt4Mix5Ml0sLi4uXeS5i+S6jOe2remZo+WIlw0KICogQHJldHVybnMge0FycmF5fE9iamVjdH0g5Zue5YKz5q2j6KaP5YyW5pW45pOa5LmL54mp5Lu25oiW6Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBhcnINCiAqIGxldCByDQogKg0KICogYXJyID0gWw0KICogICAgIFsyNDMsIDIwNiwgOTVdLA0KICogICAgIFsyMzMsIDIyNSwgMTQ2XSwNCiAqICAgICBbMjEsIDMyNSwgMjJdLA0KICogICAgIFs5NTMsIDI4LCAyMjNdLA0KICogICAgIFsxMDkyLCAyOTAsIDM5XSwNCiAqICAgICBbNzQ0LCAyMDAsIDE5MV0sDQogKiAgICAgWzE3NCwgMywgMjJdLA0KICogICAgIFs1MzcsIDM2OCwgMjQ5XSwNCiAqICAgICBbMTE1MSwgMzcxLCA4Nl0sDQogKiAgICAgWzgxNCwgMjUyLCAxMjVdDQogKiBdDQogKiByID0gbm9ybWFsaXplQXJyYXkoYXJyKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC4xOTY0NjAxNzY5OTExNTA0NSwNCiAqIC8vICAgICAgIDAuMTg3NjEwNjE5NDY5MDI2NTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44MjQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgICAgMC45NDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjYzOTgyMzAwODg0OTU1NzYsDQogKiAvLyAgICAgICAwLjEzNTM5ODIzMDA4ODQ5NTU4LA0KICogLy8gICAgICAgMC40NTY2MzcxNjgxNDE1OTI5NCwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjcwMTc2OTkxMTUwNDQyNDgNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMjEsDQogKiAvLyAgICAgbWF4OiAxMTUxLA0KICogLy8gICAgIHJhbmdlOiAxMTMwLA0KICogLy8gICAgIGF2ZzogNTk2LjINCiAqIC8vICAgfSwNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC41NTE2MzA0MzQ3ODI2MDg2LA0KICogLy8gICAgICAgMC42MDMyNjA4Njk1NjUyMTc0LA0KICogLy8gICAgICAgMC44NzUsDQogKiAvLyAgICAgICAwLjA2NzkzNDc4MjYwODY5NTY1LA0KICogLy8gICAgICAgMC43Nzk4OTEzMDQzNDc4MjYsDQogKiAvLyAgICAgICAwLjUzNTMyNjA4Njk1NjUyMTcsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC45OTE4NDc4MjYwODY5NTY1LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNjc2NjMwNDM0NzgyNjA4Ng0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAzLA0KICogLy8gICAgIG1heDogMzcxLA0KICogLy8gICAgIHJhbmdlOiAzNjgsDQogKiAvLyAgICAgYXZnOiAyMjYuOA0KICogLy8gICB9LA0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjMyMTU4NTkwMzA4MzcwMDQ0LA0KICogLy8gICAgICAgMC41NDYyNTU1MDY2MDc5Mjk1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODg1NDYyNTU1MDY2MDc5MywNCiAqIC8vICAgICAgIDAuMDc0ODg5ODY3ODQxNDA5NjksDQogKiAvLyAgICAgICAwLjc0NDQ5MzM5MjA3MDQ4NDYsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuMjgxOTM4MzI1OTkxMTg5NDUsDQogKiAvLyAgICAgICAwLjQ1Mzc0NDQ5MzM5MjA3MDQ2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDIyLA0KICogLy8gICAgIG1heDogMjQ5LA0KICogLy8gICAgIHJhbmdlOiAyMjcsDQogKiAvLyAgICAgYXZnOiAxMTkuOA0KICogLy8gICB9DQogKiAvLyBdDQogKg0KICogYXJyID0gWw0KICogICAgIDI0MywgMjMzLCAyMSwNCiAqICAgICA5NTMsIDEwOTIsIDc0NCwNCiAqICAgICAxNzQsIDUzNywgMTE1MSwNCiAqICAgICA4MTQNCiAqIF0NCiAqIHIgPSBub3JtYWxpemVBcnJheShhcnIpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gew0KICogLy8gICBhcnI6IFsNCiAqIC8vICAgICAwLjE5NjQ2MDE3Njk5MTE1MDQ1LA0KICogLy8gICAgIDAuMTg3NjEwNjE5NDY5MDI2NTUsDQogKiAvLyAgICAgMCwNCiAqIC8vICAgICAwLjgyNDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgMC45NDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgMC42Mzk4MjMwMDg4NDk1NTc2LA0KICogLy8gICAgIDAuMTM1Mzk4MjMwMDg4NDk1NTgsDQogKiAvLyAgICAgMC40NTY2MzcxNjgxNDE1OTI5NCwNCiAqIC8vICAgICAxLA0KICogLy8gICAgIDAuNzAxNzY5OTExNTA0NDI0OA0KICogLy8gICBdLA0KICogLy8gICBtaW46IDIxLA0KICogLy8gICBtYXg6IDExNTEsDQogKiAvLyAgIHJhbmdlOiAxMTMwLA0KICogLy8gICBhdmc6IDU5Ni4yDQogKiAvLyB9DQogKg0KICogYXJyID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiByID0gbm9ybWFsaXplQXJyYXkoYXJyLCBbJ3gnLCAneScsICd6J10pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjE5NjQ2MDE3Njk5MTE1MDQ1LA0KICogLy8gICAgICAgMC4xODc2MTA2MTk0NjkwMjY1NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjgyNDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjk0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuNjM5ODIzMDA4ODQ5NTU3NiwNCiAqIC8vICAgICAgIDAuMTM1Mzk4MjMwMDg4NDk1NTgsDQogKiAvLyAgICAgICAwLjQ1NjYzNzE2ODE0MTU5Mjk0LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNzAxNzY5OTExNTA0NDI0OA0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAyMSwNCiAqIC8vICAgICBtYXg6IDExNTEsDQogKiAvLyAgICAgcmFuZ2U6IDExMzAsDQogKiAvLyAgICAgYXZnOiA1OTYuMg0KICogLy8gICB9LA0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjU1MTYzMDQzNDc4MjYwODYsDQogKiAvLyAgICAgICAwLjYwMzI2MDg2OTU2NTIxNzQsDQogKiAvLyAgICAgICAwLjg3NSwNCiAqIC8vICAgICAgIDAuMDY3OTM0NzgyNjA4Njk1NjUsDQogKiAvLyAgICAgICAwLjc3OTg5MTMwNDM0NzgyNiwNCiAqIC8vICAgICAgIDAuNTM1MzI2MDg2OTU2NTIxNywNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjk5MTg0NzgyNjA4Njk1NjUsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC42NzY2MzA0MzQ3ODI2MDg2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDMsDQogKiAvLyAgICAgbWF4OiAzNzEsDQogKiAvLyAgICAgcmFuZ2U6IDM2OCwNCiAqIC8vICAgICBhdmc6IDIyNi44DQogKiAvLyAgIH0sDQogKiAvLyAgIHsNCiAqIC8vICAgICBhcnI6IFsNCiAqIC8vICAgICAgIDAuMzIxNTg1OTAzMDgzNzAwNDQsDQogKiAvLyAgICAgICAwLjU0NjI1NTUwNjYwNzkyOTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44ODU0NjI1NTUwNjYwNzkzLA0KICogLy8gICAgICAgMC4wNzQ4ODk4Njc4NDE0MDk2OSwNCiAqIC8vICAgICAgIDAuNzQ0NDkzMzkyMDcwNDg0NiwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC4yODE5MzgzMjU5OTExODk0NSwNCiAqIC8vICAgICAgIDAuNDUzNzQ0NDkzMzkyMDcwNDYNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMjIsDQogKiAvLyAgICAgbWF4OiAyNDksDQogKiAvLyAgICAgcmFuZ2U6IDIyNywNCiAqIC8vICAgICBhdmc6IDExOS44DQogKiAvLyAgIH0NCiAqIC8vIF0NCiAqDQogKi8KZnVuY3Rpb24gbm9ybWFsaXplQXJyYXkoYXJyLCBrZXlzID0gW10pIHsKICAvL2NoZWNrIHBzU3JjCiAgaWYgKCFpc2VhcnIoYXJyKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAnYXJyIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXknCiAgICB9OwogIH0KCiAgLy9rZXlzCiAgaWYgKHNpemUoa2V5cykgPiAwKSB7CiAgICAvL2NoZWNrCiAgICBsZXQgdjAgPSBnZXQoYXJyLCAwKTsKICAgIGlmICghaXNlb2JqKHYwKSkgewogICAgICByZXR1cm4gewogICAgICAgIGVycjogJ2FyciBpcyBub3QgYW4gZWZmZWN0aXZlIGFycmF5IG9mIG9iamVjdHMnCiAgICAgIH07CiAgICB9CgogICAgLy9hcnJ0LCDmj5Dlj5bmjIflrpprZXlzCiAgICBsZXQgYXJydCA9IFtdOwogICAgZm9yRWFjaChhcnIsIGR0ID0+IHsKICAgICAgbGV0IGNzID0gW107CiAgICAgIGZvckVhY2goa2V5cywgayA9PiB7CiAgICAgICAgY3MucHVzaChnZXQoZHQsIGssICcnKSk7CiAgICAgIH0pOwogICAgICBhcnJ0LnB1c2goY3MpOwogICAgfSk7CgogICAgLy9zYXZlCiAgICBhcnIgPSBhcnJ0OwogIH0KCiAgLy9ub3JtYWxpemVBcnJheUNvcmUKICBsZXQgciA9IG5vcm1hbGl6ZUFycmF5Q29yZShhcnIpOwogIHJldHVybiByOwp9CgovKioNCiAqIOWFp+aPkueUqOato+imj+WMluaVuOaTmg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ludGVycDJOb3JtYWxpemUudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwcyDovLjlhaXkuozntq3luqfmqJnliqDop4DmuKzmlbjmk5rpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MSx6OnoxfSx7eDp4Mix5OnkyLHo6ejJ9LC4uLl3pu57nianku7bkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tuS5i3jmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7bkuYt55qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlaPSd6J10g6Ly45YWl6bue54mp5Lu25LmLeuashOS9jeWtl+S4su+8jOeCuuingOa4rOWAvO+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5SW5kPSdpbmQnXSDovLjlhaXpu57nianku7bkuYtpbmTmrITkvY3lrZfkuLLvvIzmraPopo/ljJblvozlj6/lj43mn6Xljp/lp4vmlbjmk5rkuYvmjIfmqJnvvIzpoJDoqK0naW5kJw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2NhbGU9MV0g6Ly45YWl5q2j6KaP5YyW56+E5ZyN5pW45YC877yM5Zug6JmV55CG5aSa6YKK5b2i5pmC5pyJ5pW45YC85a656Kix6Kqk5beu77yM5pWF6aCI6YCa6YGO57iu5pS+5YC85Z+f5L6G5rib5bCR5ZWP6aGM77yM6aCQ6KitMeaYr+ato+imj+WMljDoh7Mx5LmL6ZaT77yM5L2/55Soc2NhbGVYWeWJh+aYr+ato+imj+WMlueCujDoh7NzY2FsZVhZ5LmL6ZaT77yM6aCQ6KitMQ0KICogQHJldHVybnMge09iamVjdH0g5Zue5YKz5q2j6KaP5YyW5pW45pOa54mp5Lu2DQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHINCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogciA9IGludGVycDJOb3JtYWxpemUocHMpDQogKiBkZWxldGUgci5udg0KICogZGVsZXRlIHIuaW52DQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IHsicHMiOlt7IngiOjAuMTk2NDYwMTc2OTkxMTUwNDUsInkiOjAuNTE2ODE0MTU5MjkyMDM1NCwieiI6MC4zMjE1ODU5MDMwODM3MDA0NCwiaW5kIjpudWxsfSx7IngiOjAuMTg3NjEwNjE5NDY5MDI2NTUsInkiOjAuNTMzNjI4MzE4NTg0MDcwOCwieiI6MC41NDYyNTU1MDY2MDc5Mjk1LCJpbmQiOm51bGx9LHsieCI6MCwieSI6MC42MjIxMjM4OTM4MDUzMDk3LCJ6IjowLCJpbmQiOm51bGx9LHsieCI6MC44MjQ3Nzg3NjEwNjE5NDY5LCJ5IjowLjM1OTI5MjAzNTM5ODIzMDA3LCJ6IjowLjg4NTQ2MjU1NTA2NjA3OTMsImluZCI6bnVsbH0seyJ4IjowLjk0Nzc4NzYxMDYxOTQ2OSwieSI6MC41OTExNTA0NDI0Nzc4NzYxLCJ6IjowLjA3NDg4OTg2Nzg0MTQwOTY5LCJpbmQiOm51bGx9LHsieCI6MC42Mzk4MjMwMDg4NDk1NTc2LCJ5IjowLjUxMTUwNDQyNDc3ODc2MSwieiI6MC43NDQ0OTMzOTIwNzA0ODQ2LCJpbmQiOm51bGx9LHsieCI6MC4xMzUzOTgyMzAwODg0OTU1OCwieSI6MC4zMzcxNjgxNDE1OTI5MjAzNiwieiI6MCwiaW5kIjpudWxsfSx7IngiOjAuNDU2NjM3MTY4MTQxNTkyOTQsInkiOjAuNjYwMTc2OTkxMTUwNDQyNSwieiI6MSwiaW5kIjpudWxsfSx7IngiOjEsInkiOjAuNjYyODMxODU4NDA3MDc5NywieiI6MC4yODE5MzgzMjU5OTExODk0NSwiaW5kIjpudWxsfSx7IngiOjAuNzAxNzY5OTExNTA0NDI0OCwieSI6MC41NTc1MjIxMjM4OTM4MDUzLCJ6IjowLjQ1Mzc0NDQ5MzM5MjA3MDQ2LCJpbmQiOm51bGx9XSwicHNNaW5NYXgiOnsieG1pbiI6MCwieG1heCI6MSwieW1pbiI6MC4zMzcxNjgxNDE1OTI5MjAzNiwieW1heCI6MC42NjI4MzE4NTg0MDcwNzk3LCJ6bWluIjowLCJ6bWF4IjoxfSwic3QiOnsieCI6eyJtaW4iOjIxLCJtYXgiOjExNTEsInJhbmdlIjoxMTMwfSwieSI6eyJtaW4iOi0zNzgsIm1heCI6NzUyLCJyYW5nZSI6MTEzMH0sInoiOnsibWluIjoyMiwibWF4IjoyNDksInJhbmdlIjoyMjd9fX0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogciA9IGludGVycDJOb3JtYWxpemUocHMsIHsgc2NhbGU6IDEwMCB9KQ0KICogZGVsZXRlIHIubnYNCiAqIGRlbGV0ZSByLmludg0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiB7InBzIjpbeyJ4IjoxOS42NDYwMTc2OTkxMTUwNDUsInkiOjUxLjY4MTQxNTkyOTIwMzU0NiwieiI6MzIuMTU4NTkwMzA4MzcwMDQ0LCJpbmQiOm51bGx9LHsieCI6MTguNzYxMDYxOTQ2OTAyNjU0LCJ5Ijo1My4zNjI4MzE4NTg0MDcwOCwieiI6NTQuNjI1NTUwNjYwNzkyOTUsImluZCI6bnVsbH0seyJ4IjowLCJ5Ijo2Mi4yMTIzODkzODA1MzA5NywieiI6MCwiaW5kIjpudWxsfSx7IngiOjgyLjQ3Nzg3NjEwNjE5NDY5LCJ5IjozNS45MjkyMDM1Mzk4MjMwMSwieiI6ODguNTQ2MjU1NTA2NjA3OTMsImluZCI6bnVsbH0seyJ4Ijo5NC43Nzg3NjEwNjE5NDY5MSwieSI6NTkuMTE1MDQ0MjQ3Nzg3NjEsInoiOjcuNDg4OTg2Nzg0MTQwOTY5LCJpbmQiOm51bGx9LHsieCI6NjMuOTgyMzAwODg0OTU1NzU1LCJ5Ijo1MS4xNTA0NDI0Nzc4NzYxLCJ6Ijo3NC40NDkzMzkyMDcwNDg0NSwiaW5kIjpudWxsfSx7IngiOjEzLjUzOTgyMzAwODg0OTU1OCwieSI6MzMuNzE2ODE0MTU5MjkyMDM1LCJ6IjowLCJpbmQiOm51bGx9LHsieCI6NDUuNjYzNzE2ODE0MTU5Mjk0LCJ5Ijo2Ni4wMTc2OTkxMTUwNDQyNSwieiI6MTAwLCJpbmQiOm51bGx9LHsieCI6MTAwLCJ5Ijo2Ni4yODMxODU4NDA3MDc5NywieiI6MjguMTkzODMyNTk5MTE4OTQ1LCJpbmQiOm51bGx9LHsieCI6NzAuMTc2OTkxMTUwNDQyNDgsInkiOjU1Ljc1MjIxMjM4OTM4MDUzLCJ6Ijo0NS4zNzQ0NDkzMzkyMDcwNSwiaW5kIjpudWxsfV0sInBzTWluTWF4Ijp7InhtaW4iOjAsInhtYXgiOjEwMCwieW1pbiI6MzMuNzE2ODE0MTU5MjkyMDM1LCJ5bWF4Ijo2Ni4yODMxODU4NDA3MDc5Nywiem1pbiI6MCwiem1heCI6MTAwfSwic3QiOnsieCI6eyJtaW4iOjIxLCJtYXgiOjExNTEsInJhbmdlIjoxMTMwfSwieSI6eyJtaW4iOi0zNzgsIm1heCI6NzUyLCJyYW5nZSI6MTEzMH0sInoiOnsibWluIjoyMiwibWF4IjoyNDksInJhbmdlIjoyMjd9fX0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSwgaW5kOiAxMDEgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2LCBpbmQ6IDEwMiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyLCBpbmQ6IDEwMyB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMywgaW5kOiAxMDQgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5LCBpbmQ6IDEwNSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEsIGluZDogMTA2IH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiwgaW5kOiAxMDcgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5LCBpbmQ6IDEwOCB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYsIGluZDogMTA5IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSwgaW5kOiAxMTAgfV0NCiAqIHIgPSBpbnRlcnAyTm9ybWFsaXplKHBzLCB7IGtleUluZDogJ2luZCcgfSkNCiAqIGRlbGV0ZSByLm52DQogKiBkZWxldGUgci5pbnYNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4geyJwcyI6W3sieCI6MC4xOTY0NjAxNzY5OTExNTA0NSwieSI6MC41MTY4MTQxNTkyOTIwMzU0LCJ6IjowLjMyMTU4NTkwMzA4MzcwMDQ0LCJpbmQiOjEwMX0seyJ4IjowLjE4NzYxMDYxOTQ2OTAyNjU1LCJ5IjowLjUzMzYyODMxODU4NDA3MDgsInoiOjAuNTQ2MjU1NTA2NjA3OTI5NSwiaW5kIjoxMDJ9LHsieCI6MCwieSI6MC42MjIxMjM4OTM4MDUzMDk3LCJ6IjowLCJpbmQiOjEwM30seyJ4IjowLjgyNDc3ODc2MTA2MTk0NjksInkiOjAuMzU5MjkyMDM1Mzk4MjMwMDcsInoiOjAuODg1NDYyNTU1MDY2MDc5MywiaW5kIjoxMDR9LHsieCI6MC45NDc3ODc2MTA2MTk0NjksInkiOjAuNTkxMTUwNDQyNDc3ODc2MSwieiI6MC4wNzQ4ODk4Njc4NDE0MDk2OSwiaW5kIjoxMDV9LHsieCI6MC42Mzk4MjMwMDg4NDk1NTc2LCJ5IjowLjUxMTUwNDQyNDc3ODc2MSwieiI6MC43NDQ0OTMzOTIwNzA0ODQ2LCJpbmQiOjEwNn0seyJ4IjowLjEzNTM5ODIzMDA4ODQ5NTU4LCJ5IjowLjMzNzE2ODE0MTU5MjkyMDM2LCJ6IjowLCJpbmQiOjEwN30seyJ4IjowLjQ1NjYzNzE2ODE0MTU5Mjk0LCJ5IjowLjY2MDE3Njk5MTE1MDQ0MjUsInoiOjEsImluZCI6MTA4fSx7IngiOjEsInkiOjAuNjYyODMxODU4NDA3MDc5NywieiI6MC4yODE5MzgzMjU5OTExODk0NSwiaW5kIjoxMDl9LHsieCI6MC43MDE3Njk5MTE1MDQ0MjQ4LCJ5IjowLjU1NzUyMjEyMzg5MzgwNTMsInoiOjAuNDUzNzQ0NDkzMzkyMDcwNDYsImluZCI6MTEwfV0sInBzTWluTWF4Ijp7InhtaW4iOjAsInhtYXgiOjEsInltaW4iOjAuMzM3MTY4MTQxNTkyOTIwMzYsInltYXgiOjAuNjYyODMxODU4NDA3MDc5Nywiem1pbiI6MCwiem1heCI6MX0sInN0Ijp7IngiOnsibWluIjoyMSwibWF4IjoxMTUxLCJyYW5nZSI6MTEzMH0sInkiOnsibWluIjotMzc4LCJtYXgiOjc1MiwicmFuZ2UiOjExMzB9LCJ6Ijp7Im1pbiI6MjIsIm1heCI6MjQ5LCJyYW5nZSI6MjI3fX19DQogKg0KICovCmZ1bmN0aW9uIGludGVycDJOb3JtYWxpemUocHMsIG9wdCA9IHt9KSB7CiAgLy9rZXlYCiAgbGV0IGtleVggPSBnZXQob3B0LCAna2V5WCcpOwogIGlmICghaXNlc3RyKGtleVgpKSB7CiAgICBrZXlYID0gJ3gnOwogIH0KCiAgLy9rZXlZCiAgbGV0IGtleVkgPSBnZXQob3B0LCAna2V5WScpOwogIGlmICghaXNlc3RyKGtleVkpKSB7CiAgICBrZXlZID0gJ3knOwogIH0KCiAgLy9rZXlaCiAgbGV0IGtleVogPSBnZXQob3B0LCAna2V5WicsICcnKTsKICBpZiAoIWlzZXN0cihrZXlaKSkgewogICAga2V5WiA9ICd6JzsKICB9CgogIC8va2V5SW5kCiAgbGV0IGtleUluZCA9IGdldChvcHQsICdrZXlJbmQnLCAnJyk7CiAgaWYgKCFpc2VzdHIoa2V5SW5kKSkgewogICAga2V5SW5kID0gJ2luZCc7CiAgfQoKICAvL3NjYWxlCiAgbGV0IHNjYWxlID0gZ2V0KG9wdCwgJ3NjYWxlJyk7CiAgaWYgKCFpc251bShzY2FsZSkpIHsKICAgIHNjYWxlID0gMTsKICB9CiAgc2NhbGUgPSBjZGJsKHNjYWxlKTsKICBpZiAoc2NhbGUgPD0gMCkgewogICAgdGhyb3cgbmV3IEVycm9yKGBzY2FsZSBuZWVkID49IDBgKTsKICB9CiAgLy8gY29uc29sZS5sb2coJ3NjYWxlJywgc2NhbGUpCgogIC8vbngsIG55LCBuegogIGxldCBueCA9IG5vcm1hbGl6ZUFycmF5KG1hcChwcywga2V5WCkpOwogIGxldCBueSA9IG5vcm1hbGl6ZUFycmF5KG1hcChwcywga2V5WSkpOwogIGxldCBueiA9IG5vcm1hbGl6ZUFycmF5KG1hcChwcywga2V5WikpOwogIC8vIGNvbnNvbGUubG9nKCdueCcsIG54KQogIC8vIGNvbnNvbGUubG9nKCdueScsIG55KQogIC8vIGNvbnNvbGUubG9nKCdueicsIG56KQoKICAvL3JhbmdlWFkKICBsZXQgcmFuZ2VYWSA9IE1hdGgubWF4KG54LnJhbmdlLCBueS5yYW5nZSk7CgogIC8vcmFuZ2VYWUhhbGYKICBsZXQgcmFuZ2VYWUhhbGYgPSByYW5nZVhZIC8gMjsKCiAgLy9zdCwgeCx55L2/55So5ZCM57ay5qC85bC65a+457iu5pS+CiAgbGV0IHN0ID0gewogICAgeDogewogICAgICBtaW46IG54Lm1pZCAtIHJhbmdlWFlIYWxmLAogICAgICBtYXg6IG54Lm1pZCArIHJhbmdlWFlIYWxmLAogICAgICByYW5nZTogcmFuZ2VYWQogICAgfSwKICAgIHk6IHsKICAgICAgbWluOiBueS5taWQgLSByYW5nZVhZSGFsZiwKICAgICAgbWF4OiBueS5taWQgKyByYW5nZVhZSGFsZiwKICAgICAgcmFuZ2U6IHJhbmdlWFkKICAgIH0sCiAgICB6OiB7CiAgICAgIG1pbjogbnoubWluLAogICAgICBtYXg6IG56Lm1heCwKICAgICAgcmFuZ2U6IG56LnJhbmdlCiAgICB9CiAgfTsKICAvLyBjb25zb2xlLmxvZygnc3QnLCBzdCkKCiAgLy9udgogIGxldCBudiA9ICh2LCBkaXIpID0+IHsKICAgIGlmICghaXNOdW1iZXIodikpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZiAoc3RbZGlyXS5yYW5nZSA8PSAwKSB7CiAgICAgIHJldHVybiB2OwogICAgfQogICAgcmV0dXJuICh2IC0gc3RbZGlyXS5taW4pIC8gc3RbZGlyXS5yYW5nZSAqIHNjYWxlOwogIH07CgogIC8vaW52CiAgbGV0IGludiA9IChpdiwgZGlyKSA9PiB7CiAgICBpZiAoIWlzTnVtYmVyKGl2KSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGlmIChzY2FsZSA8PSAwKSB7CiAgICAgIHJldHVybiBpdjsKICAgIH0KICAgIHJldHVybiBpdiAvIHNjYWxlICogc3RbZGlyXS5yYW5nZSArIHN0W2Rpcl0ubWluOwogIH07CgogIC8vbm9ybWFsaXplIHBzCiAgcHMgPSBtYXAocHMsIHYgPT4gewogICAgbGV0IHggPSBudih2W2tleVhdLCAneCcpOwogICAgbGV0IHkgPSBudih2W2tleVldLCAneScpOwogICAgbGV0IHogPSBudih2W2tleVpdLCAneicpOwogICAgbGV0IGluZCA9IGdldCh2LCBrZXlJbmQsIG51bGwpOwogICAgcmV0dXJuIHsKICAgICAgW2tleVhdOiB4LAogICAgICBba2V5WV06IHksCiAgICAgIFtrZXlaXTogeiwKICAgICAgW2tleUluZF06IGluZAogICAgfTsKICB9KTsKICAvLyBjb25zb2xlLmxvZygnbm9ybWFsaXplIHBzJywgcHMpCgogIC8vcHNNaW5NYXgKICBsZXQgcHN4ID0gbWFwKHBzLCBrZXlYKTsKICBsZXQgcHN4TWluID0gbWluKHBzeCk7CiAgbGV0IHBzeE1heCA9IG1heChwc3gpOwogIGxldCBwc3kgPSBtYXAocHMsIGtleVkpOwogIGxldCBwc3lNaW4gPSBtaW4ocHN5KTsKICBsZXQgcHN5TWF4ID0gbWF4KHBzeSk7CiAgbGV0IHBzeiA9IG1hcChwcywga2V5Wik7CiAgbGV0IHBzek1pbiA9IG1pbihwc3opOwogIGxldCBwc3pNYXggPSBtYXgocHN6KTsKICBsZXQgcHNNaW5NYXggPSB7CiAgICB4bWluOiBwc3hNaW4sCiAgICB4bWF4OiBwc3hNYXgsCiAgICB5bWluOiBwc3lNaW4sCiAgICB5bWF4OiBwc3lNYXgsCiAgICB6bWluOiBwc3pNaW4sCiAgICB6bWF4OiBwc3pNYXgKICB9OwogIHJldHVybiB7CiAgICBwcywKICAgIHBzTWluTWF4LAogICAgc3QsCiAgICBudiwKICAgIGludgogIH07Cn0KCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3ByZWFkYWJsZVN5bWJvbCA9IFN5bWJvbCQxID8gU3ltYm9sJDEuaXNDb25jYXRTcHJlYWRhYmxlIDogdW5kZWZpbmVkOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgZmxhdHRlbmFibGUgYGFyZ3VtZW50c2Agb2JqZWN0IG9yIGFycmF5LgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZmxhdHRlbmFibGUsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzRmxhdHRlbmFibGUodmFsdWUpIHsKICByZXR1cm4gaXNBcnJheSQxKHZhbHVlKSB8fCBpc0FyZ3VtZW50cyQxKHZhbHVlKSB8fCAhIShzcHJlYWRhYmxlU3ltYm9sICYmIHZhbHVlICYmIHZhbHVlW3NwcmVhZGFibGVTeW1ib2xdKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZsYXR0ZW5gIHdpdGggc3VwcG9ydCBmb3IgcmVzdHJpY3RpbmcgZmxhdHRlbmluZy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uCiAqIEBwYXJhbSB7bnVtYmVyfSBkZXB0aCBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGguCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3ByZWRpY2F0ZT1pc0ZsYXR0ZW5hYmxlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcGFyYW0ge2Jvb2xlYW59IFtpc1N0cmljdF0gUmVzdHJpY3QgdG8gdmFsdWVzIHRoYXQgcGFzcyBgcHJlZGljYXRlYCBjaGVja3MuCiAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHQ9W11dIFRoZSBpbml0aWFsIHJlc3VsdCB2YWx1ZS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LgogKi8KZnVuY3Rpb24gYmFzZUZsYXR0ZW4oYXJyYXksIGRlcHRoLCBwcmVkaWNhdGUsIGlzU3RyaWN0LCByZXN1bHQpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsKICBwcmVkaWNhdGUgfHwgKHByZWRpY2F0ZSA9IGlzRmxhdHRlbmFibGUpOwogIHJlc3VsdCB8fCAocmVzdWx0ID0gW10pOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07CiAgICBpZiAoZGVwdGggPiAwICYmIHByZWRpY2F0ZSh2YWx1ZSkpIHsKICAgICAgaWYgKGRlcHRoID4gMSkgewogICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGZsYXR0ZW4gYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGRlcHRoIC0gMSwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcnJheVB1c2gocmVzdWx0LCB2YWx1ZSk7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoIWlzU3RyaWN0KSB7CiAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IHZhbHVlOwogICAgfQogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgQXJyYXkKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS4KICogQGV4YW1wbGUKICoKICogXy5mbGF0dGVuKFsxLCBbMiwgWzMsIFs0XV0sIDVdXSk7CiAqIC8vID0+IFsxLCAyLCBbMywgWzRdXSwgNV0KICovCmZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHsKICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7CiAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCAxKSA6IFtdOwp9CgovKioNCiAqIOioiOeul+aVuOaTmuWFp+m7nueJqeS7tua3seW6pg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2dldFBvaW50RGVwdGgudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge09iamVjdH0gcCDovLjlhaXpu57luqfmqJnnianku7YNCiAqIEByZXR1cm5zIHtJbnRlZ2VyfSDlm57lgrPmt7HluqbmlbTmlbgNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHANCiAqIGxldCByDQogKg0KICogdHJ5IHsNCiAqICAgICBwID0gW1tbW1sxLCAyLjVdLCBbMS4xLCAyLjNdXV1dXQ0KICogICAgIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiB9DQogKiBjYXRjaCAoZXJyKSB7DQogKiAgICAgciA9IGVyci5tZXNzYWdlDQogKiB9DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gaW52YWxpZCBwW1tbW1tbMSwyLjVdLFsxLjEsMi4zXV1dXV1dDQogKg0KICogcCA9IFtbW1sxLCAyLjVdLCBbMS4xLCAyLjNdXV1dDQogKiByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDMNCiAqDQogKiBwID0gW1tbWzEsIDIuNV1dXV0NCiAqIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMw0KICoNCiAqIHAgPSBbW1sxLCAyLjVdXV0NCiAqIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMg0KICoNCiAqIHAgPSBbWzEsIDIuNV1dDQogKiByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDENCiAqDQogKiB0cnkgew0KICogICAgIHAgPSBbeyB4OiAxLCB5OiAyLjUgfV0NCiAqICAgICByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogfQ0KICogY2F0Y2ggKGVycikgew0KICogICAgIHIgPSBlcnIubWVzc2FnZQ0KICogfQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IGludmFsaWQgcFtbeyJ4IjoxLCJ5IjoyLjV9XV0NCiAqDQogKi8KZnVuY3Rpb24gZ2V0UG9pbnREZXB0aChwKSB7CiAgbGV0IHYxID0gZ2V0KHAsICcwJywgbnVsbCk7CiAgbGV0IGlwMSA9IHNpemUodjEpOwogIGxldCB0MSA9IGlzTnVtYmVyKHYxKTsKICBsZXQgdjIgPSBnZXQocCwgJzAuMCcsIG51bGwpOwogIGxldCBpcDIgPSBzaXplKHYyKTsKICBsZXQgdDIgPSBpc051bWJlcih2Mik7CiAgbGV0IHYzID0gZ2V0KHAsICcwLjAuMCcsIG51bGwpOwogIGxldCBpcDMgPSBzaXplKHYzKTsKICBsZXQgdDMgPSBpc051bWJlcih2Myk7CiAgbGV0IHY0ID0gZ2V0KHAsICcwLjAuMC4wJywgbnVsbCk7CiAgLy8gbGV0IGlwNCA9IHNpemUodjQpCiAgbGV0IHQ0ID0gaXNOdW1iZXIodjQpOwogIGlmIChpcDMgPT09IDIgJiYgdDQpIHsKICAgIHJldHVybiAzOwogIH0KICBpZiAoaXAyID09PSAyICYmIHQzKSB7CiAgICByZXR1cm4gMjsKICB9CiAgaWYgKGlwMSA9PT0gMiAmJiB0MikgewogICAgcmV0dXJuIDE7CiAgfQogIGlmIChpcDEgPT09IDAgJiYgdDEpIHsKICAgIHJldHVybiAwOwogIH0KICAvLyBjb25zb2xlLmxvZygndjEnLCB2MSwgJ2lwMScsIGlwMSwgJ3QyJywgdDIpCiAgLy8gY29uc29sZS5sb2coJ3YyJywgdjIsICdpcDInLCBpcDIsICd0MycsIHQzKQogIC8vIGNvbnNvbGUubG9nKCd2MycsIHYzLCAnaXAzJywgaXAzLCAndDQnLCB0NCkKICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgcFske0pTT04uc3RyaW5naWZ5KHApfV1gKTsKfQoKLyoqDQogKiDovYnmj5tSaW5nU3RyaW5n44CBcG9seWdvbuOAgU11bHRpUG9seWdvbuaIkOeCulBvbHlnb24NCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC90b1BvbHlnb24udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSB2IOi8uOWFpeizh+aWmemZo+WIlw0KICogQHJldHVybnMge0FycmF5fSDlm57lgrPos4fmlpnpmaPliJcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHJzDQogKiBsZXQgcg0KICoNCiAqIHJzID0gWyAvL3JpbmdTdHJpbmcNCiAqICAgICBbMCwgMF0sDQogKiAgICAgWzEwMCwgMF0sDQogKiAgICAgWzEwMCwgMV0sDQogKiAgICAgWzAsIDFdLA0KICogICAgIFswLCAwXSwgLy/plonlkIgNCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdLFswLDBdXV0NCiAqDQogKiBycyA9IFsgLy9yaW5nU3RyaW5nDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXV0NCiAqDQogKiBycyA9IFsgLy9wb2x5Z29uDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXV0NCiAqDQogKiBycyA9IFsgLy9wb2x5Z29uDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gdG9Qb2x5Z29uKHJzKQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxMCwwXSxbMTAsMV0sWzAsMV1dXQ0KICoNCiAqIHJzID0gWyAvL3BvbHlnb24NCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXSwNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwLCAwXSwNCiAqICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXSxbWzAsMF0sWzEwLDBdLFsxMCwxXSxbMCwxXV1dDQogKg0KICogcnMgPSBbIC8vbXVsdGlQb2x5Z29uDQogKiAgICAgWw0KICogICAgICAgICBbDQogKiAgICAgICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICAgICAgWzAsIDFdLA0KICogICAgICAgICBdLA0KICogICAgICAgICBbDQogKiAgICAgICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgICAgICBbMTAsIDBdLA0KICogICAgICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgICAgIFswLCAxXSwNCiAqICAgICAgICAgXQ0KICogICAgIF0NCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXSxbWzAsMF0sWzEwLDBdLFsxMCwxXSxbMCwxXV1dDQogKg0KICovCmZ1bmN0aW9uIHRvUG9seWdvbih2KSB7CiAgbGV0IGQgPSBnZXRQb2ludERlcHRoKHYpOwogIGlmIChkID09PSAzKSB7CiAgICByZXR1cm4gZmxhdHRlbih2KTsKICB9IGVsc2UgaWYgKGQgPT09IDIpIHsKICAgIHJldHVybiB2OwogIH0gZWxzZSBpZiAoZCA9PT0gMSkgewogICAgcmV0dXJuIFt2XTsKICB9IGVsc2UgaWYgKGQgPT09IDApIHsKICAgIHJldHVybiBbXTsKICB9CiAgcmV0dXJuIHY7Cn0KCi8qKg0KICog6KiI566XUmluZ1N0cmluZ+mdouepjQ0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2dldEFyZWFSaW5nU3RyaW5nLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcnMg6Ly45YWlUmluZ1N0cmluZ+izh+aWmemZo+WIl++8jOeCultbeDEseTFdLFt4Mix5Ml0sLi4uXeani+aIkOS5i+mZo+WIlw0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQudXNlQWJzPXRydWVdIOi8uOWFpemdouepjeaYr+WQpuWPlue1leWwjeWAvO+8jOmgkOiorXRydWUNCiAqIEByZXR1cm5zIHtOdW1iZXJ9IOWbnuWCs+mdouepjeaVuOWtlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcnMNCiAqIGxldCByDQogKg0KICogcnMgPSBbDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqICAgICBbMCwgMF0sIC8v6ZaJ5ZCIDQogKiBdDQogKiByID0gZ2V0QXJlYVJpbmdTdHJpbmcocnMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTAwDQogKg0KICogcnMgPSBbDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqIF0NCiAqIHIgPSBnZXRBcmVhUmluZ1N0cmluZyhycykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMDANCiAqDQogKiBycyA9IFsNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IGdldEFyZWFSaW5nU3RyaW5nKHJzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDANCiAqDQogKi8KZnVuY3Rpb24gZ2V0QXJlYVJpbmdTdHJpbmcocnMsIG9wdCA9IHt9KSB7CiAgLy91c2VBYnMKICBsZXQgdXNlQWJzID0gZ2V0KG9wdCwgJ3VzZUFicycpOwogIGlmICghaXNib2wodXNlQWJzKSkgewogICAgdXNlQWJzID0gdHJ1ZTsKICB9CgogIC8vY2hlY2sKICBpZiAoIWlzZWFycihycykpIHsKICAgIHJldHVybiAwOwogIH0KCiAgLy9lcnMKICBsZXQgZXJzID0gW107CiAgZm9yRWFjaChycywgdiA9PiB7CiAgICBpZiAoc2l6ZSh2KSA9PT0gMikgewogICAgICBpZiAoaXNudW0odlswXSkgJiYgaXNudW0odlsxXSkpIHsKICAgICAgICBlcnMucHVzaChbY2RibCh2WzBdKSwgY2RibCh2WzFdKV0pOwogICAgICB9CiAgICB9CiAgfSk7CgogIC8vY2hlY2sKICBpZiAoIWlzZWFycihlcnMpKSB7CiAgICByZXR1cm4gMDsKICB9CgogIC8vYXJlYQogIGxldCBpID0gLTE7CiAgbGV0IG4gPSBzaXplKGVycyk7CiAgbGV0IGE7CiAgbGV0IGIgPSBlcnNbbiAtIDFdOwogIGxldCBhcmVhID0gMDsKICB3aGlsZSAoKytpIDwgbikgewogICAgYSA9IGI7CiAgICBiID0gZXJzW2ldOwogICAgYXJlYSArPSBhWzFdICogYlswXSAtIGFbMF0gKiBiWzFdOwogIH0KICBsZXQgciA9IGFyZWEgLyAyOwoKICAvL3VzZUFicwogIGlmICh1c2VBYnMpIHsKICAgIHIgPSBNYXRoLmFicyhyKTsKICB9CiAgcmV0dXJuIHI7Cn0KCi8vIGltcG9ydCBnZXQgZnJvbSAnbG9kYXNoLWVzL2dldC5qcycKCi8qKg0KICog6KiI566XUG9seWdvbumdouepjQ0KICog5b6X6KaB6ICD5oWu5aSa5Y2A5Z+f44CB5YmU6Zmk5Y2A5Z+f5LmL57WE5ZCIOiBodHRwOi8vZXNyaS5naXRodWIuaW8vZ2VvbWV0cnktYXBpLWphdmEvZG9jL1BvbHlnb24uaHRtbA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2dldEFyZWFQb2x5Z29uLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcGcg6Ly45YWlUG9seWdvbuizh+aWmemZo+WIl++8jOeCultbW3gxLHkxXSxbeDIseTJdLC4uLl1d5qeL5oiQ5LmL6Zmj5YiXDQogKiBAcmV0dXJucyB7TnVtYmVyfSDlm57lgrPpnaLnqY3mlbjlrZcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBnDQogKiBsZXQgcg0KICoNCiAqIHBnID0gWw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiAgICAgWzAsIDBdLCAvL+mWieWQiA0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDEwMA0KICoNCiAqIHBnID0gWw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTAwDQogKg0KICogcGcgPSBbDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMDANCiAqDQogKiBwZyA9IFsNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwLCAwXSwNCiAqICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMA0KICoNCiAqIHBnID0gWw0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdLA0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAsIDBdLA0KICogICAgICAgICBbMTAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDkwDQogKg0KICogcGcgPSBbDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0sDQogKiAgICAgWyAvL+esrCAyIFJpbmdTdHJpbmcg6IiH56ysIDEgUmluZ1N0cmluZyDkuI3ph43nloosIOS9hnBvbHlnb27nrKwx5YCL54K65Li76KaB5Y2ALCDlhbblvozngrrliZTpmaTljYAsIOatpOeCuuacieWVj+mhjOWkmumCiuW9og0KICogICAgICAgICBbMjAwLCAwXSwNCiAqICAgICAgICAgWzIxMCwgMF0sDQogKiAgICAgICAgIFsyMTAsIDFdLA0KICogICAgICAgICBbMjAwLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gOTAsIOWvpumam+eCujExMA0KICoNCiAqLwpmdW5jdGlvbiBnZXRBcmVhUG9seWdvbihwZywgb3B0ID0ge30pIHsKICAvLyAvL2Vwc2lsb24KICAvLyBsZXQgZXBzaWxvbiA9IGdldChvcHQsICdlcHNpbG9uJywgMC4wMDAwMDAwMDAwMDEpCgogIC8vY2hlY2sKICBpZiAoIWlzZWFycihwZykpIHsKICAgIHJldHVybiAwOwogIH0KCiAgLy90b1BvbHlnb24KICBwZyA9IHRvUG9seWdvbihwZyk7CiAgLy8gY29uc29sZS5sb2coJ3RvUG9seWdvbiBwZycsIHBnKQoKICAvL3IKICBsZXQgciA9IDA7CiAgZm9yRWFjaChwZywgKHYsIGspID0+IHsKICAgIC8vcG9seWdvbueCuuWkmuWAi+WkmumCiuW9oue1hOaIkCwg56ysMeWAi+eCuuS4u+imgeWNgCwg5LmL5b6M54K65YmU6Zmk5Y2ACiAgICBsZXQgYSA9IGdldEFyZWFSaW5nU3RyaW5nKHYpOwogICAgaWYgKGsgPT09IDApIHsKICAgICAgciA9IGE7CiAgICB9IGVsc2UgewogICAgICByIC09IGE7CiAgICB9CiAgfSk7CgogIC8vY2hlY2sKICBpZiAociA8IDApIHsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gcjsKfQoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyB1c2VkIHN0cmljdGx5IGZvciBsb2dnaW5nIHRoZSBwcm9jZXNzaW5nIG9mIHRoZSBhbGdvcml0aG0uLi4gb25seSB1c2VmdWwgaWYgeW91IGludGVuZCBvbgovLyBsb29raW5nIHVuZGVyIHRoZSBjb3ZlcnMgKGZvciBwcmV0dHkgVUkncyBvciBkZWJ1Z2dpbmcpCi8vCgpmdW5jdGlvbiBCdWlsZExvZyQxKCkgewogIHZhciBteTsKICB2YXIgbmV4dFNlZ21lbnRJZCA9IDA7CiAgdmFyIGN1clZlcnQgPSBmYWxzZTsKICBmdW5jdGlvbiBwdXNoKHR5cGUsIGRhdGEpIHsKICAgIG15Lmxpc3QucHVzaCh7CiAgICAgIHR5cGU6IHR5cGUsCiAgICAgIGRhdGE6IGRhdGEgPyBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGRhdGEpKSA6IHZvaWQgMAogICAgfSk7CiAgICByZXR1cm4gbXk7CiAgfQogIG15ID0gewogICAgbGlzdDogW10sCiAgICBzZWdtZW50SWQ6IGZ1bmN0aW9uICgpIHsKICAgICAgcmV0dXJuIG5leHRTZWdtZW50SWQrKzsKICAgIH0sCiAgICBjaGVja0ludGVyc2VjdGlvbjogZnVuY3Rpb24gKHNlZzEsIHNlZzIpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoZWNrJywgewogICAgICAgIHNlZzE6IHNlZzEsCiAgICAgICAgc2VnMjogc2VnMgogICAgICB9KTsKICAgIH0sCiAgICBzZWdtZW50Q2hvcDogZnVuY3Rpb24gKHNlZywgZW5kKSB7CiAgICAgIHB1c2goJ2Rpdl9zZWcnLCB7CiAgICAgICAgc2VnOiBzZWcsCiAgICAgICAgcHQ6IGVuZAogICAgICB9KTsKICAgICAgcmV0dXJuIHB1c2goJ2Nob3AnLCB7CiAgICAgICAgc2VnOiBzZWcsCiAgICAgICAgcHQ6IGVuZAogICAgICB9KTsKICAgIH0sCiAgICBzdGF0dXNSZW1vdmU6IGZ1bmN0aW9uIChzZWcpIHsKICAgICAgcmV0dXJuIHB1c2goJ3BvcF9zZWcnLCB7CiAgICAgICAgc2VnOiBzZWcKICAgICAgfSk7CiAgICB9LAogICAgc2VnbWVudFVwZGF0ZTogZnVuY3Rpb24gKHNlZykgewogICAgICByZXR1cm4gcHVzaCgnc2VnX3VwZGF0ZScsIHsKICAgICAgICBzZWc6IHNlZwogICAgICB9KTsKICAgIH0sCiAgICBzZWdtZW50TmV3OiBmdW5jdGlvbiAoc2VnLCBwcmltYXJ5KSB7CiAgICAgIHJldHVybiBwdXNoKCduZXdfc2VnJywgewogICAgICAgIHNlZzogc2VnLAogICAgICAgIHByaW1hcnk6IHByaW1hcnkKICAgICAgfSk7CiAgICB9LAogICAgc2VnbWVudFJlbW92ZTogZnVuY3Rpb24gKHNlZykgewogICAgICByZXR1cm4gcHVzaCgncmVtX3NlZycsIHsKICAgICAgICBzZWc6IHNlZwogICAgICB9KTsKICAgIH0sCiAgICB0ZW1wU3RhdHVzOiBmdW5jdGlvbiAoc2VnLCBhYm92ZSwgYmVsb3cpIHsKICAgICAgcmV0dXJuIHB1c2goJ3RlbXBfc3RhdHVzJywgewogICAgICAgIHNlZzogc2VnLAogICAgICAgIGFib3ZlOiBhYm92ZSwKICAgICAgICBiZWxvdzogYmVsb3cKICAgICAgfSk7CiAgICB9LAogICAgcmV3aW5kOiBmdW5jdGlvbiAoc2VnKSB7CiAgICAgIHJldHVybiBwdXNoKCdyZXdpbmQnLCB7CiAgICAgICAgc2VnOiBzZWcKICAgICAgfSk7CiAgICB9LAogICAgc3RhdHVzOiBmdW5jdGlvbiAoc2VnLCBhYm92ZSwgYmVsb3cpIHsKICAgICAgcmV0dXJuIHB1c2goJ3N0YXR1cycsIHsKICAgICAgICBzZWc6IHNlZywKICAgICAgICBhYm92ZTogYWJvdmUsCiAgICAgICAgYmVsb3c6IGJlbG93CiAgICAgIH0pOwogICAgfSwKICAgIHZlcnQ6IGZ1bmN0aW9uICh4KSB7CiAgICAgIGlmICh4ID09PSBjdXJWZXJ0KSByZXR1cm4gbXk7CiAgICAgIGN1clZlcnQgPSB4OwogICAgICByZXR1cm4gcHVzaCgndmVydCcsIHsKICAgICAgICB4OiB4CiAgICAgIH0pOwogICAgfSwKICAgIGxvZzogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJykgZGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEsIGZhbHNlLCAnICAnKTsKICAgICAgcmV0dXJuIHB1c2goJ2xvZycsIHsKICAgICAgICB0eHQ6IGRhdGEKICAgICAgfSk7CiAgICB9LAogICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgcmV0dXJuIHB1c2goJ3Jlc2V0Jyk7CiAgICB9LAogICAgc2VsZWN0ZWQ6IGZ1bmN0aW9uIChzZWdzKSB7CiAgICAgIHJldHVybiBwdXNoKCdzZWxlY3RlZCcsIHsKICAgICAgICBzZWdzOiBzZWdzCiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluU3RhcnQ6IGZ1bmN0aW9uIChzZWcpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX3N0YXJ0JywgewogICAgICAgIHNlZzogc2VnCiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluUmVtb3ZlSGVhZDogZnVuY3Rpb24gKGluZGV4LCBwdCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fcmVtX2hlYWQnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4LAogICAgICAgIHB0OiBwdAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpblJlbW92ZVRhaWw6IGZ1bmN0aW9uIChpbmRleCwgcHQpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX3JlbV90YWlsJywgewogICAgICAgIGluZGV4OiBpbmRleCwKICAgICAgICBwdDogcHQKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5OZXc6IGZ1bmN0aW9uIChwdDEsIHB0MikgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fbmV3JywgewogICAgICAgIHB0MTogcHQxLAogICAgICAgIHB0MjogcHQyCiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluTWF0Y2g6IGZ1bmN0aW9uIChpbmRleCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fbWF0Y2gnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluQ2xvc2U6IGZ1bmN0aW9uIChpbmRleCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fY2xvc2UnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluQWRkSGVhZDogZnVuY3Rpb24gKGluZGV4LCBwdCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fYWRkX2hlYWQnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4LAogICAgICAgIHB0OiBwdAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbkFkZFRhaWw6IGZ1bmN0aW9uIChpbmRleCwgcHQpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX2FkZF90YWlsJywgewogICAgICAgIGluZGV4OiBpbmRleCwKICAgICAgICBwdDogcHQKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5Db25uZWN0OiBmdW5jdGlvbiAoaW5kZXgxLCBpbmRleDIpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX2NvbicsIHsKICAgICAgICBpbmRleDE6IGluZGV4MSwKICAgICAgICBpbmRleDI6IGluZGV4MgogICAgICB9KTsKICAgIH0sCiAgICBjaGFpblJldmVyc2U6IGZ1bmN0aW9uIChpbmRleCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fcmV2JywgewogICAgICAgIGluZGV4OiBpbmRleAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbkpvaW46IGZ1bmN0aW9uIChpbmRleDEsIGluZGV4MikgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fam9pbicsIHsKICAgICAgICBpbmRleDE6IGluZGV4MSwKICAgICAgICBpbmRleDI6IGluZGV4MgogICAgICB9KTsKICAgIH0sCiAgICBkb25lOiBmdW5jdGlvbiAoKSB7CiAgICAgIHJldHVybiBwdXNoKCdkb25lJyk7CiAgICB9CiAgfTsKICByZXR1cm4gbXk7Cn0KdmFyIGJ1aWxkTG9nJDEgPSBCdWlsZExvZyQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyBwcm92aWRlcyB0aGUgcmF3IGNvbXB1dGF0aW9uIGZ1bmN0aW9ucyB0aGF0IHRha2VzIGVwc2lsb24gaW50byBhY2NvdW50Ci8vCi8vIHplcm8gaXMgZGVmaW5lZCB0byBiZSBiZXR3ZWVuICgtZXBzaWxvbiwgZXBzaWxvbikgZXhjbHVzaXZlCi8vCgpmdW5jdGlvbiBFcHNpbG9uJDEoZXBzKSB7CiAgaWYgKHR5cGVvZiBlcHMgIT09ICdudW1iZXInKSBlcHMgPSAwLjAwMDAwMDAwMDE7IC8vIHNhbmUgZGVmYXVsdD8gc3VyZSB3aHkgbm90CiAgdmFyIG15ID0gewogICAgZXBzaWxvbjogZnVuY3Rpb24gKHYpIHsKICAgICAgaWYgKHR5cGVvZiB2ID09PSAnbnVtYmVyJykgZXBzID0gdjsKICAgICAgcmV0dXJuIGVwczsKICAgIH0sCiAgICBwb2ludEFib3ZlT3JPbkxpbmU6IGZ1bmN0aW9uIChwdCwgbGVmdCwgcmlnaHQpIHsKICAgICAgdmFyIEF4ID0gbGVmdFswXTsKICAgICAgdmFyIEF5ID0gbGVmdFsxXTsKICAgICAgdmFyIEJ4ID0gcmlnaHRbMF07CiAgICAgIHZhciBCeSA9IHJpZ2h0WzFdOwogICAgICB2YXIgQ3ggPSBwdFswXTsKICAgICAgdmFyIEN5ID0gcHRbMV07CiAgICAgIHJldHVybiAoQnggLSBBeCkgKiAoQ3kgLSBBeSkgLSAoQnkgLSBBeSkgKiAoQ3ggLSBBeCkgPj0gLWVwczsKICAgIH0sCiAgICBwb2ludEJldHdlZW46IGZ1bmN0aW9uIChwLCBsZWZ0LCByaWdodCkgewogICAgICAvLyBwIG11c3QgYmUgY29sbGluZWFyIHdpdGggbGVmdC0+cmlnaHQKICAgICAgLy8gcmV0dXJucyBmYWxzZSBpZiBwID09IGxlZnQsIHAgPT0gcmlnaHQsIG9yIGxlZnQgPT0gcmlnaHQKICAgICAgdmFyIGRfcHlfbHkgPSBwWzFdIC0gbGVmdFsxXTsKICAgICAgdmFyIGRfcnhfbHggPSByaWdodFswXSAtIGxlZnRbMF07CiAgICAgIHZhciBkX3B4X2x4ID0gcFswXSAtIGxlZnRbMF07CiAgICAgIHZhciBkX3J5X2x5ID0gcmlnaHRbMV0gLSBsZWZ0WzFdOwogICAgICB2YXIgZG90ID0gZF9weF9seCAqIGRfcnhfbHggKyBkX3B5X2x5ICogZF9yeV9seTsKICAgICAgLy8gaWYgYGRvdGAgaXMgMCwgdGhlbiBgcGAgPT0gYGxlZnRgIG9yIGBsZWZ0YCA9PSBgcmlnaHRgIChyZWplY3QpCiAgICAgIC8vIGlmIGBkb3RgIGlzIGxlc3MgdGhhbiAwLCB0aGVuIGBwYCBpcyB0byB0aGUgbGVmdCBvZiBgbGVmdGAgKHJlamVjdCkKICAgICAgaWYgKGRvdCA8IGVwcykgcmV0dXJuIGZhbHNlOwogICAgICB2YXIgc3FsZW4gPSBkX3J4X2x4ICogZF9yeF9seCArIGRfcnlfbHkgKiBkX3J5X2x5OwogICAgICAvLyBpZiBgZG90YCA+IGBzcWxlbmAsIHRoZW4gYHBgIGlzIHRvIHRoZSByaWdodCBvZiBgcmlnaHRgIChyZWplY3QpCiAgICAgIC8vIHRoZXJlZm9yZSwgaWYgYGRvdCAtIHNxbGVuYCBpcyBncmVhdGVyIHRoYW4gMCwgdGhlbiBgcGAgaXMgdG8gdGhlIHJpZ2h0IG9mIGByaWdodGAgKHJlamVjdCkKICAgICAgaWYgKGRvdCAtIHNxbGVuID4gLWVwcykgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0sCiAgICBwb2ludHNTYW1lWDogZnVuY3Rpb24gKHAxLCBwMikgewogICAgICByZXR1cm4gTWF0aC5hYnMocDFbMF0gLSBwMlswXSkgPCBlcHM7CiAgICB9LAogICAgcG9pbnRzU2FtZVk6IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgICAgcmV0dXJuIE1hdGguYWJzKHAxWzFdIC0gcDJbMV0pIDwgZXBzOwogICAgfSwKICAgIHBvaW50c1NhbWU6IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgICAgcmV0dXJuIG15LnBvaW50c1NhbWVYKHAxLCBwMikgJiYgbXkucG9pbnRzU2FtZVkocDEsIHAyKTsKICAgIH0sCiAgICBwb2ludHNDb21wYXJlOiBmdW5jdGlvbiAocDEsIHAyKSB7CiAgICAgIC8vIHJldHVybnMgLTEgaWYgcDEgaXMgc21hbGxlciwgMSBpZiBwMiBpcyBzbWFsbGVyLCAwIGlmIGVxdWFsCiAgICAgIGlmIChteS5wb2ludHNTYW1lWChwMSwgcDIpKSByZXR1cm4gbXkucG9pbnRzU2FtZVkocDEsIHAyKSA/IDAgOiBwMVsxXSA8IHAyWzFdID8gLTEgOiAxOwogICAgICByZXR1cm4gcDFbMF0gPCBwMlswXSA/IC0xIDogMTsKICAgIH0sCiAgICBwb2ludHNDb2xsaW5lYXI6IGZ1bmN0aW9uIChwdDEsIHB0MiwgcHQzKSB7CiAgICAgIC8vIGRvZXMgcHQxLT5wdDItPnB0MyBtYWtlIGEgc3RyYWlnaHQgbGluZT8KICAgICAgLy8gZXNzZW50aWFsbHkgdGhpcyBpcyBqdXN0IGNoZWNraW5nIHRvIHNlZSBpZiB0aGUgc2xvcGUocHQxLT5wdDIpID09PSBzbG9wZShwdDItPnB0MykKICAgICAgLy8gaWYgc2xvcGVzIGFyZSBlcXVhbCwgdGhlbiB0aGV5IG11c3QgYmUgY29sbGluZWFyLCBiZWNhdXNlIHRoZXkgc2hhcmUgcHQyCiAgICAgIHZhciBkeDEgPSBwdDFbMF0gLSBwdDJbMF07CiAgICAgIHZhciBkeTEgPSBwdDFbMV0gLSBwdDJbMV07CiAgICAgIHZhciBkeDIgPSBwdDJbMF0gLSBwdDNbMF07CiAgICAgIHZhciBkeTIgPSBwdDJbMV0gLSBwdDNbMV07CiAgICAgIHJldHVybiBNYXRoLmFicyhkeDEgKiBkeTIgLSBkeDIgKiBkeTEpIDwgZXBzOwogICAgfSwKICAgIGxpbmVzSW50ZXJzZWN0OiBmdW5jdGlvbiAoYTAsIGExLCBiMCwgYjEpIHsKICAgICAgLy8gcmV0dXJucyBmYWxzZSBpZiB0aGUgbGluZXMgYXJlIGNvaW5jaWRlbnQgKGUuZy4sIHBhcmFsbGVsIG9yIG9uIHRvcCBvZiBlYWNoIG90aGVyKQogICAgICAvLwogICAgICAvLyByZXR1cm5zIGFuIG9iamVjdCBpZiB0aGUgbGluZXMgaW50ZXJzZWN0OgogICAgICAvLyAgIHsKICAgICAgLy8gICAgIHB0OiBbeCwgeV0sICAgIHdoZXJlIHRoZSBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYXQKICAgICAgLy8gICAgIGFsb25nQTogd2hlcmUgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGFsb25nIEEsCiAgICAgIC8vICAgICBhbG9uZ0I6IHdoZXJlIGludGVyc2VjdGlvbiBwb2ludCBpcyBhbG9uZyBCCiAgICAgIC8vICAgfQogICAgICAvLwogICAgICAvLyAgYWxvbmdBIGFuZCBhbG9uZ0Igd2lsbCBlYWNoIGJlIG9uZSBvZjogLTIsIC0xLCAwLCAxLCAyCiAgICAgIC8vCiAgICAgIC8vICB3aXRoIHRoZSBmb2xsb3dpbmcgbWVhbmluZzoKICAgICAgLy8KICAgICAgLy8gICAgLTIgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYmVmb3JlIHNlZ21lbnQncyBmaXJzdCBwb2ludAogICAgICAvLyAgICAtMSAgIGludGVyc2VjdGlvbiBwb2ludCBpcyBkaXJlY3RseSBvbiBzZWdtZW50J3MgZmlyc3QgcG9pbnQKICAgICAgLy8gICAgIDAgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYmV0d2VlbiBzZWdtZW50J3MgZmlyc3QgYW5kIHNlY29uZCBwb2ludHMgKGV4Y2x1c2l2ZSkKICAgICAgLy8gICAgIDEgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgZGlyZWN0bHkgb24gc2VnbWVudCdzIHNlY29uZCBwb2ludAogICAgICAvLyAgICAgMiAgIGludGVyc2VjdGlvbiBwb2ludCBpcyBhZnRlciBzZWdtZW50J3Mgc2Vjb25kIHBvaW50CiAgICAgIHZhciBhZHggPSBhMVswXSAtIGEwWzBdOwogICAgICB2YXIgYWR5ID0gYTFbMV0gLSBhMFsxXTsKICAgICAgdmFyIGJkeCA9IGIxWzBdIC0gYjBbMF07CiAgICAgIHZhciBiZHkgPSBiMVsxXSAtIGIwWzFdOwogICAgICB2YXIgYXhiID0gYWR4ICogYmR5IC0gYWR5ICogYmR4OwogICAgICBpZiAoTWF0aC5hYnMoYXhiKSA8IGVwcykgcmV0dXJuIGZhbHNlOyAvLyBsaW5lcyBhcmUgY29pbmNpZGVudAoKICAgICAgdmFyIGR4ID0gYTBbMF0gLSBiMFswXTsKICAgICAgdmFyIGR5ID0gYTBbMV0gLSBiMFsxXTsKICAgICAgdmFyIEEgPSAoYmR4ICogZHkgLSBiZHkgKiBkeCkgLyBheGI7CiAgICAgIHZhciBCID0gKGFkeCAqIGR5IC0gYWR5ICogZHgpIC8gYXhiOwogICAgICB2YXIgcmV0ID0gewogICAgICAgIGFsb25nQTogMCwKICAgICAgICBhbG9uZ0I6IDAsCiAgICAgICAgcHQ6IFthMFswXSArIEEgKiBhZHgsIGEwWzFdICsgQSAqIGFkeV0KICAgICAgfTsKCiAgICAgIC8vIGNhdGVnb3JpemUgd2hlcmUgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGFsb25nIEEgYW5kIEIKCiAgICAgIGlmIChBIDw9IC1lcHMpIHJldC5hbG9uZ0EgPSAtMjtlbHNlIGlmIChBIDwgZXBzKSByZXQuYWxvbmdBID0gLTE7ZWxzZSBpZiAoQSAtIDEgPD0gLWVwcykgcmV0LmFsb25nQSA9IDA7ZWxzZSBpZiAoQSAtIDEgPCBlcHMpIHJldC5hbG9uZ0EgPSAxO2Vsc2UgcmV0LmFsb25nQSA9IDI7CiAgICAgIGlmIChCIDw9IC1lcHMpIHJldC5hbG9uZ0IgPSAtMjtlbHNlIGlmIChCIDwgZXBzKSByZXQuYWxvbmdCID0gLTE7ZWxzZSBpZiAoQiAtIDEgPD0gLWVwcykgcmV0LmFsb25nQiA9IDA7ZWxzZSBpZiAoQiAtIDEgPCBlcHMpIHJldC5hbG9uZ0IgPSAxO2Vsc2UgcmV0LmFsb25nQiA9IDI7CiAgICAgIHJldHVybiByZXQ7CiAgICB9LAogICAgcG9pbnRJbnNpZGVSZWdpb246IGZ1bmN0aW9uIChwdCwgcmVnaW9uKSB7CiAgICAgIHZhciB4ID0gcHRbMF07CiAgICAgIHZhciB5ID0gcHRbMV07CiAgICAgIHZhciBsYXN0X3ggPSByZWdpb25bcmVnaW9uLmxlbmd0aCAtIDFdWzBdOwogICAgICB2YXIgbGFzdF95ID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXVsxXTsKICAgICAgdmFyIGluc2lkZSA9IGZhbHNlOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lvbi5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBjdXJyX3ggPSByZWdpb25baV1bMF07CiAgICAgICAgdmFyIGN1cnJfeSA9IHJlZ2lvbltpXVsxXTsKCiAgICAgICAgLy8gaWYgeSBpcyBiZXR3ZWVuIGN1cnJfeSBhbmQgbGFzdF95LCBhbmQKICAgICAgICAvLyB4IGlzIHRvIHRoZSByaWdodCBvZiB0aGUgYm91bmRhcnkgY3JlYXRlZCBieSB0aGUgbGluZQogICAgICAgIGlmIChjdXJyX3kgLSB5ID4gZXBzICE9IGxhc3RfeSAtIHkgPiBlcHMgJiYgKGxhc3RfeCAtIGN1cnJfeCkgKiAoeSAtIGN1cnJfeSkgLyAobGFzdF95IC0gY3Vycl95KSArIGN1cnJfeCAtIHggPiBlcHMpIGluc2lkZSA9ICFpbnNpZGU7CiAgICAgICAgbGFzdF94ID0gY3Vycl94OwogICAgICAgIGxhc3RfeSA9IGN1cnJfeTsKICAgICAgfQogICAgICByZXR1cm4gaW5zaWRlOwogICAgfQogIH07CiAgcmV0dXJuIG15Owp9CnZhciBlcHNpbG9uJDMgPSBFcHNpbG9uJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIHNpbXBsZSBsaW5rZWQgbGlzdCBpbXBsZW1lbnRhdGlvbiB0aGF0IGFsbG93cyB5b3UgdG8gdHJhdmVyc2UgZG93biBub2RlcyBhbmQgc2F2ZSBwb3NpdGlvbnMKLy8KCnZhciBMaW5rZWRMaXN0JDEgPSB7CiAgY3JlYXRlOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgbXkgPSB7CiAgICAgIHJvb3Q6IHsKICAgICAgICByb290OiB0cnVlLAogICAgICAgIG5leHQ6IG51bGwKICAgICAgfSwKICAgICAgZXhpc3RzOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgIGlmIChub2RlID09PSBudWxsIHx8IG5vZGUgPT09IG15LnJvb3QpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfSwKICAgICAgaXNFbXB0eTogZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBteS5yb290Lm5leHQgPT09IG51bGw7CiAgICAgIH0sCiAgICAgIGdldEhlYWQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gbXkucm9vdC5uZXh0OwogICAgICB9LAogICAgICBpbnNlcnRCZWZvcmU6IGZ1bmN0aW9uIChub2RlLCBjaGVjaykgewogICAgICAgIHZhciBsYXN0ID0gbXkucm9vdDsKICAgICAgICB2YXIgaGVyZSA9IG15LnJvb3QubmV4dDsKICAgICAgICB3aGlsZSAoaGVyZSAhPT0gbnVsbCkgewogICAgICAgICAgaWYgKGNoZWNrKGhlcmUpKSB7CiAgICAgICAgICAgIG5vZGUucHJldiA9IGhlcmUucHJldjsKICAgICAgICAgICAgbm9kZS5uZXh0ID0gaGVyZTsKICAgICAgICAgICAgaGVyZS5wcmV2Lm5leHQgPSBub2RlOwogICAgICAgICAgICBoZXJlLnByZXYgPSBub2RlOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgICBsYXN0ID0gaGVyZTsKICAgICAgICAgIGhlcmUgPSBoZXJlLm5leHQ7CiAgICAgICAgfQogICAgICAgIGxhc3QubmV4dCA9IG5vZGU7CiAgICAgICAgbm9kZS5wcmV2ID0gbGFzdDsKICAgICAgICBub2RlLm5leHQgPSBudWxsOwogICAgICB9LAogICAgICBmaW5kVHJhbnNpdGlvbjogZnVuY3Rpb24gKGNoZWNrKSB7CiAgICAgICAgdmFyIHByZXYgPSBteS5yb290OwogICAgICAgIHZhciBoZXJlID0gbXkucm9vdC5uZXh0OwogICAgICAgIHdoaWxlIChoZXJlICE9PSBudWxsKSB7CiAgICAgICAgICBpZiAoY2hlY2soaGVyZSkpIGJyZWFrOwogICAgICAgICAgcHJldiA9IGhlcmU7CiAgICAgICAgICBoZXJlID0gaGVyZS5uZXh0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gewogICAgICAgICAgYmVmb3JlOiBwcmV2ID09PSBteS5yb290ID8gbnVsbCA6IHByZXYsCiAgICAgICAgICBhZnRlcjogaGVyZSwKICAgICAgICAgIGluc2VydDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgbm9kZS5wcmV2ID0gcHJldjsKICAgICAgICAgICAgbm9kZS5uZXh0ID0gaGVyZTsKICAgICAgICAgICAgcHJldi5uZXh0ID0gbm9kZTsKICAgICAgICAgICAgaWYgKGhlcmUgIT09IG51bGwpIGhlcmUucHJldiA9IG5vZGU7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgIH0KICAgIH07CiAgICByZXR1cm4gbXk7CiAgfSwKICBub2RlOiBmdW5jdGlvbiAoZGF0YSkgewogICAgZGF0YS5wcmV2ID0gbnVsbDsKICAgIGRhdGEubmV4dCA9IG51bGw7CiAgICBkYXRhLnJlbW92ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgZGF0YS5wcmV2Lm5leHQgPSBkYXRhLm5leHQ7CiAgICAgIGlmIChkYXRhLm5leHQpIGRhdGEubmV4dC5wcmV2ID0gZGF0YS5wcmV2OwogICAgICBkYXRhLnByZXYgPSBudWxsOwogICAgICBkYXRhLm5leHQgPSBudWxsOwogICAgfTsKICAgIHJldHVybiBkYXRhOwogIH0KfTsKdmFyIGxpbmtlZExpc3QgPSBMaW5rZWRMaXN0JDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIHRoaXMgaXMgdGhlIGNvcmUgd29yay1ob3JzZQovLwoKdmFyIExpbmtlZExpc3QgPSBsaW5rZWRMaXN0OwpmdW5jdGlvbiBJbnRlcnNlY3RlciQxKHNlbGZJbnRlcnNlY3Rpb24sIGVwcywgYnVpbGRMb2cpIHsKICAvLyBzZWxmSW50ZXJzZWN0aW9uIGlzIHRydWUvZmFsc2UgZGVwZW5kaW5nIG9uIHRoZSBwaGFzZSBvZiB0aGUgb3ZlcmFsbCBhbGdvcml0aG0KCiAgLy8KICAvLyBzZWdtZW50IGNyZWF0aW9uCiAgLy8KCiAgZnVuY3Rpb24gc2VnbWVudE5ldyhzdGFydCwgZW5kKSB7CiAgICByZXR1cm4gewogICAgICBpZDogYnVpbGRMb2cgPyBidWlsZExvZy5zZWdtZW50SWQoKSA6IC0xLAogICAgICBzdGFydDogc3RhcnQsCiAgICAgIGVuZDogZW5kLAogICAgICBteUZpbGw6IHsKICAgICAgICBhYm92ZTogbnVsbCwKICAgICAgICAvLyBpcyB0aGVyZSBmaWxsIGFib3ZlIHVzPwogICAgICAgIGJlbG93OiBudWxsIC8vIGlzIHRoZXJlIGZpbGwgYmVsb3cgdXM/CiAgICAgIH0sCgogICAgICBvdGhlckZpbGw6IG51bGwKICAgIH07CiAgfQogIGZ1bmN0aW9uIHNlZ21lbnRDb3B5KHN0YXJ0LCBlbmQsIHNlZykgewogICAgcmV0dXJuIHsKICAgICAgaWQ6IGJ1aWxkTG9nID8gYnVpbGRMb2cuc2VnbWVudElkKCkgOiAtMSwKICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICBlbmQ6IGVuZCwKICAgICAgbXlGaWxsOiB7CiAgICAgICAgYWJvdmU6IHNlZy5teUZpbGwuYWJvdmUsCiAgICAgICAgYmVsb3c6IHNlZy5teUZpbGwuYmVsb3cKICAgICAgfSwKICAgICAgb3RoZXJGaWxsOiBudWxsCiAgICB9OwogIH0KCiAgLy8KICAvLyBldmVudCBsb2dpYwogIC8vCgogIHZhciBldmVudF9yb290ID0gTGlua2VkTGlzdC5jcmVhdGUoKTsKICBmdW5jdGlvbiBldmVudENvbXBhcmUocDFfaXNTdGFydCwgcDFfMSwgcDFfMiwgcDJfaXNTdGFydCwgcDJfMSwgcDJfMikgewogICAgLy8gY29tcGFyZSB0aGUgc2VsZWN0ZWQgcG9pbnRzIGZpcnN0CiAgICB2YXIgY29tcCA9IGVwcy5wb2ludHNDb21wYXJlKHAxXzEsIHAyXzEpOwogICAgaWYgKGNvbXAgIT09IDApIHJldHVybiBjb21wOwogICAgLy8gdGhlIHNlbGVjdGVkIHBvaW50cyBhcmUgdGhlIHNhbWUKCiAgICBpZiAoZXBzLnBvaW50c1NhbWUocDFfMiwgcDJfMikpCiAgICAgIC8vIGlmIHRoZSBub24tc2VsZWN0ZWQgcG9pbnRzIGFyZSB0aGUgc2FtZSB0b28uLi4KICAgICAgcmV0dXJuIDA7IC8vIHRoZW4gdGhlIHNlZ21lbnRzIGFyZSBlcXVhbAoKICAgIGlmIChwMV9pc1N0YXJ0ICE9PSBwMl9pc1N0YXJ0KQogICAgICAvLyBpZiBvbmUgaXMgYSBzdGFydCBhbmQgdGhlIG90aGVyIGlzbid0Li4uCiAgICAgIHJldHVybiBwMV9pc1N0YXJ0ID8gMSA6IC0xOyAvLyBmYXZvciB0aGUgb25lIHRoYXQgaXNuJ3QgdGhlIHN0YXJ0CgogICAgLy8gb3RoZXJ3aXNlLCB3ZSdsbCBoYXZlIHRvIGNhbGN1bGF0ZSB3aGljaCBvbmUgaXMgYmVsb3cgdGhlIG90aGVyIG1hbnVhbGx5CiAgICByZXR1cm4gZXBzLnBvaW50QWJvdmVPck9uTGluZShwMV8yLCBwMl9pc1N0YXJ0ID8gcDJfMSA6IHAyXzIsCiAgICAvLyBvcmRlciBtYXR0ZXJzCiAgICBwMl9pc1N0YXJ0ID8gcDJfMiA6IHAyXzEpID8gMSA6IC0xOwogIH0KICBmdW5jdGlvbiBldmVudEFkZChldiwgb3RoZXJfcHQpIHsKICAgIGV2ZW50X3Jvb3QuaW5zZXJ0QmVmb3JlKGV2LCBmdW5jdGlvbiAoaGVyZSkgewogICAgICAvLyBzaG91bGQgZXYgYmUgaW5zZXJ0ZWQgYmVmb3JlIGhlcmU/CiAgICAgIHZhciBjb21wID0gZXZlbnRDb21wYXJlKGV2LmlzU3RhcnQsIGV2LnB0LCBvdGhlcl9wdCwgaGVyZS5pc1N0YXJ0LCBoZXJlLnB0LCBoZXJlLm90aGVyLnB0KTsKICAgICAgcmV0dXJuIGNvbXAgPCAwOwogICAgfSk7CiAgfQogIGZ1bmN0aW9uIGV2ZW50QWRkU2VnbWVudFN0YXJ0KHNlZywgcHJpbWFyeSkgewogICAgdmFyIGV2X3N0YXJ0ID0gTGlua2VkTGlzdC5ub2RlKHsKICAgICAgaXNTdGFydDogdHJ1ZSwKICAgICAgcHQ6IHNlZy5zdGFydCwKICAgICAgc2VnOiBzZWcsCiAgICAgIHByaW1hcnk6IHByaW1hcnksCiAgICAgIG90aGVyOiBudWxsLAogICAgICBzdGF0dXM6IG51bGwKICAgIH0pOwogICAgZXZlbnRBZGQoZXZfc3RhcnQsIHNlZy5lbmQpOwogICAgcmV0dXJuIGV2X3N0YXJ0OwogIH0KICBmdW5jdGlvbiBldmVudEFkZFNlZ21lbnRFbmQoZXZfc3RhcnQsIHNlZywgcHJpbWFyeSkgewogICAgdmFyIGV2X2VuZCA9IExpbmtlZExpc3Qubm9kZSh7CiAgICAgIGlzU3RhcnQ6IGZhbHNlLAogICAgICBwdDogc2VnLmVuZCwKICAgICAgc2VnOiBzZWcsCiAgICAgIHByaW1hcnk6IHByaW1hcnksCiAgICAgIG90aGVyOiBldl9zdGFydCwKICAgICAgc3RhdHVzOiBudWxsCiAgICB9KTsKICAgIGV2X3N0YXJ0Lm90aGVyID0gZXZfZW5kOwogICAgZXZlbnRBZGQoZXZfZW5kLCBldl9zdGFydC5wdCk7CiAgfQogIGZ1bmN0aW9uIGV2ZW50QWRkU2VnbWVudChzZWcsIHByaW1hcnkpIHsKICAgIHZhciBldl9zdGFydCA9IGV2ZW50QWRkU2VnbWVudFN0YXJ0KHNlZywgcHJpbWFyeSk7CiAgICBldmVudEFkZFNlZ21lbnRFbmQoZXZfc3RhcnQsIHNlZywgcHJpbWFyeSk7CiAgICByZXR1cm4gZXZfc3RhcnQ7CiAgfQogIGZ1bmN0aW9uIGV2ZW50VXBkYXRlRW5kKGV2LCBlbmQpIHsKICAgIC8vIHNsaWRlcyBhbiBlbmQgYmFja3dhcmRzCiAgICAvLyAgIChzdGFydCktLS0tLS0tLS0tLS0oZW5kKSAgICB0bzoKICAgIC8vICAgKHN0YXJ0KS0tLShlbmQpCgogICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5zZWdtZW50Q2hvcChldi5zZWcsIGVuZCk7CiAgICBldi5vdGhlci5yZW1vdmUoKTsKICAgIGV2LnNlZy5lbmQgPSBlbmQ7CiAgICBldi5vdGhlci5wdCA9IGVuZDsKICAgIGV2ZW50QWRkKGV2Lm90aGVyLCBldi5wdCk7CiAgfQogIGZ1bmN0aW9uIGV2ZW50RGl2aWRlKGV2LCBwdCkgewogICAgdmFyIG5zID0gc2VnbWVudENvcHkocHQsIGV2LnNlZy5lbmQsIGV2LnNlZyk7CiAgICBldmVudFVwZGF0ZUVuZChldiwgcHQpOwogICAgcmV0dXJuIGV2ZW50QWRkU2VnbWVudChucywgZXYucHJpbWFyeSk7CiAgfQogIGZ1bmN0aW9uIGNhbGN1bGF0ZShwcmltYXJ5UG9seUludmVydGVkLCBzZWNvbmRhcnlQb2x5SW52ZXJ0ZWQpIHsKICAgIC8vIGlmIHNlbGZJbnRlcnNlY3Rpb24gaXMgdHJ1ZSB0aGVuIHRoZXJlIGlzIG5vIHNlY29uZGFyeSBwb2x5Z29uLCBzbyB0aGF0IGlzbid0IHVzZWQKCiAgICAvLwogICAgLy8gc3RhdHVzIGxvZ2ljCiAgICAvLwoKICAgIHZhciBzdGF0dXNfcm9vdCA9IExpbmtlZExpc3QuY3JlYXRlKCk7CiAgICBmdW5jdGlvbiBzdGF0dXNDb21wYXJlKGV2MSwgZXYyKSB7CiAgICAgIHZhciBhMSA9IGV2MS5zZWcuc3RhcnQ7CiAgICAgIHZhciBhMiA9IGV2MS5zZWcuZW5kOwogICAgICB2YXIgYjEgPSBldjIuc2VnLnN0YXJ0OwogICAgICB2YXIgYjIgPSBldjIuc2VnLmVuZDsKICAgICAgaWYgKGVwcy5wb2ludHNDb2xsaW5lYXIoYTEsIGIxLCBiMikpIHsKICAgICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcihhMiwgYjEsIGIyKSkgcmV0dXJuIDE7IC8vZXZlbnRDb21wYXJlKHRydWUsIGExLCBhMiwgdHJ1ZSwgYjEsIGIyKTsKICAgICAgICByZXR1cm4gZXBzLnBvaW50QWJvdmVPck9uTGluZShhMiwgYjEsIGIyKSA/IDEgOiAtMTsKICAgICAgfQogICAgICByZXR1cm4gZXBzLnBvaW50QWJvdmVPck9uTGluZShhMSwgYjEsIGIyKSA/IDEgOiAtMTsKICAgIH0KICAgIGZ1bmN0aW9uIHN0YXR1c0ZpbmRTdXJyb3VuZGluZyhldikgewogICAgICByZXR1cm4gc3RhdHVzX3Jvb3QuZmluZFRyYW5zaXRpb24oZnVuY3Rpb24gKGhlcmUpIHsKICAgICAgICB2YXIgY29tcCA9IHN0YXR1c0NvbXBhcmUoZXYsIGhlcmUuZXYpOwogICAgICAgIHJldHVybiBjb21wID4gMDsKICAgICAgfSk7CiAgICB9CiAgICBmdW5jdGlvbiBjaGVja0ludGVyc2VjdGlvbihldjEsIGV2MikgewogICAgICAvLyByZXR1cm5zIHRoZSBzZWdtZW50IGVxdWFsIHRvIGV2MSwgb3IgZmFsc2UgaWYgbm90aGluZyBlcXVhbAoKICAgICAgdmFyIHNlZzEgPSBldjEuc2VnOwogICAgICB2YXIgc2VnMiA9IGV2Mi5zZWc7CiAgICAgIHZhciBhMSA9IHNlZzEuc3RhcnQ7CiAgICAgIHZhciBhMiA9IHNlZzEuZW5kOwogICAgICB2YXIgYjEgPSBzZWcyLnN0YXJ0OwogICAgICB2YXIgYjIgPSBzZWcyLmVuZDsKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGVja0ludGVyc2VjdGlvbihzZWcxLCBzZWcyKTsKICAgICAgdmFyIGkgPSBlcHMubGluZXNJbnRlcnNlY3QoYTEsIGEyLCBiMSwgYjIpOwogICAgICBpZiAoaSA9PT0gZmFsc2UpIHsKICAgICAgICAvLyBzZWdtZW50cyBhcmUgcGFyYWxsZWwgb3IgY29pbmNpZGVudAoKICAgICAgICAvLyBpZiBwb2ludHMgYXJlbid0IGNvbGxpbmVhciwgdGhlbiB0aGUgc2VnbWVudHMgYXJlIHBhcmFsbGVsLCBzbyBubyBpbnRlcnNlY3Rpb25zCiAgICAgICAgaWYgKCFlcHMucG9pbnRzQ29sbGluZWFyKGExLCBhMiwgYjEpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgLy8gb3RoZXJ3aXNlLCBzZWdtZW50cyBhcmUgb24gdG9wIG9mIGVhY2ggb3RoZXIgc29tZWhvdyAoYWthIGNvaW5jaWRlbnQpCgogICAgICAgIGlmIChlcHMucG9pbnRzU2FtZShhMSwgYjIpIHx8IGVwcy5wb2ludHNTYW1lKGEyLCBiMSkpIHJldHVybiBmYWxzZTsgLy8gc2VnbWVudHMgdG91Y2ggYXQgZW5kcG9pbnRzLi4uIG5vIGludGVyc2VjdGlvbgoKICAgICAgICB2YXIgYTFfZXF1X2IxID0gZXBzLnBvaW50c1NhbWUoYTEsIGIxKTsKICAgICAgICB2YXIgYTJfZXF1X2IyID0gZXBzLnBvaW50c1NhbWUoYTIsIGIyKTsKICAgICAgICBpZiAoYTFfZXF1X2IxICYmIGEyX2VxdV9iMikgcmV0dXJuIGV2MjsgLy8gc2VnbWVudHMgYXJlIGV4YWN0bHkgZXF1YWwKCiAgICAgICAgdmFyIGExX2JldHdlZW4gPSAhYTFfZXF1X2IxICYmIGVwcy5wb2ludEJldHdlZW4oYTEsIGIxLCBiMik7CiAgICAgICAgdmFyIGEyX2JldHdlZW4gPSAhYTJfZXF1X2IyICYmIGVwcy5wb2ludEJldHdlZW4oYTIsIGIxLCBiMik7CgogICAgICAgIC8vIGhhbmR5IGZvciBkZWJ1Z2dpbmc6CiAgICAgICAgLy8gYnVpbGRMb2cubG9nKHsKICAgICAgICAvLwlhMV9lcXVfYjE6IGExX2VxdV9iMSwKICAgICAgICAvLwlhMl9lcXVfYjI6IGEyX2VxdV9iMiwKICAgICAgICAvLwlhMV9iZXR3ZWVuOiBhMV9iZXR3ZWVuLAogICAgICAgIC8vCWEyX2JldHdlZW46IGEyX2JldHdlZW4KICAgICAgICAvLyB9KTsKCiAgICAgICAgaWYgKGExX2VxdV9iMSkgewogICAgICAgICAgaWYgKGEyX2JldHdlZW4pIHsKICAgICAgICAgICAgLy8gIChhMSktLS0oYTIpCiAgICAgICAgICAgIC8vICAoYjEpLS0tLS0tLS0tLShiMikKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBhMik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyAgKGExKS0tLS0tLS0tLS0oYTIpCiAgICAgICAgICAgIC8vICAoYjEpLS0tKGIyKQogICAgICAgICAgICBldmVudERpdmlkZShldjEsIGIyKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBldjI7CiAgICAgICAgfSBlbHNlIGlmIChhMV9iZXR3ZWVuKSB7CiAgICAgICAgICBpZiAoIWEyX2VxdV9iMikgewogICAgICAgICAgICAvLyBtYWtlIGEyIGVxdWFsIHRvIGIyCiAgICAgICAgICAgIGlmIChhMl9iZXR3ZWVuKSB7CiAgICAgICAgICAgICAgLy8gICAgICAgICAoYTEpLS0tKGEyKQogICAgICAgICAgICAgIC8vICAoYjEpLS0tLS0tLS0tLS0tLS0tLS0oYjIpCiAgICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBhMik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgLy8gICAgICAgICAoYTEpLS0tLS0tLS0tLShhMikKICAgICAgICAgICAgICAvLyAgKGIxKS0tLS0tLS0tLS0oYjIpCiAgICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBiMik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICAvLyAgICAgICAgIChhMSktLS0oYTIpCiAgICAgICAgICAvLyAgKGIxKS0tLS0tLS0tLS0oYjIpCiAgICAgICAgICBldmVudERpdmlkZShldjIsIGExKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gb3RoZXJ3aXNlLCBsaW5lcyBpbnRlcnNlY3QgYXQgaS5wdCwgd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgYmV0d2VlbiB0aGUgZW5kcG9pbnRzCgogICAgICAgIC8vIGlzIEEgZGl2aWRlZCBiZXR3ZWVuIGl0cyBlbmRwb2ludHM/IChleGNsdXNpdmUpCiAgICAgICAgaWYgKGkuYWxvbmdBID09PSAwKSB7CiAgICAgICAgICBpZiAoaS5hbG9uZ0IgPT09IC0xKQogICAgICAgICAgICAvLyB5ZXMsIGF0IGV4YWN0bHkgYjEKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBiMSk7ZWxzZSBpZiAoaS5hbG9uZ0IgPT09IDApCiAgICAgICAgICAgIC8vIHllcywgc29tZXdoZXJlIGJldHdlZW4gQidzIGVuZHBvaW50cwogICAgICAgICAgICBldmVudERpdmlkZShldjEsIGkucHQpO2Vsc2UgaWYgKGkuYWxvbmdCID09PSAxKQogICAgICAgICAgICAvLyB5ZXMsIGF0IGV4YWN0bHkgYjIKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBiMik7CiAgICAgICAgfQoKICAgICAgICAvLyBpcyBCIGRpdmlkZWQgYmV0d2VlbiBpdHMgZW5kcG9pbnRzPyAoZXhjbHVzaXZlKQogICAgICAgIGlmIChpLmFsb25nQiA9PT0gMCkgewogICAgICAgICAgaWYgKGkuYWxvbmdBID09PSAtMSkKICAgICAgICAgICAgLy8geWVzLCBhdCBleGFjdGx5IGExCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgYTEpO2Vsc2UgaWYgKGkuYWxvbmdBID09PSAwKQogICAgICAgICAgICAvLyB5ZXMsIHNvbWV3aGVyZSBiZXR3ZWVuIEEncyBlbmRwb2ludHMgKGV4Y2x1c2l2ZSkKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBpLnB0KTtlbHNlIGlmIChpLmFsb25nQSA9PT0gMSkKICAgICAgICAgICAgLy8geWVzLCBhdCBleGFjdGx5IGEyCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgYTIpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8KICAgIC8vIG1haW4gZXZlbnQgbG9vcAogICAgLy8KICAgIHZhciBzZWdtZW50cyA9IFtdOwogICAgd2hpbGUgKCFldmVudF9yb290LmlzRW1wdHkoKSkgewogICAgICB2YXIgZXYgPSBldmVudF9yb290LmdldEhlYWQoKTsKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy52ZXJ0KGV2LnB0WzBdKTsKICAgICAgaWYgKGV2LmlzU3RhcnQpIHsKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnNlZ21lbnROZXcoZXYuc2VnLCBldi5wcmltYXJ5KTsKICAgICAgICB2YXIgc3Vycm91bmRpbmcgPSBzdGF0dXNGaW5kU3Vycm91bmRpbmcoZXYpOwogICAgICAgIHZhciBhYm92ZSA9IHN1cnJvdW5kaW5nLmJlZm9yZSA/IHN1cnJvdW5kaW5nLmJlZm9yZS5ldiA6IG51bGw7CiAgICAgICAgdmFyIGJlbG93ID0gc3Vycm91bmRpbmcuYWZ0ZXIgPyBzdXJyb3VuZGluZy5hZnRlci5ldiA6IG51bGw7CiAgICAgICAgaWYgKGJ1aWxkTG9nKSB7CiAgICAgICAgICBidWlsZExvZy50ZW1wU3RhdHVzKGV2LnNlZywgYWJvdmUgPyBhYm92ZS5zZWcgOiBmYWxzZSwgYmVsb3cgPyBiZWxvdy5zZWcgOiBmYWxzZSk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGNoZWNrQm90aEludGVyc2VjdGlvbnMoKSB7CiAgICAgICAgICBpZiAoYWJvdmUpIHsKICAgICAgICAgICAgdmFyIGV2ZSA9IGNoZWNrSW50ZXJzZWN0aW9uKGV2LCBhYm92ZSk7CiAgICAgICAgICAgIGlmIChldmUpIHJldHVybiBldmU7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoYmVsb3cpIHJldHVybiBjaGVja0ludGVyc2VjdGlvbihldiwgYmVsb3cpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICB2YXIgZXZlID0gY2hlY2tCb3RoSW50ZXJzZWN0aW9ucygpOwogICAgICAgIGlmIChldmUpIHsKICAgICAgICAgIC8vIGV2IGFuZCBldmUgYXJlIGVxdWFsCiAgICAgICAgICAvLyB3ZSdsbCBrZWVwIGV2ZSBhbmQgdGhyb3cgYXdheSBldgoKICAgICAgICAgIC8vIG1lcmdlIGV2LnNlZydzIGZpbGwgaW5mb3JtYXRpb24gaW50byBldmUuc2VnCgogICAgICAgICAgaWYgKHNlbGZJbnRlcnNlY3Rpb24pIHsKICAgICAgICAgICAgdmFyIHRvZ2dsZTsgLy8gYXJlIHdlIGEgdG9nZ2xpbmcgZWRnZT8KICAgICAgICAgICAgaWYgKGV2LnNlZy5teUZpbGwuYmVsb3cgPT09IG51bGwpIHRvZ2dsZSA9IHRydWU7ZWxzZSB0b2dnbGUgPSBldi5zZWcubXlGaWxsLmFib3ZlICE9PSBldi5zZWcubXlGaWxsLmJlbG93OwoKICAgICAgICAgICAgLy8gbWVyZ2UgdHdvIHNlZ21lbnRzIHRoYXQgYmVsb25nIHRvIHRoZSBzYW1lIHBvbHlnb24KICAgICAgICAgICAgLy8gdGhpbmsgb2YgdGhpcyBhcyBzYW5kd2ljaGluZyB0d28gc2VnbWVudHMgdG9nZXRoZXIsIHdoZXJlIGBldmUuc2VnYCBpcwogICAgICAgICAgICAvLyB0aGUgYm90dG9tIC0tIHRoaXMgd2lsbCBjYXVzZSB0aGUgYWJvdmUgZmlsbCBmbGFnIHRvIHRvZ2dsZQogICAgICAgICAgICBpZiAodG9nZ2xlKSBldmUuc2VnLm15RmlsbC5hYm92ZSA9ICFldmUuc2VnLm15RmlsbC5hYm92ZTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIG1lcmdlIHR3byBzZWdtZW50cyB0aGF0IGJlbG9uZyB0byBkaWZmZXJlbnQgcG9seWdvbnMKICAgICAgICAgICAgLy8gZWFjaCBzZWdtZW50IGhhcyBkaXN0aW5jdCBrbm93bGVkZ2UsIHNvIG5vIHNwZWNpYWwgbG9naWMgaXMgbmVlZGVkCiAgICAgICAgICAgIC8vIG5vdGUgdGhhdCB0aGlzIGNhbiBvbmx5IGhhcHBlbiBvbmNlIHBlciBzZWdtZW50IGluIHRoaXMgcGhhc2UsIGJlY2F1c2Ugd2UKICAgICAgICAgICAgLy8gYXJlIGd1YXJhbnRlZWQgdGhhdCBhbGwgc2VsZi1pbnRlcnNlY3Rpb25zIGFyZSBnb25lCiAgICAgICAgICAgIGV2ZS5zZWcub3RoZXJGaWxsID0gZXYuc2VnLm15RmlsbDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuc2VnbWVudFVwZGF0ZShldmUuc2VnKTsKICAgICAgICAgIGV2Lm90aGVyLnJlbW92ZSgpOwogICAgICAgICAgZXYucmVtb3ZlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChldmVudF9yb290LmdldEhlYWQoKSAhPT0gZXYpIHsKICAgICAgICAgIC8vIHNvbWV0aGluZyB3YXMgaW5zZXJ0ZWQgYmVmb3JlIHVzIGluIHRoZSBldmVudCBxdWV1ZSwgc28gbG9vcCBiYWNrIGFyb3VuZCBhbmQKICAgICAgICAgIC8vIHByb2Nlc3MgaXQgYmVmb3JlIGNvbnRpbnVpbmcKICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cucmV3aW5kKGV2LnNlZyk7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIC8vCiAgICAgICAgLy8gY2FsY3VsYXRlIGZpbGwgZmxhZ3MKICAgICAgICAvLwogICAgICAgIGlmIChzZWxmSW50ZXJzZWN0aW9uKSB7CiAgICAgICAgICB2YXIgdG9nZ2xlOyAvLyBhcmUgd2UgYSB0b2dnbGluZyBlZGdlPwogICAgICAgICAgaWYgKGV2LnNlZy5teUZpbGwuYmVsb3cgPT09IG51bGwpCiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBhIG5ldyBzZWdtZW50Li4uCiAgICAgICAgICAgIHRvZ2dsZSA9IHRydWU7IC8vIHRoZW4gd2UgdG9nZ2xlCiAgICAgICAgICBlbHNlCiAgICAgICAgICAgIC8vIHdlIGFyZSBhIHNlZ21lbnQgdGhhdCBoYXMgcHJldmlvdXMga25vd2xlZGdlIGZyb20gYSBkaXZpc2lvbgogICAgICAgICAgICB0b2dnbGUgPSBldi5zZWcubXlGaWxsLmFib3ZlICE9PSBldi5zZWcubXlGaWxsLmJlbG93OyAvLyBjYWxjdWxhdGUgdG9nZ2xlCgogICAgICAgICAgLy8gbmV4dCwgY2FsY3VsYXRlIHdoZXRoZXIgd2UgYXJlIGZpbGxlZCBiZWxvdyB1cwogICAgICAgICAgaWYgKCFiZWxvdykgewogICAgICAgICAgICAvLyBpZiBub3RoaW5nIGlzIGJlbG93IHVzLi4uCiAgICAgICAgICAgIC8vIHdlIGFyZSBmaWxsZWQgYmVsb3cgdXMgaWYgdGhlIHBvbHlnb24gaXMgaW52ZXJ0ZWQKICAgICAgICAgICAgZXYuc2VnLm15RmlsbC5iZWxvdyA9IHByaW1hcnlQb2x5SW52ZXJ0ZWQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBvdGhlcndpc2UsIHdlIGtub3cgdGhlIGFuc3dlciAtLSBpdCdzIHRoZSBzYW1lIGlmIHdoYXRldmVyIGlzIGJlbG93CiAgICAgICAgICAgIC8vIHVzIGlzIGZpbGxlZCBhYm92ZSBpdAogICAgICAgICAgICBldi5zZWcubXlGaWxsLmJlbG93ID0gYmVsb3cuc2VnLm15RmlsbC5hYm92ZTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBzaW5jZSBub3cgd2Uga25vdyBpZiB3ZSdyZSBmaWxsZWQgYmVsb3cgdXMsIHdlIGNhbiBjYWxjdWxhdGUgd2hldGhlcgogICAgICAgICAgLy8gd2UncmUgZmlsbGVkIGFib3ZlIHVzIGJ5IGFwcGx5aW5nIHRvZ2dsZSB0byB3aGF0ZXZlciBpcyBiZWxvdyB1cwogICAgICAgICAgaWYgKHRvZ2dsZSkgZXYuc2VnLm15RmlsbC5hYm92ZSA9ICFldi5zZWcubXlGaWxsLmJlbG93O2Vsc2UgZXYuc2VnLm15RmlsbC5hYm92ZSA9IGV2LnNlZy5teUZpbGwuYmVsb3c7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIG5vdyB3ZSBmaWxsIGluIGFueSBtaXNzaW5nIHRyYW5zaXRpb24gaW5mb3JtYXRpb24sIHNpbmNlIHdlIGFyZSBhbGwta25vd2luZwogICAgICAgICAgLy8gYXQgdGhpcyBwb2ludAoKICAgICAgICAgIGlmIChldi5zZWcub3RoZXJGaWxsID09PSBudWxsKSB7CiAgICAgICAgICAgIC8vIGlmIHdlIGRvbid0IGhhdmUgb3RoZXIgaW5mb3JtYXRpb24sIHRoZW4gd2UgbmVlZCB0byBmaWd1cmUgb3V0IGlmIHdlJ3JlCiAgICAgICAgICAgIC8vIGluc2lkZSB0aGUgb3RoZXIgcG9seWdvbgogICAgICAgICAgICB2YXIgaW5zaWRlOwogICAgICAgICAgICBpZiAoIWJlbG93KSB7CiAgICAgICAgICAgICAgLy8gaWYgbm90aGluZyBpcyBiZWxvdyB1cywgdGhlbiB3ZSdyZSBpbnNpZGUgaWYgdGhlIG90aGVyIHBvbHlnb24gaXMKICAgICAgICAgICAgICAvLyBpbnZlcnRlZAogICAgICAgICAgICAgIGluc2lkZSA9IGV2LnByaW1hcnkgPyBzZWNvbmRhcnlQb2x5SW52ZXJ0ZWQgOiBwcmltYXJ5UG9seUludmVydGVkOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgc29tZXRoaW5nIGlzIGJlbG93IHVzCiAgICAgICAgICAgICAgLy8gc28gY29weSB0aGUgYmVsb3cgc2VnbWVudCdzIG90aGVyIHBvbHlnb24ncyBhYm92ZQogICAgICAgICAgICAgIGlmIChldi5wcmltYXJ5ID09PSBiZWxvdy5wcmltYXJ5KSBpbnNpZGUgPSBiZWxvdy5zZWcub3RoZXJGaWxsLmFib3ZlO2Vsc2UgaW5zaWRlID0gYmVsb3cuc2VnLm15RmlsbC5hYm92ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBldi5zZWcub3RoZXJGaWxsID0gewogICAgICAgICAgICAgIGFib3ZlOiBpbnNpZGUsCiAgICAgICAgICAgICAgYmVsb3c6IGluc2lkZQogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoYnVpbGRMb2cpIHsKICAgICAgICAgIGJ1aWxkTG9nLnN0YXR1cyhldi5zZWcsIGFib3ZlID8gYWJvdmUuc2VnIDogZmFsc2UsIGJlbG93ID8gYmVsb3cuc2VnIDogZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gaW5zZXJ0IHRoZSBzdGF0dXMgYW5kIHJlbWVtYmVyIGl0IGZvciBsYXRlciByZW1vdmFsCiAgICAgICAgZXYub3RoZXIuc3RhdHVzID0gc3Vycm91bmRpbmcuaW5zZXJ0KExpbmtlZExpc3Qubm9kZSh7CiAgICAgICAgICBldjogZXYKICAgICAgICB9KSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIHN0ID0gZXYuc3RhdHVzOwogICAgICAgIGlmIChzdCA9PT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb2x5Qm9vbDogWmVyby1sZW5ndGggc2VnbWVudCBkZXRlY3RlZDsgeW91ciBlcHNpbG9uIGlzICcgKyAncHJvYmFibHkgdG9vIHNtYWxsIG9yIHRvbyBsYXJnZScpOwogICAgICAgIH0KCiAgICAgICAgLy8gcmVtb3ZpbmcgdGhlIHN0YXR1cyB3aWxsIGNyZWF0ZSB0d28gbmV3IGFkamFjZW50IGVkZ2VzLCBzbyB3ZSdsbCBuZWVkIHRvIGNoZWNrCiAgICAgICAgLy8gZm9yIHRob3NlCiAgICAgICAgaWYgKHN0YXR1c19yb290LmV4aXN0cyhzdC5wcmV2KSAmJiBzdGF0dXNfcm9vdC5leGlzdHMoc3QubmV4dCkpIGNoZWNrSW50ZXJzZWN0aW9uKHN0LnByZXYuZXYsIHN0Lm5leHQuZXYpOwogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuc3RhdHVzUmVtb3ZlKHN0LmV2LnNlZyk7CgogICAgICAgIC8vIHJlbW92ZSB0aGUgc3RhdHVzCiAgICAgICAgc3QucmVtb3ZlKCk7CgogICAgICAgIC8vIGlmIHdlJ3ZlIHJlYWNoZWQgdGhpcyBwb2ludCwgd2UndmUgY2FsY3VsYXRlZCBldmVyeXRoaW5nIHRoZXJlIGlzIHRvIGtub3csIHNvCiAgICAgICAgLy8gc2F2ZSB0aGUgc2VnbWVudCBmb3IgcmVwb3J0aW5nCiAgICAgICAgaWYgKCFldi5wcmltYXJ5KSB7CiAgICAgICAgICAvLyBtYWtlIHN1cmUgYHNlZy5teUZpbGxgIGFjdHVhbGx5IHBvaW50cyB0byB0aGUgcHJpbWFyeSBwb2x5Z29uIHRob3VnaAogICAgICAgICAgdmFyIHMgPSBldi5zZWcubXlGaWxsOwogICAgICAgICAgZXYuc2VnLm15RmlsbCA9IGV2LnNlZy5vdGhlckZpbGw7CiAgICAgICAgICBldi5zZWcub3RoZXJGaWxsID0gczsKICAgICAgICB9CiAgICAgICAgc2VnbWVudHMucHVzaChldi5zZWcpOwogICAgICB9CgogICAgICAvLyByZW1vdmUgdGhlIGV2ZW50IGFuZCBjb250aW51ZQogICAgICBldmVudF9yb290LmdldEhlYWQoKS5yZW1vdmUoKTsKICAgIH0KICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuZG9uZSgpOwogICAgcmV0dXJuIHNlZ21lbnRzOwogIH0KCiAgLy8gcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBBUEkgZGVwZW5kaW5nIG9uIHdoYXQgd2UncmUgZG9pbmcKICBpZiAoIXNlbGZJbnRlcnNlY3Rpb24pIHsKICAgIC8vIHBlcmZvcm1pbmcgY29tYmluYXRpb24gb2YgcG9seWdvbnMsIHNvIG9ubHkgZGVhbCB3aXRoIGFscmVhZHktcHJvY2Vzc2VkIHNlZ21lbnRzCiAgICByZXR1cm4gewogICAgICBjYWxjdWxhdGU6IGZ1bmN0aW9uIChzZWdtZW50czEsIGludmVydGVkMSwgc2VnbWVudHMyLCBpbnZlcnRlZDIpIHsKICAgICAgICAvLyBzZWdtZW50c1ggY29tZSBmcm9tIHRoZSBzZWxmLWludGVyc2VjdGlvbiBBUEksIG9yIHRoaXMgQVBJCiAgICAgICAgLy8gaW52ZXJ0ZWRYIGlzIHdoZXRoZXIgd2UgdHJlYXQgdGhhdCBsaXN0IG9mIHNlZ21lbnRzIGFzIGFuIGludmVydGVkIHBvbHlnb24gb3Igbm90CiAgICAgICAgLy8gcmV0dXJucyBzZWdtZW50cyB0aGF0IGNhbiBiZSB1c2VkIGZvciBmdXJ0aGVyIG9wZXJhdGlvbnMKICAgICAgICBzZWdtZW50czEuZm9yRWFjaChmdW5jdGlvbiAoc2VnKSB7CiAgICAgICAgICBldmVudEFkZFNlZ21lbnQoc2VnbWVudENvcHkoc2VnLnN0YXJ0LCBzZWcuZW5kLCBzZWcpLCB0cnVlKTsKICAgICAgICB9KTsKICAgICAgICBzZWdtZW50czIuZm9yRWFjaChmdW5jdGlvbiAoc2VnKSB7CiAgICAgICAgICBldmVudEFkZFNlZ21lbnQoc2VnbWVudENvcHkoc2VnLnN0YXJ0LCBzZWcuZW5kLCBzZWcpLCBmYWxzZSk7CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGNhbGN1bGF0ZShpbnZlcnRlZDEsIGludmVydGVkMik7CiAgICAgIH0KICAgIH07CiAgfQoKICAvLyBvdGhlcndpc2UsIHBlcmZvcm1pbmcgc2VsZi1pbnRlcnNlY3Rpb24sIHNvIGRlYWwgd2l0aCByZWdpb25zCiAgcmV0dXJuIHsKICAgIGFkZFJlZ2lvbjogZnVuY3Rpb24gKHJlZ2lvbikgewogICAgICAvLyByZWdpb25zIGFyZSBhIGxpc3Qgb2YgcG9pbnRzOgogICAgICAvLyAgWyBbMCwgMF0sIFsxMDAsIDBdLCBbNTAsIDEwMF0gXQogICAgICAvLyB5b3UgY2FuIGFkZCBtdWx0aXBsZSByZWdpb25zIGJlZm9yZSBydW5uaW5nIGNhbGN1bGF0ZQogICAgICB2YXIgcHQxOwogICAgICB2YXIgcHQyID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWdpb24ubGVuZ3RoOyBpKyspIHsKICAgICAgICBwdDEgPSBwdDI7CiAgICAgICAgcHQyID0gcmVnaW9uW2ldOwogICAgICAgIHZhciBmb3J3YXJkID0gZXBzLnBvaW50c0NvbXBhcmUocHQxLCBwdDIpOwogICAgICAgIGlmIChmb3J3YXJkID09PSAwKQogICAgICAgICAgLy8gcG9pbnRzIGFyZSBlcXVhbCwgc28gd2UgaGF2ZSBhIHplcm8tbGVuZ3RoIHNlZ21lbnQKICAgICAgICAgIGNvbnRpbnVlOyAvLyBqdXN0IHNraXAgaXQKCiAgICAgICAgZXZlbnRBZGRTZWdtZW50KHNlZ21lbnROZXcoZm9yd2FyZCA8IDAgPyBwdDEgOiBwdDIsIGZvcndhcmQgPCAwID8gcHQyIDogcHQxKSwgdHJ1ZSk7CiAgICAgIH0KICAgIH0sCiAgICBjYWxjdWxhdGU6IGZ1bmN0aW9uIChpbnZlcnRlZCkgewogICAgICAvLyBpcyB0aGUgcG9seWdvbiBpbnZlcnRlZD8KICAgICAgLy8gcmV0dXJucyBzZWdtZW50cwogICAgICByZXR1cm4gY2FsY3VsYXRlKGludmVydGVkLCBmYWxzZSk7CiAgICB9CiAgfTsKfQp2YXIgaW50ZXJzZWN0ZXIgPSBJbnRlcnNlY3RlciQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyBjb252ZXJ0cyBhIGxpc3Qgb2Ygc2VnbWVudHMgaW50byBhIGxpc3Qgb2YgcmVnaW9ucywgd2hpbGUgYWxzbyByZW1vdmluZyB1bm5lY2Vzc2FyeSB2ZXJ0aWNpZXMKLy8KCmZ1bmN0aW9uIFNlZ21lbnRDaGFpbmVyJDEoc2VnbWVudHMsIGVwcywgYnVpbGRMb2cpIHsKICB2YXIgY2hhaW5zID0gW107CiAgdmFyIHJlZ2lvbnMgPSBbXTsKICBzZWdtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzZWcpIHsKICAgIHZhciBwdDEgPSBzZWcuc3RhcnQ7CiAgICB2YXIgcHQyID0gc2VnLmVuZDsKICAgIGlmIChlcHMucG9pbnRzU2FtZShwdDEsIHB0MikpIHsKICAgICAgY29uc29sZS53YXJuKCdQb2x5Qm9vbDogV2FybmluZzogWmVyby1sZW5ndGggc2VnbWVudCBkZXRlY3RlZDsgeW91ciBlcHNpbG9uIGlzICcgKyAncHJvYmFibHkgdG9vIHNtYWxsIG9yIHRvbyBsYXJnZScpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluU3RhcnQoc2VnKTsKCiAgICAvLyBzZWFyY2ggZm9yIHR3byBjaGFpbnMgdGhhdCB0aGlzIHNlZ21lbnQgbWF0Y2hlcwogICAgdmFyIGZpcnN0X21hdGNoID0gewogICAgICBpbmRleDogMCwKICAgICAgbWF0Y2hlc19oZWFkOiBmYWxzZSwKICAgICAgbWF0Y2hlc19wdDE6IGZhbHNlCiAgICB9OwogICAgdmFyIHNlY29uZF9tYXRjaCA9IHsKICAgICAgaW5kZXg6IDAsCiAgICAgIG1hdGNoZXNfaGVhZDogZmFsc2UsCiAgICAgIG1hdGNoZXNfcHQxOiBmYWxzZQogICAgfTsKICAgIHZhciBuZXh0X21hdGNoID0gZmlyc3RfbWF0Y2g7CiAgICBmdW5jdGlvbiBzZXRNYXRjaChpbmRleCwgbWF0Y2hlc19oZWFkLCBtYXRjaGVzX3B0MSkgewogICAgICAvLyByZXR1cm4gdHJ1ZSBpZiB3ZSd2ZSBtYXRjaGVkIHR3aWNlCiAgICAgIG5leHRfbWF0Y2guaW5kZXggPSBpbmRleDsKICAgICAgbmV4dF9tYXRjaC5tYXRjaGVzX2hlYWQgPSBtYXRjaGVzX2hlYWQ7CiAgICAgIG5leHRfbWF0Y2gubWF0Y2hlc19wdDEgPSBtYXRjaGVzX3B0MTsKICAgICAgaWYgKG5leHRfbWF0Y2ggPT09IGZpcnN0X21hdGNoKSB7CiAgICAgICAgbmV4dF9tYXRjaCA9IHNlY29uZF9tYXRjaDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbmV4dF9tYXRjaCA9IG51bGw7CiAgICAgIHJldHVybiB0cnVlOyAvLyB3ZSd2ZSBtYXRjaGVkIHR3aWNlLCB3ZSdyZSBkb25lIGhlcmUKICAgIH0KCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoYWlucy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgY2hhaW4gPSBjaGFpbnNbaV07CiAgICAgIHZhciBoZWFkID0gY2hhaW5bMF07CiAgICAgIGNoYWluWzFdOwogICAgICB2YXIgdGFpbCA9IGNoYWluW2NoYWluLmxlbmd0aCAtIDFdOwogICAgICBjaGFpbltjaGFpbi5sZW5ndGggLSAyXTsKICAgICAgaWYgKGVwcy5wb2ludHNTYW1lKGhlYWQsIHB0MSkpIHsKICAgICAgICBpZiAoc2V0TWF0Y2goaSwgdHJ1ZSwgdHJ1ZSkpIGJyZWFrOwogICAgICB9IGVsc2UgaWYgKGVwcy5wb2ludHNTYW1lKGhlYWQsIHB0MikpIHsKICAgICAgICBpZiAoc2V0TWF0Y2goaSwgdHJ1ZSwgZmFsc2UpKSBicmVhazsKICAgICAgfSBlbHNlIGlmIChlcHMucG9pbnRzU2FtZSh0YWlsLCBwdDEpKSB7CiAgICAgICAgaWYgKHNldE1hdGNoKGksIGZhbHNlLCB0cnVlKSkgYnJlYWs7CiAgICAgIH0gZWxzZSBpZiAoZXBzLnBvaW50c1NhbWUodGFpbCwgcHQyKSkgewogICAgICAgIGlmIChzZXRNYXRjaChpLCBmYWxzZSwgZmFsc2UpKSBicmVhazsKICAgICAgfQogICAgfQogICAgaWYgKG5leHRfbWF0Y2ggPT09IGZpcnN0X21hdGNoKSB7CiAgICAgIC8vIHdlIGRpZG4ndCBtYXRjaCBhbnl0aGluZywgc28gY3JlYXRlIGEgbmV3IGNoYWluCiAgICAgIGNoYWlucy5wdXNoKFtwdDEsIHB0Ml0pOwogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluTmV3KHB0MSwgcHQyKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKG5leHRfbWF0Y2ggPT09IHNlY29uZF9tYXRjaCkgewogICAgICAvLyB3ZSBtYXRjaGVkIGEgc2luZ2xlIGNoYWluCgogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluTWF0Y2goZmlyc3RfbWF0Y2guaW5kZXgpOwoKICAgICAgLy8gYWRkIHRoZSBvdGhlciBwb2ludCB0byB0aGUgYXBwb3JwcmlhdGUgZW5kLCBhbmQgY2hlY2sgdG8gc2VlIGlmIHdlJ3ZlIGNsb3NlZCB0aGUKICAgICAgLy8gY2hhaW4gaW50byBhIGxvb3AKCiAgICAgIHZhciBpbmRleCA9IGZpcnN0X21hdGNoLmluZGV4OwogICAgICB2YXIgcHQgPSBmaXJzdF9tYXRjaC5tYXRjaGVzX3B0MSA/IHB0MiA6IHB0MTsgLy8gaWYgd2UgbWF0Y2hlZCBwdDEsIHRoZW4gd2UgYWRkIHB0MiwgZXRjCiAgICAgIHZhciBhZGRUb0hlYWQgPSBmaXJzdF9tYXRjaC5tYXRjaGVzX2hlYWQ7IC8vIGlmIHdlIG1hdGNoZWQgYXQgaGVhZCwgdGhlbiBhZGQgdG8gdGhlIGhlYWQKCiAgICAgIHZhciBjaGFpbiA9IGNoYWluc1tpbmRleF07CiAgICAgIHZhciBncm93ID0gYWRkVG9IZWFkID8gY2hhaW5bMF0gOiBjaGFpbltjaGFpbi5sZW5ndGggLSAxXTsKICAgICAgdmFyIGdyb3cyID0gYWRkVG9IZWFkID8gY2hhaW5bMV0gOiBjaGFpbltjaGFpbi5sZW5ndGggLSAyXTsKICAgICAgdmFyIG9wcG8gPSBhZGRUb0hlYWQgPyBjaGFpbltjaGFpbi5sZW5ndGggLSAxXSA6IGNoYWluWzBdOwogICAgICB2YXIgb3BwbzIgPSBhZGRUb0hlYWQgPyBjaGFpbltjaGFpbi5sZW5ndGggLSAyXSA6IGNoYWluWzFdOwogICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcihncm93MiwgZ3JvdywgcHQpKSB7CiAgICAgICAgLy8gZ3JvdyBpc24ndCBuZWVkZWQgYmVjYXVzZSBpdCdzIGRpcmVjdGx5IGJldHdlZW4gZ3JvdzIgYW5kIHB0OgogICAgICAgIC8vIGdyb3cyIC0tLWdyb3ctLS0+IHB0CiAgICAgICAgaWYgKGFkZFRvSGVhZCkgewogICAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJlbW92ZUhlYWQoZmlyc3RfbWF0Y2guaW5kZXgsIHB0KTsKICAgICAgICAgIGNoYWluLnNoaWZ0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVUYWlsKGZpcnN0X21hdGNoLmluZGV4LCBwdCk7CiAgICAgICAgICBjaGFpbi5wb3AoKTsKICAgICAgICB9CiAgICAgICAgZ3JvdyA9IGdyb3cyOyAvLyBvbGQgZ3JvdyBpcyBnb25lLi4uIG5ldyBncm93IGlzIHdoYXQgZ3JvdzIgd2FzCiAgICAgIH0KCiAgICAgIGlmIChlcHMucG9pbnRzU2FtZShvcHBvLCBwdCkpIHsKICAgICAgICAvLyB3ZSdyZSBjbG9zaW5nIHRoZSBsb29wLCBzbyByZW1vdmUgY2hhaW4gZnJvbSBjaGFpbnMKICAgICAgICBjaGFpbnMuc3BsaWNlKGluZGV4LCAxKTsKICAgICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcihvcHBvMiwgb3BwbywgZ3JvdykpIHsKICAgICAgICAgIC8vIG9wcG8gaXNuJ3QgbmVlZGVkIGJlY2F1c2UgaXQncyBkaXJlY3RseSBiZXR3ZWVuIG9wcG8yIGFuZCBncm93OgogICAgICAgICAgLy8gb3BwbzIgLS0tb3Bwby0tLT5ncm93CiAgICAgICAgICBpZiAoYWRkVG9IZWFkKSB7CiAgICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVUYWlsKGZpcnN0X21hdGNoLmluZGV4LCBncm93KTsKICAgICAgICAgICAgY2hhaW4ucG9wKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlSGVhZChmaXJzdF9tYXRjaC5pbmRleCwgZ3Jvdyk7CiAgICAgICAgICAgIGNoYWluLnNoaWZ0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5DbG9zZShmaXJzdF9tYXRjaC5pbmRleCk7CgogICAgICAgIC8vIHdlIGhhdmUgYSBjbG9zZWQgY2hhaW4hCiAgICAgICAgcmVnaW9ucy5wdXNoKGNoYWluKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIC8vIG5vdCBjbG9zaW5nIGEgbG9vcCwgc28ganVzdCBhZGQgaXQgdG8gdGhlIGFwcG9ycHJpYXRlIHNpZGUKICAgICAgaWYgKGFkZFRvSGVhZCkgewogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5BZGRIZWFkKGZpcnN0X21hdGNoLmluZGV4LCBwdCk7CiAgICAgICAgY2hhaW4udW5zaGlmdChwdCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbkFkZFRhaWwoZmlyc3RfbWF0Y2guaW5kZXgsIHB0KTsKICAgICAgICBjaGFpbi5wdXNoKHB0KTsKICAgICAgfQogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gb3RoZXJ3aXNlLCB3ZSBtYXRjaGVkIHR3byBjaGFpbnMsIHNvIHdlIG5lZWQgdG8gY29tYmluZSB0aG9zZSBjaGFpbnMgdG9nZXRoZXIKCiAgICBmdW5jdGlvbiByZXZlcnNlQ2hhaW4oaW5kZXgpIHsKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJldmVyc2UoaW5kZXgpOwogICAgICBjaGFpbnNbaW5kZXhdLnJldmVyc2UoKTsgLy8gZ2VlLCB0aGF0J3MgZWFzeQogICAgfQoKICAgIGZ1bmN0aW9uIGFwcGVuZENoYWluKGluZGV4MSwgaW5kZXgyKSB7CiAgICAgIC8vIGluZGV4MSBnZXRzIGluZGV4MiBhcHBlbmRlZCB0byBpdCwgYW5kIGluZGV4MiBpcyByZW1vdmVkCiAgICAgIHZhciBjaGFpbjEgPSBjaGFpbnNbaW5kZXgxXTsKICAgICAgdmFyIGNoYWluMiA9IGNoYWluc1tpbmRleDJdOwogICAgICB2YXIgdGFpbCA9IGNoYWluMVtjaGFpbjEubGVuZ3RoIC0gMV07CiAgICAgIHZhciB0YWlsMiA9IGNoYWluMVtjaGFpbjEubGVuZ3RoIC0gMl07CiAgICAgIHZhciBoZWFkID0gY2hhaW4yWzBdOwogICAgICB2YXIgaGVhZDIgPSBjaGFpbjJbMV07CiAgICAgIGlmIChlcHMucG9pbnRzQ29sbGluZWFyKHRhaWwyLCB0YWlsLCBoZWFkKSkgewogICAgICAgIC8vIHRhaWwgaXNuJ3QgbmVlZGVkIGJlY2F1c2UgaXQncyBkaXJlY3RseSBiZXR3ZWVuIHRhaWwyIGFuZCBoZWFkCiAgICAgICAgLy8gdGFpbDIgLS0tdGFpbC0tLT4gaGVhZAogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVUYWlsKGluZGV4MSwgdGFpbCk7CiAgICAgICAgY2hhaW4xLnBvcCgpOwogICAgICAgIHRhaWwgPSB0YWlsMjsgLy8gb2xkIHRhaWwgaXMgZ29uZS4uLiBuZXcgdGFpbCBpcyB3aGF0IHRhaWwyIHdhcwogICAgICB9CgogICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcih0YWlsLCBoZWFkLCBoZWFkMikpIHsKICAgICAgICAvLyBoZWFkIGlzbid0IG5lZWRlZCBiZWNhdXNlIGl0J3MgZGlyZWN0bHkgYmV0d2VlbiB0YWlsIGFuZCBoZWFkMgogICAgICAgIC8vIHRhaWwgLS0taGVhZC0tLT4gaGVhZDIKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlSGVhZChpbmRleDIsIGhlYWQpOwogICAgICAgIGNoYWluMi5zaGlmdCgpOwogICAgICB9CiAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5Kb2luKGluZGV4MSwgaW5kZXgyKTsKICAgICAgY2hhaW5zW2luZGV4MV0gPSBjaGFpbjEuY29uY2F0KGNoYWluMik7CiAgICAgIGNoYWlucy5zcGxpY2UoaW5kZXgyLCAxKTsKICAgIH0KICAgIHZhciBGID0gZmlyc3RfbWF0Y2guaW5kZXg7CiAgICB2YXIgUyA9IHNlY29uZF9tYXRjaC5pbmRleDsKICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5Db25uZWN0KEYsIFMpOwogICAgdmFyIHJldmVyc2VGID0gY2hhaW5zW0ZdLmxlbmd0aCA8IGNoYWluc1tTXS5sZW5ndGg7IC8vIHJldmVyc2UgdGhlIHNob3J0ZXIgY2hhaW4sIGlmIG5lZWRlZAogICAgaWYgKGZpcnN0X21hdGNoLm1hdGNoZXNfaGVhZCkgewogICAgICBpZiAoc2Vjb25kX21hdGNoLm1hdGNoZXNfaGVhZCkgewogICAgICAgIGlmIChyZXZlcnNlRikgewogICAgICAgICAgLy8gPDw8PCBGIDw8PDwgLS0tID4+Pj4gUyA+Pj4+CiAgICAgICAgICByZXZlcnNlQ2hhaW4oRik7CiAgICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPj4+PiBTID4+Pj4KICAgICAgICAgIGFwcGVuZENoYWluKEYsIFMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyA8PDw8IEYgPDw8PCAtLS0gPj4+PiBTID4+Pj4KICAgICAgICAgIHJldmVyc2VDaGFpbihTKTsKICAgICAgICAgIC8vIDw8PDwgRiA8PDw8IC0tLSA8PDw8IFMgPDw8PCAgIGxvZ2ljYWxseSBzYW1lIGFzOgogICAgICAgICAgLy8gPj4+PiBTID4+Pj4gLS0tID4+Pj4gRiA+Pj4+CiAgICAgICAgICBhcHBlbmRDaGFpbihTLCBGKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gPDw8PCBGIDw8PDwgLS0tIDw8PDwgUyA8PDw8ICAgbG9naWNhbGx5IHNhbWUgYXM6CiAgICAgICAgLy8gPj4+PiBTID4+Pj4gLS0tID4+Pj4gRiA+Pj4+CiAgICAgICAgYXBwZW5kQ2hhaW4oUywgRik7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGlmIChzZWNvbmRfbWF0Y2gubWF0Y2hlc19oZWFkKSB7CiAgICAgICAgLy8gPj4+PiBGID4+Pj4gLS0tID4+Pj4gUyA+Pj4+CiAgICAgICAgYXBwZW5kQ2hhaW4oRiwgUyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHJldmVyc2VGKSB7CiAgICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPDw8PCBTIDw8PDwKICAgICAgICAgIHJldmVyc2VDaGFpbihGKTsKICAgICAgICAgIC8vIDw8PDwgRiA8PDw8IC0tLSA8PDw8IFMgPDw8PCAgIGxvZ2ljYWxseSBzYW1lIGFzOgogICAgICAgICAgLy8gPj4+PiBTID4+Pj4gLS0tID4+Pj4gRiA+Pj4+CiAgICAgICAgICBhcHBlbmRDaGFpbihTLCBGKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gPj4+PiBGID4+Pj4gLS0tIDw8PDwgUyA8PDw8CiAgICAgICAgICByZXZlcnNlQ2hhaW4oUyk7CiAgICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPj4+PiBTID4+Pj4KICAgICAgICAgIGFwcGVuZENoYWluKEYsIFMpOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0pOwogIHJldHVybiByZWdpb25zOwp9CnZhciBzZWdtZW50Q2hhaW5lciA9IFNlZ21lbnRDaGFpbmVyJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIGZpbHRlciBhIGxpc3Qgb2Ygc2VnbWVudHMgYmFzZWQgb24gYm9vbGVhbiBvcGVyYXRpb25zCi8vCgpmdW5jdGlvbiBzZWxlY3Qoc2VnbWVudHMsIHNlbGVjdGlvbiwgYnVpbGRMb2cpIHsKICB2YXIgcmVzdWx0ID0gW107CiAgc2VnbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoc2VnKSB7CiAgICB2YXIgaW5kZXggPSAoc2VnLm15RmlsbC5hYm92ZSA/IDggOiAwKSArIChzZWcubXlGaWxsLmJlbG93ID8gNCA6IDApICsgKHNlZy5vdGhlckZpbGwgJiYgc2VnLm90aGVyRmlsbC5hYm92ZSA/IDIgOiAwKSArIChzZWcub3RoZXJGaWxsICYmIHNlZy5vdGhlckZpbGwuYmVsb3cgPyAxIDogMCk7CiAgICBpZiAoc2VsZWN0aW9uW2luZGV4XSAhPT0gMCkgewogICAgICAvLyBjb3B5IHRoZSBzZWdtZW50IHRvIHRoZSByZXN1bHRzLCB3aGlsZSBhbHNvIGNhbGN1bGF0aW5nIHRoZSBmaWxsIHN0YXR1cwogICAgICByZXN1bHQucHVzaCh7CiAgICAgICAgaWQ6IGJ1aWxkTG9nID8gYnVpbGRMb2cuc2VnbWVudElkKCkgOiAtMSwKICAgICAgICBzdGFydDogc2VnLnN0YXJ0LAogICAgICAgIGVuZDogc2VnLmVuZCwKICAgICAgICBteUZpbGw6IHsKICAgICAgICAgIGFib3ZlOiBzZWxlY3Rpb25baW5kZXhdID09PSAxLAogICAgICAgICAgLy8gMSBpZiBmaWxsZWQgYWJvdmUKICAgICAgICAgIGJlbG93OiBzZWxlY3Rpb25baW5kZXhdID09PSAyIC8vIDIgaWYgZmlsbGVkIGJlbG93CiAgICAgICAgfSwKCiAgICAgICAgb3RoZXJGaWxsOiBudWxsCiAgICAgIH0pOwogICAgfQogIH0pOwogIGlmIChidWlsZExvZykgYnVpbGRMb2cuc2VsZWN0ZWQocmVzdWx0KTsKICByZXR1cm4gcmVzdWx0Owp9CnZhciBTZWdtZW50U2VsZWN0b3IkMSA9IHsKICB1bmlvbjogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gcHJpbWFyeSB8IHNlY29uZGFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDIsIDEsIDAsIDIsIDIsIDAsIDAsIDEsIDAsIDEsIDAsIDAsIDAsIDAsIDBdLCBidWlsZExvZyk7CiAgfSwKICBpbnRlcnNlY3Q6IGZ1bmN0aW9uIChzZWdtZW50cywgYnVpbGRMb2cpIHsKICAgIC8vIHByaW1hcnkgJiBzZWNvbmRhcnkKICAgIC8vIGFib3ZlMSBiZWxvdzEgYWJvdmUyIGJlbG93MiAgICBLZWVwPyAgICAgICAgICAgICAgIFZhbHVlCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIHJldHVybiBzZWxlY3Qoc2VnbWVudHMsIFswLCAwLCAwLCAwLCAwLCAyLCAwLCAyLCAwLCAwLCAxLCAxLCAwLCAyLCAxLCAwXSwgYnVpbGRMb2cpOwogIH0sCiAgZGlmZmVyZW5jZTogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gcHJpbWFyeSAtIHNlY29uZGFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDAsIDAsIDAsIDIsIDAsIDIsIDAsIDEsIDEsIDAsIDAsIDAsIDEsIDIsIDBdLCBidWlsZExvZyk7CiAgfSwKICBkaWZmZXJlbmNlUmV2OiBmdW5jdGlvbiAoc2VnbWVudHMsIGJ1aWxkTG9nKSB7CiAgICAvLyBzZWNvbmRhcnkgLSBwcmltYXJ5CiAgICAvLyBhYm92ZTEgYmVsb3cxIGFib3ZlMiBiZWxvdzIgICAgS2VlcD8gICAgICAgICAgICAgICBWYWx1ZQogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICByZXR1cm4gc2VsZWN0KHNlZ21lbnRzLCBbMCwgMiwgMSwgMCwgMCwgMCwgMSwgMSwgMCwgMiwgMCwgMiwgMCwgMCwgMCwgMF0sIGJ1aWxkTG9nKTsKICB9LAogIHhvcjogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gcHJpbWFyeSBeIHNlY29uZGFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDIsIDEsIDAsIDIsIDAsIDAsIDEsIDEsIDAsIDAsIDIsIDAsIDEsIDIsIDBdLCBidWlsZExvZyk7CiAgfQp9Owp2YXIgc2VnbWVudFNlbGVjdG9yID0gU2VnbWVudFNlbGVjdG9yJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTcsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIGNvbnZlcnQgYmV0d2VlbiBQb2x5Qm9vbCBwb2x5Z29uIGZvcm1hdCBhbmQgR2VvSlNPTiBmb3JtYXRzIChQb2x5Z29uIGFuZCBNdWx0aVBvbHlnb24pCi8vCgp2YXIgR2VvSlNPTiQxID0gewogIC8vIGNvbnZlcnQgYSBHZW9KU09OIG9iamVjdCB0byBhIFBvbHlCb29sIHBvbHlnb24KICB0b1BvbHlnb246IGZ1bmN0aW9uIChQb2x5Qm9vbCwgZ2VvanNvbikgewogICAgLy8gY29udmVydHMgbGlzdCBvZiBMaW5lU3RyaW5nJ3MgdG8gc2VnbWVudHMKICAgIGZ1bmN0aW9uIEdlb1BvbHkoY29vcmRzKSB7CiAgICAgIC8vIGNoZWNrIGZvciBlbXB0eSBjb29yZHMKICAgICAgaWYgKGNvb3Jkcy5sZW5ndGggPD0gMCkgcmV0dXJuIFBvbHlCb29sLnNlZ21lbnRzKHsKICAgICAgICBpbnZlcnRlZDogZmFsc2UsCiAgICAgICAgcmVnaW9uczogW10KICAgICAgfSk7CgogICAgICAvLyBjb252ZXJ0IExpbmVTdHJpbmcgdG8gc2VnbWVudHMKICAgICAgZnVuY3Rpb24gTGluZVN0cmluZyhscykgewogICAgICAgIC8vIHJlbW92ZSB0YWlsIHdoaWNoIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBoZWFkCiAgICAgICAgdmFyIHJlZyA9IGxzLnNsaWNlKDAsIGxzLmxlbmd0aCAtIDEpOwogICAgICAgIHJldHVybiBQb2x5Qm9vbC5zZWdtZW50cyh7CiAgICAgICAgICBpbnZlcnRlZDogZmFsc2UsCiAgICAgICAgICByZWdpb25zOiBbcmVnXQogICAgICAgIH0pOwogICAgICB9CgogICAgICAvLyB0aGUgZmlyc3QgTGluZVN0cmluZyBpcyBjb25zaWRlcmVkIHRoZSBvdXRzaWRlCiAgICAgIHZhciBvdXQgPSBMaW5lU3RyaW5nKGNvb3Jkc1swXSk7CgogICAgICAvLyB0aGUgcmVzdCBvZiB0aGUgTGluZVN0cmluZ3MgYXJlIGNvbnNpZGVyZWQgaW50ZXJpb3IgaG9sZXMsIHNvIHN1YnRyYWN0IHRoZW0gZnJvbSB0aGUKICAgICAgLy8gY3VycmVudCByZXN1bHQKICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIG91dCA9IFBvbHlCb29sLnNlbGVjdERpZmZlcmVuY2UoUG9seUJvb2wuY29tYmluZShvdXQsIExpbmVTdHJpbmcoY29vcmRzW2ldKSkpOwogICAgICByZXR1cm4gb3V0OwogICAgfQogICAgaWYgKGdlb2pzb24udHlwZSA9PT0gJ1BvbHlnb24nKSB7CiAgICAgIC8vIHNpbmdsZSBwb2x5Z29uLCBzbyBqdXN0IGNvbnZlcnQgaXQgYW5kIHdlJ3JlIGRvbmUKICAgICAgcmV0dXJuIFBvbHlCb29sLnBvbHlnb24oR2VvUG9seShnZW9qc29uLmNvb3JkaW5hdGVzKSk7CiAgICB9IGVsc2UgaWYgKGdlb2pzb24udHlwZSA9PT0gJ011bHRpUG9seWdvbicpIHsKICAgICAgLy8gbXVsdGlwbGUgcG9seWdvbnMsIHNvIHVuaW9uIGFsbCB0aGUgcG9seWdvbnMgdG9nZXRoZXIKICAgICAgdmFyIG91dCA9IFBvbHlCb29sLnNlZ21lbnRzKHsKICAgICAgICBpbnZlcnRlZDogZmFsc2UsCiAgICAgICAgcmVnaW9uczogW10KICAgICAgfSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2VvanNvbi5jb29yZGluYXRlcy5sZW5ndGg7IGkrKykgb3V0ID0gUG9seUJvb2wuc2VsZWN0VW5pb24oUG9seUJvb2wuY29tYmluZShvdXQsIEdlb1BvbHkoZ2VvanNvbi5jb29yZGluYXRlc1tpXSkpKTsKICAgICAgcmV0dXJuIFBvbHlCb29sLnBvbHlnb24ob3V0KTsKICAgIH0KICAgIHRocm93IG5ldyBFcnJvcignUG9seUJvb2w6IENhbm5vdCBjb252ZXJ0IEdlb0pTT04gb2JqZWN0IHRvIFBvbHlCb29sIHBvbHlnb24nKTsKICB9LAogIC8vIGNvbnZlcnQgYSBQb2x5Qm9vbCBwb2x5Z29uIHRvIGEgR2VvSlNPTiBvYmplY3QKICBmcm9tUG9seWdvbjogZnVuY3Rpb24gKFBvbHlCb29sLCBlcHMsIHBvbHkpIHsKICAgIC8vIG1ha2Ugc3VyZSBvdXQgcG9seWdvbiBpcyBjbGVhbgogICAgcG9seSA9IFBvbHlCb29sLnBvbHlnb24oUG9seUJvb2wuc2VnbWVudHMocG9seSkpOwoKICAgIC8vIHRlc3QgaWYgcjEgaXMgaW5zaWRlIHIyCiAgICBmdW5jdGlvbiByZWdpb25JbnNpZGVSZWdpb24ocjEsIHIyKSB7CiAgICAgIC8vIHdlJ3JlIGd1YXJhbnRlZWQgbm8gbGluZXMgaW50ZXJzZWN0IChiZWNhdXNlIHRoZSBwb2x5Z29uIGlzIGNsZWFuKSwgYnV0IGEgdmVydGV4CiAgICAgIC8vIGNvdWxkIGJlIG9uIHRoZSBlZGdlIC0tIHNvIHdlIGp1c3QgYXZlcmFnZSBwdFswXSBhbmQgcHRbMV0gdG8gcHJvZHVjZSBhIHBvaW50IG9uIHRoZQogICAgICAvLyBlZGdlIG9mIHRoZSBmaXJzdCBsaW5lLCB3aGljaCBjYW5ub3QgYmUgb24gYW4gZWRnZQogICAgICByZXR1cm4gZXBzLnBvaW50SW5zaWRlUmVnaW9uKFsocjFbMF1bMF0gKyByMVsxXVswXSkgKiAwLjUsIChyMVswXVsxXSArIHIxWzFdWzFdKSAqIDAuNV0sIHIyKTsKICAgIH0KCiAgICAvLyBjYWxjdWxhdGUgaW5zaWRlIGhlaXJhcmNoeQogICAgLy8KICAgIC8vICBfX19fX19fX19fX19fX19fX19fX18gICBfX19fX19fICAgIHJvb3RzIC0+IEEgICAgICAgLT4gRgogICAgLy8gfCAgICAgICAgICBBICAgICAgICAgIHwgfCAgIEYgICB8ICAgICAgICAgICAgfCAgICAgICAgICB8CiAgICAvLyB8ICBfX19fX19fICAgX19fX19fXyAgfCB8ICBfX18gIHwgICAgICAgICAgICArLS0gQiAgICAgICstLSBHCiAgICAvLyB8IHwgICBCICAgfCB8ICAgQyAgIHwgfCB8IHwgICB8IHwgICAgICAgICAgICB8ICAgfAogICAgLy8gfCB8ICBfX18gIHwgfCAgX19fICB8IHwgfCB8ICAgfCB8ICAgICAgICAgICAgfCAgICstLSBECiAgICAvLyB8IHwgfCBEIHwgfCB8IHwgRSB8IHwgfCB8IHwgRyB8IHwgICAgICAgICAgICB8CiAgICAvLyB8IHwgfF9fX3wgfCB8IHxfX198IHwgfCB8IHwgICB8IHwgICAgICAgICAgICArLS0gQwogICAgLy8gfCB8X19fX19fX3wgfF9fX19fX198IHwgfCB8X19ffCB8ICAgICAgICAgICAgICAgIHwKICAgIC8vIHxfX19fX19fX19fX19fX19fX19fX198IHxfX19fX19ffCAgICAgICAgICAgICAgICArLS0gRQoKICAgIGZ1bmN0aW9uIG5ld05vZGUocmVnaW9uKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgcmVnaW9uOiByZWdpb24sCiAgICAgICAgY2hpbGRyZW46IFtdCiAgICAgIH07CiAgICB9CiAgICB2YXIgcm9vdHMgPSBuZXdOb2RlKG51bGwpOwogICAgZnVuY3Rpb24gYWRkQ2hpbGQocm9vdCwgcmVnaW9uKSB7CiAgICAgIC8vIGZpcnN0IGNoZWNrIGlmIHdlJ3JlIGluc2lkZSBhbnkgY2hpbGRyZW4KICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb290LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGNoaWxkID0gcm9vdC5jaGlsZHJlbltpXTsKICAgICAgICBpZiAocmVnaW9uSW5zaWRlUmVnaW9uKHJlZ2lvbiwgY2hpbGQucmVnaW9uKSkgewogICAgICAgICAgLy8gd2UgYXJlLCBzbyBpbnNlcnQgaW5zaWRlIHRoZW0gaW5zdGVhZAogICAgICAgICAgYWRkQ2hpbGQoY2hpbGQsIHJlZ2lvbik7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBub3QgaW5zaWRlIGFueSBjaGlsZHJlbiwgc28gY2hlY2sgdG8gc2VlIGlmIGFueSBjaGlsZHJlbiBhcmUgaW5zaWRlIHVzCiAgICAgIHZhciBub2RlID0gbmV3Tm9kZShyZWdpb24pOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJvb3QuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgY2hpbGQgPSByb290LmNoaWxkcmVuW2ldOwogICAgICAgIGlmIChyZWdpb25JbnNpZGVSZWdpb24oY2hpbGQucmVnaW9uLCByZWdpb24pKSB7CiAgICAgICAgICAvLyBvb3BzLi4uIG1vdmUgdGhlIGNoaWxkIGJlbmVhdGggdXMsIGFuZCByZW1vdmUgdGhlbSBmcm9tIHJvb3QKICAgICAgICAgIG5vZGUuY2hpbGRyZW4ucHVzaChjaGlsZCk7CiAgICAgICAgICByb290LmNoaWxkcmVuLnNwbGljZShpLCAxKTsKICAgICAgICAgIGktLTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIG5vdyB3ZSBjYW4gYWRkIG91cnNlbHZlcwogICAgICByb290LmNoaWxkcmVuLnB1c2gobm9kZSk7CiAgICB9CgogICAgLy8gYWRkIGFsbCByZWdpb25zIHRvIHRoZSByb290CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvbHkucmVnaW9ucy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgcmVnaW9uID0gcG9seS5yZWdpb25zW2ldOwogICAgICBpZiAocmVnaW9uLmxlbmd0aCA8IDMpCiAgICAgICAgLy8gcmVnaW9ucyBtdXN0IGhhdmUgYXQgbGVhc3QgMyBwb2ludHMgKHNhbml0eSBjaGVjaykKICAgICAgICBjb250aW51ZTsKICAgICAgYWRkQ2hpbGQocm9vdHMsIHJlZ2lvbik7CiAgICB9CgogICAgLy8gd2l0aCBvdXIgaGVpcmFyY2h5LCB3ZSBjYW4gZGlzdGluZ3Vpc2ggYmV0d2VlbiBleHRlcmlvciBib3JkZXJzLCBhbmQgaW50ZXJpb3IgaG9sZXMKICAgIC8vIHRoZSByb290IG5vZGVzIGFyZSBleHRlcmlvciwgY2hpbGRyZW4gYXJlIGludGVyaW9yLCBjaGlsZHJlbidzIGNoaWxkcmVuIGFyZSBleHRlcmlvciwKICAgIC8vIGNoaWxkcmVuJ3MgY2hpbGRyZW4ncyBjaGlsZHJlbiBhcmUgaW50ZXJpb3IsIGV0YwoKICAgIC8vIHdoaWxlIHdlJ3JlIGF0IGl0LCBleHRlcmlvcnMgYXJlIGNvdW50ZXItY2xvY2t3aXNlLCBhbmQgaW50ZXJpb3JzIGFyZSBjbG9ja3dpc2UKCiAgICBmdW5jdGlvbiBmb3JjZVdpbmRpbmcocmVnaW9uLCBjbG9ja3dpc2UpIHsKICAgICAgLy8gZmlyc3QsIHNlZSBpZiB3ZSdyZSBjbG9ja3dpc2Ugb3IgY291bnRlci1jbG9ja3dpc2UKICAgICAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU2hvZWxhY2VfZm9ybXVsYQogICAgICB2YXIgd2luZGluZyA9IDA7CiAgICAgIHZhciBsYXN0X3ggPSByZWdpb25bcmVnaW9uLmxlbmd0aCAtIDFdWzBdOwogICAgICB2YXIgbGFzdF95ID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXVsxXTsKICAgICAgdmFyIGNvcHkgPSBbXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWdpb24ubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgY3Vycl94ID0gcmVnaW9uW2ldWzBdOwogICAgICAgIHZhciBjdXJyX3kgPSByZWdpb25baV1bMV07CiAgICAgICAgY29weS5wdXNoKFtjdXJyX3gsIGN1cnJfeV0pOyAvLyBjcmVhdGUgYSBjb3B5IHdoaWxlIHdlJ3JlIGF0IGl0CiAgICAgICAgd2luZGluZyArPSBjdXJyX3kgKiBsYXN0X3ggLSBjdXJyX3ggKiBsYXN0X3k7CiAgICAgICAgbGFzdF94ID0gY3Vycl94OwogICAgICAgIGxhc3RfeSA9IGN1cnJfeTsKICAgICAgfQogICAgICAvLyB0aGlzIGFzc3VtZXMgQ2FydGVzaWFuIGNvb3JkaW5hdGVzIChZIGlzIHBvc2l0aXZlIGdvaW5nIHVwKQogICAgICB2YXIgaXNjbG9ja3dpc2UgPSB3aW5kaW5nIDwgMDsKICAgICAgaWYgKGlzY2xvY2t3aXNlICE9PSBjbG9ja3dpc2UpIGNvcHkucmV2ZXJzZSgpOwogICAgICAvLyB3aGlsZSB3ZSdyZSBoZXJlLCB0aGUgbGFzdCBwb2ludCBtdXN0IGJlIHRoZSBmaXJzdCBwb2ludC4uLgogICAgICBjb3B5LnB1c2goW2NvcHlbMF1bMF0sIGNvcHlbMF1bMV1dKTsKICAgICAgcmV0dXJuIGNvcHk7CiAgICB9CiAgICB2YXIgZ2VvcG9seXMgPSBbXTsKICAgIGZ1bmN0aW9uIGFkZEV4dGVyaW9yKG5vZGUpIHsKICAgICAgdmFyIHBvbHkgPSBbZm9yY2VXaW5kaW5nKG5vZGUucmVnaW9uLCBmYWxzZSldOwogICAgICBnZW9wb2x5cy5wdXNoKHBvbHkpOwogICAgICAvLyBjaGlsZHJlbiBvZiBleHRlcmlvcnMgYXJlIGludGVyaW9yCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykgcG9seS5wdXNoKGdldEludGVyaW9yKG5vZGUuY2hpbGRyZW5baV0pKTsKICAgIH0KICAgIGZ1bmN0aW9uIGdldEludGVyaW9yKG5vZGUpIHsKICAgICAgLy8gY2hpbGRyZW4gb2YgaW50ZXJpb3JzIGFyZSBleHRlcmlvcgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIGFkZEV4dGVyaW9yKG5vZGUuY2hpbGRyZW5baV0pOwogICAgICAvLyByZXR1cm4gdGhlIGNsb2Nrd2lzZSBpbnRlcmlvcgogICAgICByZXR1cm4gZm9yY2VXaW5kaW5nKG5vZGUucmVnaW9uLCB0cnVlKTsKICAgIH0KCiAgICAvLyByb290IG5vZGVzIGFyZSBleHRlcmlvcgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb290cy5jaGlsZHJlbi5sZW5ndGg7IGkrKykgYWRkRXh0ZXJpb3Iocm9vdHMuY2hpbGRyZW5baV0pOwoKICAgIC8vIGxhc3RseSwgY29uc3RydWN0IHRoZSBhcHByb3JwcmlhdGUgR2VvSlNPTiBvYmplY3QKCiAgICBpZiAoZ2VvcG9seXMubGVuZ3RoIDw9IDApCiAgICAgIC8vIGVtcHR5IEdlb0pTT04gUG9seWdvbgogICAgICByZXR1cm4gewogICAgICAgIHR5cGU6ICdQb2x5Z29uJywKICAgICAgICBjb29yZGluYXRlczogW10KICAgICAgfTsKICAgIGlmIChnZW9wb2x5cy5sZW5ndGggPT0gMSkKICAgICAgLy8gdXNlIGEgR2VvSlNPTiBQb2x5Z29uCiAgICAgIHJldHVybiB7CiAgICAgICAgdHlwZTogJ1BvbHlnb24nLAogICAgICAgIGNvb3JkaW5hdGVzOiBnZW9wb2x5c1swXQogICAgICB9OwogICAgcmV0dXJuIHsKICAgICAgLy8gb3RoZXJ3aXNlLCB1c2UgYSBHZW9KU09OIE11bHRpUG9seWdvbgogICAgICB0eXBlOiAnTXVsdGlQb2x5Z29uJywKICAgICAgY29vcmRpbmF0ZXM6IGdlb3BvbHlzCiAgICB9OwogIH0KfTsKdmFyIGdlb2pzb24gPSBHZW9KU09OJDE7CgovKgogKiBAY29weXJpZ2h0IDIwMTYgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwogKiBAbGljZW5zZSBNSVQKICogQHByZXNlcnZlIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCiAqLwp2YXIgQnVpbGRMb2cgPSBidWlsZExvZyQxOwp2YXIgRXBzaWxvbiA9IGVwc2lsb24kMzsKdmFyIEludGVyc2VjdGVyID0gaW50ZXJzZWN0ZXI7CnZhciBTZWdtZW50Q2hhaW5lciA9IHNlZ21lbnRDaGFpbmVyOwp2YXIgU2VnbWVudFNlbGVjdG9yID0gc2VnbWVudFNlbGVjdG9yOwp2YXIgR2VvSlNPTiA9IGdlb2pzb247CnZhciBidWlsZExvZyA9IGZhbHNlOwp2YXIgZXBzaWxvbiQyID0gRXBzaWxvbigpOwp2YXIgUG9seUJvb2w7ClBvbHlCb29sID0gewogIC8vIGdldHRlci9zZXR0ZXIgZm9yIGJ1aWxkTG9nCiAgYnVpbGRMb2c6IGZ1bmN0aW9uIChibCkgewogICAgaWYgKGJsID09PSB0cnVlKSBidWlsZExvZyA9IEJ1aWxkTG9nKCk7ZWxzZSBpZiAoYmwgPT09IGZhbHNlKSBidWlsZExvZyA9IGZhbHNlOwogICAgcmV0dXJuIGJ1aWxkTG9nID09PSBmYWxzZSA/IGZhbHNlIDogYnVpbGRMb2cubGlzdDsKICB9LAogIC8vIGdldHRlci9zZXR0ZXIgZm9yIGVwc2lsb24KICBlcHNpbG9uOiBmdW5jdGlvbiAodikgewogICAgcmV0dXJuIGVwc2lsb24kMi5lcHNpbG9uKHYpOwogIH0sCiAgLy8gY29yZSBBUEkKICBzZWdtZW50czogZnVuY3Rpb24gKHBvbHkpIHsKICAgIHZhciBpID0gSW50ZXJzZWN0ZXIodHJ1ZSwgZXBzaWxvbiQyLCBidWlsZExvZyk7CiAgICBwb2x5LnJlZ2lvbnMuZm9yRWFjaChpLmFkZFJlZ2lvbik7CiAgICByZXR1cm4gewogICAgICBzZWdtZW50czogaS5jYWxjdWxhdGUocG9seS5pbnZlcnRlZCksCiAgICAgIGludmVydGVkOiBwb2x5LmludmVydGVkCiAgICB9OwogIH0sCiAgY29tYmluZTogZnVuY3Rpb24gKHNlZ21lbnRzMSwgc2VnbWVudHMyKSB7CiAgICB2YXIgaTMgPSBJbnRlcnNlY3RlcihmYWxzZSwgZXBzaWxvbiQyLCBidWlsZExvZyk7CiAgICByZXR1cm4gewogICAgICBjb21iaW5lZDogaTMuY2FsY3VsYXRlKHNlZ21lbnRzMS5zZWdtZW50cywgc2VnbWVudHMxLmludmVydGVkLCBzZWdtZW50czIuc2VnbWVudHMsIHNlZ21lbnRzMi5pbnZlcnRlZCksCiAgICAgIGludmVydGVkMTogc2VnbWVudHMxLmludmVydGVkLAogICAgICBpbnZlcnRlZDI6IHNlZ21lbnRzMi5pbnZlcnRlZAogICAgfTsKICB9LAogIHNlbGVjdFVuaW9uOiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IudW5pb24oY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IGNvbWJpbmVkLmludmVydGVkMSB8fCBjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3RJbnRlcnNlY3Q6IGZ1bmN0aW9uIChjb21iaW5lZCkgewogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IFNlZ21lbnRTZWxlY3Rvci5pbnRlcnNlY3QoY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IGNvbWJpbmVkLmludmVydGVkMSAmJiBjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3REaWZmZXJlbmNlOiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IuZGlmZmVyZW5jZShjb21iaW5lZC5jb21iaW5lZCwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogY29tYmluZWQuaW52ZXJ0ZWQxICYmICFjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3REaWZmZXJlbmNlUmV2OiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IuZGlmZmVyZW5jZVJldihjb21iaW5lZC5jb21iaW5lZCwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogIWNvbWJpbmVkLmludmVydGVkMSAmJiBjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3RYb3I6IGZ1bmN0aW9uIChjb21iaW5lZCkgewogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IFNlZ21lbnRTZWxlY3Rvci54b3IoY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IGNvbWJpbmVkLmludmVydGVkMSAhPT0gY29tYmluZWQuaW52ZXJ0ZWQyCiAgICB9OwogIH0sCiAgcG9seWdvbjogZnVuY3Rpb24gKHNlZ21lbnRzKSB7CiAgICByZXR1cm4gewogICAgICByZWdpb25zOiBTZWdtZW50Q2hhaW5lcihzZWdtZW50cy5zZWdtZW50cywgZXBzaWxvbiQyLCBidWlsZExvZyksCiAgICAgIGludmVydGVkOiBzZWdtZW50cy5pbnZlcnRlZAogICAgfTsKICB9LAogIC8vIEdlb0pTT04gY29udmVydGVycwogIHBvbHlnb25Gcm9tR2VvSlNPTjogZnVuY3Rpb24gKGdlb2pzb24pIHsKICAgIHJldHVybiBHZW9KU09OLnRvUG9seWdvbihQb2x5Qm9vbCwgZ2VvanNvbik7CiAgfSwKICBwb2x5Z29uVG9HZW9KU09OOiBmdW5jdGlvbiAocG9seSkgewogICAgcmV0dXJuIEdlb0pTT04uZnJvbVBvbHlnb24oUG9seUJvb2wsIGVwc2lsb24kMiwgcG9seSk7CiAgfSwKICAvLyBoZWxwZXIgZnVuY3Rpb25zIGZvciBjb21tb24gb3BlcmF0aW9ucwogIHVuaW9uOiBmdW5jdGlvbiAocG9seTEsIHBvbHkyKSB7CiAgICByZXR1cm4gb3BlcmF0ZShwb2x5MSwgcG9seTIsIFBvbHlCb29sLnNlbGVjdFVuaW9uKTsKICB9LAogIGludGVyc2VjdDogZnVuY3Rpb24gKHBvbHkxLCBwb2x5MikgewogICAgcmV0dXJuIG9wZXJhdGUocG9seTEsIHBvbHkyLCBQb2x5Qm9vbC5zZWxlY3RJbnRlcnNlY3QpOwogIH0sCiAgZGlmZmVyZW5jZTogZnVuY3Rpb24gKHBvbHkxLCBwb2x5MikgewogICAgcmV0dXJuIG9wZXJhdGUocG9seTEsIHBvbHkyLCBQb2x5Qm9vbC5zZWxlY3REaWZmZXJlbmNlKTsKICB9LAogIGRpZmZlcmVuY2VSZXY6IGZ1bmN0aW9uIChwb2x5MSwgcG9seTIpIHsKICAgIHJldHVybiBvcGVyYXRlKHBvbHkxLCBwb2x5MiwgUG9seUJvb2wuc2VsZWN0RGlmZmVyZW5jZVJldik7CiAgfSwKICB4b3I6IGZ1bmN0aW9uIChwb2x5MSwgcG9seTIpIHsKICAgIHJldHVybiBvcGVyYXRlKHBvbHkxLCBwb2x5MiwgUG9seUJvb2wuc2VsZWN0WG9yKTsKICB9Cn07CmZ1bmN0aW9uIG9wZXJhdGUocG9seTEsIHBvbHkyLCBzZWxlY3RvcikgewogIHZhciBzZWcxID0gUG9seUJvb2wuc2VnbWVudHMocG9seTEpOwogIHZhciBzZWcyID0gUG9seUJvb2wuc2VnbWVudHMocG9seTIpOwogIHZhciBjb21iID0gUG9seUJvb2wuY29tYmluZShzZWcxLCBzZWcyKTsKICB2YXIgc2VnMyA9IHNlbGVjdG9yKGNvbWIpOwogIHJldHVybiBQb2x5Qm9vbC5wb2x5Z29uKHNlZzMpOwp9CmlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0Jykgd2luZG93LlBvbHlCb29sID0gUG9seUJvb2w7CnZhciBwb2x5Ym9vbGpzID0gUG9seUJvb2w7CgovKioKICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZQogKiBlcXVpdmFsZW50LgogKgogKiAqKk5vdGU6KiogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGFyaW5nIGFycmF5cywgYXJyYXkgYnVmZmVycywgYm9vbGVhbnMsCiAqIGRhdGUgb2JqZWN0cywgZXJyb3Igb2JqZWN0cywgbWFwcywgbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywKICogc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkIGFycmF5cy4gYE9iamVjdGAgb2JqZWN0cyBhcmUgY29tcGFyZWQKICogYnkgdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZ1bmN0aW9ucyBhbmQgRE9NCiAqIG5vZGVzIGFyZSBjb21wYXJlZCBieSBzdHJpY3QgZXF1YWxpdHksIGkuZS4gYD09PWAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9OwogKiB2YXIgb3RoZXIgPSB7ICdhJzogMSB9OwogKgogKiBfLmlzRXF1YWwob2JqZWN0LCBvdGhlcik7CiAqIC8vID0+IHRydWUKICoKICogb2JqZWN0ID09PSBvdGhlcjsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzRXF1YWwodmFsdWUsIG90aGVyKSB7CiAgcmV0dXJuIGJhc2VJc0VxdWFsKHZhbHVlLCBvdGhlcik7Cn0KCi8qKg0KICog5L+u5b6pUG9seWdvbuWFp+WQhFJpbmdTdHJpbmfngrrplonlkIgNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9maXhDbG9zZVBvbHlnb24udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwZ3Mg6Ly45YWlUG9seWdvbuizh+aWmemZo+WIl++8jOeCultbIFtbeDExLHkxMV0sW3gxMix5MTJdLC4uLl0sIFtbeDIxLHkyMV0sW3gyMix5MjJdLC4uLl0gXV3mp4vmiJDkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHJldHVybnMge0FycmF5fSDlm57lgrNQb2x5Z29u6Zmj5YiXDQogKiBAZXhhbXBsZQ0KDQogKi8KZnVuY3Rpb24gZml4Q2xvc2VQb2x5Z29uKHBncywgb3B0ID0ge30pIHsKICAvL2NoZWNrIHBncwogIGlmICghaXNlYXJyKHBncykpIHsKICAgIHRocm93IG5ldyBFcnJvcihgbm8gcGdzYCk7CiAgfQoKICAvL3RvUG9seWdvbgogIHBncyA9IHRvUG9seWdvbihwZ3MpOwoKICAvL+S/ruW+qeaIkOeCuumWieWQiAogIHBncyA9IG1hcChwZ3MsIHJzID0+IHsKICAgIGxldCBpMCA9IDA7CiAgICBsZXQgaTEgPSBzaXplKHJzKSAtIDE7CiAgICBsZXQgcnMwID0gcnNbaTBdOwogICAgbGV0IHJzMSA9IHJzW2kxXTsKICAgIGlmICghaXNFcXVhbChyczAsIHJzMSkpIHsKICAgICAgcnMucHVzaChyczApOwogICAgfQogICAgcmV0dXJuIHJzOwogIH0pOwogIHJldHVybiBwZ3M7Cn0KCi8qKg0KICog6Yed5bCNUG9seWdvbumAsuihjOS6pOmbhihpbnRlcnNlY3Qp6JmV55CGDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvaW50ZXJzZWN0UG9seWdvbi50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBnczEg6Ly45YWl56ysMeWAi1BvbHlnb27os4fmlpnpmaPliJfvvIzngrpbIFtbeDExLHkxMV0sW3gxMix5MTJdLC4uLl0sIFtbeDIxLHkyMV0sW3gyMix5MjJdLC4uLl0gXeani+aIkOS5i+mZo+WIlw0KICogQHBhcmFtIHtBcnJheX0gcGdzMiDovLjlhaXnrKwy5YCLUG9seWdvbuizh+aWmemZo+WIl++8jOeCulsgW1t4MTEseTExXSxbeDEyLHkxMl0sLi4uXSwgW1t4MjEseTIxXSxbeDIyLHkyMl0sLi4uXSBd5qeL5oiQ5LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LmVwc2lsb249MC4wMDAwMDAwMDAwMDFdIOi8uOWFpSBwb2x5Ym9vbGpzIOioiOeul+WuueioseiqpOW3rg0KICogQHJldHVybnMge0FycmF5fSDlm57lgrNQb2x5Z29u6Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwZ3MxDQogKiBsZXQgcGdzMg0KICogbGV0IHINCiAqDQogKiBwZ3MxID0gJ25vdCBhcnJheScNCiAqIHBnczIgPSBbW1syLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFsyLCA0XV1dIC8vcG9seWdvbg0KICogdHJ5IHsNCiAqICAgICByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIH0NCiAqIGNhdGNoIChlcnIpIHsNCiAqICAgICByID0gZXJyLm1lc3NhZ2UNCiAqIH0NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBubyBwZ3MxDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gJ25vdCBhcnJheScNCiAqIHRyeSB7DQogKiAgICAgciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiB9DQogKiBjYXRjaCAoZXJyKSB7DQogKiAgICAgciA9IGVyci5tZXNzYWdlDQogKiB9DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gaW52YWxpZCBwZ3MyDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbMSwgMF0sIFsxLCAxXSwgWzAsIDFdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW10NCiAqIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxLDBdLFsxLDFdLFswLDFdLFswLDBdXV0NCiAqDQogKiBwZ3MxID0gW1tbMCwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMCwgNF1dXSAvL3BvbHlnb24NCiAqIHBnczIgPSBbW1syLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFsyLCA0XV1dIC8vcG9seWdvbg0KICogciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzQsNF0sWzQsMF0sWzIsMF0sWzIsNF0sWzQsNF1dXQ0KICoNCiAqIHBnczEgPSBbW1swLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFswLCA0XV1dIC8vcG9seWdvbg0KICogcGdzMiA9IFtbWzAsIDBdLCBbMiwgMF0sIFsyLCAyXSwgWzAsIDJdXV0gLy9wb2x5Z29uDQogKiByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMiwyXSxbMiwwXSxbMCwwXSxbMCwyXSxbMiwyXV1dDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW1tbMCwgMF0sIFsyLCAyXSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMiwyXSxbMCwwXSxbMCw0XSxbMiwyXV1dDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW1tbLTEsIDBdLCBbMiwgMV0sIFstMSwgNF1dXSAvL3BvbHlnb24NCiAqIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1syLDFdLFswLDAuMzMzMzMzMzMzMzMzMzMzM10sWzAsM10sWzIsMV1dXQ0KICoNCiAqLwpmdW5jdGlvbiBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIG9wdCA9IHt9KSB7CiAgLy90dXJm55qEaW50ZXJzZWN05rqW56K65oCn6IiH6YGp55So5oCn5q+U6LyD5beuLCDlvpfkvb/nlKhwb2x5Ym9vbGpz5q+U6LyD5aW9CgogIC8vY2hlY2sgcGdzMQogIGlmICghaXNlYXJyKHBnczEpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIHBnczFgKTsKICB9CgogIC8vY2hlY2sgcGdzMgogIGlmIChpc2FycihwZ3MyKSAmJiBzaXplKHBnczIpID09PSAwKSB7CiAgICBwZ3MxID0gZml4Q2xvc2VQb2x5Z29uKHBnczEpOwogICAgcmV0dXJuIHBnczE7CiAgfQogIGlmICghaXNhcnIocGdzMikpIHsKICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBwZ3MyYCk7CiAgfQoKICAvL2Vwc2lsb24KICBsZXQgZXBzaWxvbiA9IGdldChvcHQsICdlcHNpbG9uJywgMC4wMDAwMDAwMDAwMDEpOwoKICAvL3RvUG9seWdvbgogIHBnczEgPSB0b1BvbHlnb24ocGdzMSk7CiAgcGdzMiA9IHRvUG9seWdvbihwZ3MyKTsKICAvLyBjb25zb2xlLmxvZygncGdzMScsIHBnczEpCiAgLy8gY29uc29sZS5sb2coJ3BnczInLCBwZ3MyKQoKICAvL2ludGVyc2VjdAogIHBvbHlib29sanMuZXBzaWxvbihlcHNpbG9uKTsKICBsZXQgaW50cyA9IHBvbHlib29sanMuaW50ZXJzZWN0KHsKICAgIHJlZ2lvbnM6IHBnczEKICB9LCB7CiAgICByZWdpb25zOiBwZ3MyCiAgfSk7CiAgLy8gY29uc29sZS5sb2coJ2ludHMnLCBpbnRzKQoKICAvL3BncwogIGxldCBwZ3MgPSBnZXQoaW50cywgJ3JlZ2lvbnMnLCBbXSk7CgogIC8vZml4Q2xvc2VQb2x5Z29uCiAgcGdzID0gZml4Q2xvc2VQb2x5Z29uKHBncyk7CiAgcmV0dXJuIHBnczsKfQoKY29uc3QgZXBzaWxvbiQxID0gMS4xMTAyMjMwMjQ2MjUxNTY1ZS0xNjsKY29uc3Qgc3BsaXR0ZXIgPSAxMzQyMTc3Mjk7CmNvbnN0IHJlc3VsdGVycmJvdW5kID0gKDMgKyA4ICogZXBzaWxvbiQxKSAqIGVwc2lsb24kMTsKCi8vIGZhc3RfZXhwYW5zaW9uX3N1bV96ZXJvZWxpbSByb3V0aW5lIGZyb20gb3JpdGluYWwgY29kZQpmdW5jdGlvbiBzdW0oZWxlbiwgZSwgZmxlbiwgZiwgaCkgewogIGxldCBRLCBRbmV3LCBoaCwgYnZpcnQ7CiAgbGV0IGVub3cgPSBlWzBdOwogIGxldCBmbm93ID0gZlswXTsKICBsZXQgZWluZGV4ID0gMDsKICBsZXQgZmluZGV4ID0gMDsKICBpZiAoZm5vdyA+IGVub3cgPT09IGZub3cgPiAtZW5vdykgewogICAgUSA9IGVub3c7CiAgICBlbm93ID0gZVsrK2VpbmRleF07CiAgfSBlbHNlIHsKICAgIFEgPSBmbm93OwogICAgZm5vdyA9IGZbKytmaW5kZXhdOwogIH0KICBsZXQgaGluZGV4ID0gMDsKICBpZiAoZWluZGV4IDwgZWxlbiAmJiBmaW5kZXggPCBmbGVuKSB7CiAgICBpZiAoZm5vdyA+IGVub3cgPT09IGZub3cgPiAtZW5vdykgewogICAgICBRbmV3ID0gZW5vdyArIFE7CiAgICAgIGhoID0gUSAtIChRbmV3IC0gZW5vdyk7CiAgICAgIGVub3cgPSBlWysrZWluZGV4XTsKICAgIH0gZWxzZSB7CiAgICAgIFFuZXcgPSBmbm93ICsgUTsKICAgICAgaGggPSBRIC0gKFFuZXcgLSBmbm93KTsKICAgICAgZm5vdyA9IGZbKytmaW5kZXhdOwogICAgfQogICAgUSA9IFFuZXc7CiAgICBpZiAoaGggIT09IDApIHsKICAgICAgaFtoaW5kZXgrK10gPSBoaDsKICAgIH0KICAgIHdoaWxlIChlaW5kZXggPCBlbGVuICYmIGZpbmRleCA8IGZsZW4pIHsKICAgICAgaWYgKGZub3cgPiBlbm93ID09PSBmbm93ID4gLWVub3cpIHsKICAgICAgICBRbmV3ID0gUSArIGVub3c7CiAgICAgICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgICAgICBoaCA9IFEgLSAoUW5ldyAtIGJ2aXJ0KSArIChlbm93IC0gYnZpcnQpOwogICAgICAgIGVub3cgPSBlWysrZWluZGV4XTsKICAgICAgfSBlbHNlIHsKICAgICAgICBRbmV3ID0gUSArIGZub3c7CiAgICAgICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgICAgICBoaCA9IFEgLSAoUW5ldyAtIGJ2aXJ0KSArIChmbm93IC0gYnZpcnQpOwogICAgICAgIGZub3cgPSBmWysrZmluZGV4XTsKICAgICAgfQogICAgICBRID0gUW5ldzsKICAgICAgaWYgKGhoICE9PSAwKSB7CiAgICAgICAgaFtoaW5kZXgrK10gPSBoaDsKICAgICAgfQogICAgfQogIH0KICB3aGlsZSAoZWluZGV4IDwgZWxlbikgewogICAgUW5ldyA9IFEgKyBlbm93OwogICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgIGhoID0gUSAtIChRbmV3IC0gYnZpcnQpICsgKGVub3cgLSBidmlydCk7CiAgICBlbm93ID0gZVsrK2VpbmRleF07CiAgICBRID0gUW5ldzsKICAgIGlmIChoaCAhPT0gMCkgewogICAgICBoW2hpbmRleCsrXSA9IGhoOwogICAgfQogIH0KICB3aGlsZSAoZmluZGV4IDwgZmxlbikgewogICAgUW5ldyA9IFEgKyBmbm93OwogICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgIGhoID0gUSAtIChRbmV3IC0gYnZpcnQpICsgKGZub3cgLSBidmlydCk7CiAgICBmbm93ID0gZlsrK2ZpbmRleF07CiAgICBRID0gUW5ldzsKICAgIGlmIChoaCAhPT0gMCkgewogICAgICBoW2hpbmRleCsrXSA9IGhoOwogICAgfQogIH0KICBpZiAoUSAhPT0gMCB8fCBoaW5kZXggPT09IDApIHsKICAgIGhbaGluZGV4KytdID0gUTsKICB9CiAgcmV0dXJuIGhpbmRleDsKfQpmdW5jdGlvbiBlc3RpbWF0ZShlbGVuLCBlKSB7CiAgbGV0IFEgPSBlWzBdOwogIGZvciAobGV0IGkgPSAxOyBpIDwgZWxlbjsgaSsrKSBRICs9IGVbaV07CiAgcmV0dXJuIFE7Cn0KZnVuY3Rpb24gdmVjKG4pIHsKICByZXR1cm4gbmV3IEZsb2F0NjRBcnJheShuKTsKfQoKY29uc3QgY2N3ZXJyYm91bmRBID0gKDMgKyAxNiAqIGVwc2lsb24kMSkgKiBlcHNpbG9uJDE7CmNvbnN0IGNjd2VycmJvdW5kQiA9ICgyICsgMTIgKiBlcHNpbG9uJDEpICogZXBzaWxvbiQxOwpjb25zdCBjY3dlcnJib3VuZEMgPSAoOSArIDY0ICogZXBzaWxvbiQxKSAqIGVwc2lsb24kMSAqIGVwc2lsb24kMTsKY29uc3QgQiA9IHZlYyg0KTsKY29uc3QgQzEgPSB2ZWMoOCk7CmNvbnN0IEMyID0gdmVjKDEyKTsKY29uc3QgRCA9IHZlYygxNik7CmNvbnN0IHUgPSB2ZWMoNCk7CmZ1bmN0aW9uIG9yaWVudDJkYWRhcHQoYXgsIGF5LCBieCwgYnksIGN4LCBjeSwgZGV0c3VtKSB7CiAgbGV0IGFjeHRhaWwsIGFjeXRhaWwsIGJjeHRhaWwsIGJjeXRhaWw7CiAgbGV0IGJ2aXJ0LCBjLCBhaGksIGFsbywgYmhpLCBibG8sIF9pLCBfaiwgXzAsIHMxLCBzMCwgdDEsIHQwLCB1MzsKICBjb25zdCBhY3ggPSBheCAtIGN4OwogIGNvbnN0IGJjeCA9IGJ4IC0gY3g7CiAgY29uc3QgYWN5ID0gYXkgLSBjeTsKICBjb25zdCBiY3kgPSBieSAtIGN5OwogIHMxID0gYWN4ICogYmN5OwogIGMgPSBzcGxpdHRlciAqIGFjeDsKICBhaGkgPSBjIC0gKGMgLSBhY3gpOwogIGFsbyA9IGFjeCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3k7CiAgYmhpID0gYyAtIChjIC0gYmN5KTsKICBibG8gPSBiY3kgLSBiaGk7CiAgczAgPSBhbG8gKiBibG8gLSAoczEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIHQxID0gYWN5ICogYmN4OwogIGMgPSBzcGxpdHRlciAqIGFjeTsKICBhaGkgPSBjIC0gKGMgLSBhY3kpOwogIGFsbyA9IGFjeSAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3g7CiAgYmhpID0gYyAtIChjIC0gYmN4KTsKICBibG8gPSBiY3ggLSBiaGk7CiAgdDAgPSBhbG8gKiBibG8gLSAodDEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIF9pID0gczAgLSB0MDsKICBidmlydCA9IHMwIC0gX2k7CiAgQlswXSA9IHMwIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDApOwogIF9qID0gczEgKyBfaTsKICBidmlydCA9IF9qIC0gczE7CiAgXzAgPSBzMSAtIChfaiAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBfaSA9IF8wIC0gdDE7CiAgYnZpcnQgPSBfMCAtIF9pOwogIEJbMV0gPSBfMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQxKTsKICB1MyA9IF9qICsgX2k7CiAgYnZpcnQgPSB1MyAtIF9qOwogIEJbMl0gPSBfaiAtICh1MyAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBCWzNdID0gdTM7CiAgbGV0IGRldCA9IGVzdGltYXRlKDQsIEIpOwogIGxldCBlcnJib3VuZCA9IGNjd2VycmJvdW5kQiAqIGRldHN1bTsKICBpZiAoZGV0ID49IGVycmJvdW5kIHx8IC1kZXQgPj0gZXJyYm91bmQpIHsKICAgIHJldHVybiBkZXQ7CiAgfQogIGJ2aXJ0ID0gYXggLSBhY3g7CiAgYWN4dGFpbCA9IGF4IC0gKGFjeCArIGJ2aXJ0KSArIChidmlydCAtIGN4KTsKICBidmlydCA9IGJ4IC0gYmN4OwogIGJjeHRhaWwgPSBieCAtIChiY3ggKyBidmlydCkgKyAoYnZpcnQgLSBjeCk7CiAgYnZpcnQgPSBheSAtIGFjeTsKICBhY3l0YWlsID0gYXkgLSAoYWN5ICsgYnZpcnQpICsgKGJ2aXJ0IC0gY3kpOwogIGJ2aXJ0ID0gYnkgLSBiY3k7CiAgYmN5dGFpbCA9IGJ5IC0gKGJjeSArIGJ2aXJ0KSArIChidmlydCAtIGN5KTsKICBpZiAoYWN4dGFpbCA9PT0gMCAmJiBhY3l0YWlsID09PSAwICYmIGJjeHRhaWwgPT09IDAgJiYgYmN5dGFpbCA9PT0gMCkgewogICAgcmV0dXJuIGRldDsKICB9CiAgZXJyYm91bmQgPSBjY3dlcnJib3VuZEMgKiBkZXRzdW0gKyByZXN1bHRlcnJib3VuZCAqIE1hdGguYWJzKGRldCk7CiAgZGV0ICs9IGFjeCAqIGJjeXRhaWwgKyBiY3kgKiBhY3h0YWlsIC0gKGFjeSAqIGJjeHRhaWwgKyBiY3ggKiBhY3l0YWlsKTsKICBpZiAoZGV0ID49IGVycmJvdW5kIHx8IC1kZXQgPj0gZXJyYm91bmQpIHJldHVybiBkZXQ7CiAgczEgPSBhY3h0YWlsICogYmN5OwogIGMgPSBzcGxpdHRlciAqIGFjeHRhaWw7CiAgYWhpID0gYyAtIChjIC0gYWN4dGFpbCk7CiAgYWxvID0gYWN4dGFpbCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3k7CiAgYmhpID0gYyAtIChjIC0gYmN5KTsKICBibG8gPSBiY3kgLSBiaGk7CiAgczAgPSBhbG8gKiBibG8gLSAoczEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIHQxID0gYWN5dGFpbCAqIGJjeDsKICBjID0gc3BsaXR0ZXIgKiBhY3l0YWlsOwogIGFoaSA9IGMgLSAoYyAtIGFjeXRhaWwpOwogIGFsbyA9IGFjeXRhaWwgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN4OwogIGJoaSA9IGMgLSAoYyAtIGJjeCk7CiAgYmxvID0gYmN4IC0gYmhpOwogIHQwID0gYWxvICogYmxvIC0gKHQxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICBfaSA9IHMwIC0gdDA7CiAgYnZpcnQgPSBzMCAtIF9pOwogIHVbMF0gPSBzMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQwKTsKICBfaiA9IHMxICsgX2k7CiAgYnZpcnQgPSBfaiAtIHMxOwogIF8wID0gczEgLSAoX2ogLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgX2kgPSBfMCAtIHQxOwogIGJ2aXJ0ID0gXzAgLSBfaTsKICB1WzFdID0gXzAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MSk7CiAgdTMgPSBfaiArIF9pOwogIGJ2aXJ0ID0gdTMgLSBfajsKICB1WzJdID0gX2ogLSAodTMgLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgdVszXSA9IHUzOwogIGNvbnN0IEMxbGVuID0gc3VtKDQsIEIsIDQsIHUsIEMxKTsKICBzMSA9IGFjeCAqIGJjeXRhaWw7CiAgYyA9IHNwbGl0dGVyICogYWN4OwogIGFoaSA9IGMgLSAoYyAtIGFjeCk7CiAgYWxvID0gYWN4IC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeXRhaWw7CiAgYmhpID0gYyAtIChjIC0gYmN5dGFpbCk7CiAgYmxvID0gYmN5dGFpbCAtIGJoaTsKICBzMCA9IGFsbyAqIGJsbyAtIChzMSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgdDEgPSBhY3kgKiBiY3h0YWlsOwogIGMgPSBzcGxpdHRlciAqIGFjeTsKICBhaGkgPSBjIC0gKGMgLSBhY3kpOwogIGFsbyA9IGFjeSAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3h0YWlsOwogIGJoaSA9IGMgLSAoYyAtIGJjeHRhaWwpOwogIGJsbyA9IGJjeHRhaWwgLSBiaGk7CiAgdDAgPSBhbG8gKiBibG8gLSAodDEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIF9pID0gczAgLSB0MDsKICBidmlydCA9IHMwIC0gX2k7CiAgdVswXSA9IHMwIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDApOwogIF9qID0gczEgKyBfaTsKICBidmlydCA9IF9qIC0gczE7CiAgXzAgPSBzMSAtIChfaiAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBfaSA9IF8wIC0gdDE7CiAgYnZpcnQgPSBfMCAtIF9pOwogIHVbMV0gPSBfMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQxKTsKICB1MyA9IF9qICsgX2k7CiAgYnZpcnQgPSB1MyAtIF9qOwogIHVbMl0gPSBfaiAtICh1MyAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICB1WzNdID0gdTM7CiAgY29uc3QgQzJsZW4gPSBzdW0oQzFsZW4sIEMxLCA0LCB1LCBDMik7CiAgczEgPSBhY3h0YWlsICogYmN5dGFpbDsKICBjID0gc3BsaXR0ZXIgKiBhY3h0YWlsOwogIGFoaSA9IGMgLSAoYyAtIGFjeHRhaWwpOwogIGFsbyA9IGFjeHRhaWwgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN5dGFpbDsKICBiaGkgPSBjIC0gKGMgLSBiY3l0YWlsKTsKICBibG8gPSBiY3l0YWlsIC0gYmhpOwogIHMwID0gYWxvICogYmxvIC0gKHMxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICB0MSA9IGFjeXRhaWwgKiBiY3h0YWlsOwogIGMgPSBzcGxpdHRlciAqIGFjeXRhaWw7CiAgYWhpID0gYyAtIChjIC0gYWN5dGFpbCk7CiAgYWxvID0gYWN5dGFpbCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3h0YWlsOwogIGJoaSA9IGMgLSAoYyAtIGJjeHRhaWwpOwogIGJsbyA9IGJjeHRhaWwgLSBiaGk7CiAgdDAgPSBhbG8gKiBibG8gLSAodDEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIF9pID0gczAgLSB0MDsKICBidmlydCA9IHMwIC0gX2k7CiAgdVswXSA9IHMwIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDApOwogIF9qID0gczEgKyBfaTsKICBidmlydCA9IF9qIC0gczE7CiAgXzAgPSBzMSAtIChfaiAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBfaSA9IF8wIC0gdDE7CiAgYnZpcnQgPSBfMCAtIF9pOwogIHVbMV0gPSBfMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQxKTsKICB1MyA9IF9qICsgX2k7CiAgYnZpcnQgPSB1MyAtIF9qOwogIHVbMl0gPSBfaiAtICh1MyAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICB1WzNdID0gdTM7CiAgY29uc3QgRGxlbiA9IHN1bShDMmxlbiwgQzIsIDQsIHUsIEQpOwogIHJldHVybiBEW0RsZW4gLSAxXTsKfQpmdW5jdGlvbiBvcmllbnQyZChheCwgYXksIGJ4LCBieSwgY3gsIGN5KSB7CiAgY29uc3QgZGV0bGVmdCA9IChheSAtIGN5KSAqIChieCAtIGN4KTsKICBjb25zdCBkZXRyaWdodCA9IChheCAtIGN4KSAqIChieSAtIGN5KTsKICBjb25zdCBkZXQgPSBkZXRsZWZ0IC0gZGV0cmlnaHQ7CiAgaWYgKGRldGxlZnQgPT09IDAgfHwgZGV0cmlnaHQgPT09IDAgfHwgZGV0bGVmdCA+IDAgIT09IGRldHJpZ2h0ID4gMCkgcmV0dXJuIGRldDsKICBjb25zdCBkZXRzdW0gPSBNYXRoLmFicyhkZXRsZWZ0ICsgZGV0cmlnaHQpOwogIGlmIChNYXRoLmFicyhkZXQpID49IGNjd2VycmJvdW5kQSAqIGRldHN1bSkgcmV0dXJuIGRldDsKICByZXR1cm4gLW9yaWVudDJkYWRhcHQoYXgsIGF5LCBieCwgYnksIGN4LCBjeSwgZGV0c3VtKTsKfQoKY29uc3QgRVBTSUxPTiA9IE1hdGgucG93KDIsIC01Mik7CmNvbnN0IEVER0VfU1RBQ0sgPSBuZXcgVWludDMyQXJyYXkoNTEyKTsKY2xhc3MgRGVsYXVuYXRvciB7CiAgc3RhdGljIGZyb20ocG9pbnRzLCBnZXRYID0gZGVmYXVsdEdldFgsIGdldFkgPSBkZWZhdWx0R2V0WSkgewogICAgY29uc3QgbiA9IHBvaW50cy5sZW5ndGg7CiAgICBjb25zdCBjb29yZHMgPSBuZXcgRmxvYXQ2NEFycmF5KG4gKiAyKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGNvbnN0IHAgPSBwb2ludHNbaV07CiAgICAgIGNvb3Jkc1syICogaV0gPSBnZXRYKHApOwogICAgICBjb29yZHNbMiAqIGkgKyAxXSA9IGdldFkocCk7CiAgICB9CiAgICByZXR1cm4gbmV3IERlbGF1bmF0b3IoY29vcmRzKTsKICB9CiAgY29uc3RydWN0b3IoY29vcmRzKSB7CiAgICBjb25zdCBuID0gY29vcmRzLmxlbmd0aCA+PiAxOwogICAgaWYgKG4gPiAwICYmIHR5cGVvZiBjb29yZHNbMF0gIT09ICdudW1iZXInKSB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGNvb3JkcyB0byBjb250YWluIG51bWJlcnMuJyk7CiAgICB0aGlzLmNvb3JkcyA9IGNvb3JkczsKCiAgICAvLyBhcnJheXMgdGhhdCB3aWxsIHN0b3JlIHRoZSB0cmlhbmd1bGF0aW9uIGdyYXBoCiAgICBjb25zdCBtYXhUcmlhbmdsZXMgPSBNYXRoLm1heCgyICogbiAtIDUsIDApOwogICAgdGhpcy5fdHJpYW5nbGVzID0gbmV3IFVpbnQzMkFycmF5KG1heFRyaWFuZ2xlcyAqIDMpOwogICAgdGhpcy5faGFsZmVkZ2VzID0gbmV3IEludDMyQXJyYXkobWF4VHJpYW5nbGVzICogMyk7CgogICAgLy8gdGVtcG9yYXJ5IGFycmF5cyBmb3IgdHJhY2tpbmcgdGhlIGVkZ2VzIG9mIHRoZSBhZHZhbmNpbmcgY29udmV4IGh1bGwKICAgIHRoaXMuX2hhc2hTaXplID0gTWF0aC5jZWlsKE1hdGguc3FydChuKSk7CiAgICB0aGlzLl9odWxsUHJldiA9IG5ldyBVaW50MzJBcnJheShuKTsgLy8gZWRnZSB0byBwcmV2IGVkZ2UKICAgIHRoaXMuX2h1bGxOZXh0ID0gbmV3IFVpbnQzMkFycmF5KG4pOyAvLyBlZGdlIHRvIG5leHQgZWRnZQogICAgdGhpcy5faHVsbFRyaSA9IG5ldyBVaW50MzJBcnJheShuKTsgLy8gZWRnZSB0byBhZGphY2VudCB0cmlhbmdsZQogICAgdGhpcy5faHVsbEhhc2ggPSBuZXcgSW50MzJBcnJheSh0aGlzLl9oYXNoU2l6ZSkuZmlsbCgtMSk7IC8vIGFuZ3VsYXIgZWRnZSBoYXNoCgogICAgLy8gdGVtcG9yYXJ5IGFycmF5cyBmb3Igc29ydGluZyBwb2ludHMKICAgIHRoaXMuX2lkcyA9IG5ldyBVaW50MzJBcnJheShuKTsKICAgIHRoaXMuX2Rpc3RzID0gbmV3IEZsb2F0NjRBcnJheShuKTsKICAgIHRoaXMudXBkYXRlKCk7CiAgfQogIHVwZGF0ZSgpIHsKICAgIGNvbnN0IHsKICAgICAgY29vcmRzLAogICAgICBfaHVsbFByZXY6IGh1bGxQcmV2LAogICAgICBfaHVsbE5leHQ6IGh1bGxOZXh0LAogICAgICBfaHVsbFRyaTogaHVsbFRyaSwKICAgICAgX2h1bGxIYXNoOiBodWxsSGFzaAogICAgfSA9IHRoaXM7CiAgICBjb25zdCBuID0gY29vcmRzLmxlbmd0aCA+PiAxOwoKICAgIC8vIHBvcHVsYXRlIGFuIGFycmF5IG9mIHBvaW50IGluZGljZXM7IGNhbGN1bGF0ZSBpbnB1dCBkYXRhIGJib3gKICAgIGxldCBtaW5YID0gSW5maW5pdHk7CiAgICBsZXQgbWluWSA9IEluZmluaXR5OwogICAgbGV0IG1heFggPSAtSW5maW5pdHk7CiAgICBsZXQgbWF4WSA9IC1JbmZpbml0eTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGNvbnN0IHggPSBjb29yZHNbMiAqIGldOwogICAgICBjb25zdCB5ID0gY29vcmRzWzIgKiBpICsgMV07CiAgICAgIGlmICh4IDwgbWluWCkgbWluWCA9IHg7CiAgICAgIGlmICh5IDwgbWluWSkgbWluWSA9IHk7CiAgICAgIGlmICh4ID4gbWF4WCkgbWF4WCA9IHg7CiAgICAgIGlmICh5ID4gbWF4WSkgbWF4WSA9IHk7CiAgICAgIHRoaXMuX2lkc1tpXSA9IGk7CiAgICB9CiAgICBjb25zdCBjeCA9IChtaW5YICsgbWF4WCkgLyAyOwogICAgY29uc3QgY3kgPSAobWluWSArIG1heFkpIC8gMjsKICAgIGxldCBtaW5EaXN0ID0gSW5maW5pdHk7CiAgICBsZXQgaTAsIGkxLCBpMjsKCiAgICAvLyBwaWNrIGEgc2VlZCBwb2ludCBjbG9zZSB0byB0aGUgY2VudGVyCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBjb25zdCBkID0gZGlzdChjeCwgY3ksIGNvb3Jkc1syICogaV0sIGNvb3Jkc1syICogaSArIDFdKTsKICAgICAgaWYgKGQgPCBtaW5EaXN0KSB7CiAgICAgICAgaTAgPSBpOwogICAgICAgIG1pbkRpc3QgPSBkOwogICAgICB9CiAgICB9CiAgICBjb25zdCBpMHggPSBjb29yZHNbMiAqIGkwXTsKICAgIGNvbnN0IGkweSA9IGNvb3Jkc1syICogaTAgKyAxXTsKICAgIG1pbkRpc3QgPSBJbmZpbml0eTsKCiAgICAvLyBmaW5kIHRoZSBwb2ludCBjbG9zZXN0IHRvIHRoZSBzZWVkCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBpZiAoaSA9PT0gaTApIGNvbnRpbnVlOwogICAgICBjb25zdCBkID0gZGlzdChpMHgsIGkweSwgY29vcmRzWzIgKiBpXSwgY29vcmRzWzIgKiBpICsgMV0pOwogICAgICBpZiAoZCA8IG1pbkRpc3QgJiYgZCA+IDApIHsKICAgICAgICBpMSA9IGk7CiAgICAgICAgbWluRGlzdCA9IGQ7CiAgICAgIH0KICAgIH0KICAgIGxldCBpMXggPSBjb29yZHNbMiAqIGkxXTsKICAgIGxldCBpMXkgPSBjb29yZHNbMiAqIGkxICsgMV07CiAgICBsZXQgbWluUmFkaXVzID0gSW5maW5pdHk7CgogICAgLy8gZmluZCB0aGUgdGhpcmQgcG9pbnQgd2hpY2ggZm9ybXMgdGhlIHNtYWxsZXN0IGNpcmN1bWNpcmNsZSB3aXRoIHRoZSBmaXJzdCB0d28KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGlmIChpID09PSBpMCB8fCBpID09PSBpMSkgY29udGludWU7CiAgICAgIGNvbnN0IHIgPSBjaXJjdW1yYWRpdXMoaTB4LCBpMHksIGkxeCwgaTF5LCBjb29yZHNbMiAqIGldLCBjb29yZHNbMiAqIGkgKyAxXSk7CiAgICAgIGlmIChyIDwgbWluUmFkaXVzKSB7CiAgICAgICAgaTIgPSBpOwogICAgICAgIG1pblJhZGl1cyA9IHI7CiAgICAgIH0KICAgIH0KICAgIGxldCBpMnggPSBjb29yZHNbMiAqIGkyXTsKICAgIGxldCBpMnkgPSBjb29yZHNbMiAqIGkyICsgMV07CiAgICBpZiAobWluUmFkaXVzID09PSBJbmZpbml0eSkgewogICAgICAvLyBvcmRlciBjb2xsaW5lYXIgcG9pbnRzIGJ5IGR4IChvciBkeSBpZiBhbGwgeCBhcmUgaWRlbnRpY2FsKQogICAgICAvLyBhbmQgcmV0dXJuIHRoZSBsaXN0IGFzIGEgaHVsbAogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgIHRoaXMuX2Rpc3RzW2ldID0gY29vcmRzWzIgKiBpXSAtIGNvb3Jkc1swXSB8fCBjb29yZHNbMiAqIGkgKyAxXSAtIGNvb3Jkc1sxXTsKICAgICAgfQogICAgICBxdWlja3NvcnQodGhpcy5faWRzLCB0aGlzLl9kaXN0cywgMCwgbiAtIDEpOwogICAgICBjb25zdCBodWxsID0gbmV3IFVpbnQzMkFycmF5KG4pOwogICAgICBsZXQgaiA9IDA7CiAgICAgIGZvciAobGV0IGkgPSAwLCBkMCA9IC1JbmZpbml0eTsgaSA8IG47IGkrKykgewogICAgICAgIGNvbnN0IGlkID0gdGhpcy5faWRzW2ldOwogICAgICAgIGlmICh0aGlzLl9kaXN0c1tpZF0gPiBkMCkgewogICAgICAgICAgaHVsbFtqKytdID0gaWQ7CiAgICAgICAgICBkMCA9IHRoaXMuX2Rpc3RzW2lkXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgdGhpcy5odWxsID0gaHVsbC5zdWJhcnJheSgwLCBqKTsKICAgICAgdGhpcy50cmlhbmdsZXMgPSBuZXcgVWludDMyQXJyYXkoMCk7CiAgICAgIHRoaXMuaGFsZmVkZ2VzID0gbmV3IFVpbnQzMkFycmF5KDApOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gc3dhcCB0aGUgb3JkZXIgb2YgdGhlIHNlZWQgcG9pbnRzIGZvciBjb3VudGVyLWNsb2Nrd2lzZSBvcmllbnRhdGlvbgogICAgaWYgKG9yaWVudDJkKGkweCwgaTB5LCBpMXgsIGkxeSwgaTJ4LCBpMnkpIDwgMCkgewogICAgICBjb25zdCBpID0gaTE7CiAgICAgIGNvbnN0IHggPSBpMXg7CiAgICAgIGNvbnN0IHkgPSBpMXk7CiAgICAgIGkxID0gaTI7CiAgICAgIGkxeCA9IGkyeDsKICAgICAgaTF5ID0gaTJ5OwogICAgICBpMiA9IGk7CiAgICAgIGkyeCA9IHg7CiAgICAgIGkyeSA9IHk7CiAgICB9CiAgICBjb25zdCBjZW50ZXIgPSBjaXJjdW1jZW50ZXIoaTB4LCBpMHksIGkxeCwgaTF5LCBpMngsIGkyeSk7CiAgICB0aGlzLl9jeCA9IGNlbnRlci54OwogICAgdGhpcy5fY3kgPSBjZW50ZXIueTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIHRoaXMuX2Rpc3RzW2ldID0gZGlzdChjb29yZHNbMiAqIGldLCBjb29yZHNbMiAqIGkgKyAxXSwgY2VudGVyLngsIGNlbnRlci55KTsKICAgIH0KCiAgICAvLyBzb3J0IHRoZSBwb2ludHMgYnkgZGlzdGFuY2UgZnJvbSB0aGUgc2VlZCB0cmlhbmdsZSBjaXJjdW1jZW50ZXIKICAgIHF1aWNrc29ydCh0aGlzLl9pZHMsIHRoaXMuX2Rpc3RzLCAwLCBuIC0gMSk7CgogICAgLy8gc2V0IHVwIHRoZSBzZWVkIHRyaWFuZ2xlIGFzIHRoZSBzdGFydGluZyBodWxsCiAgICB0aGlzLl9odWxsU3RhcnQgPSBpMDsKICAgIGxldCBodWxsU2l6ZSA9IDM7CiAgICBodWxsTmV4dFtpMF0gPSBodWxsUHJldltpMl0gPSBpMTsKICAgIGh1bGxOZXh0W2kxXSA9IGh1bGxQcmV2W2kwXSA9IGkyOwogICAgaHVsbE5leHRbaTJdID0gaHVsbFByZXZbaTFdID0gaTA7CiAgICBodWxsVHJpW2kwXSA9IDA7CiAgICBodWxsVHJpW2kxXSA9IDE7CiAgICBodWxsVHJpW2kyXSA9IDI7CiAgICBodWxsSGFzaC5maWxsKC0xKTsKICAgIGh1bGxIYXNoW3RoaXMuX2hhc2hLZXkoaTB4LCBpMHkpXSA9IGkwOwogICAgaHVsbEhhc2hbdGhpcy5faGFzaEtleShpMXgsIGkxeSldID0gaTE7CiAgICBodWxsSGFzaFt0aGlzLl9oYXNoS2V5KGkyeCwgaTJ5KV0gPSBpMjsKICAgIHRoaXMudHJpYW5nbGVzTGVuID0gMDsKICAgIHRoaXMuX2FkZFRyaWFuZ2xlKGkwLCBpMSwgaTIsIC0xLCAtMSwgLTEpOwogICAgZm9yIChsZXQgayA9IDAsIHhwLCB5cDsgayA8IHRoaXMuX2lkcy5sZW5ndGg7IGsrKykgewogICAgICBjb25zdCBpID0gdGhpcy5faWRzW2tdOwogICAgICBjb25zdCB4ID0gY29vcmRzWzIgKiBpXTsKICAgICAgY29uc3QgeSA9IGNvb3Jkc1syICogaSArIDFdOwoKICAgICAgLy8gc2tpcCBuZWFyLWR1cGxpY2F0ZSBwb2ludHMKICAgICAgaWYgKGsgPiAwICYmIE1hdGguYWJzKHggLSB4cCkgPD0gRVBTSUxPTiAmJiBNYXRoLmFicyh5IC0geXApIDw9IEVQU0lMT04pIGNvbnRpbnVlOwogICAgICB4cCA9IHg7CiAgICAgIHlwID0geTsKCiAgICAgIC8vIHNraXAgc2VlZCB0cmlhbmdsZSBwb2ludHMKICAgICAgaWYgKGkgPT09IGkwIHx8IGkgPT09IGkxIHx8IGkgPT09IGkyKSBjb250aW51ZTsKCiAgICAgIC8vIGZpbmQgYSB2aXNpYmxlIGVkZ2Ugb24gdGhlIGNvbnZleCBodWxsIHVzaW5nIGVkZ2UgaGFzaAogICAgICBsZXQgc3RhcnQgPSAwOwogICAgICBmb3IgKGxldCBqID0gMCwga2V5ID0gdGhpcy5faGFzaEtleSh4LCB5KTsgaiA8IHRoaXMuX2hhc2hTaXplOyBqKyspIHsKICAgICAgICBzdGFydCA9IGh1bGxIYXNoWyhrZXkgKyBqKSAlIHRoaXMuX2hhc2hTaXplXTsKICAgICAgICBpZiAoc3RhcnQgIT09IC0xICYmIHN0YXJ0ICE9PSBodWxsTmV4dFtzdGFydF0pIGJyZWFrOwogICAgICB9CiAgICAgIHN0YXJ0ID0gaHVsbFByZXZbc3RhcnRdOwogICAgICBsZXQgZSA9IHN0YXJ0LAogICAgICAgIHE7CiAgICAgIHdoaWxlIChxID0gaHVsbE5leHRbZV0sIG9yaWVudDJkKHgsIHksIGNvb3Jkc1syICogZV0sIGNvb3Jkc1syICogZSArIDFdLCBjb29yZHNbMiAqIHFdLCBjb29yZHNbMiAqIHEgKyAxXSkgPj0gMCkgewogICAgICAgIGUgPSBxOwogICAgICAgIGlmIChlID09PSBzdGFydCkgewogICAgICAgICAgZSA9IC0xOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChlID09PSAtMSkgY29udGludWU7IC8vIGxpa2VseSBhIG5lYXItZHVwbGljYXRlIHBvaW50OyBza2lwIGl0CgogICAgICAvLyBhZGQgdGhlIGZpcnN0IHRyaWFuZ2xlIGZyb20gdGhlIHBvaW50CiAgICAgIGxldCB0ID0gdGhpcy5fYWRkVHJpYW5nbGUoZSwgaSwgaHVsbE5leHRbZV0sIC0xLCAtMSwgaHVsbFRyaVtlXSk7CgogICAgICAvLyByZWN1cnNpdmVseSBmbGlwIHRyaWFuZ2xlcyBmcm9tIHRoZSBwb2ludCB1bnRpbCB0aGV5IHNhdGlzZnkgdGhlIERlbGF1bmF5IGNvbmRpdGlvbgogICAgICBodWxsVHJpW2ldID0gdGhpcy5fbGVnYWxpemUodCArIDIpOwogICAgICBodWxsVHJpW2VdID0gdDsgLy8ga2VlcCB0cmFjayBvZiBib3VuZGFyeSB0cmlhbmdsZXMgb24gdGhlIGh1bGwKICAgICAgaHVsbFNpemUrKzsKCiAgICAgIC8vIHdhbGsgZm9yd2FyZCB0aHJvdWdoIHRoZSBodWxsLCBhZGRpbmcgbW9yZSB0cmlhbmdsZXMgYW5kIGZsaXBwaW5nIHJlY3Vyc2l2ZWx5CiAgICAgIGxldCBuID0gaHVsbE5leHRbZV07CiAgICAgIHdoaWxlIChxID0gaHVsbE5leHRbbl0sIG9yaWVudDJkKHgsIHksIGNvb3Jkc1syICogbl0sIGNvb3Jkc1syICogbiArIDFdLCBjb29yZHNbMiAqIHFdLCBjb29yZHNbMiAqIHEgKyAxXSkgPCAwKSB7CiAgICAgICAgdCA9IHRoaXMuX2FkZFRyaWFuZ2xlKG4sIGksIHEsIGh1bGxUcmlbaV0sIC0xLCBodWxsVHJpW25dKTsKICAgICAgICBodWxsVHJpW2ldID0gdGhpcy5fbGVnYWxpemUodCArIDIpOwogICAgICAgIGh1bGxOZXh0W25dID0gbjsgLy8gbWFyayBhcyByZW1vdmVkCiAgICAgICAgaHVsbFNpemUtLTsKICAgICAgICBuID0gcTsKICAgICAgfQoKICAgICAgLy8gd2FsayBiYWNrd2FyZCBmcm9tIHRoZSBvdGhlciBzaWRlLCBhZGRpbmcgbW9yZSB0cmlhbmdsZXMgYW5kIGZsaXBwaW5nCiAgICAgIGlmIChlID09PSBzdGFydCkgewogICAgICAgIHdoaWxlIChxID0gaHVsbFByZXZbZV0sIG9yaWVudDJkKHgsIHksIGNvb3Jkc1syICogcV0sIGNvb3Jkc1syICogcSArIDFdLCBjb29yZHNbMiAqIGVdLCBjb29yZHNbMiAqIGUgKyAxXSkgPCAwKSB7CiAgICAgICAgICB0ID0gdGhpcy5fYWRkVHJpYW5nbGUocSwgaSwgZSwgLTEsIGh1bGxUcmlbZV0sIGh1bGxUcmlbcV0pOwogICAgICAgICAgdGhpcy5fbGVnYWxpemUodCArIDIpOwogICAgICAgICAgaHVsbFRyaVtxXSA9IHQ7CiAgICAgICAgICBodWxsTmV4dFtlXSA9IGU7IC8vIG1hcmsgYXMgcmVtb3ZlZAogICAgICAgICAgaHVsbFNpemUtLTsKICAgICAgICAgIGUgPSBxOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gdXBkYXRlIHRoZSBodWxsIGluZGljZXMKICAgICAgdGhpcy5faHVsbFN0YXJ0ID0gaHVsbFByZXZbaV0gPSBlOwogICAgICBodWxsTmV4dFtlXSA9IGh1bGxQcmV2W25dID0gaTsKICAgICAgaHVsbE5leHRbaV0gPSBuOwoKICAgICAgLy8gc2F2ZSB0aGUgdHdvIG5ldyBlZGdlcyBpbiB0aGUgaGFzaCB0YWJsZQogICAgICBodWxsSGFzaFt0aGlzLl9oYXNoS2V5KHgsIHkpXSA9IGk7CiAgICAgIGh1bGxIYXNoW3RoaXMuX2hhc2hLZXkoY29vcmRzWzIgKiBlXSwgY29vcmRzWzIgKiBlICsgMV0pXSA9IGU7CiAgICB9CiAgICB0aGlzLmh1bGwgPSBuZXcgVWludDMyQXJyYXkoaHVsbFNpemUpOwogICAgZm9yIChsZXQgaSA9IDAsIGUgPSB0aGlzLl9odWxsU3RhcnQ7IGkgPCBodWxsU2l6ZTsgaSsrKSB7CiAgICAgIHRoaXMuaHVsbFtpXSA9IGU7CiAgICAgIGUgPSBodWxsTmV4dFtlXTsKICAgIH0KCiAgICAvLyB0cmltIHR5cGVkIHRyaWFuZ2xlIG1lc2ggYXJyYXlzCiAgICB0aGlzLnRyaWFuZ2xlcyA9IHRoaXMuX3RyaWFuZ2xlcy5zdWJhcnJheSgwLCB0aGlzLnRyaWFuZ2xlc0xlbik7CiAgICB0aGlzLmhhbGZlZGdlcyA9IHRoaXMuX2hhbGZlZGdlcy5zdWJhcnJheSgwLCB0aGlzLnRyaWFuZ2xlc0xlbik7CiAgfQogIF9oYXNoS2V5KHgsIHkpIHsKICAgIHJldHVybiBNYXRoLmZsb29yKHBzZXVkb0FuZ2xlKHggLSB0aGlzLl9jeCwgeSAtIHRoaXMuX2N5KSAqIHRoaXMuX2hhc2hTaXplKSAlIHRoaXMuX2hhc2hTaXplOwogIH0KICBfbGVnYWxpemUoYSkgewogICAgY29uc3QgewogICAgICBfdHJpYW5nbGVzOiB0cmlhbmdsZXMsCiAgICAgIF9oYWxmZWRnZXM6IGhhbGZlZGdlcywKICAgICAgY29vcmRzCiAgICB9ID0gdGhpczsKICAgIGxldCBpID0gMDsKICAgIGxldCBhciA9IDA7CgogICAgLy8gcmVjdXJzaW9uIGVsaW1pbmF0ZWQgd2l0aCBhIGZpeGVkLXNpemUgc3RhY2sKICAgIHdoaWxlICh0cnVlKSB7CiAgICAgIGNvbnN0IGIgPSBoYWxmZWRnZXNbYV07CgogICAgICAvKiBpZiB0aGUgcGFpciBvZiB0cmlhbmdsZXMgZG9lc24ndCBzYXRpc2Z5IHRoZSBEZWxhdW5heSBjb25kaXRpb24KICAgICAgICogKHAxIGlzIGluc2lkZSB0aGUgY2lyY3VtY2lyY2xlIG9mIFtwMCwgcGwsIHByXSksIGZsaXAgdGhlbSwKICAgICAgICogdGhlbiBkbyB0aGUgc2FtZSBjaGVjay9mbGlwIHJlY3Vyc2l2ZWx5IGZvciB0aGUgbmV3IHBhaXIgb2YgdHJpYW5nbGVzCiAgICAgICAqCiAgICAgICAqICAgICAgICAgICBwbCAgICAgICAgICAgICAgICAgICAgcGwKICAgICAgICogICAgICAgICAgL3x8XCAgICAgICAgICAgICAgICAgIC8gIFwKICAgICAgICogICAgICAgYWwvIHx8IFxibCAgICAgICAgICAgIGFsLyAgICBcYQogICAgICAgKiAgICAgICAgLyAgfHwgIFwgICAgICAgICAgICAgIC8gICAgICBcCiAgICAgICAqICAgICAgIC8gIGF8fGIgIFwgICAgZmxpcCAgICAvX19fYXJfX19cCiAgICAgICAqICAgICBwMFwgICB8fCAgIC9wMSAgID0+ICAgcDBcLS0tYmwtLS0vcDEKICAgICAgICogICAgICAgIFwgIHx8ICAvICAgICAgICAgICAgICBcICAgICAgLwogICAgICAgKiAgICAgICBhclwgfHwgL2JyICAgICAgICAgICAgIGJcICAgIC9icgogICAgICAgKiAgICAgICAgICBcfHwvICAgICAgICAgICAgICAgICAgXCAgLwogICAgICAgKiAgICAgICAgICAgcHIgICAgICAgICAgICAgICAgICAgIHByCiAgICAgICAqLwogICAgICBjb25zdCBhMCA9IGEgLSBhICUgMzsKICAgICAgYXIgPSBhMCArIChhICsgMikgJSAzOwogICAgICBpZiAoYiA9PT0gLTEpIHsKICAgICAgICAvLyBjb252ZXggaHVsbCBlZGdlCiAgICAgICAgaWYgKGkgPT09IDApIGJyZWFrOwogICAgICAgIGEgPSBFREdFX1NUQUNLWy0taV07CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgY29uc3QgYjAgPSBiIC0gYiAlIDM7CiAgICAgIGNvbnN0IGFsID0gYTAgKyAoYSArIDEpICUgMzsKICAgICAgY29uc3QgYmwgPSBiMCArIChiICsgMikgJSAzOwogICAgICBjb25zdCBwMCA9IHRyaWFuZ2xlc1thcl07CiAgICAgIGNvbnN0IHByID0gdHJpYW5nbGVzW2FdOwogICAgICBjb25zdCBwbCA9IHRyaWFuZ2xlc1thbF07CiAgICAgIGNvbnN0IHAxID0gdHJpYW5nbGVzW2JsXTsKICAgICAgY29uc3QgaWxsZWdhbCA9IGluQ2lyY2xlKGNvb3Jkc1syICogcDBdLCBjb29yZHNbMiAqIHAwICsgMV0sIGNvb3Jkc1syICogcHJdLCBjb29yZHNbMiAqIHByICsgMV0sIGNvb3Jkc1syICogcGxdLCBjb29yZHNbMiAqIHBsICsgMV0sIGNvb3Jkc1syICogcDFdLCBjb29yZHNbMiAqIHAxICsgMV0pOwogICAgICBpZiAoaWxsZWdhbCkgewogICAgICAgIHRyaWFuZ2xlc1thXSA9IHAxOwogICAgICAgIHRyaWFuZ2xlc1tiXSA9IHAwOwogICAgICAgIGNvbnN0IGhibCA9IGhhbGZlZGdlc1tibF07CgogICAgICAgIC8vIGVkZ2Ugc3dhcHBlZCBvbiB0aGUgb3RoZXIgc2lkZSBvZiB0aGUgaHVsbCAocmFyZSk7IGZpeCB0aGUgaGFsZmVkZ2UgcmVmZXJlbmNlCiAgICAgICAgaWYgKGhibCA9PT0gLTEpIHsKICAgICAgICAgIGxldCBlID0gdGhpcy5faHVsbFN0YXJ0OwogICAgICAgICAgZG8gewogICAgICAgICAgICBpZiAodGhpcy5faHVsbFRyaVtlXSA9PT0gYmwpIHsKICAgICAgICAgICAgICB0aGlzLl9odWxsVHJpW2VdID0gYTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBlID0gdGhpcy5faHVsbFByZXZbZV07CiAgICAgICAgICB9IHdoaWxlIChlICE9PSB0aGlzLl9odWxsU3RhcnQpOwogICAgICAgIH0KICAgICAgICB0aGlzLl9saW5rKGEsIGhibCk7CiAgICAgICAgdGhpcy5fbGluayhiLCBoYWxmZWRnZXNbYXJdKTsKICAgICAgICB0aGlzLl9saW5rKGFyLCBibCk7CiAgICAgICAgY29uc3QgYnIgPSBiMCArIChiICsgMSkgJSAzOwoKICAgICAgICAvLyBkb24ndCB3b3JyeSBhYm91dCBoaXR0aW5nIHRoZSBjYXA6IGl0IGNhbiBvbmx5IGhhcHBlbiBvbiBleHRyZW1lbHkgZGVnZW5lcmF0ZSBpbnB1dAogICAgICAgIGlmIChpIDwgRURHRV9TVEFDSy5sZW5ndGgpIHsKICAgICAgICAgIEVER0VfU1RBQ0tbaSsrXSA9IGJyOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoaSA9PT0gMCkgYnJlYWs7CiAgICAgICAgYSA9IEVER0VfU1RBQ0tbLS1pXTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGFyOwogIH0KICBfbGluayhhLCBiKSB7CiAgICB0aGlzLl9oYWxmZWRnZXNbYV0gPSBiOwogICAgaWYgKGIgIT09IC0xKSB0aGlzLl9oYWxmZWRnZXNbYl0gPSBhOwogIH0KCiAgLy8gYWRkIGEgbmV3IHRyaWFuZ2xlIGdpdmVuIHZlcnRleCBpbmRpY2VzIGFuZCBhZGphY2VudCBoYWxmLWVkZ2UgaWRzCiAgX2FkZFRyaWFuZ2xlKGkwLCBpMSwgaTIsIGEsIGIsIGMpIHsKICAgIGNvbnN0IHQgPSB0aGlzLnRyaWFuZ2xlc0xlbjsKICAgIHRoaXMuX3RyaWFuZ2xlc1t0XSA9IGkwOwogICAgdGhpcy5fdHJpYW5nbGVzW3QgKyAxXSA9IGkxOwogICAgdGhpcy5fdHJpYW5nbGVzW3QgKyAyXSA9IGkyOwogICAgdGhpcy5fbGluayh0LCBhKTsKICAgIHRoaXMuX2xpbmsodCArIDEsIGIpOwogICAgdGhpcy5fbGluayh0ICsgMiwgYyk7CiAgICB0aGlzLnRyaWFuZ2xlc0xlbiArPSAzOwogICAgcmV0dXJuIHQ7CiAgfQp9CgovLyBtb25vdG9uaWNhbGx5IGluY3JlYXNlcyB3aXRoIHJlYWwgYW5nbGUsIGJ1dCBkb2Vzbid0IG5lZWQgZXhwZW5zaXZlIHRyaWdvbm9tZXRyeQpmdW5jdGlvbiBwc2V1ZG9BbmdsZShkeCwgZHkpIHsKICBjb25zdCBwID0gZHggLyAoTWF0aC5hYnMoZHgpICsgTWF0aC5hYnMoZHkpKTsKICByZXR1cm4gKGR5ID4gMCA/IDMgLSBwIDogMSArIHApIC8gNDsgLy8gWzAuLjFdCn0KCmZ1bmN0aW9uIGRpc3QoYXgsIGF5LCBieCwgYnkpIHsKICBjb25zdCBkeCA9IGF4IC0gYng7CiAgY29uc3QgZHkgPSBheSAtIGJ5OwogIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTsKfQpmdW5jdGlvbiBpbkNpcmNsZShheCwgYXksIGJ4LCBieSwgY3gsIGN5LCBweCwgcHkpIHsKICBjb25zdCBkeCA9IGF4IC0gcHg7CiAgY29uc3QgZHkgPSBheSAtIHB5OwogIGNvbnN0IGV4ID0gYnggLSBweDsKICBjb25zdCBleSA9IGJ5IC0gcHk7CiAgY29uc3QgZnggPSBjeCAtIHB4OwogIGNvbnN0IGZ5ID0gY3kgLSBweTsKICBjb25zdCBhcCA9IGR4ICogZHggKyBkeSAqIGR5OwogIGNvbnN0IGJwID0gZXggKiBleCArIGV5ICogZXk7CiAgY29uc3QgY3AgPSBmeCAqIGZ4ICsgZnkgKiBmeTsKICByZXR1cm4gZHggKiAoZXkgKiBjcCAtIGJwICogZnkpIC0gZHkgKiAoZXggKiBjcCAtIGJwICogZngpICsgYXAgKiAoZXggKiBmeSAtIGV5ICogZngpIDwgMDsKfQpmdW5jdGlvbiBjaXJjdW1yYWRpdXMoYXgsIGF5LCBieCwgYnksIGN4LCBjeSkgewogIGNvbnN0IGR4ID0gYnggLSBheDsKICBjb25zdCBkeSA9IGJ5IC0gYXk7CiAgY29uc3QgZXggPSBjeCAtIGF4OwogIGNvbnN0IGV5ID0gY3kgLSBheTsKICBjb25zdCBibCA9IGR4ICogZHggKyBkeSAqIGR5OwogIGNvbnN0IGNsID0gZXggKiBleCArIGV5ICogZXk7CiAgY29uc3QgZCA9IDAuNSAvIChkeCAqIGV5IC0gZHkgKiBleCk7CiAgY29uc3QgeCA9IChleSAqIGJsIC0gZHkgKiBjbCkgKiBkOwogIGNvbnN0IHkgPSAoZHggKiBjbCAtIGV4ICogYmwpICogZDsKICByZXR1cm4geCAqIHggKyB5ICogeTsKfQpmdW5jdGlvbiBjaXJjdW1jZW50ZXIoYXgsIGF5LCBieCwgYnksIGN4LCBjeSkgewogIGNvbnN0IGR4ID0gYnggLSBheDsKICBjb25zdCBkeSA9IGJ5IC0gYXk7CiAgY29uc3QgZXggPSBjeCAtIGF4OwogIGNvbnN0IGV5ID0gY3kgLSBheTsKICBjb25zdCBibCA9IGR4ICogZHggKyBkeSAqIGR5OwogIGNvbnN0IGNsID0gZXggKiBleCArIGV5ICogZXk7CiAgY29uc3QgZCA9IDAuNSAvIChkeCAqIGV5IC0gZHkgKiBleCk7CiAgY29uc3QgeCA9IGF4ICsgKGV5ICogYmwgLSBkeSAqIGNsKSAqIGQ7CiAgY29uc3QgeSA9IGF5ICsgKGR4ICogY2wgLSBleCAqIGJsKSAqIGQ7CiAgcmV0dXJuIHsKICAgIHgsCiAgICB5CiAgfTsKfQpmdW5jdGlvbiBxdWlja3NvcnQoaWRzLCBkaXN0cywgbGVmdCwgcmlnaHQpIHsKICBpZiAocmlnaHQgLSBsZWZ0IDw9IDIwKSB7CiAgICBmb3IgKGxldCBpID0gbGVmdCArIDE7IGkgPD0gcmlnaHQ7IGkrKykgewogICAgICBjb25zdCB0ZW1wID0gaWRzW2ldOwogICAgICBjb25zdCB0ZW1wRGlzdCA9IGRpc3RzW3RlbXBdOwogICAgICBsZXQgaiA9IGkgLSAxOwogICAgICB3aGlsZSAoaiA+PSBsZWZ0ICYmIGRpc3RzW2lkc1tqXV0gPiB0ZW1wRGlzdCkgaWRzW2ogKyAxXSA9IGlkc1tqLS1dOwogICAgICBpZHNbaiArIDFdID0gdGVtcDsKICAgIH0KICB9IGVsc2UgewogICAgY29uc3QgbWVkaWFuID0gbGVmdCArIHJpZ2h0ID4+IDE7CiAgICBsZXQgaSA9IGxlZnQgKyAxOwogICAgbGV0IGogPSByaWdodDsKICAgIHN3YXAoaWRzLCBtZWRpYW4sIGkpOwogICAgaWYgKGRpc3RzW2lkc1tsZWZ0XV0gPiBkaXN0c1tpZHNbcmlnaHRdXSkgc3dhcChpZHMsIGxlZnQsIHJpZ2h0KTsKICAgIGlmIChkaXN0c1tpZHNbaV1dID4gZGlzdHNbaWRzW3JpZ2h0XV0pIHN3YXAoaWRzLCBpLCByaWdodCk7CiAgICBpZiAoZGlzdHNbaWRzW2xlZnRdXSA+IGRpc3RzW2lkc1tpXV0pIHN3YXAoaWRzLCBsZWZ0LCBpKTsKICAgIGNvbnN0IHRlbXAgPSBpZHNbaV07CiAgICBjb25zdCB0ZW1wRGlzdCA9IGRpc3RzW3RlbXBdOwogICAgd2hpbGUgKHRydWUpIHsKICAgICAgZG8gaSsrOyB3aGlsZSAoZGlzdHNbaWRzW2ldXSA8IHRlbXBEaXN0KTsKICAgICAgZG8gai0tOyB3aGlsZSAoZGlzdHNbaWRzW2pdXSA+IHRlbXBEaXN0KTsKICAgICAgaWYgKGogPCBpKSBicmVhazsKICAgICAgc3dhcChpZHMsIGksIGopOwogICAgfQogICAgaWRzW2xlZnQgKyAxXSA9IGlkc1tqXTsKICAgIGlkc1tqXSA9IHRlbXA7CiAgICBpZiAocmlnaHQgLSBpICsgMSA+PSBqIC0gbGVmdCkgewogICAgICBxdWlja3NvcnQoaWRzLCBkaXN0cywgaSwgcmlnaHQpOwogICAgICBxdWlja3NvcnQoaWRzLCBkaXN0cywgbGVmdCwgaiAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgcXVpY2tzb3J0KGlkcywgZGlzdHMsIGxlZnQsIGogLSAxKTsKICAgICAgcXVpY2tzb3J0KGlkcywgZGlzdHMsIGksIHJpZ2h0KTsKICAgIH0KICB9Cn0KZnVuY3Rpb24gc3dhcChhcnIsIGksIGopIHsKICBjb25zdCB0bXAgPSBhcnJbaV07CiAgYXJyW2ldID0gYXJyW2pdOwogIGFycltqXSA9IHRtcDsKfQpmdW5jdGlvbiBkZWZhdWx0R2V0WChwKSB7CiAgcmV0dXJuIHBbMF07Cn0KZnVuY3Rpb24gZGVmYXVsdEdldFkocCkgewogIHJldHVybiBwWzFdOwp9Cgpjb25zdCBlcHNpbG9uID0gMWUtNjsKY2xhc3MgUGF0aCB7CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLl94MCA9IHRoaXMuX3kwID0KICAgIC8vIHN0YXJ0IG9mIGN1cnJlbnQgc3VicGF0aAogICAgdGhpcy5feDEgPSB0aGlzLl95MSA9IG51bGw7IC8vIGVuZCBvZiBjdXJyZW50IHN1YnBhdGgKICAgIHRoaXMuXyA9ICIiOwogIH0KICBtb3ZlVG8oeCwgeSkgewogICAgdGhpcy5fICs9IGBNJHt0aGlzLl94MCA9IHRoaXMuX3gxID0gK3h9LCR7dGhpcy5feTAgPSB0aGlzLl95MSA9ICt5fWA7CiAgfQogIGNsb3NlUGF0aCgpIHsKICAgIGlmICh0aGlzLl94MSAhPT0gbnVsbCkgewogICAgICB0aGlzLl94MSA9IHRoaXMuX3gwLCB0aGlzLl95MSA9IHRoaXMuX3kwOwogICAgICB0aGlzLl8gKz0gIloiOwogICAgfQogIH0KICBsaW5lVG8oeCwgeSkgewogICAgdGhpcy5fICs9IGBMJHt0aGlzLl94MSA9ICt4fSwke3RoaXMuX3kxID0gK3l9YDsKICB9CiAgYXJjKHgsIHksIHIpIHsKICAgIHggPSAreCwgeSA9ICt5LCByID0gK3I7CiAgICBjb25zdCB4MCA9IHggKyByOwogICAgY29uc3QgeTAgPSB5OwogICAgaWYgKHIgPCAwKSB0aHJvdyBuZXcgRXJyb3IoIm5lZ2F0aXZlIHJhZGl1cyIpOwogICAgaWYgKHRoaXMuX3gxID09PSBudWxsKSB0aGlzLl8gKz0gYE0ke3gwfSwke3kwfWA7ZWxzZSBpZiAoTWF0aC5hYnModGhpcy5feDEgLSB4MCkgPiBlcHNpbG9uIHx8IE1hdGguYWJzKHRoaXMuX3kxIC0geTApID4gZXBzaWxvbikgdGhpcy5fICs9ICJMIiArIHgwICsgIiwiICsgeTA7CiAgICBpZiAoIXIpIHJldHVybjsKICAgIHRoaXMuXyArPSBgQSR7cn0sJHtyfSwwLDEsMSwke3ggLSByfSwke3l9QSR7cn0sJHtyfSwwLDEsMSwke3RoaXMuX3gxID0geDB9LCR7dGhpcy5feTEgPSB5MH1gOwogIH0KICByZWN0KHgsIHksIHcsIGgpIHsKICAgIHRoaXMuXyArPSBgTSR7dGhpcy5feDAgPSB0aGlzLl94MSA9ICt4fSwke3RoaXMuX3kwID0gdGhpcy5feTEgPSAreX1oJHsrd312JHsraH1oJHstd31aYDsKICB9CiAgdmFsdWUoKSB7CiAgICByZXR1cm4gdGhpcy5fIHx8IG51bGw7CiAgfQp9CgpjbGFzcyBQb2x5Z29uIHsKICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMuXyA9IFtdOwogIH0KICBtb3ZlVG8oeCwgeSkgewogICAgdGhpcy5fLnB1c2goW3gsIHldKTsKICB9CiAgY2xvc2VQYXRoKCkgewogICAgdGhpcy5fLnB1c2godGhpcy5fWzBdLnNsaWNlKCkpOwogIH0KICBsaW5lVG8oeCwgeSkgewogICAgdGhpcy5fLnB1c2goW3gsIHldKTsKICB9CiAgdmFsdWUoKSB7CiAgICByZXR1cm4gdGhpcy5fLmxlbmd0aCA/IHRoaXMuXyA6IG51bGw7CiAgfQp9CgpjbGFzcyBWb3Jvbm9pIHsKICBjb25zdHJ1Y3RvcihkZWxhdW5heSwgW3htaW4sIHltaW4sIHhtYXgsIHltYXhdID0gWzAsIDAsIDk2MCwgNTAwXSkgewogICAgaWYgKCEoKHhtYXggPSAreG1heCkgPj0gKHhtaW4gPSAreG1pbikpIHx8ICEoKHltYXggPSAreW1heCkgPj0gKHltaW4gPSAreW1pbikpKSB0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgYm91bmRzIik7CiAgICB0aGlzLmRlbGF1bmF5ID0gZGVsYXVuYXk7CiAgICB0aGlzLl9jaXJjdW1jZW50ZXJzID0gbmV3IEZsb2F0NjRBcnJheShkZWxhdW5heS5wb2ludHMubGVuZ3RoICogMik7CiAgICB0aGlzLnZlY3RvcnMgPSBuZXcgRmxvYXQ2NEFycmF5KGRlbGF1bmF5LnBvaW50cy5sZW5ndGggKiAyKTsKICAgIHRoaXMueG1heCA9IHhtYXgsIHRoaXMueG1pbiA9IHhtaW47CiAgICB0aGlzLnltYXggPSB5bWF4LCB0aGlzLnltaW4gPSB5bWluOwogICAgdGhpcy5faW5pdCgpOwogIH0KICB1cGRhdGUoKSB7CiAgICB0aGlzLmRlbGF1bmF5LnVwZGF0ZSgpOwogICAgdGhpcy5faW5pdCgpOwogICAgcmV0dXJuIHRoaXM7CiAgfQogIF9pbml0KCkgewogICAgY29uc3QgewogICAgICBkZWxhdW5heTogewogICAgICAgIHBvaW50cywKICAgICAgICBodWxsLAogICAgICAgIHRyaWFuZ2xlcwogICAgICB9LAogICAgICB2ZWN0b3JzCiAgICB9ID0gdGhpczsKICAgIGxldCBieCwgYnk7IC8vIGxhemlseSBjb21wdXRlZCBiYXJ5Y2VudGVyIG9mIHRoZSBodWxsCgogICAgLy8gQ29tcHV0ZSBjaXJjdW1jZW50ZXJzLgogICAgY29uc3QgY2lyY3VtY2VudGVycyA9IHRoaXMuY2lyY3VtY2VudGVycyA9IHRoaXMuX2NpcmN1bWNlbnRlcnMuc3ViYXJyYXkoMCwgdHJpYW5nbGVzLmxlbmd0aCAvIDMgKiAyKTsKICAgIGZvciAobGV0IGkgPSAwLCBqID0gMCwgbiA9IHRyaWFuZ2xlcy5sZW5ndGgsIHgsIHk7IGkgPCBuOyBpICs9IDMsIGogKz0gMikgewogICAgICBjb25zdCB0MSA9IHRyaWFuZ2xlc1tpXSAqIDI7CiAgICAgIGNvbnN0IHQyID0gdHJpYW5nbGVzW2kgKyAxXSAqIDI7CiAgICAgIGNvbnN0IHQzID0gdHJpYW5nbGVzW2kgKyAyXSAqIDI7CiAgICAgIGNvbnN0IHgxID0gcG9pbnRzW3QxXTsKICAgICAgY29uc3QgeTEgPSBwb2ludHNbdDEgKyAxXTsKICAgICAgY29uc3QgeDIgPSBwb2ludHNbdDJdOwogICAgICBjb25zdCB5MiA9IHBvaW50c1t0MiArIDFdOwogICAgICBjb25zdCB4MyA9IHBvaW50c1t0M107CiAgICAgIGNvbnN0IHkzID0gcG9pbnRzW3QzICsgMV07CiAgICAgIGNvbnN0IGR4ID0geDIgLSB4MTsKICAgICAgY29uc3QgZHkgPSB5MiAtIHkxOwogICAgICBjb25zdCBleCA9IHgzIC0geDE7CiAgICAgIGNvbnN0IGV5ID0geTMgLSB5MTsKICAgICAgY29uc3QgYWIgPSAoZHggKiBleSAtIGR5ICogZXgpICogMjsKICAgICAgaWYgKE1hdGguYWJzKGFiKSA8IDFlLTkpIHsKICAgICAgICAvLyBGb3IgYSBkZWdlbmVyYXRlIHRyaWFuZ2xlLCB0aGUgY2lyY3VtY2VudGVyIGlzIGF0IHRoZSBpbmZpbml0eSwgaW4gYQogICAgICAgIC8vIGRpcmVjdGlvbiBvcnRob2dvbmFsIHRvIHRoZSBoYWxmZWRnZSBhbmQgYXdheSBmcm9tIHRoZSDigJxjZW50ZXLigJ0gb2YKICAgICAgICAvLyB0aGUgZGlhZ3JhbSA8YngsIGJ5PiwgZGVmaW5lZCBhcyB0aGUgaHVsbOKAmXMgYmFyeWNlbnRlci4KICAgICAgICBpZiAoYnggPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgYnggPSBieSA9IDA7CiAgICAgICAgICBmb3IgKGNvbnN0IGkgb2YgaHVsbCkgYnggKz0gcG9pbnRzW2kgKiAyXSwgYnkgKz0gcG9pbnRzW2kgKiAyICsgMV07CiAgICAgICAgICBieCAvPSBodWxsLmxlbmd0aCwgYnkgLz0gaHVsbC5sZW5ndGg7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGEgPSAxZTkgKiBNYXRoLnNpZ24oKGJ4IC0geDEpICogZXkgLSAoYnkgLSB5MSkgKiBleCk7CiAgICAgICAgeCA9ICh4MSArIHgzKSAvIDIgLSBhICogZXk7CiAgICAgICAgeSA9ICh5MSArIHkzKSAvIDIgKyBhICogZXg7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29uc3QgZCA9IDEgLyBhYjsKICAgICAgICBjb25zdCBibCA9IGR4ICogZHggKyBkeSAqIGR5OwogICAgICAgIGNvbnN0IGNsID0gZXggKiBleCArIGV5ICogZXk7CiAgICAgICAgeCA9IHgxICsgKGV5ICogYmwgLSBkeSAqIGNsKSAqIGQ7CiAgICAgICAgeSA9IHkxICsgKGR4ICogY2wgLSBleCAqIGJsKSAqIGQ7CiAgICAgIH0KICAgICAgY2lyY3VtY2VudGVyc1tqXSA9IHg7CiAgICAgIGNpcmN1bWNlbnRlcnNbaiArIDFdID0geTsKICAgIH0KCiAgICAvLyBDb21wdXRlIGV4dGVyaW9yIGNlbGwgcmF5cy4KICAgIGxldCBoID0gaHVsbFtodWxsLmxlbmd0aCAtIDFdOwogICAgbGV0IHAwLAogICAgICBwMSA9IGggKiA0OwogICAgbGV0IHgwLAogICAgICB4MSA9IHBvaW50c1syICogaF07CiAgICBsZXQgeTAsCiAgICAgIHkxID0gcG9pbnRzWzIgKiBoICsgMV07CiAgICB2ZWN0b3JzLmZpbGwoMCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bGwubGVuZ3RoOyArK2kpIHsKICAgICAgaCA9IGh1bGxbaV07CiAgICAgIHAwID0gcDEsIHgwID0geDEsIHkwID0geTE7CiAgICAgIHAxID0gaCAqIDQsIHgxID0gcG9pbnRzWzIgKiBoXSwgeTEgPSBwb2ludHNbMiAqIGggKyAxXTsKICAgICAgdmVjdG9yc1twMCArIDJdID0gdmVjdG9yc1twMV0gPSB5MCAtIHkxOwogICAgICB2ZWN0b3JzW3AwICsgM10gPSB2ZWN0b3JzW3AxICsgMV0gPSB4MSAtIHgwOwogICAgfQogIH0KICByZW5kZXIoY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIGRlbGF1bmF5OiB7CiAgICAgICAgaGFsZmVkZ2VzLAogICAgICAgIGluZWRnZXMsCiAgICAgICAgaHVsbAogICAgICB9LAogICAgICBjaXJjdW1jZW50ZXJzLAogICAgICB2ZWN0b3JzCiAgICB9ID0gdGhpczsKICAgIGlmIChodWxsLmxlbmd0aCA8PSAxKSByZXR1cm4gbnVsbDsKICAgIGZvciAobGV0IGkgPSAwLCBuID0gaGFsZmVkZ2VzLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgICBjb25zdCBqID0gaGFsZmVkZ2VzW2ldOwogICAgICBpZiAoaiA8IGkpIGNvbnRpbnVlOwogICAgICBjb25zdCB0aSA9IE1hdGguZmxvb3IoaSAvIDMpICogMjsKICAgICAgY29uc3QgdGogPSBNYXRoLmZsb29yKGogLyAzKSAqIDI7CiAgICAgIGNvbnN0IHhpID0gY2lyY3VtY2VudGVyc1t0aV07CiAgICAgIGNvbnN0IHlpID0gY2lyY3VtY2VudGVyc1t0aSArIDFdOwogICAgICBjb25zdCB4aiA9IGNpcmN1bWNlbnRlcnNbdGpdOwogICAgICBjb25zdCB5aiA9IGNpcmN1bWNlbnRlcnNbdGogKyAxXTsKICAgICAgdGhpcy5fcmVuZGVyU2VnbWVudCh4aSwgeWksIHhqLCB5aiwgY29udGV4dCk7CiAgICB9CiAgICBsZXQgaDAsCiAgICAgIGgxID0gaHVsbFtodWxsLmxlbmd0aCAtIDFdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBodWxsLmxlbmd0aDsgKytpKSB7CiAgICAgIGgwID0gaDEsIGgxID0gaHVsbFtpXTsKICAgICAgY29uc3QgdCA9IE1hdGguZmxvb3IoaW5lZGdlc1toMV0gLyAzKSAqIDI7CiAgICAgIGNvbnN0IHggPSBjaXJjdW1jZW50ZXJzW3RdOwogICAgICBjb25zdCB5ID0gY2lyY3VtY2VudGVyc1t0ICsgMV07CiAgICAgIGNvbnN0IHYgPSBoMCAqIDQ7CiAgICAgIGNvbnN0IHAgPSB0aGlzLl9wcm9qZWN0KHgsIHksIHZlY3RvcnNbdiArIDJdLCB2ZWN0b3JzW3YgKyAzXSk7CiAgICAgIGlmIChwKSB0aGlzLl9yZW5kZXJTZWdtZW50KHgsIHksIHBbMF0sIHBbMV0sIGNvbnRleHQpOwogICAgfQogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgcmVuZGVyQm91bmRzKGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29udGV4dC5yZWN0KHRoaXMueG1pbiwgdGhpcy55bWluLCB0aGlzLnhtYXggLSB0aGlzLnhtaW4sIHRoaXMueW1heCAtIHRoaXMueW1pbik7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICByZW5kZXJDZWxsKGksIGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgcG9pbnRzID0gdGhpcy5fY2xpcChpKTsKICAgIGlmIChwb2ludHMgPT09IG51bGwgfHwgIXBvaW50cy5sZW5ndGgpIHJldHVybjsKICAgIGNvbnRleHQubW92ZVRvKHBvaW50c1swXSwgcG9pbnRzWzFdKTsKICAgIGxldCBuID0gcG9pbnRzLmxlbmd0aDsKICAgIHdoaWxlIChwb2ludHNbMF0gPT09IHBvaW50c1tuIC0gMl0gJiYgcG9pbnRzWzFdID09PSBwb2ludHNbbiAtIDFdICYmIG4gPiAxKSBuIC09IDI7CiAgICBmb3IgKGxldCBpID0gMjsgaSA8IG47IGkgKz0gMikgewogICAgICBpZiAocG9pbnRzW2ldICE9PSBwb2ludHNbaSAtIDJdIHx8IHBvaW50c1tpICsgMV0gIT09IHBvaW50c1tpIC0gMV0pIGNvbnRleHQubGluZVRvKHBvaW50c1tpXSwgcG9pbnRzW2kgKyAxXSk7CiAgICB9CiAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgKmNlbGxQb2x5Z29ucygpIHsKICAgIGNvbnN0IHsKICAgICAgZGVsYXVuYXk6IHsKICAgICAgICBwb2ludHMKICAgICAgfQogICAgfSA9IHRoaXM7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvaW50cy5sZW5ndGggLyAyOyBpIDwgbjsgKytpKSB7CiAgICAgIGNvbnN0IGNlbGwgPSB0aGlzLmNlbGxQb2x5Z29uKGkpOwogICAgICBpZiAoY2VsbCkgY2VsbC5pbmRleCA9IGksIHlpZWxkIGNlbGw7CiAgICB9CiAgfQogIGNlbGxQb2x5Z29uKGkpIHsKICAgIGNvbnN0IHBvbHlnb24gPSBuZXcgUG9seWdvbigpOwogICAgdGhpcy5yZW5kZXJDZWxsKGksIHBvbHlnb24pOwogICAgcmV0dXJuIHBvbHlnb24udmFsdWUoKTsKICB9CiAgX3JlbmRlclNlZ21lbnQoeDAsIHkwLCB4MSwgeTEsIGNvbnRleHQpIHsKICAgIGxldCBTOwogICAgY29uc3QgYzAgPSB0aGlzLl9yZWdpb25jb2RlKHgwLCB5MCk7CiAgICBjb25zdCBjMSA9IHRoaXMuX3JlZ2lvbmNvZGUoeDEsIHkxKTsKICAgIGlmIChjMCA9PT0gMCAmJiBjMSA9PT0gMCkgewogICAgICBjb250ZXh0Lm1vdmVUbyh4MCwgeTApOwogICAgICBjb250ZXh0LmxpbmVUbyh4MSwgeTEpOwogICAgfSBlbHNlIGlmIChTID0gdGhpcy5fY2xpcFNlZ21lbnQoeDAsIHkwLCB4MSwgeTEsIGMwLCBjMSkpIHsKICAgICAgY29udGV4dC5tb3ZlVG8oU1swXSwgU1sxXSk7CiAgICAgIGNvbnRleHQubGluZVRvKFNbMl0sIFNbM10pOwogICAgfQogIH0KICBjb250YWlucyhpLCB4LCB5KSB7CiAgICBpZiAoKHggPSAreCwgeCAhPT0geCkgfHwgKHkgPSAreSwgeSAhPT0geSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0aGlzLmRlbGF1bmF5Ll9zdGVwKGksIHgsIHkpID09PSBpOwogIH0KICAqbmVpZ2hib3JzKGkpIHsKICAgIGNvbnN0IGNpID0gdGhpcy5fY2xpcChpKTsKICAgIGlmIChjaSkgZm9yIChjb25zdCBqIG9mIHRoaXMuZGVsYXVuYXkubmVpZ2hib3JzKGkpKSB7CiAgICAgIGNvbnN0IGNqID0gdGhpcy5fY2xpcChqKTsKICAgICAgLy8gZmluZCB0aGUgY29tbW9uIGVkZ2UKICAgICAgaWYgKGNqKSBsb29wOiBmb3IgKGxldCBhaSA9IDAsIGxpID0gY2kubGVuZ3RoOyBhaSA8IGxpOyBhaSArPSAyKSB7CiAgICAgICAgZm9yIChsZXQgYWogPSAwLCBsaiA9IGNqLmxlbmd0aDsgYWogPCBsajsgYWogKz0gMikgewogICAgICAgICAgaWYgKGNpW2FpXSA9PT0gY2pbYWpdICYmIGNpW2FpICsgMV0gPT09IGNqW2FqICsgMV0gJiYgY2lbKGFpICsgMikgJSBsaV0gPT09IGNqWyhhaiArIGxqIC0gMikgJSBsal0gJiYgY2lbKGFpICsgMykgJSBsaV0gPT09IGNqWyhhaiArIGxqIC0gMSkgJSBsal0pIHsKICAgICAgICAgICAgeWllbGQgajsKICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CiAgX2NlbGwoaSkgewogICAgY29uc3QgewogICAgICBjaXJjdW1jZW50ZXJzLAogICAgICBkZWxhdW5heTogewogICAgICAgIGluZWRnZXMsCiAgICAgICAgaGFsZmVkZ2VzLAogICAgICAgIHRyaWFuZ2xlcwogICAgICB9CiAgICB9ID0gdGhpczsKICAgIGNvbnN0IGUwID0gaW5lZGdlc1tpXTsKICAgIGlmIChlMCA9PT0gLTEpIHJldHVybiBudWxsOyAvLyBjb2luY2lkZW50IHBvaW50CiAgICBjb25zdCBwb2ludHMgPSBbXTsKICAgIGxldCBlID0gZTA7CiAgICBkbyB7CiAgICAgIGNvbnN0IHQgPSBNYXRoLmZsb29yKGUgLyAzKTsKICAgICAgcG9pbnRzLnB1c2goY2lyY3VtY2VudGVyc1t0ICogMl0sIGNpcmN1bWNlbnRlcnNbdCAqIDIgKyAxXSk7CiAgICAgIGUgPSBlICUgMyA9PT0gMiA/IGUgLSAyIDogZSArIDE7CiAgICAgIGlmICh0cmlhbmdsZXNbZV0gIT09IGkpIGJyZWFrOyAvLyBiYWQgdHJpYW5ndWxhdGlvbgogICAgICBlID0gaGFsZmVkZ2VzW2VdOwogICAgfSB3aGlsZSAoZSAhPT0gZTAgJiYgZSAhPT0gLTEpOwogICAgcmV0dXJuIHBvaW50czsKICB9CiAgX2NsaXAoaSkgewogICAgLy8gZGVnZW5lcmF0ZSBjYXNlICgxIHZhbGlkIHBvaW50OiByZXR1cm4gdGhlIGJveCkKICAgIGlmIChpID09PSAwICYmIHRoaXMuZGVsYXVuYXkuaHVsbC5sZW5ndGggPT09IDEpIHsKICAgICAgcmV0dXJuIFt0aGlzLnhtYXgsIHRoaXMueW1pbiwgdGhpcy54bWF4LCB0aGlzLnltYXgsIHRoaXMueG1pbiwgdGhpcy55bWF4LCB0aGlzLnhtaW4sIHRoaXMueW1pbl07CiAgICB9CiAgICBjb25zdCBwb2ludHMgPSB0aGlzLl9jZWxsKGkpOwogICAgaWYgKHBvaW50cyA9PT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICBjb25zdCB7CiAgICAgIHZlY3RvcnM6IFYKICAgIH0gPSB0aGlzOwogICAgY29uc3QgdiA9IGkgKiA0OwogICAgcmV0dXJuIHRoaXMuX3NpbXBsaWZ5KFZbdl0gfHwgVlt2ICsgMV0gPyB0aGlzLl9jbGlwSW5maW5pdGUoaSwgcG9pbnRzLCBWW3ZdLCBWW3YgKyAxXSwgVlt2ICsgMl0sIFZbdiArIDNdKSA6IHRoaXMuX2NsaXBGaW5pdGUoaSwgcG9pbnRzKSk7CiAgfQogIF9jbGlwRmluaXRlKGksIHBvaW50cykgewogICAgY29uc3QgbiA9IHBvaW50cy5sZW5ndGg7CiAgICBsZXQgUCA9IG51bGw7CiAgICBsZXQgeDAsCiAgICAgIHkwLAogICAgICB4MSA9IHBvaW50c1tuIC0gMl0sCiAgICAgIHkxID0gcG9pbnRzW24gLSAxXTsKICAgIGxldCBjMCwKICAgICAgYzEgPSB0aGlzLl9yZWdpb25jb2RlKHgxLCB5MSk7CiAgICBsZXQgZTAsCiAgICAgIGUxID0gMDsKICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaiArPSAyKSB7CiAgICAgIHgwID0geDEsIHkwID0geTEsIHgxID0gcG9pbnRzW2pdLCB5MSA9IHBvaW50c1tqICsgMV07CiAgICAgIGMwID0gYzEsIGMxID0gdGhpcy5fcmVnaW9uY29kZSh4MSwgeTEpOwogICAgICBpZiAoYzAgPT09IDAgJiYgYzEgPT09IDApIHsKICAgICAgICBlMCA9IGUxLCBlMSA9IDA7CiAgICAgICAgaWYgKFApIFAucHVzaCh4MSwgeTEpO2Vsc2UgUCA9IFt4MSwgeTFdOwogICAgICB9IGVsc2UgewogICAgICAgIGxldCBTLCBzeDAsIHN5MCwgc3gxLCBzeTE7CiAgICAgICAgaWYgKGMwID09PSAwKSB7CiAgICAgICAgICBpZiAoKFMgPSB0aGlzLl9jbGlwU2VnbWVudCh4MCwgeTAsIHgxLCB5MSwgYzAsIGMxKSkgPT09IG51bGwpIGNvbnRpbnVlOwogICAgICAgICAgW3N4MCwgc3kwLCBzeDEsIHN5MV0gPSBTOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoKFMgPSB0aGlzLl9jbGlwU2VnbWVudCh4MSwgeTEsIHgwLCB5MCwgYzEsIGMwKSkgPT09IG51bGwpIGNvbnRpbnVlOwogICAgICAgICAgW3N4MSwgc3kxLCBzeDAsIHN5MF0gPSBTOwogICAgICAgICAgZTAgPSBlMSwgZTEgPSB0aGlzLl9lZGdlY29kZShzeDAsIHN5MCk7CiAgICAgICAgICBpZiAoZTAgJiYgZTEpIHRoaXMuX2VkZ2UoaSwgZTAsIGUxLCBQLCBQLmxlbmd0aCk7CiAgICAgICAgICBpZiAoUCkgUC5wdXNoKHN4MCwgc3kwKTtlbHNlIFAgPSBbc3gwLCBzeTBdOwogICAgICAgIH0KICAgICAgICBlMCA9IGUxLCBlMSA9IHRoaXMuX2VkZ2Vjb2RlKHN4MSwgc3kxKTsKICAgICAgICBpZiAoZTAgJiYgZTEpIHRoaXMuX2VkZ2UoaSwgZTAsIGUxLCBQLCBQLmxlbmd0aCk7CiAgICAgICAgaWYgKFApIFAucHVzaChzeDEsIHN5MSk7ZWxzZSBQID0gW3N4MSwgc3kxXTsKICAgICAgfQogICAgfQogICAgaWYgKFApIHsKICAgICAgZTAgPSBlMSwgZTEgPSB0aGlzLl9lZGdlY29kZShQWzBdLCBQWzFdKTsKICAgICAgaWYgKGUwICYmIGUxKSB0aGlzLl9lZGdlKGksIGUwLCBlMSwgUCwgUC5sZW5ndGgpOwogICAgfSBlbHNlIGlmICh0aGlzLmNvbnRhaW5zKGksICh0aGlzLnhtaW4gKyB0aGlzLnhtYXgpIC8gMiwgKHRoaXMueW1pbiArIHRoaXMueW1heCkgLyAyKSkgewogICAgICByZXR1cm4gW3RoaXMueG1heCwgdGhpcy55bWluLCB0aGlzLnhtYXgsIHRoaXMueW1heCwgdGhpcy54bWluLCB0aGlzLnltYXgsIHRoaXMueG1pbiwgdGhpcy55bWluXTsKICAgIH0KICAgIHJldHVybiBQOwogIH0KICBfY2xpcFNlZ21lbnQoeDAsIHkwLCB4MSwgeTEsIGMwLCBjMSkgewogICAgLy8gZm9yIG1vcmUgcm9idXN0bmVzcywgYWx3YXlzIGNvbnNpZGVyIHRoZSBzZWdtZW50IGluIHRoZSBzYW1lIG9yZGVyCiAgICBjb25zdCBmbGlwID0gYzAgPCBjMTsKICAgIGlmIChmbGlwKSBbeDAsIHkwLCB4MSwgeTEsIGMwLCBjMV0gPSBbeDEsIHkxLCB4MCwgeTAsIGMxLCBjMF07CiAgICB3aGlsZSAodHJ1ZSkgewogICAgICBpZiAoYzAgPT09IDAgJiYgYzEgPT09IDApIHJldHVybiBmbGlwID8gW3gxLCB5MSwgeDAsIHkwXSA6IFt4MCwgeTAsIHgxLCB5MV07CiAgICAgIGlmIChjMCAmIGMxKSByZXR1cm4gbnVsbDsKICAgICAgbGV0IHgsCiAgICAgICAgeSwKICAgICAgICBjID0gYzAgfHwgYzE7CiAgICAgIGlmIChjICYgMGIxMDAwKSB4ID0geDAgKyAoeDEgLSB4MCkgKiAodGhpcy55bWF4IC0geTApIC8gKHkxIC0geTApLCB5ID0gdGhpcy55bWF4O2Vsc2UgaWYgKGMgJiAwYjAxMDApIHggPSB4MCArICh4MSAtIHgwKSAqICh0aGlzLnltaW4gLSB5MCkgLyAoeTEgLSB5MCksIHkgPSB0aGlzLnltaW47ZWxzZSBpZiAoYyAmIDBiMDAxMCkgeSA9IHkwICsgKHkxIC0geTApICogKHRoaXMueG1heCAtIHgwKSAvICh4MSAtIHgwKSwgeCA9IHRoaXMueG1heDtlbHNlIHkgPSB5MCArICh5MSAtIHkwKSAqICh0aGlzLnhtaW4gLSB4MCkgLyAoeDEgLSB4MCksIHggPSB0aGlzLnhtaW47CiAgICAgIGlmIChjMCkgeDAgPSB4LCB5MCA9IHksIGMwID0gdGhpcy5fcmVnaW9uY29kZSh4MCwgeTApO2Vsc2UgeDEgPSB4LCB5MSA9IHksIGMxID0gdGhpcy5fcmVnaW9uY29kZSh4MSwgeTEpOwogICAgfQogIH0KICBfY2xpcEluZmluaXRlKGksIHBvaW50cywgdngwLCB2eTAsIHZ4biwgdnluKSB7CiAgICBsZXQgUCA9IEFycmF5LmZyb20ocG9pbnRzKSwKICAgICAgcDsKICAgIGlmIChwID0gdGhpcy5fcHJvamVjdChQWzBdLCBQWzFdLCB2eDAsIHZ5MCkpIFAudW5zaGlmdChwWzBdLCBwWzFdKTsKICAgIGlmIChwID0gdGhpcy5fcHJvamVjdChQW1AubGVuZ3RoIC0gMl0sIFBbUC5sZW5ndGggLSAxXSwgdnhuLCB2eW4pKSBQLnB1c2gocFswXSwgcFsxXSk7CiAgICBpZiAoUCA9IHRoaXMuX2NsaXBGaW5pdGUoaSwgUCkpIHsKICAgICAgZm9yIChsZXQgaiA9IDAsIG4gPSBQLmxlbmd0aCwgYzAsIGMxID0gdGhpcy5fZWRnZWNvZGUoUFtuIC0gMl0sIFBbbiAtIDFdKTsgaiA8IG47IGogKz0gMikgewogICAgICAgIGMwID0gYzEsIGMxID0gdGhpcy5fZWRnZWNvZGUoUFtqXSwgUFtqICsgMV0pOwogICAgICAgIGlmIChjMCAmJiBjMSkgaiA9IHRoaXMuX2VkZ2UoaSwgYzAsIGMxLCBQLCBqKSwgbiA9IFAubGVuZ3RoOwogICAgICB9CiAgICB9IGVsc2UgaWYgKHRoaXMuY29udGFpbnMoaSwgKHRoaXMueG1pbiArIHRoaXMueG1heCkgLyAyLCAodGhpcy55bWluICsgdGhpcy55bWF4KSAvIDIpKSB7CiAgICAgIFAgPSBbdGhpcy54bWluLCB0aGlzLnltaW4sIHRoaXMueG1heCwgdGhpcy55bWluLCB0aGlzLnhtYXgsIHRoaXMueW1heCwgdGhpcy54bWluLCB0aGlzLnltYXhdOwogICAgfQogICAgcmV0dXJuIFA7CiAgfQogIF9lZGdlKGksIGUwLCBlMSwgUCwgaikgewogICAgd2hpbGUgKGUwICE9PSBlMSkgewogICAgICBsZXQgeCwgeTsKICAgICAgc3dpdGNoIChlMCkgewogICAgICAgIGNhc2UgMGIwMTAxOgogICAgICAgICAgZTAgPSAwYjAxMDA7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICAvLyB0b3AtbGVmdAogICAgICAgIGNhc2UgMGIwMTAwOgogICAgICAgICAgZTAgPSAwYjAxMTAsIHggPSB0aGlzLnhtYXgsIHkgPSB0aGlzLnltaW47CiAgICAgICAgICBicmVhazsKICAgICAgICAvLyB0b3AKICAgICAgICBjYXNlIDBiMDExMDoKICAgICAgICAgIGUwID0gMGIwMDEwOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgLy8gdG9wLXJpZ2h0CiAgICAgICAgY2FzZSAwYjAwMTA6CiAgICAgICAgICBlMCA9IDBiMTAxMCwgeCA9IHRoaXMueG1heCwgeSA9IHRoaXMueW1heDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIHJpZ2h0CiAgICAgICAgY2FzZSAwYjEwMTA6CiAgICAgICAgICBlMCA9IDBiMTAwMDsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIC8vIGJvdHRvbS1yaWdodAogICAgICAgIGNhc2UgMGIxMDAwOgogICAgICAgICAgZTAgPSAwYjEwMDEsIHggPSB0aGlzLnhtaW4sIHkgPSB0aGlzLnltYXg7CiAgICAgICAgICBicmVhazsKICAgICAgICAvLyBib3R0b20KICAgICAgICBjYXNlIDBiMTAwMToKICAgICAgICAgIGUwID0gMGIwMDAxOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgLy8gYm90dG9tLWxlZnQKICAgICAgICBjYXNlIDBiMDAwMToKICAgICAgICAgIGUwID0gMGIwMTAxLCB4ID0gdGhpcy54bWluLCB5ID0gdGhpcy55bWluOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gbGVmdAogICAgICB9CiAgICAgIC8vIE5vdGU6IHRoaXMgaW1wbGljaXRseSBjaGVja3MgZm9yIG91dCBvZiBib3VuZHM6IGlmIFBbal0gb3IgUFtqKzFdIGFyZQogICAgICAvLyB1bmRlZmluZWQsIHRoZSBjb25kaXRpb25hbCBzdGF0ZW1lbnQgd2lsbCBiZSBleGVjdXRlZC4KICAgICAgaWYgKChQW2pdICE9PSB4IHx8IFBbaiArIDFdICE9PSB5KSAmJiB0aGlzLmNvbnRhaW5zKGksIHgsIHkpKSB7CiAgICAgICAgUC5zcGxpY2UoaiwgMCwgeCwgeSksIGogKz0gMjsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGo7CiAgfQogIF9wcm9qZWN0KHgwLCB5MCwgdngsIHZ5KSB7CiAgICBsZXQgdCA9IEluZmluaXR5LAogICAgICBjLAogICAgICB4LAogICAgICB5OwogICAgaWYgKHZ5IDwgMCkgewogICAgICAvLyB0b3AKICAgICAgaWYgKHkwIDw9IHRoaXMueW1pbikgcmV0dXJuIG51bGw7CiAgICAgIGlmICgoYyA9ICh0aGlzLnltaW4gLSB5MCkgLyB2eSkgPCB0KSB5ID0gdGhpcy55bWluLCB4ID0geDAgKyAodCA9IGMpICogdng7CiAgICB9IGVsc2UgaWYgKHZ5ID4gMCkgewogICAgICAvLyBib3R0b20KICAgICAgaWYgKHkwID49IHRoaXMueW1heCkgcmV0dXJuIG51bGw7CiAgICAgIGlmICgoYyA9ICh0aGlzLnltYXggLSB5MCkgLyB2eSkgPCB0KSB5ID0gdGhpcy55bWF4LCB4ID0geDAgKyAodCA9IGMpICogdng7CiAgICB9CiAgICBpZiAodnggPiAwKSB7CiAgICAgIC8vIHJpZ2h0CiAgICAgIGlmICh4MCA+PSB0aGlzLnhtYXgpIHJldHVybiBudWxsOwogICAgICBpZiAoKGMgPSAodGhpcy54bWF4IC0geDApIC8gdngpIDwgdCkgeCA9IHRoaXMueG1heCwgeSA9IHkwICsgKHQgPSBjKSAqIHZ5OwogICAgfSBlbHNlIGlmICh2eCA8IDApIHsKICAgICAgLy8gbGVmdAogICAgICBpZiAoeDAgPD0gdGhpcy54bWluKSByZXR1cm4gbnVsbDsKICAgICAgaWYgKChjID0gKHRoaXMueG1pbiAtIHgwKSAvIHZ4KSA8IHQpIHggPSB0aGlzLnhtaW4sIHkgPSB5MCArICh0ID0gYykgKiB2eTsKICAgIH0KICAgIHJldHVybiBbeCwgeV07CiAgfQogIF9lZGdlY29kZSh4LCB5KSB7CiAgICByZXR1cm4gKHggPT09IHRoaXMueG1pbiA/IDBiMDAwMSA6IHggPT09IHRoaXMueG1heCA/IDBiMDAxMCA6IDBiMDAwMCkgfCAoeSA9PT0gdGhpcy55bWluID8gMGIwMTAwIDogeSA9PT0gdGhpcy55bWF4ID8gMGIxMDAwIDogMGIwMDAwKTsKICB9CiAgX3JlZ2lvbmNvZGUoeCwgeSkgewogICAgcmV0dXJuICh4IDwgdGhpcy54bWluID8gMGIwMDAxIDogeCA+IHRoaXMueG1heCA/IDBiMDAxMCA6IDBiMDAwMCkgfCAoeSA8IHRoaXMueW1pbiA/IDBiMDEwMCA6IHkgPiB0aGlzLnltYXggPyAwYjEwMDAgOiAwYjAwMDApOwogIH0KICBfc2ltcGxpZnkoUCkgewogICAgaWYgKFAgJiYgUC5sZW5ndGggPiA0KSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUC5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGogPSAoaSArIDIpICUgUC5sZW5ndGgsCiAgICAgICAgICBrID0gKGkgKyA0KSAlIFAubGVuZ3RoOwogICAgICAgIGlmIChQW2ldID09PSBQW2pdICYmIFBbal0gPT09IFBba10gfHwgUFtpICsgMV0gPT09IFBbaiArIDFdICYmIFBbaiArIDFdID09PSBQW2sgKyAxXSkgewogICAgICAgICAgUC5zcGxpY2UoaiwgMiksIGkgLT0gMjsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKCFQLmxlbmd0aCkgUCA9IG51bGw7CiAgICB9CiAgICByZXR1cm4gUDsKICB9Cn0KCmNvbnN0IHRhdSA9IDIgKiBNYXRoLlBJLAogIHBvdyA9IE1hdGgucG93OwpmdW5jdGlvbiBwb2ludFgocCkgewogIHJldHVybiBwWzBdOwp9CmZ1bmN0aW9uIHBvaW50WShwKSB7CiAgcmV0dXJuIHBbMV07Cn0KCi8vIEEgdHJpYW5ndWxhdGlvbiBpcyBjb2xsaW5lYXIgaWYgYWxsIGl0cyB0cmlhbmdsZXMgaGF2ZSBhIG5vbi1udWxsIGFyZWEKZnVuY3Rpb24gY29sbGluZWFyKGQpIHsKICBjb25zdCB7CiAgICB0cmlhbmdsZXMsCiAgICBjb29yZHMKICB9ID0gZDsKICBmb3IgKGxldCBpID0gMDsgaSA8IHRyaWFuZ2xlcy5sZW5ndGg7IGkgKz0gMykgewogICAgY29uc3QgYSA9IDIgKiB0cmlhbmdsZXNbaV0sCiAgICAgIGIgPSAyICogdHJpYW5nbGVzW2kgKyAxXSwKICAgICAgYyA9IDIgKiB0cmlhbmdsZXNbaSArIDJdLAogICAgICBjcm9zcyA9IChjb29yZHNbY10gLSBjb29yZHNbYV0pICogKGNvb3Jkc1tiICsgMV0gLSBjb29yZHNbYSArIDFdKSAtIChjb29yZHNbYl0gLSBjb29yZHNbYV0pICogKGNvb3Jkc1tjICsgMV0gLSBjb29yZHNbYSArIDFdKTsKICAgIGlmIChjcm9zcyA+IDFlLTEwKSByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiB0cnVlOwp9CmZ1bmN0aW9uIGppdHRlcih4LCB5LCByKSB7CiAgcmV0dXJuIFt4ICsgTWF0aC5zaW4oeCArIHkpICogciwgeSArIE1hdGguY29zKHggLSB5KSAqIHJdOwp9CmNsYXNzIERlbGF1bmF5IHsKICBzdGF0aWMgZnJvbShwb2ludHMsIGZ4ID0gcG9pbnRYLCBmeSA9IHBvaW50WSwgdGhhdCkgewogICAgcmV0dXJuIG5ldyBEZWxhdW5heSgibGVuZ3RoIiBpbiBwb2ludHMgPyBmbGF0QXJyYXkocG9pbnRzLCBmeCwgZnksIHRoYXQpIDogRmxvYXQ2NEFycmF5LmZyb20oZmxhdEl0ZXJhYmxlKHBvaW50cywgZngsIGZ5LCB0aGF0KSkpOwogIH0KICBjb25zdHJ1Y3Rvcihwb2ludHMpIHsKICAgIHRoaXMuX2RlbGF1bmF0b3IgPSBuZXcgRGVsYXVuYXRvcihwb2ludHMpOwogICAgdGhpcy5pbmVkZ2VzID0gbmV3IEludDMyQXJyYXkocG9pbnRzLmxlbmd0aCAvIDIpOwogICAgdGhpcy5faHVsbEluZGV4ID0gbmV3IEludDMyQXJyYXkocG9pbnRzLmxlbmd0aCAvIDIpOwogICAgdGhpcy5wb2ludHMgPSB0aGlzLl9kZWxhdW5hdG9yLmNvb3JkczsKICAgIHRoaXMuX2luaXQoKTsKICB9CiAgdXBkYXRlKCkgewogICAgdGhpcy5fZGVsYXVuYXRvci51cGRhdGUoKTsKICAgIHRoaXMuX2luaXQoKTsKICAgIHJldHVybiB0aGlzOwogIH0KICBfaW5pdCgpIHsKICAgIGNvbnN0IGQgPSB0aGlzLl9kZWxhdW5hdG9yLAogICAgICBwb2ludHMgPSB0aGlzLnBvaW50czsKCiAgICAvLyBjaGVjayBmb3IgY29sbGluZWFyCiAgICBpZiAoZC5odWxsICYmIGQuaHVsbC5sZW5ndGggPiAyICYmIGNvbGxpbmVhcihkKSkgewogICAgICB0aGlzLmNvbGxpbmVhciA9IEludDMyQXJyYXkuZnJvbSh7CiAgICAgICAgbGVuZ3RoOiBwb2ludHMubGVuZ3RoIC8gMgogICAgICB9LCAoXywgaSkgPT4gaSkuc29ydCgoaSwgaikgPT4gcG9pbnRzWzIgKiBpXSAtIHBvaW50c1syICogal0gfHwgcG9pbnRzWzIgKiBpICsgMV0gLSBwb2ludHNbMiAqIGogKyAxXSk7IC8vIGZvciBleGFjdCBuZWlnaGJvcnMKICAgICAgY29uc3QgZSA9IHRoaXMuY29sbGluZWFyWzBdLAogICAgICAgIGYgPSB0aGlzLmNvbGxpbmVhclt0aGlzLmNvbGxpbmVhci5sZW5ndGggLSAxXSwKICAgICAgICBib3VuZHMgPSBbcG9pbnRzWzIgKiBlXSwgcG9pbnRzWzIgKiBlICsgMV0sIHBvaW50c1syICogZl0sIHBvaW50c1syICogZiArIDFdXSwKICAgICAgICByID0gMWUtOCAqIE1hdGguaHlwb3QoYm91bmRzWzNdIC0gYm91bmRzWzFdLCBib3VuZHNbMl0gLSBib3VuZHNbMF0pOwogICAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvaW50cy5sZW5ndGggLyAyOyBpIDwgbjsgKytpKSB7CiAgICAgICAgY29uc3QgcCA9IGppdHRlcihwb2ludHNbMiAqIGldLCBwb2ludHNbMiAqIGkgKyAxXSwgcik7CiAgICAgICAgcG9pbnRzWzIgKiBpXSA9IHBbMF07CiAgICAgICAgcG9pbnRzWzIgKiBpICsgMV0gPSBwWzFdOwogICAgICB9CiAgICAgIHRoaXMuX2RlbGF1bmF0b3IgPSBuZXcgRGVsYXVuYXRvcihwb2ludHMpOwogICAgfSBlbHNlIHsKICAgICAgZGVsZXRlIHRoaXMuY29sbGluZWFyOwogICAgfQogICAgY29uc3QgaGFsZmVkZ2VzID0gdGhpcy5oYWxmZWRnZXMgPSB0aGlzLl9kZWxhdW5hdG9yLmhhbGZlZGdlczsKICAgIGNvbnN0IGh1bGwgPSB0aGlzLmh1bGwgPSB0aGlzLl9kZWxhdW5hdG9yLmh1bGw7CiAgICBjb25zdCB0cmlhbmdsZXMgPSB0aGlzLnRyaWFuZ2xlcyA9IHRoaXMuX2RlbGF1bmF0b3IudHJpYW5nbGVzOwogICAgY29uc3QgaW5lZGdlcyA9IHRoaXMuaW5lZGdlcy5maWxsKC0xKTsKICAgIGNvbnN0IGh1bGxJbmRleCA9IHRoaXMuX2h1bGxJbmRleC5maWxsKC0xKTsKCiAgICAvLyBDb21wdXRlIGFuIGluZGV4IGZyb20gZWFjaCBwb2ludCB0byBhbiAoYXJiaXRyYXJ5KSBpbmNvbWluZyBoYWxmZWRnZQogICAgLy8gVXNlZCB0byBnaXZlIHRoZSBmaXJzdCBuZWlnaGJvciBvZiBlYWNoIHBvaW50OyBmb3IgdGhpcyByZWFzb24sCiAgICAvLyBvbiB0aGUgaHVsbCB3ZSBnaXZlIHByaW9yaXR5IHRvIGV4dGVyaW9yIGhhbGZlZGdlcwogICAgZm9yIChsZXQgZSA9IDAsIG4gPSBoYWxmZWRnZXMubGVuZ3RoOyBlIDwgbjsgKytlKSB7CiAgICAgIGNvbnN0IHAgPSB0cmlhbmdsZXNbZSAlIDMgPT09IDIgPyBlIC0gMiA6IGUgKyAxXTsKICAgICAgaWYgKGhhbGZlZGdlc1tlXSA9PT0gLTEgfHwgaW5lZGdlc1twXSA9PT0gLTEpIGluZWRnZXNbcF0gPSBlOwogICAgfQogICAgZm9yIChsZXQgaSA9IDAsIG4gPSBodWxsLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgICBodWxsSW5kZXhbaHVsbFtpXV0gPSBpOwogICAgfQoKICAgIC8vIGRlZ2VuZXJhdGUgY2FzZTogMSBvciAyIChkaXN0aW5jdCkgcG9pbnRzCiAgICBpZiAoaHVsbC5sZW5ndGggPD0gMiAmJiBodWxsLmxlbmd0aCA+IDApIHsKICAgICAgdGhpcy50cmlhbmdsZXMgPSBuZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKTsKICAgICAgdGhpcy5oYWxmZWRnZXMgPSBuZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKTsKICAgICAgdGhpcy50cmlhbmdsZXNbMF0gPSBodWxsWzBdOwogICAgICBpbmVkZ2VzW2h1bGxbMF1dID0gMTsKICAgICAgaWYgKGh1bGwubGVuZ3RoID09PSAyKSB7CiAgICAgICAgaW5lZGdlc1todWxsWzFdXSA9IDA7CiAgICAgICAgdGhpcy50cmlhbmdsZXNbMV0gPSBodWxsWzFdOwogICAgICAgIHRoaXMudHJpYW5nbGVzWzJdID0gaHVsbFsxXTsKICAgICAgfQogICAgfQogIH0KICB2b3Jvbm9pKGJvdW5kcykgewogICAgcmV0dXJuIG5ldyBWb3Jvbm9pKHRoaXMsIGJvdW5kcyk7CiAgfQogICpuZWlnaGJvcnMoaSkgewogICAgY29uc3QgewogICAgICBpbmVkZ2VzLAogICAgICBodWxsLAogICAgICBfaHVsbEluZGV4LAogICAgICBoYWxmZWRnZXMsCiAgICAgIHRyaWFuZ2xlcywKICAgICAgY29sbGluZWFyCiAgICB9ID0gdGhpczsKCiAgICAvLyBkZWdlbmVyYXRlIGNhc2Ugd2l0aCBzZXZlcmFsIGNvbGxpbmVhciBwb2ludHMKICAgIGlmIChjb2xsaW5lYXIpIHsKICAgICAgY29uc3QgbCA9IGNvbGxpbmVhci5pbmRleE9mKGkpOwogICAgICBpZiAobCA+IDApIHlpZWxkIGNvbGxpbmVhcltsIC0gMV07CiAgICAgIGlmIChsIDwgY29sbGluZWFyLmxlbmd0aCAtIDEpIHlpZWxkIGNvbGxpbmVhcltsICsgMV07CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGUwID0gaW5lZGdlc1tpXTsKICAgIGlmIChlMCA9PT0gLTEpIHJldHVybjsgLy8gY29pbmNpZGVudCBwb2ludAogICAgbGV0IGUgPSBlMCwKICAgICAgcDAgPSAtMTsKICAgIGRvIHsKICAgICAgeWllbGQgcDAgPSB0cmlhbmdsZXNbZV07CiAgICAgIGUgPSBlICUgMyA9PT0gMiA/IGUgLSAyIDogZSArIDE7CiAgICAgIGlmICh0cmlhbmdsZXNbZV0gIT09IGkpIHJldHVybjsgLy8gYmFkIHRyaWFuZ3VsYXRpb24KICAgICAgZSA9IGhhbGZlZGdlc1tlXTsKICAgICAgaWYgKGUgPT09IC0xKSB7CiAgICAgICAgY29uc3QgcCA9IGh1bGxbKF9odWxsSW5kZXhbaV0gKyAxKSAlIGh1bGwubGVuZ3RoXTsKICAgICAgICBpZiAocCAhPT0gcDApIHlpZWxkIHA7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICB9IHdoaWxlIChlICE9PSBlMCk7CiAgfQogIGZpbmQoeCwgeSwgaSA9IDApIHsKICAgIGlmICgoeCA9ICt4LCB4ICE9PSB4KSB8fCAoeSA9ICt5LCB5ICE9PSB5KSkgcmV0dXJuIC0xOwogICAgY29uc3QgaTAgPSBpOwogICAgbGV0IGM7CiAgICB3aGlsZSAoKGMgPSB0aGlzLl9zdGVwKGksIHgsIHkpKSA+PSAwICYmIGMgIT09IGkgJiYgYyAhPT0gaTApIGkgPSBjOwogICAgcmV0dXJuIGM7CiAgfQogIF9zdGVwKGksIHgsIHkpIHsKICAgIGNvbnN0IHsKICAgICAgaW5lZGdlcywKICAgICAgaHVsbCwKICAgICAgX2h1bGxJbmRleCwKICAgICAgaGFsZmVkZ2VzLAogICAgICB0cmlhbmdsZXMsCiAgICAgIHBvaW50cwogICAgfSA9IHRoaXM7CiAgICBpZiAoaW5lZGdlc1tpXSA9PT0gLTEgfHwgIXBvaW50cy5sZW5ndGgpIHJldHVybiAoaSArIDEpICUgKHBvaW50cy5sZW5ndGggPj4gMSk7CiAgICBsZXQgYyA9IGk7CiAgICBsZXQgZGMgPSBwb3coeCAtIHBvaW50c1tpICogMl0sIDIpICsgcG93KHkgLSBwb2ludHNbaSAqIDIgKyAxXSwgMik7CiAgICBjb25zdCBlMCA9IGluZWRnZXNbaV07CiAgICBsZXQgZSA9IGUwOwogICAgZG8gewogICAgICBsZXQgdCA9IHRyaWFuZ2xlc1tlXTsKICAgICAgY29uc3QgZHQgPSBwb3coeCAtIHBvaW50c1t0ICogMl0sIDIpICsgcG93KHkgLSBwb2ludHNbdCAqIDIgKyAxXSwgMik7CiAgICAgIGlmIChkdCA8IGRjKSBkYyA9IGR0LCBjID0gdDsKICAgICAgZSA9IGUgJSAzID09PSAyID8gZSAtIDIgOiBlICsgMTsKICAgICAgaWYgKHRyaWFuZ2xlc1tlXSAhPT0gaSkgYnJlYWs7IC8vIGJhZCB0cmlhbmd1bGF0aW9uCiAgICAgIGUgPSBoYWxmZWRnZXNbZV07CiAgICAgIGlmIChlID09PSAtMSkgewogICAgICAgIGUgPSBodWxsWyhfaHVsbEluZGV4W2ldICsgMSkgJSBodWxsLmxlbmd0aF07CiAgICAgICAgaWYgKGUgIT09IHQpIHsKICAgICAgICAgIGlmIChwb3coeCAtIHBvaW50c1tlICogMl0sIDIpICsgcG93KHkgLSBwb2ludHNbZSAqIDIgKyAxXSwgMikgPCBkYykgcmV0dXJuIGU7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9IHdoaWxlIChlICE9PSBlMCk7CiAgICByZXR1cm4gYzsKICB9CiAgcmVuZGVyKGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgewogICAgICBwb2ludHMsCiAgICAgIGhhbGZlZGdlcywKICAgICAgdHJpYW5nbGVzCiAgICB9ID0gdGhpczsKICAgIGZvciAobGV0IGkgPSAwLCBuID0gaGFsZmVkZ2VzLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgICBjb25zdCBqID0gaGFsZmVkZ2VzW2ldOwogICAgICBpZiAoaiA8IGkpIGNvbnRpbnVlOwogICAgICBjb25zdCB0aSA9IHRyaWFuZ2xlc1tpXSAqIDI7CiAgICAgIGNvbnN0IHRqID0gdHJpYW5nbGVzW2pdICogMjsKICAgICAgY29udGV4dC5tb3ZlVG8ocG9pbnRzW3RpXSwgcG9pbnRzW3RpICsgMV0pOwogICAgICBjb250ZXh0LmxpbmVUbyhwb2ludHNbdGpdLCBwb2ludHNbdGogKyAxXSk7CiAgICB9CiAgICB0aGlzLnJlbmRlckh1bGwoY29udGV4dCk7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICByZW5kZXJQb2ludHMoY29udGV4dCwgcikgewogICAgaWYgKHIgPT09IHVuZGVmaW5lZCAmJiAoIWNvbnRleHQgfHwgdHlwZW9mIGNvbnRleHQubW92ZVRvICE9PSAiZnVuY3Rpb24iKSkgciA9IGNvbnRleHQsIGNvbnRleHQgPSBudWxsOwogICAgciA9IHIgPT0gdW5kZWZpbmVkID8gMiA6ICtyOwogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIHBvaW50cwogICAgfSA9IHRoaXM7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBuOyBpICs9IDIpIHsKICAgICAgY29uc3QgeCA9IHBvaW50c1tpXSwKICAgICAgICB5ID0gcG9pbnRzW2kgKyAxXTsKICAgICAgY29udGV4dC5tb3ZlVG8oeCArIHIsIHkpOwogICAgICBjb250ZXh0LmFyYyh4LCB5LCByLCAwLCB0YXUpOwogICAgfQogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgcmVuZGVySHVsbChjb250ZXh0KSB7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IHsKICAgICAgaHVsbCwKICAgICAgcG9pbnRzCiAgICB9ID0gdGhpczsKICAgIGNvbnN0IGggPSBodWxsWzBdICogMiwKICAgICAgbiA9IGh1bGwubGVuZ3RoOwogICAgY29udGV4dC5tb3ZlVG8ocG9pbnRzW2hdLCBwb2ludHNbaCArIDFdKTsKICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbjsgKytpKSB7CiAgICAgIGNvbnN0IGggPSAyICogaHVsbFtpXTsKICAgICAgY29udGV4dC5saW5lVG8ocG9pbnRzW2hdLCBwb2ludHNbaCArIDFdKTsKICAgIH0KICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICBodWxsUG9seWdvbigpIHsKICAgIGNvbnN0IHBvbHlnb24gPSBuZXcgUG9seWdvbigpOwogICAgdGhpcy5yZW5kZXJIdWxsKHBvbHlnb24pOwogICAgcmV0dXJuIHBvbHlnb24udmFsdWUoKTsKICB9CiAgcmVuZGVyVHJpYW5nbGUoaSwgY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIHBvaW50cywKICAgICAgdHJpYW5nbGVzCiAgICB9ID0gdGhpczsKICAgIGNvbnN0IHQwID0gdHJpYW5nbGVzW2kgKj0gM10gKiAyOwogICAgY29uc3QgdDEgPSB0cmlhbmdsZXNbaSArIDFdICogMjsKICAgIGNvbnN0IHQyID0gdHJpYW5nbGVzW2kgKyAyXSAqIDI7CiAgICBjb250ZXh0Lm1vdmVUbyhwb2ludHNbdDBdLCBwb2ludHNbdDAgKyAxXSk7CiAgICBjb250ZXh0LmxpbmVUbyhwb2ludHNbdDFdLCBwb2ludHNbdDEgKyAxXSk7CiAgICBjb250ZXh0LmxpbmVUbyhwb2ludHNbdDJdLCBwb2ludHNbdDIgKyAxXSk7CiAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgKnRyaWFuZ2xlUG9seWdvbnMoKSB7CiAgICBjb25zdCB7CiAgICAgIHRyaWFuZ2xlcwogICAgfSA9IHRoaXM7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHRyaWFuZ2xlcy5sZW5ndGggLyAzOyBpIDwgbjsgKytpKSB7CiAgICAgIHlpZWxkIHRoaXMudHJpYW5nbGVQb2x5Z29uKGkpOwogICAgfQogIH0KICB0cmlhbmdsZVBvbHlnb24oaSkgewogICAgY29uc3QgcG9seWdvbiA9IG5ldyBQb2x5Z29uKCk7CiAgICB0aGlzLnJlbmRlclRyaWFuZ2xlKGksIHBvbHlnb24pOwogICAgcmV0dXJuIHBvbHlnb24udmFsdWUoKTsKICB9Cn0KZnVuY3Rpb24gZmxhdEFycmF5KHBvaW50cywgZngsIGZ5LCB0aGF0KSB7CiAgY29uc3QgbiA9IHBvaW50cy5sZW5ndGg7CiAgY29uc3QgYXJyYXkgPSBuZXcgRmxvYXQ2NEFycmF5KG4gKiAyKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47ICsraSkgewogICAgY29uc3QgcCA9IHBvaW50c1tpXTsKICAgIGFycmF5W2kgKiAyXSA9IGZ4LmNhbGwodGhhdCwgcCwgaSwgcG9pbnRzKTsKICAgIGFycmF5W2kgKiAyICsgMV0gPSBmeS5jYWxsKHRoYXQsIHAsIGksIHBvaW50cyk7CiAgfQogIHJldHVybiBhcnJheTsKfQpmdW5jdGlvbiogZmxhdEl0ZXJhYmxlKHBvaW50cywgZngsIGZ5LCB0aGF0KSB7CiAgbGV0IGkgPSAwOwogIGZvciAoY29uc3QgcCBvZiBwb2ludHMpIHsKICAgIHlpZWxkIGZ4LmNhbGwodGhhdCwgcCwgaSwgcG9pbnRzKTsKICAgIHlpZWxkIGZ5LmNhbGwodGhhdCwgcCwgaSwgcG9pbnRzKTsKICAgICsraTsKICB9Cn0KCi8qKg0KICog6Ieq54S26YSw6bue5YWn5o+S5rOVKE5hdHVyYWwgTmVpZ2hib3IgSW50ZXJwb2xhdGlvbinlhafmj5Lpu57mlbjlgLwNCiAqDQogKiBBIEZhc3QgYW5kIEFjY3VyYXRlIEFsZ29yaXRobSBmb3IgTmF0dXJhbCBOZWlnaGJvciBJbnRlcnBvbGF0aW9uDQogKiBodHRwczovL2d3bHVjYXN0cmlnLmdpdGh1Yi5pby9UaW5mb3VyRG9jcy9OYXR1cmFsTmVpZ2hib3JUaW5mb3VyQWxnb3JpdGhtL2luZGV4Lmh0bWwNCiAqDQogKiBBbiBJbnRyb2R1Y3Rpb24gdG8gTmF0dXJhbCBOZWlnaGJvciBJbnRlcnBvbGF0aW9uDQogKiBodHRwczovL2d3bHVjYXN0cmlnLmdpdGh1Yi5pby9UaW5mb3VyRG9jcy9OYXR1cmFsTmVpZ2hib3JJbnRyby9pbmRleC5odG1sDQogKg0KICogW3dpa2ldTmF0dXJhbCBuZWlnaGJvciBpbnRlcnBvbGF0aW9uDQogKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9OYXR1cmFsX25laWdoYm9yX2ludGVycG9sYXRpb24NCiAqDQogKiBOYXR1cmFsIG5laWdoYm9yIGludGVycG9sYXRpb24NCiAqIGh0dHBzOi8vb2JzZXJ2YWJsZWhxLmNvbS9Aa2FybGVyc3MvbmF0dXJhbC1uZWlnaGJvci1pbnRlcnBvbGF0aW9uDQogKg0KICogZDMtZGVsYXVuYXkNCiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1kZWxhdW5heQ0KICoNCiAqIG9ubGluZSB0ZXN0DQogKiBodHRwczovL2NhcnRvZ3JhcGh5LXBsYXlncm91bmQuZ2l0bGFiLmlvL3BsYXlncm91bmRzL3RyaWFuZ3VsYXRpb24tZGVsYXVuYXktdm9yb25vaS1kaWFncmFtLw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ludGVycDJOYXR1cmFsTmVpZ2hib3IudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwc1NyYyDovLjlhaXkuozntq3luqfmqJnliqDop4DmuKzmlbjmk5rpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MSx6OnoxfSx7eDp4Mix5OnkyLHo6ejJ9LC4uLl3pu57nianku7bkuYvpmaPliJcNCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBwc1RhciDovLjlhaXkuozntq3luqfmqJnpu57pmaPliJfmiJbpu57nianku7bvvIzngrpbe3g6eDEseTp5MX0se3g6eDIseTp5Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIl++8jOaIlnt4OngxLHk6eTF96bue54mp5Lu2DQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7bkuYt45qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu25LmLeeashOS9jeWtl+S4su+8jOeCuuW6p+aome+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5Wj0neiddIOi8uOWFpem7nueJqeS7tuS5i3rmrITkvY3lrZfkuLLvvIzngrrop4DmuKzlgLzvvIzpoJDoqK0neicNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LnNjYWxlPTFdIOi8uOWFpeato+imj+WMluevhOWcjeaVuOWAvO+8jOWboOiZleeQhuWkmumCiuW9ouaZguacieaVuOWAvOWuueioseiqpOW3ru+8jOaVhemgiOmAmumBjue4ruaUvuWAvOWfn+S+hua4m+WwkeWVj+mhjO+8jOmgkOiorTHmmK/mraPopo/ljJYw6IezMeS5i+mWk++8jOS9v+eUqHNjYWxlWFnliYfmmK/mraPopo/ljJbngrow6Iezc2NhbGVYWeS5i+mWk++8jOmgkOiorTENCiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IOWbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpeeZvOeUn+mMr+iqpOWJh+WbnuWCs+mMr+iqpOioiuaBr+eJqeS7tg0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCBwDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTI0MywNCiAqICAgICB5OiAxMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAxMjQzLCB5OiAxMjA3LCB6OiBudWxsIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IG51bGwsIHk6IDIwMSwgejogMTIyIH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiBsZXQgZnVuSW50ZXJwRnJhZ21lbnQgPSAobXNnKSA9PiB7DQogKiAgICAgLy8gY29uc29sZS5sb2coJ2Z1bkludGVycEZyYWdtZW50JywgbXNnKQ0KICogICAgIHJldHVybiBtc2cudiAvL+mgkOioreWbnuWCs21zZy52LCDkuInop5LlvaLkuInop5Lpu57lkITpu55254K6ckEqeiwg5pWF5LiJ6bue5LmLckHlkIjngroxLCDmjIflrprlhafmj5LlgLx654K65LiJ6KeS6bueduS5i+e4veWSjCh2MSx2Mix2MykNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwLCB7IGZ1bkludGVycEZyYWdtZW50IH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogbnVsbCwgeTogMjAxLCB6OiAxMjIgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTI0MywNCiAqICAgICB5OiAxMjA3LA0KICogfQ0KICogbGV0IGZ1bkludGVycEZyYWdtZW50Tm9Vc2UgPSAobXNnKSA9PiB7DQogKiAgICAgLy8gY29uc29sZS5sb2coJ2Z1bkludGVycEZyYWdtZW50Tm9Vc2UnLCBtc2cpDQogKiAgICAgcmV0dXJuIG1zZy52IC8v6aCQ6Kit5Zue5YKzbXNnLnYsIOatpOiZleWboOWFp+aPkum7nuaWvOWOn+Wni+m7nuaJgOW9ouaIkOacgOWwj+WHuOWkmumCiuW9ouS5i+Wkliwg5pWF54Sh5rOV5YWn5o+SLCDkuqbkuI3mnIPlkbzlj6tmdW5JbnRlcnBGcmFnbWVudA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsgZnVuSW50ZXJwRnJhZ21lbnQ6IGZ1bkludGVycEZyYWdtZW50Tm9Vc2UgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDEyNDMsIHk6IDEyMDcsIHo6IG51bGwgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogbnVsbCwgeTogMjAxLCB6OiAxMjIgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIGxldCBmdW5JbnRlcnBGcmFnbWVudHMgPSAobXNnKSA9PiB7DQogKiAgICAgLy8gY29uc29sZS5sb2coJ2Z1bkludGVycEZyYWdtZW50cycsIG1zZykNCiAqICAgICAvLyBsZXQgdiA9IHBzWzBdLnYgKyBwc1sxXS52ICsgcHNbMl0udg0KICogICAgIHJldHVybiBtc2cudiAvL+mgkOioreWbnuWCs21zZy52LCDkuInop5LlvaLkuInop5Lpu57ngrptc2cucHMsIOWQhOm7nnbngrpyQSp6LCDmlYXkuInpu57kuYtyQeWQiOeCujEsIOaMh+WumuWFp+aPkuWAvHrngrrkuInop5Lpu5525LmL57i95ZKMKHYxLHYyLHYzKQ0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsgZnVuSW50ZXJwRnJhZ21lbnRzIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI4MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI4MywgeTogMjA3LCB6OiAxMTQuNDMwNDA0MjE5NTE5MDggfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDExNjAsDQogKiAgICAgeTogMzgwLA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAxMTYwLCB5OiAzODAsIHo6IG51bGwgfQ0KICoNCiAqIHBzID0gW3sgYTogMjQzLCBiOiAyMDYsIGM6IDk1IH0sIHsgYTogMjMzLCBiOiAyMjUsIGM6IDE0NiB9LCB7IGE6IDIxLCBiOiAzMjUsIGM6IDIyIH0sIHsgYTogOTUzLCBiOiAyOCwgYzogMjIzIH0sIHsgYTogMTA5MiwgYjogMjkwLCBjOiAzOSB9LCB7IGE6IDc0NCwgYjogMjAwLCBjOiAxOTEgfSwgeyBhOiAxNzQsIGI6IDMsIGM6IDIyIH0sIHsgYTogNTM3LCBiOiAzNjgsIGM6IDI0OSB9LCB7IGE6IDExNTEsIGI6IDM3MSwgYzogODYgfSwgeyBhOiA4MTQsIGI6IDI1MiwgYzogMTI1IH1dDQogKiBwID0gew0KICogICAgIGE6IDI0MywNCiAqICAgICBiOiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCwgeyBrZXlYOiAnYScsIGtleVk6ICdiJywga2V5WjogJ2MnIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyBhOiAyNDMsIGI6IDIwNywgYzogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gWw0KICogICAgIHsNCiAqICAgICAgICAgeDogMjQzLA0KICogICAgICAgICB5OiAyMDcsDQogKiAgICAgfSwNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI4MywNCiAqICAgICAgICAgeTogMjA3LA0KICogICAgIH0sDQogKiBdDQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0sDQogKiAvLyAgIHsgeDogMjgzLCB5OiAyMDcsIHo6IDExNC40MzA0MDQyMTk1MTkwOCB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyB4OiAwLjAwMDI0MywgeTogMC4wMDAyMDYsIHo6IDk1IH0sIHsgeDogMC4wMDAyMzMsIHk6IDAuMDAwMjI1LCB6OiAxNDYgfSwgeyB4OiAwLjAwMDAyMSwgeTogMC4wMDAzMjUsIHo6IDIyIH0sIHsgeDogMC4wMDA5NTMsIHk6IDAuMDAwMDI4LCB6OiAyMjMgfSwgeyB4OiAwLjAwMTA5MiwgeTogMC4wMDAyOSwgejogMzkgfSwgeyB4OiAwLjAwMDc0NCwgeTogMC4wMDAyMDAsIHo6IDE5MSB9LCB7IHg6IDAuMDAwMTc0LCB5OiAwLjAwMDAwMywgejogMjIgfSwgeyB4OiAwLjAwMDUzNywgeTogMC4wMDAzNjgsIHo6IDI0OSB9LCB7IHg6IDAuMDAxMTUxLCB5OiAwLjAwMDM3MSwgejogODYgfSwgeyB4OiAwLjAwMDgxNCwgeTogMC4wMDAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAwLjAwMDI0MywNCiAqICAgICB5OiAwLjAwMDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMC4wMDAyNDMsIHk6IDAuMDAwMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4Njc4IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsgc2NhbGU6IDEwMDAgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4Njg1NSB9DQogKg0KICovCmZ1bmN0aW9uIGludGVycDJOYXR1cmFsTmVpZ2hib3IocHNTcmMsIHBzVGFyLCBvcHQgPSB7fSkgewogIC8vY2hlY2sgcHNTcmMKICBpZiAoIWlzZWFycihwc1NyYykpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzU3JjIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXknCiAgICB9OwogIH0KCiAgLy9jaGVjayBwc1RhcgogIGlmICghaXNlb2JqKHBzVGFyKSAmJiAhaXNlYXJyKHBzVGFyKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNUYXIgaXMgbm90IGFuIGVmZmVjdGl2ZSBvYmplY3Qgb3IgYXJyYXknCiAgICB9OwogIH0KCiAgLy9pc09uZQogIGxldCBpc09uZSA9IGlzZW9iaihwc1Rhcik7CiAgaWYgKGlzT25lKSB7CiAgICBwc1RhciA9IFtwc1Rhcl07CiAgfQoKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleVoKICBsZXQga2V5WiA9IGdldChvcHQsICdrZXlaJyk7CiAgaWYgKCFpc2VzdHIoa2V5WikpIHsKICAgIGtleVogPSAneic7CiAgfQoKICAvL3NjYWxlCiAgbGV0IHNjYWxlID0gZ2V0KG9wdCwgJ3NjYWxlJyk7CiAgaWYgKCFpc251bShzY2FsZSkpIHsKICAgIHNjYWxlID0gMTsKICB9CiAgc2NhbGUgPSBjZGJsKHNjYWxlKTsKCiAgLy9mdW5JbnRlcnBGcmFnbWVudAogIGxldCBmdW5JbnRlcnBGcmFnbWVudCA9IGdldChvcHQsICdmdW5JbnRlcnBGcmFnbWVudCcpOwogIGxldCB1c2VGdW5JbnRlcnBGcmFnbWVudCA9IGlzZnVuKGZ1bkludGVycEZyYWdtZW50KTsKCiAgLy9mdW5JbnRlcnBGcmFnbWVudHMKICBsZXQgZnVuSW50ZXJwRnJhZ21lbnRzID0gZ2V0KG9wdCwgJ2Z1bkludGVycEZyYWdtZW50cycpOwogIGxldCB1c2VGdW5JbnRlcnBGcmFnbWVudHMgPSBpc2Z1bihmdW5JbnRlcnBGcmFnbWVudHMpOwoKICAvL2tleUluZAogIGxldCBrZXlJbmQgPSAnaW5kJzsKCiAgLy9wdHNYWVp0b0FycgogIHBzU3JjID0gcHRzWFladG9BcnIocHNTcmMsIHsKICAgIGtleVgsCiAgICBrZXlZLAogICAga2V5WiwKICAgIGtleUluZAogIH0pOwoKICAvL2NoZWNrIHBzU3JjCiAgaWYgKHNpemUocHNTcmMpID09PSAwKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1NyYyBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KICAvLyBjb25zb2xlLmxvZygncHRzWFladG9BcnIgcHNTcmMnLCBwc1NyYykKCiAgLy9wdHNYWXRvQXJyCiAgcHNUYXIgPSBwdHNYWXRvQXJyKHBzVGFyLCB7CiAgICBrZXlYLAogICAga2V5WSwKICAgIGtleUluZAogIH0pOwoKICAvL2NoZWNrIHBzVGFyCiAgaWYgKHNpemUocHNUYXIpID09PSAwKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1RhciBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KICAvLyBjb25zb2xlLmxvZygncHRzWFl0b0FyciBwc1RhcicsIHBzVGFyKQoKICAvL2ludGVycDJOb3JtYWxpemUKICBsZXQgaXRubSA9IGludGVycDJOb3JtYWxpemUocHNTcmMsIHsKICAgIGtleUluZCwKICAgIHNjYWxlCiAgfSk7CiAgLy8gY29uc29sZS5sb2coJ2l0bm0uc3QnLCBpdG5tLnN0KQogIC8vIGNvbnNvbGUubG9nKCdpdG5tLnBzTWluTWF4JywgaXRubS5wc01pbk1heCkKICBwc1NyYyA9IGl0bm0ucHM7IC8v6KSH5a+r5q2j6KaP5YyW5pW45pOaCiAgbGV0IG52ID0gaXRubS5udjsKICBsZXQgaW52ID0gaXRubS5pbnY7CiAgLy8gY29uc29sZS5sb2coJ2ludGVycDJOb3JtYWxpemUgcHNTcmMnLCBwc1NyYykKCiAgLy9wc1NyY0l0cgogIGxldCBwc1NyY0l0ciA9IFsuLi5wc1NyY107CgogIC8vcHNTcmNPcmkKICBsZXQgcHNTcmNPcmkgPSBbLi4ucHNTcmNdOwoKICAvL2twS25vd24KICBsZXQga3BLbm93biA9IHt9OwogIGZvckVhY2gocHNTcmMsIHYgPT4gewogICAgbGV0IGsgPSBgJHt2Lnh9LSR7di55fWA7IC8veCx55bey57aT6KKr5q2j6KaP5YyWCiAgICBrcEtub3duW2tdID0gdi56OyAvL3gseSx65bey57aT6KKr5q2j6KaP5YyWCiAgfSk7CgogIC8vaW50RG55CiAgbGV0IGludERueSA9IERlbGF1bmF5LmZyb20ocHNTcmNPcmksIGQgPT4gZC54LCBkID0+IGQueSk7IC8veCx55bey57aT6KKr5q2j6KaP5YyWCgogIC8vIC8vaHBnLCDljp/lp4vmlbjmk5rlvaLmiJDmnIDlpJbmoYbpgornlYwKICAvLyBsZXQgaHBnID0gaW50RG55Lmh1bGxQb2x5Z29uKCkKICAvLyAvLyBjb25zb2xlLmxvZygnaW50RG55Lmh1bGxQb2x5Z29uJywgaHBnKQoKICAvL3Zib3gKICBsZXQgdmJveCA9IFswLCAwLCBzY2FsZSwgc2NhbGVdOwoKICAvL2luaVZvcgogIGxldCBpbmlWb3IgPSBpbnREbnkudm9yb25vaSh2Ym94KTsKICAvLyBjb25zb2xlLmxvZygnaW5pVm9yJywgaW5pVm9yKQoKICAvL2FkZFBvaW50Q29yZQogIGxldCBhZGRQb2ludENvcmUgPSAoZGF0YSwgeCwgeSwgaW5kVGFyKSA9PiB7CiAgICAvL3BzU3JjVGVtcAogICAgbGV0IHBzU3JjVGVtcCA9IFsuLi5wc1NyY107CgogICAgLy9uZXdJdGVtCiAgICBsZXQgbmV3SXRlbSA9IHsKICAgICAgeCwKICAgICAgeSwKICAgICAgejogMAogICAgfTsgLy94LHkseuW3sue2k+iiq+ato+imj+WMlgoKICAgIC8vcHVzaAogICAgcHNTcmNUZW1wLnB1c2gobmV3SXRlbSk7CiAgICBkYXRhLnB1c2gobmV3SXRlbSk7CgogICAgLy9wb3N0Vm9yCiAgICBsZXQgcG9zdFZvciA9IERlbGF1bmF5LmZyb20ocHNTcmNUZW1wLCBkID0+IGQueCwgZCA9PiBkLnkpLnZvcm9ub2kodmJveCk7IC8veCx55bey57aT6KKr5q2j6KaP5YyWCiAgICAvLyBjb25zb2xlLmxvZygncG9zdFZvcicsIHBvc3RWb3IpCgogICAgLy9uZXdJZHgKICAgIGxldCBuZXdJZHggPSBwc1NyY1RlbXAubGVuZ3RoIC0gMTsKICAgIC8vIGNvbnNvbGUubG9nKCduZXdJZHgnLCBuZXdJZHgpCgogICAgLy9wZ3NRdWVyeQogICAgbGV0IHBnc1F1ZXJ5ID0gcG9zdFZvci5jZWxsUG9seWdvbihuZXdJZHgpOwogICAgLy8gY29uc29sZS5sb2coJ3Bnc1F1ZXJ5JywgcGdzUXVlcnkpCgogICAgLy9hcmVhUXVlcnkKICAgIGxldCBhcmVhUXVlcnkgPSBnZXRBcmVhUG9seWdvbihwZ3NRdWVyeSk7CiAgICAvLyBjb25zb2xlLmxvZygnYXJlYVF1ZXJ5JywgYXJlYVF1ZXJ5KQoKICAgIC8vbmV3UG9pbnRWYWwKICAgIGxldCBuZXdQb2ludFZhbCA9IG51bGw7CiAgICB7CiAgICAgIC8vbmVpZ2hib3JJbmRpY2VzCiAgICAgIGxldCBuZWlnaGJvckluZGljZXMgPSBbXTsKICAgICAgLy8gZm9yIChsZXQgaSBvZiBwb3N0Vm9yLmRlbGF1bmF5Lm5laWdoYm9ycyhuZXdJZHgpKSB7IC8v5Zug54K6cG9zdFZvci5kZWxhdW5heS5uZWlnaGJvcnPmmK9nZW5lcmF0b3IsIOiAg+aFruimgeaUr+aPtGllMTHlvpfkvb/nlKh3aGlsZeiIh25leHToroDlj5YKICAgICAgLy8gICAgIG5laWdoYm9ySW5kaWNlcy5wdXNoKGkpCiAgICAgIC8vIH0KICAgICAgbGV0IHNxID0gcG9zdFZvci5kZWxhdW5heS5uZWlnaGJvcnMobmV3SWR4KTsKICAgICAgLy8gY29uc29sZS5sb2coYHNxYCwgc3EpCiAgICAgIGxldCBuZXh0ID0gc3EubmV4dCgpOwogICAgICB3aGlsZSAoIW5leHQuZG9uZSkgewogICAgICAgIGxldCB2ID0gbmV4dC52YWx1ZTsKICAgICAgICBuZWlnaGJvckluZGljZXMucHVzaCh2KTsKICAgICAgICBuZXh0ID0gc3EubmV4dCgpOwogICAgICB9CiAgICAgIC8vIGNvbnNvbGUubG9nKCduZWlnaGJvckluZGljZXMnLCBuZWlnaGJvckluZGljZXMpCgogICAgICAvL3N1YlZhbHVlcwogICAgICBsZXQgc3ViVmFsdWVzID0gbWFwKG5laWdoYm9ySW5kaWNlcywgaWR4ID0+IHsKICAgICAgICAvLyBjb25zb2xlLmxvZygnaWR4JywgaWR4KQoKICAgICAgICAvL3BnczEsIHBnczIKICAgICAgICBsZXQgcGdzMSA9IFtwZ3NRdWVyeV07CiAgICAgICAgbGV0IHBnczIgPSBbaW5pVm9yLmNlbGxQb2x5Z29uKGlkeCldOwogICAgICAgIC8vIGNvbnNvbGUubG9nKCdwZ3MxJywgcGdzMSwgJ3BnczInLCBwZ3MyKQoKICAgICAgICAvL2ludGVyc2VjdAogICAgICAgIGxldCBwZ3NJbnRzID0gW107CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHBnc0ludHMgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIpOwogICAgICAgICAgLy8gY29uc29sZS5sb2coJ3Bnc0ludHMnLCBwZ3NJbnRzKQogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgLy9jb25zb2xlLmxvZygncGdzMScsIHBnczEpCiAgICAgICAgICAvL2NvbnNvbGUubG9nKCdwZ3MyJywgcGdzMikKICAgICAgICAgIC8vY29uc29sZS5sb2coZXJyKQogICAgICAgIH0KCiAgICAgICAgLy9hcmVhSW50cwogICAgICAgIGxldCBhcmVhSW50cyA9IDA7CiAgICAgICAgaWYgKHNpemUocGdzSW50cykgPT09IDEpIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGFyZWFJbnRzID0gZ2V0QXJlYVBvbHlnb24ocGdzSW50c1swXSk7CiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ2dldEFyZWFQb2x5Z29uJyxkMy5nZXRBcmVhUG9seWdvbihpcy5yZWdpb25zWzBdKSxnZXRBcmVhUG9seWdvbihpcy5yZWdpb25zWzBdKSkKICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICBjb25zb2xlLmxvZygncGdzSW50cycsIHBnc0ludHMpOwogICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gewogICAgICAgICAgaWE6IGFyZWFJbnRzLAogICAgICAgICAgaWR4CiAgICAgICAgfTsKICAgICAgfSk7CiAgICAgIC8vIGNvbnNvbGUubG9nKCdzdWJWYWx1ZXMnLCBzdWJWYWx1ZXMpCgogICAgICAvL2NoZWNrCiAgICAgIHsKICAgICAgICAvL24KICAgICAgICBsZXQgbiA9IHNpemUoc3ViVmFsdWVzKTsKCiAgICAgICAgLy9pYXMKICAgICAgICBsZXQgaWFzID0gbWFwKHN1YlZhbHVlcywgJ2lhJyk7CgogICAgICAgIC8vcgogICAgICAgIGxldCByID0gc3VtJDEoaWFzKTsKCiAgICAgICAgLy9jaGVjawogICAgICAgIGlmIChyICE9PSBhcmVhUXVlcnkpIHsKICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBpYee4veWSjOacieaZguacg+S4jeetieaWvGFyZWFRdWVyeWApCiAgICAgICAgICAvL2lh57i95ZKM5pyJ5pmC5pyD5LiN562J5pa8YXJlYVF1ZXJ5CgogICAgICAgICAgaWYgKGFyZWFRdWVyeSA+IDAgJiYgciA+IDApIHsKICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYOiLpWlh57i95ZKM6IiHYXJlYVF1ZXJ56YO9PjAsIOWJh+iqv+aVtOWQhGlh5L2/5YW257i95ZKM57iu5pS+6IezYXJlYVF1ZXJ5YCkKICAgICAgICAgICAgLy/oi6VpYee4veWSjOiIh2FyZWFRdWVyeemDvT4wLCDliYfoqr/mlbTlkIRpYeS9v+WFtue4veWSjOe4ruaUvuiHs2FyZWFRdWVyeQogICAgICAgICAgICBsZXQgcyA9IGFyZWFRdWVyeSAvIHI7CiAgICAgICAgICAgIHN1YlZhbHVlcyA9IG1hcChzdWJWYWx1ZXMsIHN2ID0+IHsKICAgICAgICAgICAgICBzdi5pYSAqPSBzOwogICAgICAgICAgICAgIHJldHVybiBzdjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9IGVsc2UgaWYgKGFyZWFRdWVyeSA9PT0gMCAmJiByID4gMCkgewogICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhg6IulYXJlYVF1ZXJ554K6MOS4lGlh57i95ZKMPjAsIOWJh+S9v+eUqGlh57i95ZKM54K6YXJlYVF1ZXJ5YCkKICAgICAgICAgICAgLy/oi6VhcmVhUXVlcnnngrow5LiUaWHnuL3lkow+MCwg5YmH5L2/55SoaWHnuL3lkozngrphcmVhUXVlcnkKICAgICAgICAgICAgYXJlYVF1ZXJ5ID0gcjsKICAgICAgICAgIH0gZWxzZSBpZiAoYXJlYVF1ZXJ5ID4gMCAmJiByID09PSAwKSB7CiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGDoi6VhcmVhUXVlcnk+MOS4lGlh57i95ZKMPTAsIOWJh+WBh+ioreWQhGlh54K65bmz5YiGYXJlYVF1ZXJ5YCkKICAgICAgICAgICAgLy/oi6VhcmVhUXVlcnk+MOS4lGlh57i95ZKMPTAsIOWJh+WBh+ioreWQhGlh54K65bmz5YiGYXJlYVF1ZXJ5CiAgICAgICAgICAgIGxldCBzID0gYXJlYVF1ZXJ5IC8gbjsKICAgICAgICAgICAgc3ViVmFsdWVzID0gbWFwKHN1YlZhbHVlcywgc3YgPT4gewogICAgICAgICAgICAgIHN2LmlhID0gczsKICAgICAgICAgICAgICByZXR1cm4gc3Y7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29uc29sZS5sb2coJ2FyZWFRdWVyeScsIGFyZWFRdWVyeSk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzdW0oaWFzKScsIHIpOwogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FyZWFRdWVyeSE9PXN1bShpYXMpICYmIChhcmVhUXVlcnk8MCBvciBzdW0oaWFzKTwwKScpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoYXJlYVF1ZXJ5ID09PSAwKSB7CiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhg6IulYXJlYVF1ZXJ5PTDkuJRpYee4veWSjD0wLCDliYflgYfoqK1hcmVhUXVlcnnngroxLCDogIzlkIRpYeeCuuW5s+WIhjFgKQogICAgICAgICAgLy/oi6VhcmVhUXVlcnk9aWHnuL3lkow9MCwg5YmH5YGH6KitYXJlYVF1ZXJ554K6MSwg6ICM5ZCEaWHngrrlubPliIYxCiAgICAgICAgICBhcmVhUXVlcnkgPSAxOwogICAgICAgICAgbGV0IHMgPSAxIC8gbjsKICAgICAgICAgIHN1YlZhbHVlcyA9IG1hcChzdWJWYWx1ZXMsIHN2ID0+IHsKICAgICAgICAgICAgc3YuaWEgPSBzOwogICAgICAgICAgICByZXR1cm4gc3Y7CiAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKGFyZWFRdWVyeSA8IDApIHsKICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGDoi6VhcmVhUXVlcnk9aWHnuL3lkow8MCwg5YmH5aCx6YyvYCkKICAgICAgICAgIC8v6IulYXJlYVF1ZXJ5PWlh57i95ZKMPDAsIOWJh+WgsemMrwogICAgICAgICAgY29uc29sZS5sb2coJ2FyZWFRdWVyeScsIGFyZWFRdWVyeSk7CiAgICAgICAgICBjb25zb2xlLmxvZygnc3VtKGlhcyknLCByKTsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXJlYVF1ZXJ5PDAgJiYgc3VtKGlhcyk8MCcpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy9uZXdQb2ludFZhbHMKICAgICAgbGV0IG5ld1BvaW50VmFscyA9IFtdOwogICAgICBmb3JFYWNoKHN1YlZhbHVlcywgbyA9PiB7CiAgICAgICAgLy9yQSwgeiwgdgogICAgICAgIGxldCByQSA9IG8uaWEgLyBhcmVhUXVlcnk7CiAgICAgICAgbGV0IHogPSBkYXRhW28uaWR4XS56OyAvL3gseSx65bey57aT6KKr5q2j6KaP5YyWCiAgICAgICAgbGV0IHYgPSByQSAqIHo7CiAgICAgICAgLy8gY29uc29sZS5sb2coJ3N1YlZhbHVlJywgJ3JBJywgckEsICdvLmlkeCcsIG8uaWR4LCAneicsIHosICd2JywgdikKCiAgICAgICAgLy91c2VGdW5JbnRlcnBGcmFnbWVudAogICAgICAgIGlmICh1c2VGdW5JbnRlcnBGcmFnbWVudCkgewogICAgICAgICAgdiA9IGZ1bkludGVycEZyYWdtZW50KHsKICAgICAgICAgICAgdiwKICAgICAgICAgICAgYXJlYTogby5pYSwKICAgICAgICAgICAgYXJlYVRvdGFsOiBhcmVhUXVlcnksCiAgICAgICAgICAgIGFyZWFSYXRpbzogckEsCiAgICAgICAgICAgIHosCiAgICAgICAgICAgIGluZFNyYzogby5pZHgsCiAgICAgICAgICAgIGluZFRhcgogICAgICAgICAgICAvLyBkYXRhLAogICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvL3AKICAgICAgICBsZXQgcCA9IHsKICAgICAgICAgIHYsCiAgICAgICAgICBhcmVhOiBvLmlhLAogICAgICAgICAgYXJlYVRvdGFsOiBhcmVhUXVlcnksCiAgICAgICAgICBhcmVhUmF0aW86IHJBLAogICAgICAgICAgeiwKICAgICAgICAgIGluZFNyYzogby5pZHgsCiAgICAgICAgICBpbmRUYXIKICAgICAgICB9OwoKICAgICAgICAvL3B1c2gKICAgICAgICBuZXdQb2ludFZhbHMucHVzaChwKTsKICAgICAgfSk7CgogICAgICAvL25ld1BvaW50VmFsCiAgICAgIGxldCB2dCA9IHN1bSQxKG1hcChuZXdQb2ludFZhbHMsICd2JykpOwogICAgICBpZiAodXNlRnVuSW50ZXJwRnJhZ21lbnRzKSB7CiAgICAgICAgdnQgPSBmdW5JbnRlcnBGcmFnbWVudHMoewogICAgICAgICAgcHM6IG5ld1BvaW50VmFscywKICAgICAgICAgIHY6IHZ0LAogICAgICAgICAgaW5kVGFyLAogICAgICAgICAgZnVuSW52OiB2diA9PiB7CiAgICAgICAgICAgIHJldHVybiBpbnYodnYsIDIpOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICAgIG5ld1BvaW50VmFsID0gdnQ7CgogICAgICAvLyBpZiAoaXNOYU4obmV3UG9pbnRWYWwpKSB7CiAgICAgIC8vICAgICBjb25zb2xlLmxvZygnaXNOYU4obmV3UG9pbnRWYWwpJywgc3ViVmFsdWVzLCAnYXJlYVF1ZXJ5JywgYXJlYVF1ZXJ5KQogICAgICAvLyB9CiAgICAgIC8vIGNvbnNvbGUubG9nKGBhcmVhUXVlcnlbJHthcmVhUXVlcnl9XSA+IDBgLCAnbmV3UG9pbnRWYWwnLCBuZXdQb2ludFZhbCkKICAgIH0KCiAgICAvL3VwZGF0ZSBuZXdQb2ludFZhbAogICAgZGF0YVtkYXRhLmxlbmd0aCAtIDFdLnogPSBuZXdQb2ludFZhbDsgLy94LHkseuW3sue2k+iiq+ato+imj+WMlgoKICAgIHJldHVybiBuZXdQb2ludFZhbDsKICB9OwoKICAvL2FkZFBvaW50CiAgbGV0IGFkZFBvaW50ID0gKGRhdGEsIHgsIHksIGluZFRhcikgPT4gewogICAgLy9yCiAgICBsZXQgcjsKICAgIHRyeSB7CiAgICAgIHIgPSBhZGRQb2ludENvcmUoZGF0YSwgeCwgeSwgaW5kVGFyKTsKICAgIH0gY2F0Y2ggKGVycikgewogICAgICBjb25zb2xlLmxvZyhlcnIpOwogICAgICByID0gbnVsbDsKICAgICAgZGF0YS5wb3AoKTsKICAgIH0KICAgIHJldHVybiByOwogIH07CgogIC8vZ2V0TnoKICBsZXQgZ2V0TnogPSAobngsIG55LCBpbmRUYXIpID0+IHsKICAgIC8vY2hlY2sKICAgIGxldCBrID0gYCR7bnh9LSR7bnl9YDsgLy94LHnlt7LntpPooqvmraPopo/ljJYKICAgIGlmIChoYXNrZXkoa3BLbm93biwgaykpIHsKICAgICAgcmV0dXJuIGtwS25vd25ba107CiAgICB9CgogICAgLy9jaGVjawogICAgaWYgKG54IDwgdmJveFswXSB8fCBueCA+IHZib3hbMl0gfHwgbnkgPCB2Ym94WzFdIHx8IG55ID4gdmJveFszXSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvL3ByZWRpY3QKICAgIGxldCBueiA9IGFkZFBvaW50KHBzU3JjSXRyLCBueCwgbnksIGluZFRhcik7CgogICAgLy9zYXZlCiAgICBrcEtub3duW2tdID0gbno7CiAgICByZXR1cm4gbno7CiAgfTsKCiAgLy9pdHYKICBsZXQgaXR2ID0gKHAsIGluZFRhcikgPT4gewogICAgLy94LCBueAogICAgbGV0IHggPSBwLng7CiAgICBsZXQgbnggPSBudih4LCAneCcpOwogICAgaWYgKCFpc051bWJlcihueCkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG54WyR7bnh9XWApOyAvL3gseemgkOacn+mDveaYr+acieWAvAogICAgfQoKICAgIC8veSwgbnkKICAgIGxldCB5ID0gcC55OwogICAgbGV0IG55ID0gbnYoeSwgJ3knKTsKICAgIGlmICghaXNOdW1iZXIobnkpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBueVske255fV1gKTsgLy94LHnpoJDmnJ/pg73mmK/mnInlgLwKICAgIH0KCiAgICAvL256LCB6CiAgICBsZXQgbnogPSBnZXROeihueCwgbnksIGluZFRhcik7CiAgICBsZXQgeiA9IGludihueiwgJ3onKTsKICAgIGlmICghaXNOdW1iZXIoeikpIHsKICAgICAgeiA9IG51bGw7IC8veumgiOaUr+aPtOWPr+iDveeEoeazleWFp+aPkgogICAgfQoKICAgIC8vIGNvbnNvbGUubG9nKCd4JywgeCwgJ3knLCB5LCAneicsIHopCiAgICAvLyBjb25zb2xlLmxvZygnbngnLCBueCwgJ255JywgbnksICdueicsIG56KQoKICAgIC8vcgogICAgbGV0IHIgPSB7CiAgICAgIFtrZXlYXTogeCwKICAgICAgW2tleVldOiB5LAogICAgICBba2V5Wl06IHoKICAgIH07CiAgICByZXR1cm4gcjsKICB9OwoKICAvL3IKICBsZXQgcjsKICBpZiAoaXNPbmUpIHsKICAgIGxldCBwID0gcHNUYXJbMF07CiAgICByID0gaXR2KHAsIDApOwogIH0gZWxzZSB7CiAgICByID0gW107CiAgICBmb3JFYWNoKHBzVGFyLCAocCwgaW5kVGFyKSA9PiB7CiAgICAgIHIucHVzaChpdHYocCwgaW5kVGFyKSk7CiAgICB9KTsKICB9CiAgcmV0dXJuIHI7Cn0KCi8vZm9yayBmcm9tOiBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vb2VvNGIva3JpZ2luZy5qcy9tYXN0ZXIva3JpZ2luZy5qcwoKLy/nqbrplpPntbHoqIjliIbmnpDkuYvorornlbDmlbjnmoTnkIboq5bmqKHlnos6IGh0dHBzOi8vd3d3LnN1cGVyZ2VvdGVrLmNvbS90dy9tYW51YWxzL1NTQS90b3BpYzMyLmh0bQovL+WcqOepuumWk+WIhuaekOeahOWBh+ioreS5i+S4i++8jOebuOmEsOaEiOi/keeahOWFqem7nu+8jOWcqOebuOS8vOaIluaYr+ebuOmXnOeoi+W6puS4iuaHieaciei8g+W8t+eahOmXnOS/guOAguWPjeS5i++8jOiLpeWFqem7nueahOi3nembouaLieWkp++8jOWJh+WFtumWk+eahOebuOmXnOeoi+W6puaHieS5n+acg+WwseatpOmZjeS9juOAggovL+iAjOWNiuiuiueVsOWclu+8iFNlbWl2YXJpb2dyYW1z77yJ6IiH5YWx6K6K5pW477yIQ292YXJpYW5jZe+8ieeQhuirlueahOeZvOWxle+8jOWdh+aYr+eUqOmHj+a4rOi3nemboueahOS6kuebuOmXnOeoi+W6pu+8jOWNs+aYr+Wwh+atpOingOW/temAj+mBjuaWueeoi+W8j+eahOi9ieaPm+Wwh+WFtumHj+WMluOAggoKLy8gLy8gRXh0ZW5kIHRoZSBBcnJheSBjbGFzcwovLyBBcnJheS5wcm90b3R5cGUubWF4ID0gZnVuY3Rpb24oKSB7Ci8vICAgICByZXR1cm4gTWF0aC5tYXguYXBwbHkobnVsbCwgdGhpcykKLy8gfQovLyBBcnJheS5wcm90b3R5cGUubWluID0gZnVuY3Rpb24oKSB7Ci8vICAgICByZXR1cm4gTWF0aC5taW4uYXBwbHkobnVsbCwgdGhpcykKLy8gfQovLyBBcnJheS5wcm90b3R5cGUubWVhbiA9IGZ1bmN0aW9uKCkgewovLyAgICAgbGV0IGksIHN1bQovLyAgICAgZm9yIChpID0gMCwgc3VtID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHsKLy8gICAgICAgICBzdW0gKz0gdGhpc1tpXQovLyAgICAgfQovLyAgICAgcmV0dXJuIHN1bSAvIHRoaXMubGVuZ3RoCi8vIH0KLy8gQXJyYXkucHJvdG90eXBlLnBpcCA9IGZ1bmN0aW9uKHgsIHkpIHsKLy8gICAgIGxldCBpOyBsZXQgajsgbGV0IGMgPSBmYWxzZQovLyAgICAgZm9yIChpID0gMCwgaiA9IHRoaXMubGVuZ3RoIC0gMTsgaSA8IHRoaXMubGVuZ3RoOyBqID0gaSsrKSB7Ci8vICAgICAgICAgaWYgKCgodGhpc1tpXVsxXSA+IHkpICE9PSAodGhpc1tqXVsxXSA+IHkpKSAmJgovLyAgICAgICh4IDwgKHRoaXNbal1bMF0gLSB0aGlzW2ldWzBdKSAqICh5IC0gdGhpc1tpXVsxXSkgLyAodGhpc1tqXVsxXSAtIHRoaXNbaV1bMV0pICsgdGhpc1tpXVswXSkpIHsKLy8gICAgICBjID0gIWMKLy8gICAgICAgICB9Ci8vICAgICB9Ci8vICAgICByZXR1cm4gYwovLyB9CgpsZXQga3JpZ2luZyA9IHt9OwoKLy8gbGV0IHBpcCA9IGZ1bmN0aW9uKGFyciwgeCwgeSkgewovLyAgICAgbGV0IGkKLy8gICAgIGxldCBqCi8vICAgICBsZXQgYyA9IGZhbHNlCi8vICAgICBmb3IgKGkgPSAwLCBqID0gYXJyLmxlbmd0aCAtIDE7IGkgPCBhcnIubGVuZ3RoOyBqID0gaSsrKSB7Ci8vICAgICAgICAgaWYgKCgoYXJyW2ldWzFdID4geSkgIT09IChhcnJbal1bMV0gPiB5KSkgJiYKLy8gICAgICAgICAgKHggPCAoYXJyW2pdWzBdIC0gYXJyW2ldWzBdKSAqICh5IC0gYXJyW2ldWzFdKSAvIChhcnJbal1bMV0gLSBhcnJbaV1bMV0pICsgYXJyW2ldWzBdKSkgewovLyAgICAgICAgICAgICBjID0gIWMKLy8gICAgICAgICB9Ci8vICAgICB9Ci8vICAgICByZXR1cm4gYwovLyB9CgpsZXQgY3JlYXRlQXJyYXlXaXRoVmFsdWVzID0gZnVuY3Rpb24gKHZhbHVlLCBuKSB7CiAgbGV0IGFycmF5ID0gW107CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGFycmF5LnB1c2godmFsdWUpOwogIH0KICByZXR1cm4gYXJyYXk7Cn07CgovLyBNYXRyaXggYWxnZWJyYQpsZXQga3JpZ2luZ19tYXRyaXhfZGlhZyA9IGZ1bmN0aW9uIChjLCBuKSB7CiAgbGV0IFogPSBjcmVhdGVBcnJheVdpdGhWYWx1ZXMoMCwgbiAqIG4pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBaW2kgKiBuICsgaV0gPSBjOwogIHJldHVybiBaOwp9OwpsZXQga3JpZ2luZ19tYXRyaXhfdHJhbnNwb3NlID0gZnVuY3Rpb24gKFgsIG4sIG0pIHsKICBsZXQgaTsKICBsZXQgajsKICBsZXQgWiA9IEFycmF5KG0gKiBuKTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgbTsgaisrKSB7CiAgICAgIFpbaiAqIG4gKyBpXSA9IFhbaSAqIG0gKyBqXTsKICAgIH0KICB9CiAgcmV0dXJuIFo7Cn07CgovLyBsZXQga3JpZ2luZ19tYXRyaXhfc2NhbGUgPSBmdW5jdGlvbihYLCBjLCBuLCBtKSB7Ci8vICAgICBsZXQgaSwgagovLyAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewovLyAgICAgICAgIGZvciAoaiA9IDA7IGogPCBtOyBqKyspIHsKLy8gICAgICAgICAgICAgWFtpICogbSArIGpdICo9IGMKLy8gICAgICAgICB9Ci8vICAgICB9Ci8vIH0KCmxldCBrcmlnaW5nX21hdHJpeF9hZGQgPSBmdW5jdGlvbiAoWCwgWSwgbiwgbSkgewogIGxldCBpOwogIGxldCBqOwogIGxldCBaID0gQXJyYXkobiAqIG0pOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBtOyBqKyspIHsKICAgICAgWltpICogbSArIGpdID0gWFtpICogbSArIGpdICsgWVtpICogbSArIGpdOwogICAgfQogIH0KICByZXR1cm4gWjsKfTsKCi8vIE5haXZlIG1hdHJpeCBtdWx0aXBsaWNhdGlvbgpsZXQga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkgPSBmdW5jdGlvbiAoWCwgWSwgbiwgbSwgcCkgewogIGxldCBpOwogIGxldCBqOwogIGxldCBrOwogIGxldCBaID0gQXJyYXkobiAqIHApOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBwOyBqKyspIHsKICAgICAgWltpICogcCArIGpdID0gMDsKICAgICAgZm9yIChrID0gMDsgayA8IG07IGsrKykgewogICAgICAgIFpbaSAqIHAgKyBqXSArPSBYW2kgKiBtICsga10gKiBZW2sgKiBwICsgal07CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFo7Cn07CgovLyBDaG9sZXNreSBkZWNvbXBvc2l0aW9uCmxldCBrcmlnaW5nX21hdHJpeF9jaG9sID0gZnVuY3Rpb24gKFgsIG4pIHsKICBsZXQgaTsKICBsZXQgajsKICBsZXQgazsKICBsZXQgcCA9IEFycmF5KG4pOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHBbaV0gPSBYW2kgKiBuICsgaV07CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IGk7IGorKykgewogICAgICBwW2ldIC09IFhbaSAqIG4gKyBqXSAqIFhbaSAqIG4gKyBqXTsKICAgIH0KICAgIGlmIChwW2ldIDw9IDApIHJldHVybiBmYWxzZTsKICAgIHBbaV0gPSBNYXRoLnNxcnQocFtpXSk7CiAgICBmb3IgKGogPSBpICsgMTsgaiA8IG47IGorKykgewogICAgICBmb3IgKGsgPSAwOyBrIDwgaTsgaysrKSB7CiAgICAgICAgWFtqICogbiArIGldIC09IFhbaiAqIG4gKyBrXSAqIFhbaSAqIG4gKyBrXTsKICAgICAgfQogICAgICBYW2ogKiBuICsgaV0gLz0gcFtpXTsKICAgIH0KICB9CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgWFtpICogbiArIGldID0gcFtpXTsKICByZXR1cm4gdHJ1ZTsKfTsKCi8vIEludmVyc2lvbiBvZiBjaG9sZXNreSBkZWNvbXBvc2l0aW9uCmxldCBrcmlnaW5nX21hdHJpeF9jaG9sMmludiA9IGZ1bmN0aW9uIChYLCBuKSB7CiAgbGV0IGk7CiAgbGV0IGo7CiAgbGV0IGs7CiAgbGV0IHN1bTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBYW2kgKiBuICsgaV0gPSAxIC8gWFtpICogbiArIGldOwogICAgZm9yIChqID0gaSArIDE7IGogPCBuOyBqKyspIHsKICAgICAgc3VtID0gMDsKICAgICAgZm9yIChrID0gaTsgayA8IGo7IGsrKykgewogICAgICAgIHN1bSAtPSBYW2ogKiBuICsga10gKiBYW2sgKiBuICsgaV07CiAgICAgIH0KICAgICAgWFtqICogbiArIGldID0gc3VtIC8gWFtqICogbiArIGpdOwogICAgfQogIH0KICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSBpICsgMTsgaiA8IG47IGorKykgewogICAgICBYW2kgKiBuICsgal0gPSAwOwogICAgfQogIH0KICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBYW2kgKiBuICsgaV0gKj0gWFtpICogbiArIGldOwogICAgZm9yIChrID0gaSArIDE7IGsgPCBuOyBrKyspIHsKICAgICAgWFtpICogbiArIGldICs9IFhbayAqIG4gKyBpXSAqIFhbayAqIG4gKyBpXTsKICAgIH0KICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7CiAgICAgIGZvciAoayA9IGo7IGsgPCBuOyBrKyspIHsKICAgICAgICBYW2kgKiBuICsgal0gKz0gWFtrICogbiArIGldICogWFtrICogbiArIGpdOwogICAgICB9CiAgICB9CiAgfQogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBpOyBqKyspIHsKICAgICAgWFtpICogbiArIGpdID0gWFtqICogbiArIGldOwogICAgfQogIH0KfTsKCi8vIEludmVyc2lvbiB2aWEgZ2F1c3Mtam9yZGFuIGVsaW1pbmF0aW9uCmxldCBrcmlnaW5nX21hdHJpeF9zb2x2ZSA9IGZ1bmN0aW9uIChYLCBuKSB7CiAgbGV0IG0gPSBuOwogIGxldCBiID0gQXJyYXkobiAqIG4pOwogIGxldCBpbmR4YyA9IEFycmF5KG4pOwogIGxldCBpbmR4ciA9IEFycmF5KG4pOwogIGxldCBpcGl2ID0gQXJyYXkobik7CiAgbGV0IGk7CiAgbGV0IGljb2w7CiAgbGV0IGlyb3c7CiAgbGV0IGo7CiAgbGV0IGs7CiAgbGV0IGw7CiAgbGV0IGxsOwogIGxldCBiaWcsIGR1bSwgcGl2aW52LCB0ZW1wOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgaWYgKGkgPT09IGopIGJbaSAqIG4gKyBqXSA9IDE7ZWxzZSBiW2kgKiBuICsgal0gPSAwOwogICAgfQogIH0KICBmb3IgKGogPSAwOyBqIDwgbjsgaisrKSBpcGl2W2pdID0gMDsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBiaWcgPSAwOwogICAgZm9yIChqID0gMDsgaiA8IG47IGorKykgewogICAgICBpZiAoaXBpdltqXSAhPT0gMSkgewogICAgICAgIGZvciAoayA9IDA7IGsgPCBuOyBrKyspIHsKICAgICAgICAgIGlmIChpcGl2W2tdID09PSAwKSB7CiAgICAgICAgICAgIGlmIChNYXRoLmFicyhYW2ogKiBuICsga10pID49IGJpZykgewogICAgICAgICAgICAgIGJpZyA9IE1hdGguYWJzKFhbaiAqIG4gKyBrXSk7CiAgICAgICAgICAgICAgaXJvdyA9IGo7CiAgICAgICAgICAgICAgaWNvbCA9IGs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgICsraXBpdltpY29sXTsKICAgIGlmIChpcm93ICE9PSBpY29sKSB7CiAgICAgIGZvciAobCA9IDA7IGwgPCBuOyBsKyspIHsKICAgICAgICB0ZW1wID0gWFtpcm93ICogbiArIGxdOwogICAgICAgIFhbaXJvdyAqIG4gKyBsXSA9IFhbaWNvbCAqIG4gKyBsXTsKICAgICAgICBYW2ljb2wgKiBuICsgbF0gPSB0ZW1wOwogICAgICB9CiAgICAgIGZvciAobCA9IDA7IGwgPCBtOyBsKyspIHsKICAgICAgICB0ZW1wID0gYltpcm93ICogbiArIGxdOwogICAgICAgIGJbaXJvdyAqIG4gKyBsXSA9IGJbaWNvbCAqIG4gKyBsXTsKICAgICAgICBiW2ljb2wgKiBuICsgbF0gPSB0ZW1wOwogICAgICB9CiAgICB9CiAgICBpbmR4cltpXSA9IGlyb3c7CiAgICBpbmR4Y1tpXSA9IGljb2w7CiAgICBpZiAoWFtpY29sICogbiArIGljb2xdID09PSAwKSByZXR1cm4gZmFsc2U7IC8vIFNpbmd1bGFyCgogICAgcGl2aW52ID0gMSAvIFhbaWNvbCAqIG4gKyBpY29sXTsKICAgIFhbaWNvbCAqIG4gKyBpY29sXSA9IDE7CiAgICBmb3IgKGwgPSAwOyBsIDwgbjsgbCsrKSBYW2ljb2wgKiBuICsgbF0gKj0gcGl2aW52OwogICAgZm9yIChsID0gMDsgbCA8IG07IGwrKykgYltpY29sICogbiArIGxdICo9IHBpdmludjsKICAgIGZvciAobGwgPSAwOyBsbCA8IG47IGxsKyspIHsKICAgICAgaWYgKGxsICE9PSBpY29sKSB7CiAgICAgICAgZHVtID0gWFtsbCAqIG4gKyBpY29sXTsKICAgICAgICBYW2xsICogbiArIGljb2xdID0gMDsKICAgICAgICBmb3IgKGwgPSAwOyBsIDwgbjsgbCsrKSBYW2xsICogbiArIGxdIC09IFhbaWNvbCAqIG4gKyBsXSAqIGR1bTsKICAgICAgICBmb3IgKGwgPSAwOyBsIDwgbTsgbCsrKSBiW2xsICogbiArIGxdIC09IGJbaWNvbCAqIG4gKyBsXSAqIGR1bTsKICAgICAgfQogICAgfQogIH0KICBmb3IgKGwgPSBuIC0gMTsgbCA+PSAwOyBsLS0pIHsKICAgIGlmIChpbmR4cltsXSAhPT0gaW5keGNbbF0pIHsKICAgICAgZm9yIChrID0gMDsgayA8IG47IGsrKykgewogICAgICAgIHRlbXAgPSBYW2sgKiBuICsgaW5keHJbbF1dOwogICAgICAgIFhbayAqIG4gKyBpbmR4cltsXV0gPSBYW2sgKiBuICsgaW5keGNbbF1dOwogICAgICAgIFhbayAqIG4gKyBpbmR4Y1tsXV0gPSB0ZW1wOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiB0cnVlOwp9OwoKLy8gVmFyaW9ncmFtIG1vZGVscwpsZXQga3JpZ2luZ192YXJpb2dyYW1fZ2F1c3NpYW4gPSBmdW5jdGlvbiAoaCwgbnVnZ2V0LCByYW5nZSwgc2lsbCwgQSkgewogIHJldHVybiBudWdnZXQgKyAoc2lsbCAtIG51Z2dldCkgLyByYW5nZSAqICgxLjAgLSBNYXRoLmV4cCgtKDEuMCAvIEEpICogTWF0aC5wb3coaCAvIHJhbmdlLCAyKSkpOwp9OwpsZXQga3JpZ2luZ192YXJpb2dyYW1fZXhwb25lbnRpYWwgPSBmdW5jdGlvbiAoaCwgbnVnZ2V0LCByYW5nZSwgc2lsbCwgQSkgewogIHJldHVybiBudWdnZXQgKyAoc2lsbCAtIG51Z2dldCkgLyByYW5nZSAqICgxLjAgLSBNYXRoLmV4cCgtKDEuMCAvIEEpICogKGggLyByYW5nZSkpKTsKfTsKbGV0IGtyaWdpbmdfdmFyaW9ncmFtX3NwaGVyaWNhbCA9IGZ1bmN0aW9uIChoLCBudWdnZXQsIHJhbmdlLCBzaWxsLCBBKSB7CiAgaWYgKGggPiByYW5nZSkgcmV0dXJuIG51Z2dldCArIChzaWxsIC0gbnVnZ2V0KSAvIHJhbmdlOwogIHJldHVybiBudWdnZXQgKyAoc2lsbCAtIG51Z2dldCkgLyByYW5nZSAqICgxLjUgKiAoaCAvIHJhbmdlKSAtIDAuNSAqIE1hdGgucG93KGggLyByYW5nZSwgMykpOwp9OwoKLy8gVHJhaW4gdXNpbmcgZ2F1c3NpYW4gcHJvY2Vzc2VzIHdpdGggYmF5ZXNpYW4gcHJpb3JzCmtyaWdpbmcudHJhaW4gPSBmdW5jdGlvbiAodCwgeCwgeSwgbW9kZWwsIHNpZ21hMiwgYWxwaGEpIHsKICBsZXQgdmFyaW9ncmFtID0gewogICAgdCwKICAgIHgsCiAgICB5LAogICAgbnVnZ2V0OiAwLjAsCiAgICByYW5nZTogMC4wLAogICAgc2lsbDogMC4wLAogICAgQTogMSAvIDMsCiAgICBuOiAwCiAgfTsKICBzd2l0Y2ggKG1vZGVsKSB7CiAgICBjYXNlICdnYXVzc2lhbic6CiAgICAgIHZhcmlvZ3JhbS5tb2RlbCA9IGtyaWdpbmdfdmFyaW9ncmFtX2dhdXNzaWFuOwogICAgICBicmVhazsKICAgIGNhc2UgJ2V4cG9uZW50aWFsJzoKICAgICAgdmFyaW9ncmFtLm1vZGVsID0ga3JpZ2luZ192YXJpb2dyYW1fZXhwb25lbnRpYWw7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnc3BoZXJpY2FsJzoKICAgICAgdmFyaW9ncmFtLm1vZGVsID0ga3JpZ2luZ192YXJpb2dyYW1fc3BoZXJpY2FsOwogICAgICBicmVhazsKICB9CgogIC8vIExhZyBkaXN0YW5jZS9zZW1pdmFyaWFuY2UKICBsZXQgaTsKICBsZXQgajsKICBsZXQgazsKICBsZXQgbDsKICBsZXQgbiA9IHQubGVuZ3RoOwogIGxldCBkaXN0YW5jZSA9IEFycmF5KChuICogbiAtIG4pIC8gMik7CiAgZm9yIChpID0gMCwgayA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBpOyBqKyssIGsrKykgewogICAgICBkaXN0YW5jZVtrXSA9IEFycmF5KDIpOwogICAgICBkaXN0YW5jZVtrXVswXSA9IE1hdGgucG93KE1hdGgucG93KHhbaV0gLSB4W2pdLCAyKSArIE1hdGgucG93KHlbaV0gLSB5W2pdLCAyKSwgMC41KTsKICAgICAgZGlzdGFuY2Vba11bMV0gPSBNYXRoLmFicyh0W2ldIC0gdFtqXSk7CiAgICB9CiAgfQogIGRpc3RhbmNlLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsKICAgIHJldHVybiBhWzBdIC0gYlswXTsKICB9KTsKICB2YXJpb2dyYW0ucmFuZ2UgPSBkaXN0YW5jZVsobiAqIG4gLSBuKSAvIDIgLSAxXVswXTsKCiAgLy8gQmluIGxhZyBkaXN0YW5jZQogIGxldCBsYWdzID0gKG4gKiBuIC0gbikgLyAyID4gMzAgPyAzMCA6IChuICogbiAtIG4pIC8gMjsKICAvLyBjb25zb2xlLmxvZygnbGFncycsIGxhZ3MpCiAgbGV0IHRvbGVyYW5jZSA9IHZhcmlvZ3JhbS5yYW5nZSAvIGxhZ3M7CiAgbGV0IGxhZyA9IGNyZWF0ZUFycmF5V2l0aFZhbHVlcygwLCBsYWdzKTsKICBsZXQgc2VtaSA9IGNyZWF0ZUFycmF5V2l0aFZhbHVlcygwLCBsYWdzKTsKICBpZiAobGFncyA8IDMwKSB7CiAgICBmb3IgKGwgPSAwOyBsIDwgbGFnczsgbCsrKSB7CiAgICAgIGxhZ1tsXSA9IGRpc3RhbmNlW2xdWzBdOwogICAgICBzZW1pW2xdID0gZGlzdGFuY2VbbF1bMV07CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvciAoaSA9IDAsIGogPSAwLCBrID0gMCwgbCA9IDA7IGkgPCBsYWdzICYmIGogPCAobiAqIG4gLSBuKSAvIDI7IGkrKywgayA9IDApIHsKICAgICAgd2hpbGUgKGRpc3RhbmNlW2pdWzBdIDw9IChpICsgMSkgKiB0b2xlcmFuY2UpIHsKICAgICAgICBsYWdbbF0gKz0gZGlzdGFuY2Vbal1bMF07CiAgICAgICAgc2VtaVtsXSArPSBkaXN0YW5jZVtqXVsxXTsKICAgICAgICBqKys7CiAgICAgICAgaysrOwogICAgICAgIGlmIChqID49IChuICogbiAtIG4pIC8gMikgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKGsgPiAwKSB7CiAgICAgICAgbGFnW2xdIC89IGs7CiAgICAgICAgc2VtaVtsXSAvPSBrOwogICAgICAgIGwrKzsKICAgICAgICAvLyBjb25zb2xlLmxvZygnbCsrJywgbCkKICAgICAgfQogICAgfQoKICAgIGlmIChsIDwgMikgcmV0dXJuIHZhcmlvZ3JhbTsgLy8gRXJyb3I6IE5vdCBlbm91Z2ggcG9pbnRzCiAgfQoKICAvL3NhdmUKICBsZXQgYmFycyA9IFtdOwogIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHsKICAgIGxldCBzMCA9IGxhZ1tpXTsKICAgIGxldCBzMSA9IHNlbWlbaV07CiAgICBiYXJzLnB1c2goW3MwLCBzMV0pOwogIH0KICBsZXQgc3ZwZCA9IHsKICAgIGRhdGE6IGRpc3RhbmNlLAogICAgYmFycwogIH07CiAgdmFyaW9ncmFtLnN2cGQgPSBzdnBkOwoKICAvLyBGZWF0dXJlIHRyYW5zZm9ybWF0aW9uCiAgbiA9IGw7CiAgdmFyaW9ncmFtLnJhbmdlID0gbGFnW24gLSAxXSAtIGxhZ1swXTsKICBsZXQgWCA9IGNyZWF0ZUFycmF5V2l0aFZhbHVlcygxLCAyICogbik7CiAgbGV0IFkgPSBBcnJheShuKTsKICBsZXQgQSA9IHZhcmlvZ3JhbS5BOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIHN3aXRjaCAobW9kZWwpIHsKICAgICAgY2FzZSAnZ2F1c3NpYW4nOgogICAgICAgIFhbaSAqIDIgKyAxXSA9IDEuMCAtIE1hdGguZXhwKC0oMS4wIC8gQSkgKiBNYXRoLnBvdyhsYWdbaV0gLyB2YXJpb2dyYW0ucmFuZ2UsIDIpKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnZXhwb25lbnRpYWwnOgogICAgICAgIFhbaSAqIDIgKyAxXSA9IDEuMCAtIE1hdGguZXhwKC0oMS4wIC8gQSkgKiBsYWdbaV0gLyB2YXJpb2dyYW0ucmFuZ2UpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzcGhlcmljYWwnOgogICAgICAgIFhbaSAqIDIgKyAxXSA9IDEuNSAqIChsYWdbaV0gLyB2YXJpb2dyYW0ucmFuZ2UpIC0gMC41ICogTWF0aC5wb3cobGFnW2ldIC8gdmFyaW9ncmFtLnJhbmdlLCAzKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIFlbaV0gPSBzZW1pW2ldOwogIH0KCiAgLy8gTGVhc3Qgc3F1YXJlcwogIGxldCBYdCA9IGtyaWdpbmdfbWF0cml4X3RyYW5zcG9zZShYLCBuLCAyKTsKICBsZXQgWiA9IGtyaWdpbmdfbWF0cml4X211bHRpcGx5KFh0LCBYLCAyLCBuLCAyKTsKICBaID0ga3JpZ2luZ19tYXRyaXhfYWRkKFosIGtyaWdpbmdfbWF0cml4X2RpYWcoMSAvIGFscGhhLCAyKSwgMiwgMik7CiAgbGV0IGNsb25lWiA9IFouc2xpY2UoMCk7CiAgaWYgKGtyaWdpbmdfbWF0cml4X2Nob2woWiwgMikpIHsKICAgIGtyaWdpbmdfbWF0cml4X2Nob2wyaW52KFosIDIpOwogIH0gZWxzZSB7CiAgICBrcmlnaW5nX21hdHJpeF9zb2x2ZShjbG9uZVosIDIpOwogICAgWiA9IGNsb25lWjsKICB9CiAgbGV0IFcgPSBrcmlnaW5nX21hdHJpeF9tdWx0aXBseShrcmlnaW5nX21hdHJpeF9tdWx0aXBseShaLCBYdCwgMiwgMiwgbiksIFksIDIsIG4sIDEpOwoKICAvLyBWYXJpb2dyYW0gcGFyYW1ldGVycwogIHZhcmlvZ3JhbS5udWdnZXQgPSBXWzBdOwogIHZhcmlvZ3JhbS5zaWxsID0gV1sxXSAqIHZhcmlvZ3JhbS5yYW5nZSArIHZhcmlvZ3JhbS5udWdnZXQ7CiAgdmFyaW9ncmFtLm4gPSB4Lmxlbmd0aDsKCiAgLy8gR3JhbSBtYXRyaXggd2l0aCBwcmlvcgogIG4gPSB4Lmxlbmd0aDsKICBsZXQgSyA9IEFycmF5KG4gKiBuKTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgaTsgaisrKSB7CiAgICAgIEtbaSAqIG4gKyBqXSA9IHZhcmlvZ3JhbS5tb2RlbChNYXRoLnBvdyhNYXRoLnBvdyh4W2ldIC0geFtqXSwgMikgKyBNYXRoLnBvdyh5W2ldIC0geVtqXSwgMiksIDAuNSksIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKTsKICAgICAgS1tqICogbiArIGldID0gS1tpICogbiArIGpdOwogICAgfQogICAgS1tpICogbiArIGldID0gdmFyaW9ncmFtLm1vZGVsKDAsIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKTsKICB9CgogIC8vIEludmVyc2UgcGVuYWxpemVkIEdyYW0gbWF0cml4IHByb2plY3RlZCB0byB0YXJnZXQgdmVjdG9yCiAgbGV0IEMgPSBrcmlnaW5nX21hdHJpeF9hZGQoSywga3JpZ2luZ19tYXRyaXhfZGlhZyhzaWdtYTIsIG4pLCBuLCBuKTsKICBsZXQgY2xvbmVDID0gQy5zbGljZSgwKTsKICBpZiAoa3JpZ2luZ19tYXRyaXhfY2hvbChDLCBuKSkgewogICAga3JpZ2luZ19tYXRyaXhfY2hvbDJpbnYoQywgbik7CiAgfSBlbHNlIHsKICAgIGtyaWdpbmdfbWF0cml4X3NvbHZlKGNsb25lQywgbik7CiAgICBDID0gY2xvbmVDOwogIH0KCiAgLy8gQ29weSB1bnByb2plY3RlZCBpbnZlcnRlZCBtYXRyaXggYXMgSwogIGxldCBfSyA9IEMuc2xpY2UoMCk7CiAgbGV0IF9NID0ga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoQywgdCwgbiwgbiwgMSk7CiAgdmFyaW9ncmFtLksgPSBfSzsKICB2YXJpb2dyYW0uTSA9IF9NOwogIHJldHVybiB2YXJpb2dyYW07Cn07CgovLyBNb2RlbCBwcmVkaWN0aW9uCmtyaWdpbmcucHJlZGljdCA9IGZ1bmN0aW9uICh4LCB5LCB2YXJpb2dyYW0pIHsKICBsZXQgaTsKICBsZXQgayA9IEFycmF5KHZhcmlvZ3JhbS5uKTsKICBmb3IgKGkgPSAwOyBpIDwgdmFyaW9ncmFtLm47IGkrKykgewogICAga1tpXSA9IHZhcmlvZ3JhbS5tb2RlbChNYXRoLnBvdyhNYXRoLnBvdyh4IC0gdmFyaW9ncmFtLnhbaV0sIDIpICsgTWF0aC5wb3coeSAtIHZhcmlvZ3JhbS55W2ldLCAyKSwgMC41KSwgdmFyaW9ncmFtLm51Z2dldCwgdmFyaW9ncmFtLnJhbmdlLCB2YXJpb2dyYW0uc2lsbCwgdmFyaW9ncmFtLkEpOwogIH0KICByZXR1cm4ga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoaywgdmFyaW9ncmFtLk0sIDEsIHZhcmlvZ3JhbS5uLCAxKVswXTsKfTsKa3JpZ2luZy52YXJpYW5jZSA9IGZ1bmN0aW9uICh4LCB5LCB2YXJpb2dyYW0pIHsKICBsZXQgaTsKICBsZXQgayA9IEFycmF5KHZhcmlvZ3JhbS5uKTsKICBmb3IgKGkgPSAwOyBpIDwgdmFyaW9ncmFtLm47IGkrKykgewogICAga1tpXSA9IHZhcmlvZ3JhbS5tb2RlbChNYXRoLnBvdyhNYXRoLnBvdyh4IC0gdmFyaW9ncmFtLnhbaV0sIDIpICsgTWF0aC5wb3coeSAtIHZhcmlvZ3JhbS55W2ldLCAyKSwgMC41KSwgdmFyaW9ncmFtLm51Z2dldCwgdmFyaW9ncmFtLnJhbmdlLCB2YXJpb2dyYW0uc2lsbCwgdmFyaW9ncmFtLkEpOwogIH0KICByZXR1cm4gdmFyaW9ncmFtLm1vZGVsKDAsIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKSArIGtyaWdpbmdfbWF0cml4X211bHRpcGx5KGtyaWdpbmdfbWF0cml4X211bHRpcGx5KGssIHZhcmlvZ3JhbS5LLCAxLCB2YXJpb2dyYW0ubiwgdmFyaW9ncmFtLm4pLCBrLCAxLCB2YXJpb2dyYW0ubiwgMSlbMF07Cn07CgovLyEgTGluZWFyIGFsZ2VicmEgcHJpbWl0aXZlcyAocHVyZSBKUywgemVybyBkZXBlbmRlbmNpZXMpCi8vIQovLyEgUG9ydCBvZiBgZnJpZWRyaWNoIDAuNi4wYDoKLy8hICAgLSBgc3JjL2FsZ2VicmEvbW9kLnJzYCAgICAgICAgICAgICAgKGNvdmFyaWFuY2UtbWF0cml4IGhlbHBlcnMpCi8vISAgIC0gYHNyYy9hbGdlYnJhL2V4dGVuZGFibGVfbWF0cml4LnJzYCAoRU1hdHJpeCAvIEVWZWN0b3Ig4oaSIEV4dGVuZGFibGVNYXRyaXggLyBFeHRlbmRhYmxlVmVjdG9yKQovLyEgICAtIHRoZSBzbGljZSBvZiBgbmFsZ2VicmFgIHRoYXQgZnJpZWRyaWNoIGFjdHVhbGx5IHVzZXMKLy8hICAgICAobWF0cml4IC8gdmVjdG9yIG9wcywgQ2hvbGVza3kgZGVjb21wb3NpdGlvbiwgdHJpYW5ndWxhciBzb2x2ZXMsCi8vISAgICAgIENob2xlc2t5IHNvbHZlIC8gaW52ZXJzZSwgbGVhc3Qtc3F1YXJlcykuCi8vIQovLyEgRGF0YSByZXByZXNlbnRhdGlvbiAoc2VlIFBPUlRfU1BFQyDCpzIpOgovLyEgICAtIHZlY3RvciA9IG51bWJlcltdCi8vISAgIC0gbWF0cml4ID0gbnVtYmVyW11bXSAocm93LW1ham9yOyBtYXRyaXhbcl1bY10gPSByb3cgciwgY29sIGMpCi8vIQovLyEgQWxsIG1hdHJpeCBtYXRoIGhlcmUgaXMgcm93LW1ham9yOyB3ZSBkbyBOT1QgZW11bGF0ZSBuYWxnZWJyYSdzCi8vISBjb2x1bW4tbWFqb3IgbWVtb3J5IGxheW91dCwgb25seSBpdHMgbWF0aGVtYXRpY2FsIHNlbWFudGljcy4KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gQkFTSUMgVkVDVE9SIE9QRVJBVElPTlMgKGlucHV0OiBudW1iZXJbXSkKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIERvdCBwcm9kdWN0IM6jIGHhtaLCt2LhtaIuCiAqIEBwYXJhbSB7bnVtYmVyW119IGEKICogQHBhcmFtIHtudW1iZXJbXX0gYgogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gZG90KGEsIGIpIHsKICBsZXQgcyA9IDA7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSBzICs9IGFbaV0gKiBiW2ldOwogIHJldHVybiBzOwp9CgovKioKICogRWxlbWVudC13aXNlIHN1YnRyYWN0aW9uIGEg4oiSIGIuCiAqIEBwYXJhbSB7bnVtYmVyW119IGEKICogQHBhcmFtIHtudW1iZXJbXX0gYgogKiBAcmV0dXJucyB7bnVtYmVyW119CiAqLwpmdW5jdGlvbiBzdWJWZWMoYSwgYikgewogIGNvbnN0IG91dCA9IG5ldyBBcnJheShhLmxlbmd0aCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSBvdXRbaV0gPSBhW2ldIC0gYltpXTsKICByZXR1cm4gb3V0Owp9CgovKioKICogRXVjbGlkZWFuIG5vcm0gc3FydCjOoyBh4bWiwrIpLgogKiBAcGFyYW0ge251bWJlcltdfSBhCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBub3JtKGEpIHsKICByZXR1cm4gTWF0aC5zcXJ0KG5vcm1TcXVhcmVkKGEpKTsKfQoKLyoqCiAqIFNxdWFyZWQgRXVjbGlkZWFuIG5vcm0gzqMgYeG1osKyLgogKiBAcGFyYW0ge251bWJlcltdfSBhCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBub3JtU3F1YXJlZChhKSB7CiAgbGV0IHMgPSAwOwogIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgcyArPSBhW2ldICogYVtpXTsKICByZXR1cm4gczsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNQVRSSVggLyBNQVRSSVgtVkVDVE9SIE9QRVJBVElPTlMgKG1hdHJpeCA9IG51bWJlcltdW10sIG9uZSByb3cgcGVyIHJvdykKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIE1hdHJpeCBwcm9kdWN0IEEobcOXaykgwrcgQihrw5duKSDihpIgKG3Dl24pLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHBhcmFtIHtudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gbWF0TXVsKEEsIEIpIHsKICBjb25zdCBtID0gQS5sZW5ndGg7CiAgY29uc3QgayA9IEFbMF0ubGVuZ3RoOwogIGNvbnN0IG4gPSBCWzBdLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobSk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIHsKICAgIGNvbnN0IEFpID0gQVtpXTsKICAgIGNvbnN0IHJvdyA9IG5ldyBBcnJheShuKS5maWxsKDApOwogICAgZm9yIChsZXQgcCA9IDA7IHAgPCBrOyBwKyspIHsKICAgICAgY29uc3QgYSA9IEFpW3BdOwogICAgICBjb25zdCBCcCA9IEJbcF07CiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSByb3dbal0gKz0gYSAqIEJwW2pdOwogICAgfQogICAgb3V0W2ldID0gcm93OwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogTWF0cml4LXZlY3RvciBwcm9kdWN0IEEobcOXbikgwrcgeChuKSDihpIgbnVtYmVyW10obSkuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcGFyYW0ge251bWJlcltdfSB4CiAqIEByZXR1cm5zIHtudW1iZXJbXX0KICovCmZ1bmN0aW9uIG1hdFZlYyhBLCB4KSB7CiAgY29uc3QgbSA9IEEubGVuZ3RoOwogIGNvbnN0IG91dCA9IG5ldyBBcnJheShtKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG07IGkrKykgewogICAgY29uc3QgQWkgPSBBW2ldOwogICAgbGV0IHMgPSAwOwogICAgZm9yIChsZXQgaiA9IDA7IGogPCBBaS5sZW5ndGg7IGorKykgcyArPSBBaVtqXSAqIHhbal07CiAgICBvdXRbaV0gPSBzOwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogVHJhbnNwb3NlIG9mIEEuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHRyYW5zcG9zZShBKSB7CiAgY29uc3QgbSA9IEEubGVuZ3RoOwogIGNvbnN0IG4gPSBBWzBdLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgIGNvbnN0IGNvbCA9IG5ldyBBcnJheShtKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSBjb2xbaV0gPSBBW2ldW2pdOwogICAgb3V0W2pdID0gY29sOwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogRWxlbWVudC13aXNlIG1hdHJpeCBzdWJ0cmFjdGlvbiBBIOKIkiBCLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHBhcmFtIHtudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gbWF0U3ViKEEsIEIpIHsKICBjb25zdCBtID0gQS5sZW5ndGg7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG0pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICBjb25zdCBuID0gQVtpXS5sZW5ndGg7CiAgICBjb25zdCByb3cgPSBuZXcgQXJyYXkobik7CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykgcm93W2pdID0gQVtpXVtqXSAtIEJbaV1bal07CiAgICBvdXRbaV0gPSByb3c7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBuw5duIGlkZW50aXR5IG1hdHJpeC4KICogQHBhcmFtIHtudW1iZXJ9IG4KICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiBpZGVudGl0eShuKSB7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBjb25zdCByb3cgPSBuZXcgQXJyYXkobikuZmlsbCgwKTsKICAgIHJvd1tpXSA9IDE7CiAgICBvdXRbaV0gPSByb3c7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBtw5duIHplcm8gbWF0cml4LgogKiBAcGFyYW0ge251bWJlcn0gbQogKiBAcGFyYW0ge251bWJlcn0gbgogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHplcm9zKG0sIG4pIHsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobSk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIG91dFtpXSA9IG5ldyBBcnJheShuKS5maWxsKDApOwogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBUcmFjZSDOoyBB4bWi4bWiIChhbHNvIHVzZWQgYXMgZ2VuZXJpYyBkaWFnb25hbCBzdW0sIGUuZy4gdHJhY2UoQeKBu8K5KSkuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gdHJhY2UoQSkgewogIGNvbnN0IG4gPSBNYXRoLm1pbihBLmxlbmd0aCwgQVswXS5sZW5ndGgpOwogIGxldCBzID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgcyArPSBBW2ldW2ldOwogIHJldHVybiBzOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIENIT0xFU0tZIERFQ09NUE9TSVRJT04gJiBUUklBTkdVTEFSIFNPTFZFUwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQ2hvbGVza3kgZGVjb21wb3NpdGlvbiBvZiBhIHN5bW1ldHJpYyBwb3NpdGl2ZS1kZWZpbml0ZSBtYXRyaXggQShuw5duKSwKICogcmV0dXJuaW5nIHRoZSBsb3dlci10cmlhbmd1bGFyIGZhY3RvciBMIHN1Y2ggdGhhdCBBID0gTMK3TOG1gC4KICoKICogRmFpbHVyZSAobm9uLXBvc2l0aXZlLWRlZmluaXRlKSBiZWhhdmlvdXI6CiAqICAgLSBgZXBzaWxvbiA9PT0gbnVsbGAg4oaSIHRocm93IEVycm9yIChtYXRjaGVzIFJ1c3QgYC5leHBlY3QoKWAgcGFuaWMpLgogKiAgIC0gYGVwc2lsb25gIGEgZmluaXRlIHBvc2l0aXZlIG51bWJlciDihpIgbWltaWMgbmFsZ2VicmEKICogICAgIGBDaG9sZXNreTo6bmV3X3dpdGhfc3Vic3RpdHV0ZWA6IHdoZW5ldmVyIGEgZGlhZ29uYWwgcGl2b3QgZOKxvCDiiaQgMCwKICogICAgIHN1YnN0aXR1dGUgYGVwc2lsb25gIGZvciB0aGF0IHBpdm90IGFuZCBrZWVwIGdvaW5nLiBJZiBldmVuIHRoZQogKiAgICAgc3Vic3RpdHV0ZSBmYWlscyB0byBrZWVwIHRoaW5ncyByZWFsIChjYW5ub3QgaGFwcGVuIGZvciBlcHNpbG9uID4gMCksCiAqICAgICB0aHJvdy4KICoKICogUmVhZHMgb25seSB0aGUgbG93ZXIgdHJpYW5nbGUgb2YgQSAodGhlIHVwcGVyIHRyaWFuZ2xlIGlzIGlnbm9yZWQpLCBtYXRjaGluZwogKiBuYWxnZWJyYSdzIGJlaGF2aW91ciBvZiB1c2luZyBvbmx5IHRoZSBsb3dlci10cmlhbmd1bGFyIHBhcnQuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcGFyYW0ge251bWJlcnxudWxsfSBbZXBzaWxvbj1udWxsXQogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0gbG93ZXItdHJpYW5ndWxhciBMCiAqLwpmdW5jdGlvbiBjaG9sZXNreShBLCBlcHNpbG9uID0gbnVsbCkgewogIGNvbnN0IG4gPSBBLmxlbmd0aDsKICAvLyBMIHN0YXJ0cyBhcyBhIHplcm8gbWF0cml4OyB3ZSBmaWxsIHRoZSBsb3dlciB0cmlhbmdsZSBjb2x1bW4gYnkgY29sdW1uLAogIC8vIG1pcnJvcmluZyBuYWxnZWJyYSdzIGluLXBsYWNlIGFsZ29yaXRobSAobG93ZXItdHJpYW5ndWxhciwgY29sdW1uLW1ham9yKS4KICBjb25zdCBMID0gemVyb3Mobiwgbik7CiAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgIC8vIERpYWdvbmFsIHBpdm90OiBBW2pdW2pdIOKIkiDOo197azxqfSBMW2pdW2tdwrIKICAgIGxldCBkaWFnID0gQVtqXVtqXTsKICAgIGZvciAobGV0IGsgPSAwOyBrIDwgajsgaysrKSBkaWFnIC09IExbal1ba10gKiBMW2pdW2tdOwogICAgaWYgKGVwc2lsb24gPT09IG51bGwpIHsKICAgICAgaWYgKCEoZGlhZyA+IDApKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJDaG9sZXNreSBkZWNvbXBvc2l0aW9uIGZhaWxlZCwgY29uc2lkZXIgc2V0dGluZyBgY2hvbGVza3lfZXBzaWxvbmAgdmlhIGBHYXVzc2lhblByb2Nlc3NCdWlsZGVyYCIpOwogICAgICB9CiAgICB9IGVsc2UgaWYgKCEoZGlhZyA+IDApKSB7CiAgICAgIC8vIG5ld193aXRoX3N1YnN0aXR1dGU6IHJlcGxhY2UgdGhlIG5vbi1wb3NpdGl2ZSBwaXZvdCB3aXRoIGVwc2lsb24uCiAgICAgIGRpYWcgPSBlcHNpbG9uOwogICAgfQogICAgY29uc3QgbGpqID0gTWF0aC5zcXJ0KGRpYWcpOwogICAgTFtqXVtqXSA9IGxqajsKCiAgICAvLyBCZWxvdy1kaWFnb25hbCBlbnRyaWVzIG9mIGNvbHVtbiBqOgogICAgLy8gICBMW2ldW2pdID0gKEFbaV1bal0g4oiSIM6jX3trPGp9IExbaV1ba13Ct0xbal1ba10pIC8gTFtqXVtqXQogICAgZm9yIChsZXQgaSA9IGogKyAxOyBpIDwgbjsgaSsrKSB7CiAgICAgIGxldCBzID0gQVtpXVtqXTsKICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBqOyBrKyspIHMgLT0gTFtpXVtrXSAqIExbal1ba107CiAgICAgIExbaV1bal0gPSBzIC8gbGpqOwogICAgfQogIH0KICByZXR1cm4gTDsKfQoKLyoqCiAqIFNvbHZlIEzCt1ggPSBCIHdoZXJlIEwgaXMgbG93ZXItdHJpYW5ndWxhciAoZm9yd2FyZCBzdWJzdGl0dXRpb24pLgogKiBCIG1heSBiZSBhIHZlY3RvciAobnVtYmVyW10pIOKGkiBzb2x2ZXMgb25lIFJIUywgb3IgYSBtYXRyaXggKG51bWJlcltdW10pCiAqIOKGkiBzb2x2ZXMgY29sdW1uIGJ5IGNvbHVtbiAoZWFjaCBjb2x1bW4gaXMgb25lIFJIUyksIHJldHVybmluZyB0aGUgc2FtZSBzaGFwZS4KICogTWF0Y2hlcyBuYWxnZWJyYSBgc29sdmVfbG93ZXJfdHJpYW5ndWxhcmAuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTCBsb3dlci10cmlhbmd1bGFyCiAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gQgogKiBAcmV0dXJucyB7bnVtYmVyW118bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHNvbHZlTG93ZXJUcmkoTCwgQikgewogIGlmIChBcnJheS5pc0FycmF5KEJbMF0pKSB7CiAgICAvLyBCIGlzIGEgbWF0cml4OiBzb2x2ZSBlYWNoIGNvbHVtbi4KICAgIGNvbnN0IG4gPSBMLmxlbmd0aDsKICAgIGNvbnN0IG5jb2xzID0gQlswXS5sZW5ndGg7CiAgICBjb25zdCBYID0gemVyb3MobiwgbmNvbHMpOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuY29sczsgYysrKSB7CiAgICAgIGNvbnN0IGNvbCA9IG5ldyBBcnJheShuKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIGNvbFtpXSA9IEJbaV1bY107CiAgICAgIGNvbnN0IHNvbCA9IHNvbHZlTG93ZXJUcmlWZWMoTCwgY29sKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIFhbaV1bY10gPSBzb2xbaV07CiAgICB9CiAgICByZXR1cm4gWDsKICB9CiAgcmV0dXJuIHNvbHZlTG93ZXJUcmlWZWMoTCwgQik7Cn0KCi8qKgogKiBGb3J3YXJkIHN1YnN0aXR1dGlvbiBmb3IgYSBzaW5nbGUgUkhTIHZlY3Rvcjogc29sdmUgTMK3eCA9IGIuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTCBsb3dlci10cmlhbmd1bGFyCiAqIEBwYXJhbSB7bnVtYmVyW119IGIKICogQHJldHVybnMge251bWJlcltdfQogKi8KZnVuY3Rpb24gc29sdmVMb3dlclRyaVZlYyhMLCBiKSB7CiAgY29uc3QgbiA9IEwubGVuZ3RoOwogIGNvbnN0IHggPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGxldCBzID0gYltpXTsKICAgIGNvbnN0IExpID0gTFtpXTsKICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaTsgaysrKSBzIC09IExpW2tdICogeFtrXTsKICAgIHhbaV0gPSBzIC8gTGlbaV07CiAgfQogIHJldHVybiB4Owp9CgovKioKICogU29sdmUgVcK3WCA9IEIgd2hlcmUgVSBpcyB1cHBlci10cmlhbmd1bGFyIChiYWNrIHN1YnN0aXR1dGlvbikuCiAqIEluIGZyaWVkcmljaCB0aGUgdXBwZXItdHJpYW5ndWxhciBzeXN0ZW0gaXMgVSA9IEzhtYAuCiAqIEIgbWF5IGJlIG51bWJlcltdIG9yIG51bWJlcltdW10gKGNvbHVtbi13aXNlKSwgcmV0dXJuaW5nIHRoZSBzYW1lIHNoYXBlLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IFUgdXBwZXItdHJpYW5ndWxhcgogKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IEIKICogQHJldHVybnMge251bWJlcltdfG51bWJlcltdW119CiAqLwpmdW5jdGlvbiBzb2x2ZVVwcGVyVHJpKFUsIEIpIHsKICBpZiAoQXJyYXkuaXNBcnJheShCWzBdKSkgewogICAgY29uc3QgbiA9IFUubGVuZ3RoOwogICAgY29uc3QgbmNvbHMgPSBCWzBdLmxlbmd0aDsKICAgIGNvbnN0IFggPSB6ZXJvcyhuLCBuY29scyk7CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG5jb2xzOyBjKyspIHsKICAgICAgY29uc3QgY29sID0gbmV3IEFycmF5KG4pOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgY29sW2ldID0gQltpXVtjXTsKICAgICAgY29uc3Qgc29sID0gc29sdmVVcHBlclRyaVZlYyhVLCBjb2wpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgWFtpXVtjXSA9IHNvbFtpXTsKICAgIH0KICAgIHJldHVybiBYOwogIH0KICByZXR1cm4gc29sdmVVcHBlclRyaVZlYyhVLCBCKTsKfQoKLyoqCiAqIEJhY2sgc3Vic3RpdHV0aW9uIGZvciBhIHNpbmdsZSBSSFMgdmVjdG9yOiBzb2x2ZSBVwrd4ID0gYi4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBVIHVwcGVyLXRyaWFuZ3VsYXIKICogQHBhcmFtIHtudW1iZXJbXX0gYgogKiBAcmV0dXJucyB7bnVtYmVyW119CiAqLwpmdW5jdGlvbiBzb2x2ZVVwcGVyVHJpVmVjKFUsIGIpIHsKICBjb25zdCBuID0gVS5sZW5ndGg7CiAgY29uc3QgeCA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCBpID0gbiAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICBsZXQgcyA9IGJbaV07CiAgICBjb25zdCBVaSA9IFVbaV07CiAgICBmb3IgKGxldCBrID0gaSArIDE7IGsgPCBuOyBrKyspIHMgLT0gVWlba10gKiB4W2tdOwogICAgeFtpXSA9IHMgLyBVaVtpXTsKICB9CiAgcmV0dXJuIHg7Cn0KCi8qKgogKiBTb2x2ZSBBwrdYID0gQiBnaXZlbiB0aGUgbG93ZXItdHJpYW5ndWxhciBDaG9sZXNreSBmYWN0b3IgTCAoQSA9IEzCt0zhtYApOgogKiBmaXJzdCBzb2x2ZSBMwrdZID0gQiAoZm9yd2FyZCksIHRoZW4gTOG1gMK3WCA9IFkgKGJhY2spLgogKiBNYXRjaGVzIG5hbGdlYnJhIGBDaG9sZXNreTo6c29sdmVgLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IEwgbG93ZXItdHJpYW5ndWxhciBmYWN0b3IKICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXXxudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gY2hvbGVza3lTb2x2ZShMLCBCKSB7CiAgY29uc3QgeSA9IHNvbHZlTG93ZXJUcmkoTCwgQik7CiAgY29uc3QgTHQgPSB0cmFuc3Bvc2UoTCk7CiAgcmV0dXJuIHNvbHZlVXBwZXJUcmkoTHQsIHkpOwp9CgovKioKICogQ29tcHV0ZSBB4oG7wrkgPSAoTMK3TOG1gCnigbvCuSBmcm9tIHRoZSBsb3dlci10cmlhbmd1bGFyIENob2xlc2t5IGZhY3RvciBMLAogKiBieSBzb2x2aW5nIEHCt1ggPSBJLiBNYXRjaGVzIG5hbGdlYnJhIGBDaG9sZXNreTo6aW52ZXJzZWAuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTCBsb3dlci10cmlhbmd1bGFyIGZhY3RvcgogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0gQeKBu8K5CiAqLwpmdW5jdGlvbiBjaG9sZXNreUludmVyc2UoTCkgewogIGNvbnN0IG4gPSBMLmxlbmd0aDsKICByZXR1cm4gY2hvbGVza3lTb2x2ZShMLCBpZGVudGl0eShuKSk7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gRVhURU5EQUJMRSBNQVRSSVggLyBWRUNUT1IgIChFTWF0cml4IC8gRVZlY3RvcikKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIEEgbWF0cml4IHRoYXQgY2FuIGdyb3cgYnkgYXBwZW5kaW5nIHJvd3MuCiAqCiAqIEpTIHBvcnQgbm90ZTogd2Ugc2ltcGx5IGBwdXNoYCByb3dzLiBUaGUgUnVzdCB2ZXJzaW9uIHByZS1hbGxvY2F0ZXMgd2l0aCBhCiAqIDEuNcOXIGNhcGFjaXR5LWRvdWJsaW5nIHN0cmF0ZWd5IHB1cmVseSBmb3IgbWVtb3J5IGVmZmljaWVuY3k7IHRoYXQgaGFzIG5vCiAqIGVmZmVjdCBvbiB0aGUgbnVtZXJpY2FsIHJlc3VsdCwgc28gd2Ugb21pdCBpdCAoUE9SVF9TUEVDIMKnMi4zKS4KICovCmNsYXNzIEV4dGVuZGFibGVNYXRyaXggewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gZGF0YQogICAqLwogIGNvbnN0cnVjdG9yKGRhdGEpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW11bXX0gKi8KICAgIHRoaXMuZGF0YSA9IGRhdGE7CiAgfQoKICAvKiogTnVtYmVyIG9mIHJvd3MuIEByZXR1cm5zIHtudW1iZXJ9ICovCiAgZ2V0IG5yb3dzKCkgewogICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGg7CiAgfQoKICAvKiogTnVtYmVyIG9mIGNvbHVtbnMuIEByZXR1cm5zIHtudW1iZXJ9ICovCiAgZ2V0IG5jb2xzKCkgewogICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggPT09IDAgPyAwIDogdGhpcy5kYXRhWzBdLmxlbmd0aDsKICB9CgogIC8qKgogICAqIEN1cnJlbnQgZGF0YSBhcyBudW1iZXJbXVtdIChpbnRlcm5hbCByZWZlcmVuY2U7IGNhbGxlciBtdXN0IHRyZWF0IGFzIHJlYWQtb25seSkuCiAgICogQHJldHVybnMge251bWJlcltdW119CiAgICovCiAgYXNNYXRyaXgoKSB7CiAgICByZXR1cm4gdGhpcy5kYXRhOwogIH0KCiAgLyoqCiAgICogQXBwZW5kIHJvd3MgYXQgdGhlIGJvdHRvbSAoaW4gcGxhY2UpLgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gcm93cwogICAqLwogIGFkZFJvd3Mocm93cykgewogICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB0aGlzLmRhdGEucHVzaChyb3dzW2ldKTsKICB9Cn0KCi8qKgogKiBBIHZlY3RvciB0aGF0IGNhbiBncm93IGJ5IGFwcGVuZGluZyBlbnRyaWVzLgogKi8KY2xhc3MgRXh0ZW5kYWJsZVZlY3RvciB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXX0gZGF0YQogICAqLwogIGNvbnN0cnVjdG9yKGRhdGEpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW119ICovCiAgICB0aGlzLmRhdGEgPSBkYXRhOwogIH0KCiAgLyoqIE51bWJlciBvZiByb3dzIChlbnRyaWVzKS4gQHJldHVybnMge251bWJlcn0gKi8KICBnZXQgbnJvd3MoKSB7CiAgICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aDsKICB9CgogIC8qKgogICAqIEN1cnJlbnQgZGF0YSBhcyBudW1iZXJbXSAoaW50ZXJuYWwgcmVmZXJlbmNlOyBjYWxsZXIgbXVzdCB0cmVhdCBhcyByZWFkLW9ubHkpLgogICAqIEByZXR1cm5zIHtudW1iZXJbXX0KICAgKi8KICBhc1ZlY3RvcigpIHsKICAgIHJldHVybiB0aGlzLmRhdGE7CiAgfQoKICAvKioKICAgKiBBcHBlbmQgZW50cmllcyAoaW4gcGxhY2UpLgogICAqIEBwYXJhbSB7bnVtYmVyW119IHJvd3MKICAgKi8KICBhZGRSb3dzKHJvd3MpIHsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykgdGhpcy5kYXRhLnB1c2gocm93c1tpXSk7CiAgfQoKICAvKioKICAgKiBPdmVyd3JpdGUgdGhlIHdob2xlIGNvbnRlbnQ7IGxlbmd0aCBtdXN0IGVxdWFsIHRoZSBjdXJyZW50IGxlbmd0aAogICAqIChtYXRjaGVzIFJ1c3QgYGFzc2VydF9lcSFgKS4KICAgKiBAcGFyYW0ge251bWJlcltdfSByb3dzCiAgICovCiAgYXNzaWduKHJvd3MpIHsKICAgIGlmIChyb3dzLmxlbmd0aCAhPT0gdGhpcy5kYXRhLmxlbmd0aCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4dGVuZGFibGVWZWN0b3IuYXNzaWduOiBsZW5ndGggbWlzbWF0Y2ggKGdvdCAke3Jvd3MubGVuZ3RofSwgZXhwZWN0ZWQgJHt0aGlzLmRhdGEubGVuZ3RofSlgKTsKICAgIH0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykgdGhpcy5kYXRhW2ldID0gcm93c1tpXTsKICB9Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gQ0hPTEVTS1kgREVDT01QT1NJVElPTiBDTEFTUyAoaW5jcmVtZW50YWwgTyhuwrIpIHVwZGF0ZSkKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIEEgc3RvcmVkIENob2xlc2t5IGRlY29tcG9zaXRpb24gb2YgYSBzeW1tZXRyaWMgcG9zaXRpdmUtZGVmaW5pdGUgbWF0cml4LAogKiBzdXBwb3J0aW5nIGluY3JlbWVudGFsIE8obsKyKSBncm93dGggdmlhIGBpbnNlcnRDb2x1bW5gICh1c2VkIGJ5CiAqIEdhdXNzaWFuUHJvY2Vzcy5hZGRTYW1wbGVzKS4gTWlycm9ycyBuYWxnZWJyYSdzIGBDaG9sZXNreWAgb2JqZWN0IHRoYXQKICogZnJpZWRyaWNoIGtlZXBzIGluc2lkZSB0aGUgR1AuCiAqLwpjbGFzcyBDaG9sZXNreURlY29tcG9zaXRpb24gewogIC8qKgogICAqIEJ1aWxkIGZyb20gYSBzeW1tZXRyaWMgcG9zaXRpdmUtZGVmaW5pdGUgbWF0cml4LgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogICAqIEBwYXJhbSB7bnVtYmVyfG51bGx9IFtlcHNpbG9uPW51bGxdIG51bGwg4oaSIHRocm93IG9uIGZhaWx1cmU7IHBvc2l0aXZlIOKGkiBzdWJzdGl0dXRlIG1vZGUuCiAgICovCiAgY29uc3RydWN0b3IoQSwgZXBzaWxvbiA9IG51bGwpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW11bXX0gbG93ZXItdHJpYW5ndWxhciBmYWN0b3IgTCAoQSA9IEzCt0zhtYApICovCiAgICB0aGlzLl9MID0gY2hvbGVza3koQSwgZXBzaWxvbik7CiAgICAvKiogQHR5cGUge251bWJlcnxudWxsfSAqLwogICAgdGhpcy5fZXBzaWxvbiA9IGVwc2lsb247CiAgfQoKICAvKioKICAgKiBMb3dlci10cmlhbmd1bGFyIGZhY3RvciBMLgogICAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogICAqLwogIGwoKSB7CiAgICByZXR1cm4gdGhpcy5fTDsKICB9CgogIC8qKgogICAqIFNvbHZlIEHCt1ggPSBCIChCOiBudW1iZXJbXSB8IG51bWJlcltdW10pLCBzYW1lIHNoYXBlIG91dC4KICAgKiBFcXVpdmFsZW50IHRvIGNob2xlc2t5U29sdmUodGhpcy5sKCksIEIpLgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gQgogICAqIEByZXR1cm5zIHtudW1iZXJbXXxudW1iZXJbXVtdfQogICAqLwogIHNvbHZlKEIpIHsKICAgIHJldHVybiBjaG9sZXNreVNvbHZlKHRoaXMuX0wsIEIpOwogIH0KCiAgLyoqCiAgICogU29sdmUgTMK3WCA9IEIgKGZvcndhcmQgc3Vic3RpdHV0aW9uIG9ubHkpLgogICAqIEVxdWl2YWxlbnQgdG8gc29sdmVMb3dlclRyaSh0aGlzLmwoKSwgQikuCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBCCiAgICogQHJldHVybnMge251bWJlcltdfG51bWJlcltdW119CiAgICovCiAgc29sdmVMb3dlcihCKSB7CiAgICByZXR1cm4gc29sdmVMb3dlclRyaSh0aGlzLl9MLCBCKTsKICB9CgogIC8qKgogICAqIEludmVyc2UgQeKBu8K5LgogICAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogICAqLwogIGludmVyc2UoKSB7CiAgICByZXR1cm4gY2hvbGVza3lJbnZlcnNlKHRoaXMuX0wpOwogIH0KCiAgLyoqCiAgICogSW5zZXJ0IGEgcm93L2NvbHVtbiBhdCBwb3NpdGlvbiBgY29sSW5kZXhgLCB5aWVsZGluZyB0aGUKICAgKiAobisxKcOXKG4rMSkgZGVjb21wb3NpdGlvbi4gSW4gZnJpZWRyaWNoIGBjb2xJbmRleGAgaXMgYWx3YXlzIHRoZSBvbGQKICAgKiBkaW1lbnNpb24gKGkuZS4gYXBwZW5kZWQgYXQgdGhlIGVuZCksIHNvIHRoaXMgaW1wbGVtZW50cyB0aGUgc3RhbmRhcmQKICAgKiAiYm9yZGVyaW5nIiB1cGRhdGU6CiAgICoKICAgKiAgIEwnID0gWyBMICAgICAgMCAgIF0gICAgICB3aXRoICAgTCDCtyBsMjEgPSB2WzAuLm5dICAgKGxvd2VyLXRyaSBzb2x2ZSkKICAgKiAgICAgICAgWyBsMjHhtYAgICBsMjIgXSAgICAgICAgICAgICBsMjIgPSBzcXJ0KHZbbl0g4oiSIGwyMcK3bDIxKQogICAqCiAgICogd2hlcmUgYHZgID0gYG5ld0NvbHVtbmAgKGxlbmd0aCBuKzEpOiB2WzAuLm5dIGFyZSBjb3ZhcmlhbmNlcyB3aXRoIHRoZQogICAqIGV4aXN0aW5nIHJvd3MgYW5kIHZbbl0gaXMgdGhlIG5ldyBwb2ludCdzIHNlbGYtY292YXJpYW5jZSAoYWxyZWFkeQogICAqIGluY2x1ZGluZyBub2lzZcKyKS4KICAgKgogICAqIElmIGwyMsKyIOKJpCAwIGFuZCBhbiBlcHNpbG9uIHdhcyBjb25maWd1cmVkLCBzdWJzdGl0dXRlIGVwc2lsb24gZm9yIHRoZQogICAqIHBpdm90IChtYXRjaGVzIHRoZSBzdWJzdGl0dXRlIGJlaGF2aW91ciBvZiB0aGUgYmF0Y2ggQ2hvbGVza3kpLgogICAqCiAgICogVXBkYXRlcyB0aGlzIG9iamVjdCBpbiBwbGFjZSBhbmQgcmV0dXJucyBgdGhpc2AuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcn0gY29sSW5kZXggIG11c3QgZXF1YWwgdGhlIGN1cnJlbnQgZGltZW5zaW9uIChlbmQgaW5zZXJ0aW9uKQogICAqIEBwYXJhbSB7bnVtYmVyW119IG5ld0NvbHVtbiBsZW5ndGggY29sSW5kZXgrMQogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIGluc2VydENvbHVtbihjb2xJbmRleCwgbmV3Q29sdW1uKSB7CiAgICBjb25zdCBuID0gdGhpcy5fTC5sZW5ndGg7IC8vIG9sZCBkaW1lbnNpb24KICAgIC8vIGZyaWVkcmljaCBvbmx5IGV2ZXIgaW5zZXJ0cyBhdCB0aGUgZW5kLgogICAgaWYgKGNvbEluZGV4ICE9PSBuKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hvbGVza3lEZWNvbXBvc2l0aW9uLmluc2VydENvbHVtbjogb25seSBlbmQgaW5zZXJ0aW9uIHN1cHBvcnRlZCAoY29sSW5kZXg9JHtjb2xJbmRleH0sIGRpbT0ke259KWApOwogICAgfQogICAgY29uc3QgTCA9IHRoaXMuX0w7CgogICAgLy8gU29sdmUgTCDCtyBsMjEgPSB2WzAuLm5dICAoZm9yd2FyZCBzdWJzdGl0dXRpb24pLgogICAgY29uc3QgdiA9IG5ld0NvbHVtbjsKICAgIGNvbnN0IGwyMSA9IG5ldyBBcnJheShuKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGxldCBzID0gdltpXTsKICAgICAgY29uc3QgTGkgPSBMW2ldOwogICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykgcyAtPSBMaVtrXSAqIGwyMVtrXTsKICAgICAgbDIxW2ldID0gcyAvIExpW2ldOwogICAgfQoKICAgIC8vIGwyMiA9IHNxcnQodltuXSDiiJIgbDIxwrdsMjEpCiAgICBsZXQgcGl2b3QgPSB2W25dOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHBpdm90IC09IGwyMVtpXSAqIGwyMVtpXTsKICAgIGlmICh0aGlzLl9lcHNpbG9uID09PSBudWxsKSB7CiAgICAgIGlmICghKHBpdm90ID4gMCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkNob2xlc2t5IGRlY29tcG9zaXRpb24gZmFpbGVkLCBjb25zaWRlciBzZXR0aW5nIGBjaG9sZXNreV9lcHNpbG9uYCB2aWEgYEdhdXNzaWFuUHJvY2Vzc0J1aWxkZXJgIik7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoIShwaXZvdCA+IDApKSB7CiAgICAgIHBpdm90ID0gdGhpcy5fZXBzaWxvbjsKICAgIH0KICAgIGNvbnN0IGwyMiA9IE1hdGguc3FydChwaXZvdCk7CgogICAgLy8gQnVpbGQgdGhlIChuKzEpw5cobisxKSBsb3dlci10cmlhbmd1bGFyIGZhY3Rvci4KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBMW2ldLnB1c2goMCk7IC8vIHBhZCBleGlzdGluZyByb3dzIHdpdGggYSAwIGluIHRoZSBuZXcgY29sdW1uCiAgICBjb25zdCBsYXN0Um93ID0gbmV3IEFycmF5KG4gKyAxKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBsYXN0Um93W2ldID0gbDIxW2ldOwogICAgbGFzdFJvd1tuXSA9IGwyMjsKICAgIEwucHVzaChsYXN0Um93KTsKICAgIHJldHVybiB0aGlzOwogIH0KfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDT1ZBUklBTkNFLU1BVFJJWCBIRUxQRVJTICAoYWxnZWJyYS9tb2QucnMgZnJlZSBmdW5jdGlvbnMpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBDb3ZhcmlhbmNlIG1hdHJpeCBiZXR3ZWVuIHJvd3Mgb2YgbTEgYW5kIHJvd3Mgb2YgbTIgdXNpbmcgYGtlcm5lbGAuCiAqIG91dFtyXVtjXSA9IGtlcm5lbC5rZXJuZWwobTFbcl0sIG0yW2NdKS4gU2hhcGUgKG0xLmxlbmd0aCDDlyBtMi5sZW5ndGgpLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IG0xCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gbTIKICogQHBhcmFtIHt7a2VybmVsOiAoeDE6bnVtYmVyW10sIHgyOm51bWJlcltdKSA9PiBudW1iZXJ9fSBrZXJuZWwKICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiBtYWtlQ292YXJpYW5jZU1hdHJpeChtMSwgbTIsIGtlcm5lbCkgewogIGNvbnN0IHIgPSBtMS5sZW5ndGg7CiAgY29uc3QgYyA9IG0yLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkocik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByOyBpKyspIHsKICAgIGNvbnN0IHJvdyA9IG5ldyBBcnJheShjKTsKICAgIGNvbnN0IHhpID0gbTFbaV07CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGM7IGorKykgcm93W2pdID0ga2VybmVsLmtlcm5lbCh4aSwgbTJbal0pOwogICAgb3V0W2ldID0gcm93OwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogQ292YXJpYW5jZSBtYXRyaXggb2YgYGlucHV0c2Agd2l0aCBkaWFnb25hbCBub2lzZcKyLCByZXR1cm5lZCBhcyBpdHMKICogQ2hvbGVza3lEZWNvbXBvc2l0aW9uLgogKgogKiAgIGNvdltpXVtqXSA9IGtlcm5lbC5rZXJuZWwoaW5wdXRzW2ldLCBpbnB1dHNbal0pCiAqICAgY292W2ldW2ldICs9IGRpYWdvbmFsTm9pc2XCsiAgIChub3RlOiB0aGUgU1FVQVJFIG9mIHRoZSBub2lzZSkKICoKICogYGVwc2lsb25gIGlzIGZvcndhcmRlZCB0byB0aGUgQ2hvbGVza3kgKG51bGwg4oaSIHRocm93IG9uIGZhaWx1cmU7CiAqIHBvc2l0aXZlIOKGkiBzdWJzdGl0dXRlIG1vZGUpLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogKiBAcGFyYW0ge3trZXJuZWw6ICh4MTpudW1iZXJbXSwgeDI6bnVtYmVyW10pID0+IG51bWJlcn19IGtlcm5lbAogKiBAcGFyYW0ge251bWJlcn0gZGlhZ29uYWxOb2lzZSB0aGUgbm9pc2UgU1RBTkRBUkQgREVWSUFUSU9OCiAqIEBwYXJhbSB7bnVtYmVyfG51bGx9IFtlcHNpbG9uPW51bGxdCiAqIEByZXR1cm5zIHtDaG9sZXNreURlY29tcG9zaXRpb259CiAqLwpmdW5jdGlvbiBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoaW5wdXRzLCBrZXJuZWwsIGRpYWdvbmFsTm9pc2UsIGVwc2lsb24gPSBudWxsKSB7CiAgY29uc3QgbiA9IGlucHV0cy5sZW5ndGg7CiAgY29uc3Qgbm9pc2VTcSA9IGRpYWdvbmFsTm9pc2UgKiBkaWFnb25hbE5vaXNlOwogIGNvbnN0IGNvdiA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgY29uc3Qgcm93ID0gbmV3IEFycmF5KG4pOwogICAgY29uc3QgeGkgPSBpbnB1dHNbaV07CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykgcm93W2pdID0ga2VybmVsLmtlcm5lbCh4aSwgaW5wdXRzW2pdKTsKICAgIHJvd1tpXSArPSBub2lzZVNxOwogICAgY292W2ldID0gcm93OwogIH0KICByZXR1cm4gbmV3IENob2xlc2t5RGVjb21wb3NpdGlvbihjb3YsIGVwc2lsb24pOwp9CgovKioKICogSW5jcmVtZW50YWxseSBhZGQgdGhlIGxhc3QgYG5iTmV3SW5wdXRzYCByb3dzIG9mIGBhbGxJbnB1dHNgIHRvIGFuIGV4aXN0aW5nCiAqIENob2xlc2t5IGRlY29tcG9zaXRpb24gKGluIHBsYWNlKSwgb25lIHJvdyBhdCBhIHRpbWUuIEZvciBlYWNoIG5ldyByb3c6CiAqICAgLSBjb21wdXRlIHRoZSBuZXcgY29sdW1uIChjb3ZhcmlhbmNlcyB3aXRoIGFsbCByb3dzIHVwIHRvIGFuZCBpbmNsdWRpbmcKICogICAgIGl0c2VsZiwgbGVuZ3RoIGNvbF9pbmRleCsxKSwKICogICAtIGFkZCBub2lzZcKyIHRvIHRoZSBmaW5hbCAoc2VsZikgZW50cnksCiAqICAgLSBjYWxsIGBjaG9sZXNreS5pbnNlcnRDb2x1bW4oY29sX2luZGV4LCBjb2x1bW4pYC4KICoKICogQHBhcmFtIHtDaG9sZXNreURlY29tcG9zaXRpb259IGNob2xlc2t5IHVwZGF0ZWQgaW4gcGxhY2UKICogQHBhcmFtIHtudW1iZXJbXVtdfSBhbGxJbnB1dHMgZnVsbCBpbnB1dCBtYXRyaXggKG9sZCByb3dzIHRoZW4gbmV3IHJvd3MpCiAqIEBwYXJhbSB7bnVtYmVyfSBuYk5ld0lucHV0cyBudW1iZXIgb2YgdHJhaWxpbmcgcm93cyB0byBhZGQKICogQHBhcmFtIHt7a2VybmVsOiAoeDE6bnVtYmVyW10sIHgyOm51bWJlcltdKSA9PiBudW1iZXJ9fSBrZXJuZWwKICogQHBhcmFtIHtudW1iZXJ9IGRpYWdvbmFsTm9pc2UgdGhlIG5vaXNlIFNUQU5EQVJEIERFVklBVElPTgogKi8KZnVuY3Rpb24gYWRkUm93c0Nob2xlc2t5Q292TWF0cml4KGNob2xlc2t5LCBhbGxJbnB1dHMsIG5iTmV3SW5wdXRzLCBrZXJuZWwsIGRpYWdvbmFsTm9pc2UpIHsKICBjb25zdCB0b3RhbCA9IGFsbElucHV0cy5sZW5ndGg7CiAgY29uc3QgbmJPbGQgPSB0b3RhbCAtIG5iTmV3SW5wdXRzOwogIGNvbnN0IG5vaXNlU3EgPSBkaWFnb25hbE5vaXNlICogZGlhZ29uYWxOb2lzZTsKICBmb3IgKGxldCByb3dJbmRleCA9IDA7IHJvd0luZGV4IDwgbmJOZXdJbnB1dHM7IHJvd0luZGV4KyspIHsKICAgIGNvbnN0IGNvbEluZGV4ID0gbmJPbGQgKyByb3dJbmRleDsKICAgIGNvbnN0IHJvdyA9IGFsbElucHV0c1tjb2xJbmRleF07CiAgICBjb25zdCBjb2x1bW5TaXplID0gY29sSW5kZXggKyAxOwogICAgY29uc3QgbmV3Q29sdW1uID0gbmV3IEFycmF5KGNvbHVtblNpemUpOwogICAgZm9yIChsZXQgdHJhaW5pbmdSb3dJbmRleCA9IDA7IHRyYWluaW5nUm93SW5kZXggPCBjb2x1bW5TaXplOyB0cmFpbmluZ1Jvd0luZGV4KyspIHsKICAgICAgbmV3Q29sdW1uW3RyYWluaW5nUm93SW5kZXhdID0ga2VybmVsLmtlcm5lbChhbGxJbnB1dHNbdHJhaW5pbmdSb3dJbmRleF0sIHJvdyk7CiAgICB9CiAgICBuZXdDb2x1bW5bY29sSW5kZXhdICs9IG5vaXNlU3E7CiAgICBjaG9sZXNreS5pbnNlcnRDb2x1bW4oY29sSW5kZXgsIG5ld0NvbHVtbik7CiAgfQp9CgovKioKICogRm9yIGVhY2gga2VybmVsIGh5cGVyLXBhcmFtZXRlciwgYnVpbGQgdGhlIChzeW1tZXRyaWMpIGdyYWRpZW50IG1hdHJpeAogKiDiiIJLL+KIgnBhcmFtLiBSZXR1cm5zIG51bWJlcltdW11bXSBvZiBsZW5ndGgga2VybmVsLm5iUGFyYW1ldGVycygpLgogKgogKiAgIG1hdHNbcF1bcl1bY10gPSBtYXRzW3BdW2NdW3JdID0ga2VybmVsLmdyYWRpZW50KGlucHV0c1tyXSwgaW5wdXRzW2NdKVtwXQogKgogKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogKiBAcGFyYW0ge3tuYlBhcmFtZXRlcnM6ICgpID0+IG51bWJlciwgZ3JhZGllbnQ6ICh4MTpudW1iZXJbXSwgeDI6bnVtYmVyW10pID0+IG51bWJlcltdfX0ga2VybmVsCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdW119CiAqLwpmdW5jdGlvbiBtYWtlR3JhZGllbnRDb3ZhcmlhbmNlTWF0cmljZXMoaW5wdXRzLCBrZXJuZWwpIHsKICBjb25zdCBuID0gaW5wdXRzLmxlbmd0aDsKICBjb25zdCBuYlBhcmFtcyA9IGtlcm5lbC5uYlBhcmFtZXRlcnMoKTsKICBjb25zdCBtYXRzID0gbmV3IEFycmF5KG5iUGFyYW1zKTsKICBmb3IgKGxldCBwID0gMDsgcCA8IG5iUGFyYW1zOyBwKyspIG1hdHNbcF0gPSB6ZXJvcyhuLCBuKTsKICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgewogICAgY29uc3QgeHIgPSBpbnB1dHNbcl07CiAgICAvLyBTeW1tZXRyaWM6IGZpbGwgKHIsYykgYW5kIChjLHIpIHRvZ2V0aGVyIGZvciBjIOKJpSByLgogICAgZm9yIChsZXQgYyA9IHI7IGMgPCBuOyBjKyspIHsKICAgICAgY29uc3QgZ3JhZCA9IGtlcm5lbC5ncmFkaWVudCh4ciwgaW5wdXRzW2NdKTsKICAgICAgZm9yIChsZXQgcCA9IDA7IHAgPCBuYlBhcmFtczsgcCsrKSB7CiAgICAgICAgbWF0c1twXVtyXVtjXSA9IGdyYWRbcF07CiAgICAgICAgbWF0c1twXVtjXVtyXSA9IGdyYWRbcF07CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIG1hdHM7Cn0KCi8vISAjIEtlcm5lbHMKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gRklUIEhFVVJJU1RJQ1MgKGZyZWUgZnVuY3Rpb25zLCBleHBvcnRlZCBmb3Iga2VybmVscyAmIHRlc3RzKQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogUm91Z2ggYmFuZHdpZHRoIGVzdGltYXRlOiBtZWFuIEV1Y2xpZGVhbiBkaXN0YW5jZSBiZXR3ZWVuIGRpc3RpbmN0IHNhbXBsZXMuCiAqICAgzqNfe2k8an0g4oCWeOG1oiDiiJIgeOKxvOKAliAvIChuKG7iiJIxKS8yKQogKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gZml0QmFuZHdpZHRoTWVhbihpbnB1dHMpIHsKICBsZXQgc3VtRGlzdGFuY2VzID0gMDsKICBjb25zdCBuYlNhbXBsZXMgPSBpbnB1dHMubGVuZ3RoOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbmJTYW1wbGVzOyBpKyspIHsKICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IG5iU2FtcGxlczsgaisrKSB7CiAgICAgIHN1bURpc3RhbmNlcyArPSBub3JtKHN1YlZlYyhpbnB1dHNbaV0sIGlucHV0c1tqXSkpOwogICAgfQogIH0KICAvLyBJbnRlZ2VyIGFyaXRobWV0aWMgbWF0Y2hlcyBSdXN0IGAobipuIC0gbikgLyAyYC4KICBjb25zdCBuYkRpc3RhbmNlcyA9IChuYlNhbXBsZXMgKiBuYlNhbXBsZXMgLSBuYlNhbXBsZXMpIC8gMjsKICByZXR1cm4gc3VtRGlzdGFuY2VzIC8gbmJEaXN0YW5jZXM7Cn0KCi8qKgogKiBCZXN0LWd1ZXNzIGFtcGxpdHVkZSA9IHZhcmlhbmNlIG9mIHRoZSBvdXRwdXRzLgogKgogKiBNYXRjaGVzIG5hbGdlYnJhIGB2YXJpYW5jZSgpYDogzqMoeeG1oiDiiJIgbWVhbinCsiAvIE4gKGRpdmlkZXMgYnkgTiwgdGhlIHNhbXBsZQogKiBjb3VudCDigJQgTk9UIE7iiJIxKS4gQ29uZmlybWVkIGZyb20gbmFsZ2VicmEgMC4zNC4yIHN0YXRpc3RpY3MucnMgKFBPUlRfU1BFQyDCpzQuMSkuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW119IG91dHB1dHMKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIGZpdEFtcGxpdHVkZVZhcihvdXRwdXRzKSB7CiAgY29uc3QgbiA9IG91dHB1dHMubGVuZ3RoOwogIGxldCBtZWFuID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgbWVhbiArPSBvdXRwdXRzW2ldOwogIG1lYW4gLz0gbjsKICBsZXQgYWNjID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgY29uc3QgZCA9IG91dHB1dHNbaV0gLSBtZWFuOwogICAgYWNjICs9IGQgKiBkOwogIH0KICByZXR1cm4gYWNjIC8gbjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIFNxdWFyZWQgZXhwb25lbnRpYWwgKGEuay5hLiBHYXVzc2lhbikga2VybmVsOgogKiAgIGsoeCx5KSA9IEHCt2V4cCjiiJLigJZ44oiSeeKAlsKyIC8gKDLCt2xzwrIpKSwgIEEgPSB8YW1wbHwuCiAqIFBhcmFtZXRlcnM6IFtscywgYW1wbF0gKGRlZmF1bHRzIGxzID0gMSwgYW1wbCA9IDEpLiBuYlBhcmFtZXRlcnMgPSAyLiBTY2FsYWJsZS4KICovCmNsYXNzIFNxdWFyZWRFeHAgewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyfSBbbHM9MV0KICAgKiBAcGFyYW0ge251bWJlcn0gW2FtcGw9MV0KICAgKi8KICBjb25zdHJ1Y3RvcihscyA9IDEsIGFtcGwgPSAxKSB7CiAgICAvKiogQHR5cGUge251bWJlcn0gbGVuZ3RoIHNjYWxlICovCiAgICB0aGlzLmxzID0gbHM7CiAgICAvKiogQHR5cGUge251bWJlcn0gYW1wbGl0dWRlICovCiAgICB0aGlzLmFtcGwgPSBhbXBsOwogIH0KICBuYlBhcmFtZXRlcnMoKSB7CiAgICByZXR1cm4gMjsKICB9CiAgaXNTY2FsYWJsZSgpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDEKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MgogICAqIEByZXR1cm5zIHtudW1iZXJ9CiAgICovCiAga2VybmVsKHgxLCB4MikgewogICAgLy8gU2FuaXRpemUgcGFyYW1ldGVycy4KICAgIGNvbnN0IGFtcGwgPSBNYXRoLmFicyh0aGlzLmFtcGwpOwogICAgY29uc3QgZGlzdGFuY2VTcXVhcmVkID0gbm9ybVNxdWFyZWQoc3ViVmVjKHgxLCB4MikpOwogICAgY29uc3QgeCA9IC1kaXN0YW5jZVNxdWFyZWQgLyAoMiAqIHRoaXMubHMgKiB0aGlzLmxzKTsKICAgIHJldHVybiBhbXBsICogTWF0aC5leHAoeCk7CiAgfQoKICAvKioKICAgKiBncmFkaWVudCA9IFtncmFkX2xzLCBncmFkX2FtcGxdIHdpdGggZMKyID0g4oCWeOKIknnigJbCsiwgQSA9IHxhbXBsfCwKICAgKiAgIGUgPSBleHAo4oiSZMKyLygywrdsc8KyKSk6CiAgICogICBncmFkX2xzICAgPSAoZMKyIMK3IEEgwrcgZSkgLyBsc8KzCiAgICogICBncmFkX2FtcGwgPSBzaWduKGFtcGwpIMK3IGUKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MQogICAqIEBwYXJhbSB7bnVtYmVyW119IHgyCiAgICogQHJldHVybnMge251bWJlcltdfQogICAqLwogIGdyYWRpZW50KHgxLCB4MikgewogICAgY29uc3QgYW1wbCA9IE1hdGguYWJzKHRoaXMuYW1wbCk7CiAgICBjb25zdCBkaXN0YW5jZVNxdWFyZWQgPSBub3JtU3F1YXJlZChzdWJWZWMoeDEsIHgyKSk7CiAgICBjb25zdCBleHBvbmVudGlhbCA9IE1hdGguZXhwKC1kaXN0YW5jZVNxdWFyZWQgLyAoMiAqIHRoaXMubHMgKiB0aGlzLmxzKSk7CiAgICBjb25zdCBncmFkTHMgPSBkaXN0YW5jZVNxdWFyZWQgKiBhbXBsICogZXhwb25lbnRpYWwgLyBNYXRoLnBvdyh0aGlzLmxzLCAzKTsKICAgIGNvbnN0IGdyYWRBbXBsID0gTWF0aC5zaWduKHRoaXMuYW1wbCkgKiBleHBvbmVudGlhbDsKICAgIHJldHVybiBbZ3JhZExzLCBncmFkQW1wbF07CiAgfQoKICAvKiogQHBhcmFtIHtudW1iZXJ9IHNjYWxlICovCiAgcmVzY2FsZShzY2FsZSkgewogICAgdGhpcy5hbXBsICo9IHNjYWxlOwogIH0KICBnZXRQYXJhbWV0ZXJzKCkgewogICAgcmV0dXJuIFt0aGlzLmxzLCB0aGlzLmFtcGxdOwogIH0KCiAgLyoqIEBwYXJhbSB7bnVtYmVyW119IHBhcmFtZXRlcnMgKi8KICBzZXRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpIHsKICAgIHRoaXMubHMgPSBwYXJhbWV0ZXJzWzBdOwogICAgdGhpcy5hbXBsID0gcGFyYW1ldGVyc1sxXTsKICB9CgogIC8qKgogICAqIGhldXJpc3RpYzogbHMgPSBtZWFuIGludGVyLXNhbXBsZSBkaXN0YW5jZSwgYW1wbCA9IG91dHB1dCB2YXJpYW5jZS4KICAgKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyW119IG91dHB1dHMKICAgKi8KICBoZXVyaXN0aWNGaXQoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICB0aGlzLmxzID0gZml0QmFuZHdpZHRoTWVhbihpbnB1dHMpOwogICAgdGhpcy5hbXBsID0gZml0QW1wbGl0dWRlVmFyKG91dHB1dHMpOwogIH0KfQoKLyoqIEdhdXNzaWFuIGtlcm5lbCDigJQgYWxpYXMgb2YgU3F1YXJlZEV4cCAoUnVzdCBgcHViIHR5cGUgR2F1c3NpYW4gPSBTcXVhcmVkRXhwYCkuICovCmNvbnN0IEdhdXNzaWFuID0gU3F1YXJlZEV4cDsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBFeHBvbmVudGlhbCBrZXJuZWw6CiAqICAgayh4LHkpID0gQcK3ZXhwKOKIkuKAlnjiiJJ54oCWIC8gKDLCt2xzwrIpKSwgIEEgPSB8YW1wbHwuCiAqIE5PVEUgdGhlIGRlbm9taW5hdG9yIGlzIDLCt2xzwrIgKE5PVCBscyksIGZhaXRoZnVsIHRvIFJ1c3QuCiAqIFBhcmFtZXRlcnM6IFtscywgYW1wbF0gKGRlZmF1bHRzIGxzID0gMSwgYW1wbCA9IDEpLiBuYlBhcmFtZXRlcnMgPSAyLiBTY2FsYWJsZS4KICovCmNsYXNzIEV4cG9uZW50aWFsIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcn0gW2xzPTFdCiAgICogQHBhcmFtIHtudW1iZXJ9IFthbXBsPTFdCiAgICovCiAgY29uc3RydWN0b3IobHMgPSAxLCBhbXBsID0gMSkgewogICAgLyoqIEB0eXBlIHtudW1iZXJ9IGxlbmd0aCBzY2FsZSAqLwogICAgdGhpcy5scyA9IGxzOwogICAgLyoqIEB0eXBlIHtudW1iZXJ9IGFtcGxpdHVkZSAqLwogICAgdGhpcy5hbXBsID0gYW1wbDsKICB9CiAgbmJQYXJhbWV0ZXJzKCkgewogICAgcmV0dXJuIDI7CiAgfQogIGlzU2NhbGFibGUoKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW119IHgxCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDIKICAgKiBAcmV0dXJucyB7bnVtYmVyfQogICAqLwogIGtlcm5lbCh4MSwgeDIpIHsKICAgIGNvbnN0IGFtcGwgPSBNYXRoLmFicyh0aGlzLmFtcGwpOwogICAgY29uc3QgZGlzdGFuY2UgPSBub3JtKHN1YlZlYyh4MSwgeDIpKTsKICAgIGNvbnN0IHggPSAtZGlzdGFuY2UgLyAoMiAqIHRoaXMubHMgKiB0aGlzLmxzKTsKICAgIHJldHVybiBhbXBsICogTWF0aC5leHAoeCk7CiAgfQoKICAvKioKICAgKiBncmFkaWVudCA9IFtncmFkX2xzLCBncmFkX2FtcGxdIHdpdGggZCA9IOKAlnjiiJJ54oCWLCBBID0gfGFtcGx8LAogICAqICAgZSA9IGV4cCjiiJJkLygywrdsc8KyKSk6CiAgICogICBncmFkX2xzICAgPSAoZCDCtyBBIMK3IGUpIC8gbHPCswogICAqICAgZ3JhZF9hbXBsID0gc2lnbihhbXBsKSDCtyBlCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDEKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MgogICAqIEByZXR1cm5zIHtudW1iZXJbXX0KICAgKi8KICBncmFkaWVudCh4MSwgeDIpIHsKICAgIGNvbnN0IGFtcGwgPSBNYXRoLmFicyh0aGlzLmFtcGwpOwogICAgY29uc3QgZGlzdGFuY2UgPSBub3JtKHN1YlZlYyh4MSwgeDIpKTsKICAgIGNvbnN0IGV4cG9uZW50aWFsID0gTWF0aC5leHAoLWRpc3RhbmNlIC8gKDIgKiB0aGlzLmxzICogdGhpcy5scykpOwogICAgY29uc3QgZ3JhZExzID0gZGlzdGFuY2UgKiBhbXBsICogZXhwb25lbnRpYWwgLyBNYXRoLnBvdyh0aGlzLmxzLCAzKTsKICAgIGNvbnN0IGdyYWRBbXBsID0gTWF0aC5zaWduKHRoaXMuYW1wbCkgKiBleHBvbmVudGlhbDsKICAgIHJldHVybiBbZ3JhZExzLCBncmFkQW1wbF07CiAgfQoKICAvKiogQHBhcmFtIHtudW1iZXJ9IHNjYWxlICovCiAgcmVzY2FsZShzY2FsZSkgewogICAgdGhpcy5hbXBsICo9IHNjYWxlOwogIH0KICBnZXRQYXJhbWV0ZXJzKCkgewogICAgcmV0dXJuIFt0aGlzLmxzLCB0aGlzLmFtcGxdOwogIH0KCiAgLyoqIEBwYXJhbSB7bnVtYmVyW119IHBhcmFtZXRlcnMgKi8KICBzZXRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpIHsKICAgIHRoaXMubHMgPSBwYXJhbWV0ZXJzWzBdOwogICAgdGhpcy5hbXBsID0gcGFyYW1ldGVyc1sxXTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJbXX0gb3V0cHV0cwogICAqLwogIGhldXJpc3RpY0ZpdChpbnB1dHMsIG91dHB1dHMpIHsKICAgIHRoaXMubHMgPSBmaXRCYW5kd2lkdGhNZWFuKGlucHV0cyk7CiAgICB0aGlzLmFtcGwgPSBmaXRBbXBsaXR1ZGVWYXIob3V0cHV0cyk7CiAgfQp9CgovKioKICogUHJpb3IgbW9kZWxzIGZvciBHYXVzc2lhbiBQcm9jZXNzIFJlZ3Jlc3Npb24uCiAqCiAqIFBvcnQgb2YgYGZyaWVkcmljaCAwLjYuMCBzcmMvcGFyYW1ldGVycy9wcmlvci5yc2AuCiAqCiAqIFdoZW4gYXNrZWQgdG8gcHJlZGljdCBhIHZhbHVlIGZvciBhbiBpbnB1dCB0aGF0IGlzIHRvbyBkaXNzaW1pbGFyIHRvIGtub3duCiAqIGlucHV0cywgdGhlIG1vZGVsIHJldHVybnMgdGhlIHByaW9yLiBUaGUgR1AgaXMgZml0dGVkIG9uIHRoZSAqcmVzaWR1YWwqIG9mCiAqIHRoZSBwcmlvciwgc28gYSBnb29kIHByaW9yIGNhbiBzaWduaWZpY2FudGx5IGltcHJvdmUgcHJlY2lzaW9uLgogKgogKiBEYXRhIHJlcHJlc2VudGF0aW9uIChzZWUgUE9SVF9TUEVDIMKnMik6CiAqICAgLSBpbnB1dHMgIDogbnVtYmVyW11bXSAocm93LW1ham9yOyBvbmUgc2FtcGxlIHBlciByb3cpCiAqICAgLSBvdXRwdXRzIDogbnVtYmVyW10KICoKICogRGVwZW5kZW5jaWVzOiBhbGdlYnJhLm1qcyAoZG90LCBsc3RzcVNvbHZlKQogKi8KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBDb25zdGFudFByaW9yCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIFRoZSBDb25zdGFudCBwcmlvci4KICoKICogUmV0dXJucyBhIHNpbmdsZSBjb25zdGFudCB2YWx1ZSBmb3IgZXZlcnkgaW5wdXQgcG9pbnQ6IGYoeCkgPSBjLgogKiBDYW4gYmUgZml0dGVkIHRvIHRoZSBtZWFuIG9mIHRoZSB0cmFpbmluZyBvdXRwdXRzLgogKi8KY2xhc3MgQ29uc3RhbnRQcmlvciB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJ9IGMgdGhlIGNvbnN0YW50IHByaW9yIHZhbHVlCiAgICovCiAgY29uc3RydWN0b3IoYykgewogICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovCiAgICB0aGlzLmMgPSBjOwogIH0KCiAgLyoqCiAgICogQ3JlYXRlcyB0aGUgZGVmYXVsdCBDb25zdGFudFByaW9yIHdpdGggYyA9IDAuCiAgICogTWF0Y2hlcyBSdXN0IGBDb25zdGFudFByaW9yOjpkZWZhdWx0KF9pbnB1dF9kaW1lbnNpb24pIOKGkiBTZWxmOjpuZXcoMGY2NClgLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJ9IF9pbnB1dERpbWVuc2lvbiBpZ25vcmVkCiAgICogQHJldHVybnMge0NvbnN0YW50UHJpb3J9CiAgICovCiAgc3RhdGljIGRlZmF1bHQoX2lucHV0RGltZW5zaW9uKSB7CiAgICByZXR1cm4gbmV3IENvbnN0YW50UHJpb3IoMCk7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIGEgY29uc3RhbnQgdmVjdG9yIG9mIGxlbmd0aCBgaW5wdXRzLmxlbmd0aGAsIGVhY2ggZW50cnkgPSB0aGlzLmMuCiAgICogTWF0Y2hlcyBSdXN0IGBwcmlvcihpbnB1dCkg4oaSIERWZWN0b3I6OmZyb21fZWxlbWVudChpbnB1dC5ucm93cygpLCBzZWxmLmMpYC4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzIG9uZSBzYW1wbGUgcGVyIHJvdwogICAqIEByZXR1cm5zIHtudW1iZXJbXX0gY29uc3RhbnQgYXJyYXksIGxlbmd0aCA9IGlucHV0cy5sZW5ndGgKICAgKi8KICBwcmlvcihpbnB1dHMpIHsKICAgIHJldHVybiBuZXcgQXJyYXkoaW5wdXRzLmxlbmd0aCkuZmlsbCh0aGlzLmMpOwogIH0KCiAgLyoqCiAgICogRml0cyB0aGUgcHJpb3IgdG8gdGhlIGFyaXRobWV0aWMgbWVhbiBvZiBgb3V0cHV0c2AuCiAgICogTWF0Y2hlcyBSdXN0IGBmaXQoXywgdHJhaW5pbmdfb3V0cHV0cykgeyBzZWxmLmMgPSB0cmFpbmluZ19vdXRwdXRzLm1lYW4oKSB9YC4KICAgKiBuYWxnZWJyYSdzIGBtZWFuKClgIGRpdmlkZXMgYnkgTiAoZWxlbWVudCBjb3VudCksIG1hdGNoaW5nIEpTIGFyaXRobWV0aWMgbWVhbi4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gX2lucHV0cyBpZ25vcmVkCiAgICogQHBhcmFtIHtudW1iZXJbXX0gb3V0cHV0cyB0cmFpbmluZyBvdXRwdXQgdmFsdWVzCiAgICovCiAgZml0KF9pbnB1dHMsIG91dHB1dHMpIHsKICAgIGNvbnN0IG4gPSBvdXRwdXRzLmxlbmd0aDsKICAgIGxldCBzdW0gPSAwOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHN1bSArPSBvdXRwdXRzW2ldOwogICAgdGhpcy5jID0gc3VtIC8gbjsKICB9Cn0KCi8qKgogKiBjb252ZXJzaW9uLm1qcyDigJQgSW5wdXQgZmxleGliaWxpdHkgZm9yIHRoZSBKUyBwb3J0IG9mIGZyaWVkcmljaCAwLjYuMC4KICoKICogUG9ydCBvZiBgc3JjL2NvbnZlcnNpb24vbW9kLnJzYC4KICoKICogUnVzdCdzIGBJbnB1dGAgdHJhaXQgdXNlcyB0aGUgdHlwZSBzeXN0ZW0gdG8gZGlzdGluZ3Vpc2g6CiAqICAgLSBgVmVjPGY2ND5gICAgICAgIChzaW5nbGUgbXVsdGlkaW1lbnNpb25hbCBwb2ludCkg4oaSIG91dHB1dCBgZjY0YAogKiAgIC0gYFZlYzxWZWM8ZjY0Pj5gIChtdWx0aXBsZSBwb2ludHMpICAgICAgICAgICAgICAg4oaSIG91dHB1dCBgVmVjPGY2ND5gCiAqICAgLSBgRE1hdHJpeDxmNjQ+YCAgKG5hbGdlYnJhIG1hdHJpeCkgICAgICAgICAgICAgICDihpIgb3V0cHV0IGBEVmVjdG9yPGY2ND5gCiAqCiAqIEpTIGhhcyBubyBwYXJhbWV0cmljIHR5cGVzLCBzbyB3ZSB1c2UgKipydW50aW1lIGRldGVjdGlvbioqIG9uIHRoZSBmaXJzdAogKiBlbGVtZW50IG9mIHRoZSBpbnB1dCBhcnJheToKICogICAtIGBudW1iZXJbXWAgICB3aGVyZSBgdHlwZW9mIGlucHV0WzBdID09PSAnbnVtYmVyJ2Ag4oaSIHNpbmdsZSBwb2ludAogKiAgIC0gYG51bWJlcltdW11gIHdoZXJlIGBBcnJheS5pc0FycmF5KGlucHV0WzBdKWAgICAgICDihpIgbXVsdGlwbGUgcG9pbnRzCiAqCiAqIFRoZSAiaXNTaW5nbGUiIGZsYWcgaXMgcHJvcGFnYXRlZCBpbnRvIEdQIHJlc3VsdHMgc28gdGhhdDoKICogICAtIHNpbmdsZS1wb2ludCBpbnB1dHMgIOKGkiBzY2FsYXIgb3V0cHV0cyAgKGBudW1iZXJgKQogKiAgIC0gbXVsdGktcG9pbnQgaW5wdXRzICAg4oaSIHZlY3RvciBvdXRwdXRzICAoYG51bWJlcltdYCkKICoKICogVGhpcyBtYXRjaGVzIHRoZSBgT3V0VmVjdG9yID0gZjY0YCB2cyBgT3V0VmVjdG9yID0gVmVjPGY2ND5gIGRpc3RpbmN0aW9uCiAqIG9mIHRoZSBSdXN0IHRyYWl0IGltcGxzLgogKgogKiBQT1JUX1NQRUMgwqc5IChjb252ZXJzaW9uLm1qcyksIMKnMTIgaXRlbSAxMCAoY29sdW1uLW1ham9yIHZzIHJvdy1tYWpvcikuCiAqCiAqIE5vIGludGVybmFsIGRlcGVuZGVuY2llcyAoY29udmVyc2lvbi5tanMgaGFzIG5vIGltcG9ydHMgcGVyIFBPUlRfU1BFQyDCpzEKICogZGVwZW5kZW5jeSBncmFwaCkuCiAqLwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIGlzU2luZ2xlCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIERldGVjdCB3aGV0aGVyIGBpbnB1dGAgcmVwcmVzZW50cyBhICoqc2luZ2xlKiogbXVsdGlkaW1lbnNpb25hbCBwb2ludC4KICoKICogUnVsZXMgKG1pcnJvcnMgUnVzdCB0cmFpdCBkaXNwYXRjaCk6CiAqICAgLSBgbnVtYmVyW11gICAgKGFsbCBlbGVtZW50cyBhcmUgbnVtYmVycykgIOKGkiB0cnVlICAgKHNpbmdsZSBwb2ludCwgbGlrZSBgVmVjPGY2ND5gKQogKiAgIC0gYG51bWJlcltdW11gIChmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5KSAg4oaSIGZhbHNlICAobXVsdGlwbGUgcG9pbnRzLCBsaWtlIGBWZWM8VmVjPGY2ND4+YCkKICoKICogQW4gZW1wdHkgYXJyYXkgaXMgdHJlYXRlZCBhcyBtdWx0aS1wb2ludCAoZmFsc3kgc2luZ2xlLCBtYXRjaGVzCiAqIHRoZSBgYXNzZXJ0X25lIShuYl9yb3dzLCAwKWAgZ3VhcmQgaW4gdGhlIFJ1c3QgYFZlYzxWZWM8ZjY0Pj5gIGltcGwg4oCUCiAqIGVtcHR5IGlucHV0cyBhcmUgcmVqZWN0ZWQgdXBzdHJlYW0gYW55d2F5KS4KICoKICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dAogKiBAcmV0dXJucyB7Ym9vbGVhbn0KICovCmZ1bmN0aW9uIGlzU2luZ2xlKGlucHV0KSB7CiAgaWYgKCFBcnJheS5pc0FycmF5KGlucHV0KSB8fCBpbnB1dC5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTsKICByZXR1cm4gdHlwZW9mIGlucHV0WzBdID09PSAnbnVtYmVyJzsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIHRvTWF0cml4Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIE5vcm1hbGlzZSBhbnkgcmVjb2duaXNlZCBpbnB1dCBmb3JtIHRvIGBudW1iZXJbXVtdYCAob25lIHJvdyBwZXIgc2FtcGxlKS4KICoKICogfCBKUyBpbnB1dCAgICAgICAgICAgICAgfCBSdXN0IGFuYWxvZ3VlICAgICAgICAgfCBSZXN1bHQgICAgICAgICAgICAgICB8CiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAogKiB8IGBbYSwgYiwgY11gICAgICAgICAgICB8IGBWZWM8ZjY0PmAgICAgICAgICAgICB8IGBbW2EsIGIsIGNdXWAgKDHDl2QpICB8CiAqIHwgYFtbYSxiXSxbYyxkXSzigKZdYCAgICAgfCBgVmVjPFZlYzxmNjQ+PmAgICAgICAgfCB1bmNoYW5nZWQgICAgICAgICAgICB8CiAqCiAqIE1hdGNoZXMgYElucHV0Ojp0b19kbWF0cml4YCAoYm90aCBpbXBscyk6CiAqICAgLSBgVmVjPGY2ND5gIOKGkiBgRE1hdHJpeDo6ZnJvbV9yb3dfc2xpY2UoMSwgbS5sZW4oKSwgbSlgIOKAlCB3cmFwcyBpbiAxIHJvdy4KICogICAtIGBWZWM8VmVjPGY2ND4+YCDihpIgYERNYXRyaXg6OmZyb21fZm4obmJfcm93cywgbmJfY29scywgfHIsY3wgbVtyXVtjXSlgIOKAlCBkaXJlY3QuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXQKICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiB0b01hdHJpeChpbnB1dCkgewogIGlmIChpc1NpbmdsZShpbnB1dCkpIHsKICAgIC8vIFNpbmdsZSBwb2ludDogd3JhcCBpbnRvIGEgMS1yb3cgbWF0cml4LgogICAgcmV0dXJuIFtpbnB1dC5zbGljZSgpXTsKICB9CiAgLy8gTXVsdGlwbGUgcG9pbnRzOiByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhlIG91dGVyIGFycmF5IHNvIGNhbGxlcnMKICAvLyBjYW5ub3QgYWNjaWRlbnRhbGx5IG11dGF0ZSB0aGUgb3JpZ2luYWwsIHdoaWxlIGtlZXBpbmcgaW5uZXIgcm93IHJlZnMuCiAgcmV0dXJuIGlucHV0LnNsaWNlKCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyB0b1ZlY3RvcgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBOb3JtYWxpc2UgYSB0cmFpbmluZy1vdXRwdXQgdmFsdWUgdG8gYG51bWJlcltdYC4KICoKICogfCBKUyBvdXRwdXQgICB8IFJ1c3QgYW5hbG9ndWUgIHwgUmVzdWx0ICAgfAogKiB8LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS18CiAqIHwgYG51bWJlcmAgICAgfCBgZjY0YCAgICAgICAgICB8IGBbdl1gICAgIHwKICogfCBgbnVtYmVyW11gICB8IGBWZWM8ZjY0PmAgICAgIHwgdW5jaGFuZ2VkfAogKgogKiBNYXRjaGVzIGBJbnB1dDo6dG9fZHZlY3RvcmA6CiAqICAgLSBgVmVjPGY2ND5gIGltcGw6IGBEVmVjdG9yOjpmcm9tX2VsZW1lbnQoMSwgKnYpYCDigJQgd3JhcHMgc2NhbGFyIGluIDEtZWxlbWVudCB2ZWN0b3IuCiAqICAgLSBgVmVjPFZlYzxmNjQ+PmAgaW1wbDogYERWZWN0b3I6OmZyb21fY29sdW1uX3NsaWNlKHYpYCDigJQgZGlyZWN0IHNsaWNlLgogKgogKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gb3V0cHV0CiAqIEByZXR1cm5zIHtudW1iZXJbXX0KICovCmZ1bmN0aW9uIHRvVmVjdG9yKG91dHB1dCkgewogIGlmICh0eXBlb2Ygb3V0cHV0ID09PSAnbnVtYmVyJykgewogICAgcmV0dXJuIFtvdXRwdXRdOwogIH0KICByZXR1cm4gb3V0cHV0LnNsaWNlKCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBmcm9tVmVjdG9yCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIENvbnZlcnQgYW4gaW50ZXJuYWwgcmVzdWx0IHZlY3RvciBiYWNrIHRvIHRoZSB1c2VyLWZhY2luZyBvdXRwdXQgdHlwZS4KICoKICogfCBgc2luZ2xlYCB8IFJlc3VsdCAgICAgICAgICB8IFJ1c3QgYW5hbG9ndWUgKGBmcm9tX2R2ZWN0b3JgKSAgICAgICAgIHwKICogfC0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKICogfCBgdHJ1ZWAgICB8IGB2WzBdYCAobnVtYmVyKSB8IGBWZWM8ZjY0PmAgaW1wbDogYGFzc2VydF9lcSEobnJvd3MsMSk7IHZbMF1gIHwKICogfCBgZmFsc2VgICB8IGB2LnNsaWNlKClgICAgICB8IGBWZWM8VmVjPGY2ND4+YCBpbXBsOiBgdi5pdGVyKCkuY2xvbmVkKCkuY29sbGVjdCgpYCB8CiAqCiAqIE5vdGU6IGBwcmVkaWN0Q292YXJpYW5jZWAgKiphbHdheXMqKiByZXR1cm5zIGBudW1iZXJbXVtdYCBhbmQgbXVzdCBOT1QgY2FsbAogKiB0aGlzIGZ1bmN0aW9uIChQT1JUX1NQRUMgwqc5LCDCpzYuNykuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW119IHYgICAgICBpbnRlcm5hbCByZXN1bHQgdmVjdG9yCiAqIEBwYXJhbSB7Ym9vbGVhbn0gIHNpbmdsZSB0cnVlIGlmIHRoZSBvcmlnaW5hbCBpbnB1dCB3YXMgYSBzaW5nbGUgcG9pbnQKICogQHJldHVybnMge251bWJlcnxudW1iZXJbXX0KICovCmZ1bmN0aW9uIGZyb21WZWN0b3Iodiwgc2luZ2xlKSB7CiAgaWYgKHNpbmdsZSkgewogICAgLy8gTWlycm9yczogYXNzZXJ0X2VxISh2Lm5yb3dzKCksIDEpOyB2WzBdCiAgICByZXR1cm4gdlswXTsKICB9CiAgcmV0dXJuIHYuc2xpY2UoKTsKfQoKLyoqCiAqIE11bHRpdmFyaWF0ZSBOb3JtYWwgRGlzdHJpYnV0aW9uIHNhbXBsZXIuCiAqCiAqIFBvcnQgb2YgYGZyaWVkcmljaCAwLjYuMGAgYHNyYy9nYXVzc2lhbl9wcm9jZXNzL211bHRpdmFyaWF0ZV9ub3JtYWwucnNgLgogKgogKiBFeHBvcnRzOgogKiAgIC0gYG11bGJlcnJ5MzIoc2VlZClgICAgICDigJMgc2VlZGFibGUgUFJORyAoUE9SVF9TUEVDIMKnMykKICogICAtIGBzdGFuZGFyZE5vcm1hbChybmcpYCAg4oCTIEJveC1NdWxsZXIgTigwLDEpIHNhbXBsZXIgKFBPUlRfU1BFQyDCpzMpCiAqICAgLSBgTXVsdGl2YXJpYXRlTm9ybWFsYCAgIOKAkyBjbGFzcyBwcm9kdWNlZCBieSBgR2F1c3NpYW5Qcm9jZXNzLnNhbXBsZUF0YAogKgogKiBaZXJvIGV4dGVybmFsIG5wbSBkZXBlbmRlbmNpZXMuIFBSTkcgY2hvaWNlIChtdWxiZXJyeTMyICsgQm94LU11bGxlcikgaXMKICogTk9UIGJpdC1mb3ItYml0IGlkZW50aWNhbCB0byBSdXN0J3MgcmFuZCAvIHJhbmRfZGlzdHIsIGJ1dCBpcyBzdGF0aXN0aWNhbGx5CiAqIGNvcnJlY3QgYW5kIHJlcHJvZHVjaWJsZSBnaXZlbiBhIHNlZWQgKFBPUlRfU1BFQyDCpzEyLjYpLgogKgogKiBEYXRhIHJlcHJlc2VudGF0aW9uIChQT1JUX1NQRUMgwqcyKToKICogICB2ZWN0b3IgPSBudW1iZXJbXQogKiAgIG1hdHJpeCA9IG51bWJlcltdW10gKHJvdy1tYWpvcikKICovCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE5PUk1BTCBTQU1QTEVSIOKAkyBCb3gtTXVsbGVyIChQT1JUX1NQRUMgwqczLCBleGFjdCBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpZWQpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBEcmF3IG9uZSBzdGFuZGFyZC1ub3JtYWwgc2FtcGxlIE4oMCwxKSB1c2luZyB0aGUgQm94LU11bGxlciB0cmFuc2Zvcm0uCiAqCiAqIENvbnN1bWVzIHR3byB1bmlmb3JtIGRyYXdzIGZyb20gYHJuZ2A7IHJldHJpZXMgaWYgdGhlIGZpcnN0IGRyYXcgaXMgZXhhY3RseQogKiAwICh0byBhdm9pZCBsb2coMCkg4oaSIC1JbmZpbml0eSkuCiAqCiAqIE5vdGU6IHRoaXMgdXNlcyBvbmx5IHRoZSBjb3NpbmUgYnJhbmNoIG9mIEJveC1NdWxsZXIgKHRoZSBzaW5lIGJyYW5jaCBpcwogKiBkaXNjYXJkZWQpLCBtYXRjaGluZyB0aGUgUE9SVF9TUEVDIMKnMyBjYW5vbmljYWwgaW1wbGVtZW50YXRpb24uIFN0YXRpc3RpY2FsCiAqIGNvcnJlY3RuZXNzIGlzIG1haW50YWluZWQ7IHRoZSBzaW5lIGJyYW5jaCB3b3VsZCBnaXZlIGVxdWFsbHkgdmFsaWQgc2FtcGxlcwogKiBidXQgaXMgbm90IHJlcXVpcmVkLgogKgogKiBAcGFyYW0geygpID0+IG51bWJlcn0gcm5nICB1bmlmb3JtIFswLCAxKSBnZW5lcmF0b3IgKGUuZy4gZnJvbSBtdWxiZXJyeTMyKQogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gc3RhbmRhcmROb3JtYWwocm5nKSB7CiAgbGV0IHUxID0gMCwKICAgIHUyID0gMDsKICB3aGlsZSAodTEgPT09IDApIHUxID0gcm5nKCk7IC8vIGF2b2lkIGxvZygwKQogIHUyID0gcm5nKCk7CiAgcmV0dXJuIE1hdGguc3FydCgtMiAqIE1hdGgubG9nKHUxKSkgKiBNYXRoLmNvcygyICogTWF0aC5QSSAqIHUyKTsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNdWx0aXZhcmlhdGVOb3JtYWwgQ0xBU1MKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIE11bHRpdmFyaWF0ZSBOb3JtYWwgRGlzdHJpYnV0aW9uIE4obWVhbiwgzqMpLgogKgogKiBQcm9kdWNlZCBieSBgR2F1c3NpYW5Qcm9jZXNzLnNhbXBsZUF0KGlucHV0cylgLiBTdG9yZXMgdGhlIENob2xlc2t5IGZhY3RvcgogKiBMIG9mIHRoZSBwb3N0ZXJpb3IgY292YXJpYW5jZSDOoyAod2hlcmUgzqMgPSBMwrdM4bWAKS4gU2FtcGxpbmcgdXNlczoKICoKICogICB6IH4gTigwLCBJKSAgKGRyYXcgZWFjaCBjb21wb25lbnQgdmlhIEJveC1NdWxsZXIpCiAqICAgeCA9IG1lYW4gKyBMwrd6ICDihpIgIHggfiBOKG1lYW4sIM6jKQogKgogKiBUaGUgYGlzU2luZ2xlYCBmbGFnIG1pcnJvcnMgdGhlIFJ1c3QgYFBoYW50b21EYXRhPFQ+YCBtZWNoYW5pc206IHdoZW4gdGhlCiAqIEdQIHdhcyBxdWVyaWVkIGF0IGEgc2luZ2xlIHBvaW50IChgVCA9IFZlYzxmNjQ+YCkgdGhlIG91dHB1dCBvZiBgbWVhbigpYCBhbmQKICogYHNhbXBsZSgpYCBpcyBhIGBudW1iZXJgOyB3aGVuIHF1ZXJpZWQgYXQgbXVsdGlwbGUgcG9pbnRzIGl0IGlzIGEgYG51bWJlcltdYC4KICoKICogUG9ydCBub3RlczoKICogICAtIFJ1c3Qgc3RvcmVzIGBjaG9sZXNreV9jb3ZhcmlhbmNlYCAoYWxyZWFkeSB0aGUgbG93ZXItdHJpYW5ndWxhciBmYWN0b3IgTAogKiAgICAgZnJvbSBgbmFsZ2VicmE6OkNob2xlc2t5Ojp1bnBhY2soKWApLiBKUyBsaWtld2lzZSBzdG9yZXMgb25seSBMIGFmdGVyCiAqICAgICBkZWNvbXBvc2luZyB0aGUgY292YXJpYW5jZSBpbiB0aGUgY29uc3RydWN0b3IuCiAqICAgLSBDaG9sZXNreSBmYWlsdXJlIOKGkiB0aHJvdyAobWF0Y2hlcyBSdXN0IGAuZXhwZWN0KCIuLi4iKWApLgogKi8KY2xhc3MgTXVsdGl2YXJpYXRlTm9ybWFsIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdfSAgIG1lYW4gICAgICAgIHBvc3RlcmlvciBtZWFuIHZlY3RvciAobGVuZ3RoIG4pCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBjb3ZhcmlhbmNlICBwb3N0ZXJpb3IgY292YXJpYW5jZSBtYXRyaXggKG7Dl24pLCBzeW1tZXRyaWMgcG9zaXRpdmUtZGVmaW5pdGUKICAgKiBAcGFyYW0ge2Jvb2xlYW59ICAgIGlzU2luZ2xlICAgIHRydWUgd2hlbiB0aGUgR1AgaW5wdXQgd2FzIGEgc2luZ2xlIHBvaW50IChudW1iZXJbXSk7CiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSB3aGVuIG11bHRpcGxlIHBvaW50cyAobnVtYmVyW11bXSkKICAgKi8KICBjb25zdHJ1Y3RvcihtZWFuLCBjb3ZhcmlhbmNlLCBpc1NpbmdsZSkgewogICAgLyoqIEB0eXBlIHtudW1iZXJbXX0gKi8KICAgIHRoaXMuX21lYW4gPSBtZWFuOwogICAgLyoqCiAgICAgKiBMb3dlci10cmlhbmd1bGFyIENob2xlc2t5IGZhY3RvciBMIG9mIHRoZSBjb3ZhcmlhbmNlICjOoyA9IEzCt0zhtYApLgogICAgICogQHR5cGUge251bWJlcltdW119CiAgICAgKi8KICAgIHRoaXMuX0wgPSBjaG9sZXNreShjb3ZhcmlhbmNlLCBudWxsKTsgLy8gbnVsbCDihpIgdGhyb3cgb24gZmFpbHVyZSAobWF0Y2hlcyBSdXN0IC5leHBlY3QpCiAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovCiAgICB0aGlzLl9pc1NpbmdsZSA9IGlzU2luZ2xlOwogIH0KCiAgLyoqCiAgICogUG9zdGVyaW9yIG1lYW4uCiAgICoKICAgKiBSZXR1cm5zIGEgYG51bWJlcmAgd2hlbiBgaXNTaW5nbGVgIGlzIHRydWUgKHNpbmdsZS1wb2ludCBxdWVyeSksCiAgICogb3IgYSBgbnVtYmVyW11gIHdoZW4gZmFsc2UgKG11bHRpLXBvaW50IHF1ZXJ5KS4KICAgKgogICAqIEByZXR1cm5zIHtudW1iZXIgfCBudW1iZXJbXX0KICAgKi8KICBtZWFuKCkgewogICAgcmV0dXJuIGZyb21WZWN0b3IodGhpcy5fbWVhbiwgdGhpcy5faXNTaW5nbGUpOwogIH0KCiAgLyoqCiAgICogRHJhdyBvbmUgc2FtcGxlIGZyb20gTihtZWFuLCDOoykuCiAgICoKICAgKiBBbGdvcml0aG0gKFBPUlRfU1BFQyDCpzgpOgogICAqICAgMS4geiA9IFtzdGFuZGFyZE5vcm1hbChybmcpLCDigKZdICAob25lIE4oMCwxKSBwZXIgZGltZW5zaW9uKQogICAqICAgMi4gc2FtcGxlVmVjID0gbWVhbiArIEzCt3oKICAgKiAgIDMuIHJldHVybiBmcm9tVmVjdG9yKHNhbXBsZVZlYywgaXNTaW5nbGUpCiAgICoKICAgKiBgcm5nYCBtdXN0IGJlIGEgYCgpID0+IG51bWJlciDiiIggWzAsIDEpYCBmdW5jdGlvbiwgZS5nLiB0aGUgY2xvc3VyZQogICAqIHJldHVybmVkIGJ5IGBtdWxiZXJyeTMyKHNlZWQpYC4gVGhlIG91dHB1dCB0eXBlIG1pcnJvcnMgYG1lYW4oKWAuCiAgICoKICAgKiBOdW1lcmljIG5vdGU6IHRoZSBQUk5HIGFuZCBCb3gtTXVsbGVyIGltcGxlbWVudGF0aW9uIGRpZmZlciBmcm9tIFJ1c3QncwogICAqIGByYW5kYC9gcmFuZF9kaXN0cmAsIHNvIHNhbXBsZSB2YWx1ZXMgd2lsbCBub3QgbWF0Y2ggUnVzdCBiaXQtZm9yLWJpdC4KICAgKiBTdGF0aXN0aWNhbCBjb3JyZWN0bmVzcyBhbmQgcmVwcm9kdWNpYmlsaXR5IGdpdmVuIGEgc2VlZCBhcmUgZ3VhcmFudGVlZC4KICAgKgogICAqIEBwYXJhbSB7KCkgPT4gbnVtYmVyfSBybmcKICAgKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVtYmVyW119CiAgICovCiAgc2FtcGxlKHJuZykgewogICAgY29uc3QgbiA9IHRoaXMuX21lYW4ubGVuZ3RoOwogICAgLy8gU3RlcCAxOiBkcmF3IHogfiBOKDAsIEkpCiAgICBjb25zdCB6ID0gbmV3IEFycmF5KG4pOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHpbaV0gPSBzdGFuZGFyZE5vcm1hbChybmcpOwogICAgLy8gU3RlcCAyOiBzYW1wbGVWZWMgPSBtZWFuICsgTMK3egogICAgY29uc3QgTHogPSBtYXRWZWModGhpcy5fTCwgeik7CiAgICBjb25zdCBzYW1wbGVWZWMgPSBuZXcgQXJyYXkobik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgc2FtcGxlVmVjW2ldID0gdGhpcy5fbWVhbltpXSArIEx6W2ldOwogICAgLy8gU3RlcCAzOiBjb252ZXJ0IHRvIHNjYWxhciBvciB2ZWN0b3IgZGVwZW5kaW5nIG9uIHF1ZXJ5IHR5cGUKICAgIHJldHVybiBmcm9tVmVjdG9yKHNhbXBsZVZlYywgdGhpcy5faXNTaW5nbGUpOwogIH0KfQoKLy8hIFBhcmFtZXRlciBvcHRpbWl6YXRpb24gKEFEQU0gZ3JhZGllbnQgYXNjZW50IG9uIHRoZSBtYXJnaW5hbCBsb2ctbGlrZWxpaG9vZCkuCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE5PTi1TQ0FMQUJMRSBLRVJORUwKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIENvbXB1dGVzIHRoZSBncmFkaWVudCBvZiB0aGUgbWFyZ2luYWwgbGlrZWxpaG9vZCBmb3IgdGhlIGN1cnJlbnQgdmFsdWUgb2YKICogZWFjaCBwYXJhbWV0ZXIuIFRoZSBwcm9kdWNlZCB2ZWN0b3IgY29udGFpbnMgdGhlIGdyYWRpZW50IHBlciBrZXJuZWwKICogcGFyYW1ldGVyIGZvbGxvd2VkIGJ5IHRoZSBncmFkaWVudCBmb3IgdGhlIG5vaXNlIHBhcmFtZXRlci4KICoKICogUGVyLXBhcmFtZXRlciBmb3JtdWxhIChgb3B0aW1pemVyLnJzOjI0YCk6CiAqICAgwr0gKCBhbHBoYeG1gCDCtyBkcCDCtyBhbHBoYSDiiJIgdHJhY2UoS+KBu8K5IMK3IGRwKSApCiAqIHdoZXJlCiAqICAgSyAgICAgPSBjb3YodHJhaW4sIHRyYWluKQogKiAgIGFscGhhID0gS+KBu8K5IMK3IG91dHB1dAogKiAgIGRwICAgID0g4oiCSy/iiIJwYXJhbWV0ZXIKICoKICogTm9pc2UgZ3JhZGllbnQgKGBncmFkaWVudChLLCBub2lzZSkgPSAywrdub2lzZcK3SWRgKToKICogICBub2lzZSDCtyAoIGFscGhhwrdhbHBoYSDiiJIgdHJhY2UoS+KBu8K5KSApCiAqCiAqIEBwYXJhbSB7b2JqZWN0fSBncCBHYXVzc2lhblByb2Nlc3MgKHNlZSBtb2R1bGUgbm90ZSkKICogQHJldHVybnMge251bWJlcltdfSBsZW5ndGggPSBrZXJuZWwubmJQYXJhbWV0ZXJzKCkgKyAxIChsYXN0IGVudHJ5ID0gbm9pc2UpCiAqLwpmdW5jdGlvbiBncmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZChncCkgewogIC8vIE5lZWRlZCBmb3IgdGhlIHBlci1wYXJhbWV0ZXIgZ3JhZGllbnQgY29tcHV0YXRpb24uCiAgY29uc3QgY292SW52ID0gZ3AuY292bWF0Q2hvbGVza3kuaW52ZXJzZSgpOyAvLyBL4oG7wrkKICBjb25zdCBvdXRwdXQgPSBncC50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsKCiAgLy8gYWxwaGEgPSBL4oG7wrkgwrcgb3V0cHV0ICAobWF0VmVjOyBjb3ZJbnYgaXMgc3ltbWV0cmljKS4KICBjb25zdCBuID0gb3V0cHV0Lmxlbmd0aDsKICBjb25zdCBhbHBoYSA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgewogICAgbGV0IHMgPSAwOwogICAgY29uc3Qgcm93ID0gY292SW52W3JdOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuOyBjKyspIHMgKz0gcm93W2NdICogb3V0cHV0W2NdOwogICAgYWxwaGFbcl0gPSBzOwogIH0KICBjb25zdCBpbnB1dHMgPSBncC50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwogIGNvbnN0IHJlc3VsdHMgPSBbXTsKCiAgLy8gTG9vcCBvdmVyIHRoZSBncmFkaWVudCBtYXRyaXggZm9yIGVhY2ggcGFyYW1ldGVyLgogIGZvciAoY29uc3QgY292R3JhZGllbnQgb2YgbWFrZUdyYWRpZW50Q292YXJpYW5jZU1hdHJpY2VzKGlucHV0cywgZ3Aua2VybmVsKSkgewogICAgLy8gZGF0YV9maXQgPSDOo19jIGFscGhhW2NdIMK3IChhbHBoYSDCtyBjb2xfYykgID0gIGFscGhh4bWAIMK3IGNvdkdyYWRpZW50IMK3IGFscGhhCiAgICAvLyBjb3ZHcmFkaWVudCBpcyBzeW1tZXRyaWMsIHNvIGl0cyBjb2x1bW4gYyBlcXVhbHMgaXRzIHJvdyBjLgogICAgbGV0IGRhdGFGaXQgPSAwOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuOyBjKyspIHsKICAgICAgLy8gYWxwaGEgwrcgKGNvbHVtbiBjIG9mIGNvdkdyYWRpZW50KQogICAgICBsZXQgYWNvbCA9IDA7CiAgICAgIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSBhY29sICs9IGFscGhhW3JdICogY292R3JhZGllbnRbcl1bY107CiAgICAgIGRhdGFGaXQgKz0gYWNvbCAqIGFscGhhW2NdOwogICAgfQoKICAgIC8vIGNvbXBsZXhpdHlfcGVuYWx0eSA9IM6jX3IgKHJvdyByIG9mIGNvdkludikgwrcgKGNvbHVtbiByIG9mIGNvdkdyYWRpZW50KQogICAgLy8gICAgICAgICAgICAgICAgICAgID0gdHJhY2UoY292SW52IMK3IGNvdkdyYWRpZW50KQogICAgbGV0IGNvbXBsZXhpdHlQZW5hbHR5ID0gMDsKICAgIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSB7CiAgICAgIGNvbnN0IGNSb3cgPSBjb3ZJbnZbcl07CiAgICAgIGxldCB0ciA9IDA7CiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgbjsgaysrKSB0ciArPSBjUm93W2tdICogY292R3JhZGllbnRba11bcl07CiAgICAgIGNvbXBsZXhpdHlQZW5hbHR5ICs9IHRyOwogICAgfQogICAgcmVzdWx0cy5wdXNoKChkYXRhRml0IC0gY29tcGxleGl0eVBlbmFsdHkpIC8gMik7CiAgfQoKICAvLyBOb2lzZSBwYXJhbWV0ZXI6IGdyYWRpZW50KEssIG5vaXNlKSA9IDLCt25vaXNlwrdJZC4KICBjb25zdCBkYXRhRml0ID0gZG90KGFscGhhLCBhbHBoYSk7CiAgY29uc3QgY29tcGxleGl0eVBlbmFsdHkgPSB0cmFjZShjb3ZJbnYpOyAvLyB0cmFjZShL4oG7wrkpCiAgY29uc3Qgbm9pc2VHcmFkaWVudCA9IGdwLm5vaXNlICogKGRhdGFGaXQgLSBjb21wbGV4aXR5UGVuYWx0eSk7CiAgcmVzdWx0cy5wdXNoKG5vaXNlR3JhZGllbnQpOwogIHJldHVybiByZXN1bHRzOwp9CgovKioKICogRml0IHBhcmFtZXRlcnMgdXNpbmcgdGhlIEFEQU0gZ3JhZGllbnQtYXNjZW50IGFsZ29yaXRobS4KICoKICogUnVucyBmb3IgYXQgbW9zdCBgbWF4SXRlcmAgaXRlcmF0aW9ucy4gU3RvcHMgZWFybHkgaWYgZXZlcnkgY29tcG9uZW50IG9mIHRoZQogKiB1cGRhdGUgc3RlcCBgZGVsdGFgIGlzIOKJpCBgY29udmVyZ2VuY2VGcmFjdGlvbmAgaW4gbWFnbml0dWRlIChubyBzaWduaWZpY2FudAogKiBwcm9ncmVzcyksIG9yIGlmIHRoZSBydW50aW1lIGV4Y2VlZHMgYG1heFRpbWVgIChtaWxsaXNlY29uZHMpLgogKgogKiBUaGUgYG5vaXNlYCBwYXJhbWV0ZXIgaXMgZml0dGVkIGluIGxvZy1zY2FsZSwgc2luY2UgaXRzIG1hZ25pdHVkZSBtYXR0ZXJzCiAqIG1vcmUgdGhhbiBpdHMgcHJlY2lzZSB2YWx1ZS4KICoKICogQURBTSBjb25zdGFudHMgKGBvcHRpbWl6ZXIucnM6NzlgKTogYmV0YTE9MC45LCBiZXRhMj0wLjk5OSwgZXBzaWxvbj0xZS04LAogKiBsZWFybmluZ1JhdGU9MC4xLgogKgogKiBAcGFyYW0ge29iamVjdH0gZ3AKICogQHBhcmFtIHtudW1iZXJ9IG1heEl0ZXIKICogQHBhcmFtIHtudW1iZXJ9IGNvbnZlcmdlbmNlRnJhY3Rpb24KICogQHBhcmFtIHtudW1iZXJ9IG1heFRpbWUgbWlsbGlzZWNvbmRzCiAqLwpmdW5jdGlvbiBvcHRpbWl6ZVBhcmFtZXRlcnMoZ3AsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpIHsKICBjb25zdCBiZXRhMSA9IDAuOTsKICBjb25zdCBiZXRhMiA9IDAuOTk5OwogIGNvbnN0IGVwc2lsb24gPSAxZS04OwogIGNvbnN0IGxlYXJuaW5nUmF0ZSA9IDAuMTsKCiAgLy8gSW5pdGlhbCBwYXJhbWV0ZXJzOiBrZXJuZWwgcGFyYW1zIHdpdGggYW55IDAgcmVwbGFjZWQgYnkgZXBzaWxvbiAoYSAwCiAgLy8gcGFyYW1ldGVyIHdvdWxkIGJsb2NrIHRoZSBtdWx0aXBsaWNhdGl2ZSBBREFNIHVwZGF0ZSksIHRoZW4gbm9pc2UgaW4KICAvLyBsb2ctc3BhY2UuCiAgY29uc3QgcGFyYW1ldGVycyA9IGdwLmtlcm5lbC5nZXRQYXJhbWV0ZXJzKCkubWFwKHAgPT4gcCA9PT0gMCA/IGVwc2lsb24gOiBwKTsKICBwYXJhbWV0ZXJzLnB1c2goTWF0aC5sb2coZ3Aubm9pc2UpKTsgLy8gbm9pc2UgaW4gbG9nLXNwYWNlCgogIGNvbnN0IG1lYW5HcmFkID0gbmV3IEFycmF5KHBhcmFtZXRlcnMubGVuZ3RoKS5maWxsKDApOwogIGNvbnN0IHZhckdyYWQgPSBuZXcgQXJyYXkocGFyYW1ldGVycy5sZW5ndGgpLmZpbGwoMCk7CiAgY29uc3QgdGltZVN0YXJ0ID0gRGF0ZS5ub3coKTsKICBmb3IgKGxldCBpID0gMTsgaSA8PSBtYXhJdGVyOyBpKyspIHsKICAgIGNvbnN0IGdyYWRpZW50cyA9IGdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKGdwKTsKICAgIC8vIENvcnJlY3QgdGhlIG5vaXNlIGdyYWRpZW50IGZvciBsb2ctc3BhY2UuCiAgICBncmFkaWVudHNbZ3JhZGllbnRzLmxlbmd0aCAtIDFdICo9IGdwLm5vaXNlOwogICAgbGV0IGhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgPSBmYWxzZTsKICAgIGZvciAobGV0IHAgPSAwOyBwIDwgcGFyYW1ldGVycy5sZW5ndGg7IHArKykgewogICAgICBtZWFuR3JhZFtwXSA9IGJldGExICogbWVhbkdyYWRbcF0gKyAoMSAtIGJldGExKSAqIGdyYWRpZW50c1twXTsKICAgICAgdmFyR3JhZFtwXSA9IGJldGEyICogdmFyR3JhZFtwXSArICgxIC0gYmV0YTIpICogZ3JhZGllbnRzW3BdICogZ3JhZGllbnRzW3BdOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkTWVhbiA9IG1lYW5HcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMSwgaSkpOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkVmFyaWFuY2UgPSB2YXJHcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMiwgaSkpOwogICAgICBjb25zdCBkZWx0YSA9IGxlYXJuaW5nUmF0ZSAqIGJpYXNDb3JyZWN0ZWRNZWFuIC8gKE1hdGguc3FydChiaWFzQ29ycmVjdGVkVmFyaWFuY2UpICsgZXBzaWxvbik7CiAgICAgIGlmIChNYXRoLmFicyhkZWx0YSkgPiBjb252ZXJnZW5jZUZyYWN0aW9uKSBoYWRTaWduaWZpY2FudFByb2dyZXNzID0gdHJ1ZTsKICAgICAgcGFyYW1ldGVyc1twXSAqPSAxICsgZGVsdGE7CiAgICB9CgogICAgLy8gU2V0IGtlcm5lbCBwYXJhbWV0ZXJzICh0aGUga2VybmVsIHJlYWRzIG9ubHkgaXRzIG93biBsZWFkaW5nIHByZWZpeAogICAgLy8gb2YgYHBhcmFtZXRlcnNgOyB0aGUgdHJhaWxpbmcgbm9pc2UgbG9nLXZhbHVlIGlzIGlnbm9yZWQgYnkgaXQpLgogICAgZ3Aua2VybmVsLnNldFBhcmFtZXRlcnMocGFyYW1ldGVycyk7CiAgICAvLyBHZXQgdGhlIG5vaXNlIG91dCBvZiBsb2ctc3BhY2UgYmVmb3JlIHNldHRpbmcgaXQuCiAgICBncC5ub2lzZSA9IE1hdGguZXhwKHBhcmFtZXRlcnNbcGFyYW1ldGVycy5sZW5ndGggLSAxXSk7CgogICAgLy8gUmVmaXQgdGhlIG1vZGVsIChyZWJ1aWxkIHRoZSBDaG9sZXNreSBmYWN0b3Igb2YgdGhlIGNvdmFyaWFuY2UgbWF0cml4KS4KICAgIGdwLmNvdm1hdENob2xlc2t5ID0gbWFrZUNob2xlc2t5Q292TWF0cml4KGdwLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCksIGdwLmtlcm5lbCwgZ3Aubm9pc2UsIGdwLmNob2xlc2t5RXBzaWxvbik7CiAgICBpZiAoIWhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgfHwgRGF0ZS5ub3coKSAtIHRpbWVTdGFydCA+IG1heFRpbWUpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFNDQUxBQkxFIEtFUk5FTAovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogUmV0dXJucyBgW3NjYWxlLCBncmFkaWVudHNdYDogdGhlIG9wdGltYWwgc2NhbGUgZm9yIHRoZSBrZXJuZWwrbm9pc2UgKHVzZWQgdG8KICogb3B0aW1pemUgdGhlIG5vaXNlKSBwbHVzIHRoZSBncmFkaWVudCBwZXIga2VybmVsIHBhcmFtZXRlciAoTk9UIGluY2x1ZGluZyB0aGUKICogbm9pc2UgZ3JhZGllbnQpLgogKgogKiBQZXItcGFyYW1ldGVyIGZvcm11bGEgKGBvcHRpbWl6ZXIucnM6MTUwYCk6CiAqICAgwr0gKCBhbHBoYeG1gCDCtyBkcCDCtyBhbHBoYSAvIHNjYWxlIOKIkiB0cmFjZShL4oG7wrkgwrcgZHApICkKICogICBzY2FsZSA9IG91dHB1dOG1gCDCtyBL4oG7wrkgwrcgb3V0cHV0IC8gbgogKiBOT1RFOiB0aGUgZGF0YS1maXQgdGVybSBpcyBkaXZpZGVkIGJ5IGBzY2FsZWAsIHVubGlrZSB0aGUgdW5zY2FsZWQgZ3JhZGllbnQuCiAqCiAqIEBwYXJhbSB7b2JqZWN0fSBncAogKiBAcmV0dXJucyB7W251bWJlciwgbnVtYmVyW11dfSBbc2NhbGUsIHJlc3VsdHNdIChyZXN1bHRzIGxlbmd0aCA9IG5iUGFyYW1ldGVycykKICovCmZ1bmN0aW9uIHNjYWxlZEdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKGdwKSB7CiAgY29uc3QgY292SW52ID0gZ3AuY292bWF0Q2hvbGVza3kuaW52ZXJzZSgpOyAvLyBL4oG7wrkKICBjb25zdCBvdXRwdXQgPSBncC50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsKICBjb25zdCBuID0gb3V0cHV0Lmxlbmd0aDsKCiAgLy8gYWxwaGEgPSBL4oG7wrkgwrcgb3V0cHV0CiAgY29uc3QgYWxwaGEgPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIHsKICAgIGxldCBzID0gMDsKICAgIGNvbnN0IHJvdyA9IGNvdkludltyXTsKICAgIGZvciAobGV0IGMgPSAwOyBjIDwgbjsgYysrKSBzICs9IHJvd1tjXSAqIG91dHB1dFtjXTsKICAgIGFscGhhW3JdID0gczsKICB9CgogIC8vIFNjYWxpbmcgZm9yIHRoZSBrZXJuZWw6IG91dHB1dOG1gCDCtyBL4oG7wrkgwrcgb3V0cHV0IC8gbiA9IG91dHB1dMK3YWxwaGEgLyBuLgogIGNvbnN0IHNjYWxlID0gZG90KG91dHB1dCwgYWxwaGEpIC8gbjsKICBjb25zdCBpbnB1dHMgPSBncC50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBmb3IgKGNvbnN0IGNvdkdyYWRpZW50IG9mIG1ha2VHcmFkaWVudENvdmFyaWFuY2VNYXRyaWNlcyhpbnB1dHMsIGdwLmtlcm5lbCkpIHsKICAgIC8vIGRhdGFfZml0ID0gKGFscGhh4bWAIMK3IGNvdkdyYWRpZW50IMK3IGFscGhhKSAvIHNjYWxlCiAgICBsZXQgZGF0YUZpdCA9IDA7CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG47IGMrKykgewogICAgICBsZXQgYWNvbCA9IDA7CiAgICAgIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSBhY29sICs9IGFscGhhW3JdICogY292R3JhZGllbnRbcl1bY107CiAgICAgIGRhdGFGaXQgKz0gYWNvbCAqIGFscGhhW2NdOwogICAgfQogICAgZGF0YUZpdCAvPSBzY2FsZTsKCiAgICAvLyBjb21wbGV4aXR5X3BlbmFsdHkgPSB0cmFjZShjb3ZJbnYgwrcgY292R3JhZGllbnQpCiAgICBsZXQgY29tcGxleGl0eVBlbmFsdHkgPSAwOwogICAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIHsKICAgICAgY29uc3QgY1JvdyA9IGNvdkludltyXTsKICAgICAgbGV0IHRyID0gMDsKICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBuOyBrKyspIHRyICs9IGNSb3dba10gKiBjb3ZHcmFkaWVudFtrXVtyXTsKICAgICAgY29tcGxleGl0eVBlbmFsdHkgKz0gdHI7CiAgICB9CiAgICByZXN1bHRzLnB1c2goKGRhdGFGaXQgLSBjb21wbGV4aXR5UGVuYWx0eSkgLyAyKTsKICB9CgogIC8vIE5PVEU6IGZhaXRoZnVsIHRvIFJ1c3Qgc291cmNlIOKAlCB0aGUgbm9pc2UgZ3JhZGllbnQgaXMgaW50ZW50aW9uYWxseSBOT1QKICAvLyBwdXNoZWQgaGVyZSAoaXQgaXMgY29tbWVudGVkIG91dCBpbiBvcHRpbWl6ZXIucnM6MTg4LTE5MSk7IHRoZSBub2lzZSBpcwogIC8vIGluc3RlYWQgZml0dGVkIHZpYSBga2VybmVsLnJlc2NhbGUoc2NhbGUpYCArIGBncC5ub2lzZSAqPSBzY2FsZWAuCgogIHJldHVybiBbc2NhbGUsIHJlc3VsdHNdOwp9CgovKioKICogRml0IHBhcmFtZXRlcnMgdXNpbmcgQURBTSBncmFkaWVudCBhc2NlbnQ7IGFkZGl0aW9uYWxseSwgYXQgZWFjaCBzdGVwIHRoZQogKiBrZXJuZWwgYW5kIG5vaXNlIGFyZSByZXNjYWxlZCBieSB0aGUgb3B0aW1hbCBtYWduaXR1ZGUgYHNjYWxlYC4KICoKICogUnVucyBmb3IgYXQgbW9zdCBgbWF4SXRlcmAgaXRlcmF0aW9ucy4gU3RvcHMgZWFybHkgb24gbm8gc2lnbmlmaWNhbnQgcHJvZ3Jlc3MKICogKGFsbCBgZGVsdGFgIOKJpCBgY29udmVyZ2VuY2VGcmFjdGlvbmApIG9yIGlmIHRoZSBydW50aW1lIGV4Y2VlZHMgYG1heFRpbWVgCiAqIChtaWxsaXNlY29uZHMpLgogKgogKiBBREFNIGNvbnN0YW50cyBpZGVudGljYWwgdG8ge0BsaW5rIG9wdGltaXplUGFyYW1ldGVyc30uCiAqCiAqIEBwYXJhbSB7b2JqZWN0fSBncAogKiBAcGFyYW0ge251bWJlcn0gbWF4SXRlcgogKiBAcGFyYW0ge251bWJlcn0gY29udmVyZ2VuY2VGcmFjdGlvbgogKiBAcGFyYW0ge251bWJlcn0gbWF4VGltZSBtaWxsaXNlY29uZHMKICovCmZ1bmN0aW9uIHNjYWxlZE9wdGltaXplUGFyYW1ldGVycyhncCwgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSkgewogIGNvbnN0IGJldGExID0gMC45OwogIGNvbnN0IGJldGEyID0gMC45OTk7CiAgY29uc3QgZXBzaWxvbiA9IDFlLTg7CiAgY29uc3QgbGVhcm5pbmdSYXRlID0gMC4xOwoKICAvLyBJbml0aWFsIHBhcmFtZXRlcnM6IGtlcm5lbCBwYXJhbXMgd2l0aCAwIHJlcGxhY2VkIGJ5IGVwc2lsb24uCiAgLy8gKE5vIG5vaXNlIHB1c2hlZDogdGhlIG5vaXNlIGlzIGZpdHRlZCBieSByZXNjYWxpbmcsIG5vdCBieSBncmFkaWVudC4pCiAgbGV0IHBhcmFtZXRlcnMgPSBncC5rZXJuZWwuZ2V0UGFyYW1ldGVycygpLm1hcChwID0+IHAgPT09IDAgPyBlcHNpbG9uIDogcCk7CiAgY29uc3QgbWVhbkdyYWQgPSBuZXcgQXJyYXkocGFyYW1ldGVycy5sZW5ndGgpLmZpbGwoMCk7CiAgY29uc3QgdmFyR3JhZCA9IG5ldyBBcnJheShwYXJhbWV0ZXJzLmxlbmd0aCkuZmlsbCgwKTsKICBjb25zdCB0aW1lU3RhcnQgPSBEYXRlLm5vdygpOwogIGZvciAobGV0IGkgPSAxOyBpIDw9IG1heEl0ZXI7IGkrKykgewogICAgY29uc3QgW3NjYWxlLCBncmFkaWVudHNdID0gc2NhbGVkR3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QoZ3ApOwogICAgbGV0IGhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgPSBmYWxzZTsKICAgIGZvciAobGV0IHAgPSAwOyBwIDwgcGFyYW1ldGVycy5sZW5ndGg7IHArKykgewogICAgICBtZWFuR3JhZFtwXSA9IGJldGExICogbWVhbkdyYWRbcF0gKyAoMSAtIGJldGExKSAqIGdyYWRpZW50c1twXTsKICAgICAgdmFyR3JhZFtwXSA9IGJldGEyICogdmFyR3JhZFtwXSArICgxIC0gYmV0YTIpICogZ3JhZGllbnRzW3BdICogZ3JhZGllbnRzW3BdOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkTWVhbiA9IG1lYW5HcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMSwgaSkpOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkVmFyaWFuY2UgPSB2YXJHcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMiwgaSkpOwogICAgICBjb25zdCBkZWx0YSA9IGxlYXJuaW5nUmF0ZSAqIGJpYXNDb3JyZWN0ZWRNZWFuIC8gKE1hdGguc3FydChiaWFzQ29ycmVjdGVkVmFyaWFuY2UpICsgZXBzaWxvbik7CiAgICAgIGlmIChNYXRoLmFicyhkZWx0YSkgPiBjb252ZXJnZW5jZUZyYWN0aW9uKSBoYWRTaWduaWZpY2FudFByb2dyZXNzID0gdHJ1ZTsKICAgICAgcGFyYW1ldGVyc1twXSAqPSAxICsgZGVsdGE7CiAgICB9CgogICAgLy8gU2V0IHBhcmFtZXRlcnMsIHRoZW4gcmVzY2FsZSB0aGUga2VybmVsIGFuZCBub2lzZSBieSB0aGUgb3B0aW1hbCBzY2FsZS4KICAgIGdwLmtlcm5lbC5zZXRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpOwogICAgZ3Aua2VybmVsLnJlc2NhbGUoc2NhbGUpOwogICAgZ3Aubm9pc2UgKj0gc2NhbGU7CiAgICAvLyBHZXQgcGFyYW1ldGVycyBiYWNrIGFzIHRoZXkgaGF2ZSBiZWVuIHJlc2NhbGVkIChyZXNjYWxlIGNoYW5nZXMgdGhlCiAgICAvLyBhbXBsaXR1ZGUsIHNvIHRoZSBsb2NhbCBgcGFyYW1ldGVyc2AgbXVzdCBiZSByZWZyZXNoZWQgZnJvbSB0aGUga2VybmVsKS4KICAgIHBhcmFtZXRlcnMgPSBncC5rZXJuZWwuZ2V0UGFyYW1ldGVycygpOwoKICAgIC8vIFJlZml0IHRoZSBtb2RlbC4KICAgIGdwLmNvdm1hdENob2xlc2t5ID0gbWFrZUNob2xlc2t5Q292TWF0cml4KGdwLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCksIGdwLmtlcm5lbCwgZ3Aubm9pc2UsIGdwLmNob2xlc2t5RXBzaWxvbik7CiAgICBpZiAoIWhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgfHwgRGF0ZS5ub3coKSAtIHRpbWVTdGFydCA+IG1heFRpbWUpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgovLyEgR2F1c3NpYW4gcHJvY2Vzcy4KCi8qKiBEZWZhdWx0IG1heGltdW0gZml0dGluZyB0aW1lOiBvbmUgaG91ciwgZXhwcmVzc2VkIGluIG1pbGxpc2Vjb25kcyAoUnVzdCB1c2VzIGNocm9ubzo6RHVyYXRpb246OnNlY29uZHMoMzYwMCkpLiAqLwpjb25zdCBERUZBVUxUX01BWF9USU1FX01TID0gMzYwMCAqIDEwMDA7CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEdhdXNzaWFuUHJvY2VzcwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQSBHYXVzc2lhbiBwcm9jZXNzIHRoYXQgY2FuIGJlIHVzZWQgdG8gbWFrZSBwcmVkaWN0aW9ucyBiYXNlZCBvbiBpdHMgdHJhaW5pbmcKICogZGF0YS4KICoKICogSW50ZXJuYWwgc3RhdGUgKG1pcnJvcnMgdGhlIFJ1c3QgYEdhdXNzaWFuUHJvY2Vzc2Agc3RydWN0LCBgbW9kLnJzOjU5YCk6CiAqICAgLSBgcHJpb3JgICAgICAgICAgICBQcmlvciBpbnN0YW5jZS4KICogICAtIGBrZXJuZWxgICAgICAgICAgIEtlcm5lbCBpbnN0YW5jZS4KICogICAtIGBub2lzZWAgICAgICAgICAgIG51bWJlciDigJQgbm9pc2UgU1RBTkRBUkQgREVWSUFUSU9OIChub3QgdmFyaWFuY2UpLgogKiAgIC0gYGNob2xlc2t5RXBzaWxvbmAgbnVtYmVyIHwgbnVsbCDigJQgc3Vic3RpdHV0ZSBwaXZvdCBmb3IgQ2hvbGVza3kgKG9yIG51bGwpLgogKiAgIC0gYHRyYWluaW5nSW5wdXRzYCAgRXh0ZW5kYWJsZU1hdHJpeC4KICogICAtIGB0cmFpbmluZ091dHB1dHNgIEV4dGVuZGFibGVWZWN0b3Ig4oCUIHN0b3JlcyBgb3V0cHV0cyDiiJIgcHJpb3IoaW5wdXRzKWAgKHRoZSByZXNpZHVhbCEpLgogKiAgIC0gYGNvdm1hdENob2xlc2t5YCAgQ2hvbGVza3lEZWNvbXBvc2l0aW9uIG9mIEsgPSBrZXJuZWwoWCxYKSArIG5vaXNlwrLCt0kuCiAqLwpjbGFzcyBHYXVzc2lhblByb2Nlc3MgewogIC8qKgogICAqIFJhdyBjb25zdHJ1Y3RvciAoYG1vZC5yczoxNDJgKS4gUHJlZmVyIHtAbGluayBHYXVzc2lhblByb2Nlc3MuZGVmYXVsdH0gb3IKICAgKiB7QGxpbmsgR2F1c3NpYW5Qcm9jZXNzLmJ1aWxkZXJ9LgogICAqCiAgICogQHBhcmFtIHtvYmplY3R9ICAgICAgIHByaW9yICAgICAgICAgICAgUHJpb3IgaW5zdGFuY2UuCiAgICogQHBhcmFtIHtvYmplY3R9ICAgICAgIGtlcm5lbCAgICAgICAgICAgS2VybmVsIGluc3RhbmNlLgogICAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICBub2lzZSAgICAgICAgICAgIG5vaXNlIHN0YW5kYXJkIGRldmlhdGlvbiAo4omlIDApLgogICAqIEBwYXJhbSB7bnVtYmVyfG51bGx9ICBjaG9sZXNreUVwc2lsb24gIHN1YnN0aXR1dGUgcGl2b3QgKG9yIG51bGwgdG8gdGhyb3cgb24gZmFpbHVyZSkuCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSB0cmFpbmluZ0lucHV0cyAgcmF3IGlucHV0cy4KICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIHRyYWluaW5nT3V0cHV0cyByYXcgb3V0cHV0cyAoTk9UIHlldCByZXNpZHVhbGlzZWQpLgogICAqLwogIGNvbnN0cnVjdG9yKHByaW9yLCBrZXJuZWwsIG5vaXNlLCBjaG9sZXNreUVwc2lsb24sIHRyYWluaW5nSW5wdXRzLCB0cmFpbmluZ091dHB1dHMpIHsKICAgIGlmICghKG5vaXNlID49IDApKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIG5vaXNlIHBhcmFtZXRlciBzaG91bGQgYmUgbm9uLW5lZ2F0aXZlIGJ1dCB3ZSB0cmllZCB0byBzZXQgaXQgdG8gJHtub2lzZX1gKTsKICAgIH0KCiAgICAvLyBOb3JtYWxpc2UgaW5wdXRzL291dHB1dHMgaW50byBtYXRyaXggLyB2ZWN0b3IgZm9ybSAobWF0Y2hlcyBUOjppbnRvX2RtYXRyaXggLyBpbnRvX2R2ZWN0b3IpLgogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgodHJhaW5pbmdJbnB1dHMpOwogICAgY29uc3Qgb3V0cHV0c1ZlY3RvciA9IHRvVmVjdG9yKHRyYWluaW5nT3V0cHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4Lmxlbmd0aCAhPT0gb3V0cHV0c1ZlY3Rvci5sZW5ndGgpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGB0cmFpbmluZ19pbnB1dHMubnJvd3MoKSAoJHtpbnB1dHNNYXRyaXgubGVuZ3RofSkgIT09IHRyYWluaW5nX291dHB1dHMubnJvd3MoKSAoJHtvdXRwdXRzVmVjdG9yLmxlbmd0aH0pYCk7CiAgICB9CgogICAgLyoqIEB0eXBlIHtvYmplY3R9ICovCiAgICB0aGlzLnByaW9yID0gcHJpb3I7CiAgICAvKiogQHR5cGUge29iamVjdH0gKi8KICAgIHRoaXMua2VybmVsID0ga2VybmVsOwogICAgLyoqIEB0eXBlIHtudW1iZXJ9IG5vaXNlIHN0YW5kYXJkIGRldmlhdGlvbiAqLwogICAgdGhpcy5ub2lzZSA9IG5vaXNlOwogICAgLyoqIEB0eXBlIHtudW1iZXJ8bnVsbH0gKi8KICAgIHRoaXMuY2hvbGVza3lFcHNpbG9uID0gY2hvbGVza3lFcHNpbG9uOwoKICAgIC8vIEV4dGVuZGFibGUgdHJhaW5pbmcgZGF0YS4gdHJhaW5pbmdPdXRwdXRzIGhvbGRzIHRoZSBQUklPUiBSRVNJRFVBTC4KICAgIC8qKiBAdHlwZSB7RXh0ZW5kYWJsZU1hdHJpeH0gKi8KICAgIHRoaXMudHJhaW5pbmdJbnB1dHMgPSBuZXcgRXh0ZW5kYWJsZU1hdHJpeChpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgcHJpb3JWYWx1ZXMgPSBwcmlvci5wcmlvcihpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgcmVzaWR1YWwgPSBuZXcgQXJyYXkob3V0cHV0c1ZlY3Rvci5sZW5ndGgpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRzVmVjdG9yLmxlbmd0aDsgaSsrKSB7CiAgICAgIHJlc2lkdWFsW2ldID0gb3V0cHV0c1ZlY3RvcltpXSAtIHByaW9yVmFsdWVzW2ldOwogICAgfQogICAgLyoqIEB0eXBlIHtFeHRlbmRhYmxlVmVjdG9yfSAqLwogICAgdGhpcy50cmFpbmluZ091dHB1dHMgPSBuZXcgRXh0ZW5kYWJsZVZlY3RvcihyZXNpZHVhbCk7CgogICAgLy8gQ2hvbGVza3kgb2YgdGhlIGNvdmFyaWFuY2UgbWF0cml4IEsgPSBrZXJuZWwoWCxYKSArIG5vaXNlwrLCt0kuCiAgICAvKiogQHR5cGUge2ltcG9ydCgnLi9hbGdlYnJhLm1qcycpLkNob2xlc2t5RGVjb21wb3NpdGlvbn0gKi8KICAgIHRoaXMuY292bWF0Q2hvbGVza3kgPSBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoaW5wdXRzTWF0cml4LCBrZXJuZWwsIG5vaXNlLCBjaG9sZXNreUVwc2lsb24pOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFNUQVRJQyBDT05TVFJVQ1RPUlMKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFJldHVybnMgYSBHYXVzc2lhbiBwcm9jZXNzIHdpdGggYSBHYXVzc2lhbiBrZXJuZWwgYW5kIGEgY29uc3RhbnQgcHJpb3IsCiAgICogYm90aCBmaXR0ZWQgdG8gdGhlIGRhdGEgKGBtb2QucnM6OTZgKS4KICAgKgogICAqIEVxdWl2YWxlbnQgdG8gYGJ1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKS5maXRfa2VybmVsKCkuZml0X3ByaW9yKCkudHJhaW4oKWAuCiAgICoKICAgKiBOb3RlOiBgZGVmYXVsdGAgaXMgYSB2YWxpZCBzdGF0aWMtbWV0aG9kIG5hbWUgaW4gSlMgY2xhc3Nlczsgc2VlCiAgICoge0BsaW5rIEdhdXNzaWFuUHJvY2Vzcy5mcm9tRGF0YX0gZm9yIGEgc2FmZSBhbGlhcy4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICBvdXRwdXRzCiAgICogQHJldHVybnMge0dhdXNzaWFuUHJvY2Vzc30KICAgKi8KICBzdGF0aWMgZGVmYXVsdChpbnB1dHMsIG91dHB1dHMpIHsKICAgIHJldHVybiBHYXVzc2lhblByb2Nlc3MuYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpLmZpdEtlcm5lbCgpLmZpdFByaW9yKCkudHJhaW4oKTsKICB9CgogIC8qKgogICAqIFNhZmUgYWxpYXMgb2Yge0BsaW5rIEdhdXNzaWFuUHJvY2Vzcy5kZWZhdWx0fSAoaW4gY2FzZSBhIHRvb2xjaGFpbiBkaXNsaWtlcwogICAqIHRoZSBgZGVmYXVsdGAgbWV0aG9kIG5hbWUpLiBJZGVudGljYWwgYmVoYXZpb3VyLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIG91dHB1dHMKICAgKiBAcmV0dXJucyB7R2F1c3NpYW5Qcm9jZXNzfQogICAqLwogIHN0YXRpYyBmcm9tRGF0YShpbnB1dHMsIG91dHB1dHMpIHsKICAgIHJldHVybiBHYXVzc2lhblByb2Nlc3MuZGVmYXVsdChpbnB1dHMsIG91dHB1dHMpOwogIH0KCiAgLyoqCiAgICogUmV0dXJucyBhIGJ1aWxkZXIgdG8gZGVmaW5lIHNwZWNpZmljIHBhcmFtZXRlcnMgb2YgdGhlIEdhdXNzaWFuIHByb2Nlc3MKICAgKiAoYG1vZC5yczoxMjlgKS4gRGVmYXVsdHMgdG8gYSBHYXVzc2lhbiBrZXJuZWwgKyBjb25zdGFudCBwcmlvci4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICBvdXRwdXRzCiAgICogQHJldHVybnMge0dhdXNzaWFuUHJvY2Vzc0J1aWxkZXJ9CiAgICovCiAgc3RhdGljIGJ1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICByZXR1cm4gbmV3IEdhdXNzaWFuUHJvY2Vzc0J1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBBREQgU0FNUExFUwogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogQWRkcyBuZXcgc2FtcGxlcyB0byB0aGUgbW9kZWwgKGBtb2QucnM6MTczYCkuCiAgICoKICAgKiBVcGRhdGVzIHRoZSBtb2RlbCBpbiBPKG7CsikgKGZhc3RlciB0aGFuIHJldHJhaW5pbmcgZnJvbSBzY3JhdGNoKSBidXQgZG9lcwogICAqIE5PVCByZWZpdCB0aGUgcGFyYW1ldGVycy4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICBvdXRwdXRzCiAgICovCiAgYWRkX3NhbXBsZXMoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgY29uc3Qgb3V0cHV0c1ZlY3RvciA9IHRvVmVjdG9yKG91dHB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeC5sZW5ndGggIT09IG91dHB1dHNWZWN0b3IubGVuZ3RoKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5yb3dzKCkgKCR7aW5wdXRzTWF0cml4Lmxlbmd0aH0pICE9PSBvdXRwdXRzLm5yb3dzKCkgKCR7b3V0cHV0c1ZlY3Rvci5sZW5ndGh9KWApOwogICAgfQogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQoKICAgIC8vIFJlc2lkdWFsaXNlIHRoZSBuZXcgb3V0cHV0cyBhZ2FpbnN0IHRoZSBjdXJyZW50IHByaW9yLgogICAgY29uc3QgcHJpb3JWYWx1ZXMgPSB0aGlzLnByaW9yLnByaW9yKGlucHV0c01hdHJpeCk7CiAgICBjb25zdCByZXNpZHVhbCA9IG5ldyBBcnJheShvdXRwdXRzVmVjdG9yLmxlbmd0aCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dHNWZWN0b3IubGVuZ3RoOyBpKyspIHsKICAgICAgcmVzaWR1YWxbaV0gPSBvdXRwdXRzVmVjdG9yW2ldIC0gcHJpb3JWYWx1ZXNbaV07CiAgICB9CgogICAgLy8gR3JvdyB0aGUgdHJhaW5pbmcgZGF0YS4KICAgIHRoaXMudHJhaW5pbmdJbnB1dHMuYWRkUm93cyhpbnB1dHNNYXRyaXgpOwogICAgdGhpcy50cmFpbmluZ091dHB1dHMuYWRkUm93cyhyZXNpZHVhbCk7CgogICAgLy8gSW5jcmVtZW50YWxseSBleHRlbmQgdGhlIENob2xlc2t5IGRlY29tcG9zaXRpb24gd2l0aCB0aGUgbmV3IHJvd3MuCiAgICBjb25zdCBuYk5ld0lucHV0cyA9IGlucHV0c01hdHJpeC5sZW5ndGg7CiAgICBhZGRSb3dzQ2hvbGVza3lDb3ZNYXRyaXgodGhpcy5jb3ZtYXRDaG9sZXNreSwgdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpLCBuYk5ld0lucHV0cywgdGhpcy5rZXJuZWwsIHRoaXMubm9pc2UpOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIExJS0VMSUhPT0QKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIExvZyBsaWtlbGlob29kIG9mIHRoZSBjdXJyZW50IG1vZGVsIGdpdmVuIHRoZSB0cmFpbmluZyBkYXRhIChgbW9kLnJzOjE5NmApLgogICAqCiAgICogRm9ybXVsYToKICAgKiAgIOKIksK9ICggb3V0cHV04bWAwrdL4oG7wrnCt291dHB1dCArIM6jX3IgbG58a2VybmVsKHjhtaMseOG1oykgKyBub2lzZcKyfCArIG7Ct2xuKDLPgCkgKQogICAqCiAgICogd2hlcmUgYG91dHB1dGAgaXMgdGhlIHByaW9yIHJlc2lkdWFsLgogICAqCiAgICogQHJldHVybnMge251bWJlcn0KICAgKi8KICBsaWtlbGlob29kKCkgewogICAgY29uc3Qgb3V0cHV0ID0gdGhpcy50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsgLy8gcmVzaWR1YWwKICAgIGNvbnN0IEwgPSB0aGlzLmNvdm1hdENob2xlc2t5LmwoKTsKCiAgICAvLyB0cmFuc3Bvc2Uob2wpwrdvbCA9IG91dHB1dOG1gMK3S+KBu8K5wrdvdXRwdXQsIHdoZXJlIEzCt29sID0gb3V0cHV0LgogICAgY29uc3Qgb2wgPSBzb2x2ZUxvd2VyVHJpKEwsIG91dHB1dCk7CiAgICBjb25zdCBkYXRhRml0ID0gbm9ybVNxdWFyZWQob2wpOwoKICAgIC8vIENvbXBsZXhpdHkgcGVuYWx0eTogzqMgbG58IHNlbGYtY292YXJpYW5jZSArIG5vaXNlwrIgfC4KICAgIGNvbnN0IGlucHV0cyA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKICAgIGNvbnN0IG5vaXNlU3EgPSB0aGlzLm5vaXNlICogdGhpcy5ub2lzZTsKICAgIGxldCBjb21wbGV4aXR5UGVuYWx0eSA9IDA7CiAgICBmb3IgKGxldCByID0gMDsgciA8IGlucHV0cy5sZW5ndGg7IHIrKykgewogICAgICBjb25zdCBzZWxmQ292ID0gdGhpcy5rZXJuZWwua2VybmVsKGlucHV0c1tyXSwgaW5wdXRzW3JdKSArIG5vaXNlU3E7CiAgICAgIGNvbXBsZXhpdHlQZW5hbHR5ICs9IE1hdGgubG9nKE1hdGguYWJzKHNlbGZDb3YpKTsKICAgIH0KICAgIGNvbnN0IG4gPSBpbnB1dHMubGVuZ3RoOwogICAgY29uc3Qgbm9ybWFsaXphdGlvbkNvbnN0YW50ID0gbiAqIE1hdGgubG9nKDIgKiBNYXRoLlBJKTsKICAgIHJldHVybiAtKGRhdGFGaXQgKyBjb21wbGV4aXR5UGVuYWx0eSArIG5vcm1hbGl6YXRpb25Db25zdGFudCkgLyAyOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFBSRURJQ1QKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFByZWRpY3RzIHRoZSBtZWFuIG9mIHRoZSBHYXVzc2lhbiBwcm9jZXNzIGZvciBlYWNoIHJvdyBvZiBgaW5wdXRzYAogICAqIChgbW9kLnJzOjIyNmApLgogICAqCiAgICogRm9ybXVsYTogYHByaW9yICsgY292KGlucHV0LHRyYWluKcK3S+KBu8K5wrdvdXRwdXRgLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcmV0dXJucyB7bnVtYmVyfG51bWJlcltdfSBudW1iZXIgZm9yIGEgc2luZ2xlLXBvaW50IGlucHV0LCBudW1iZXJbXSBvdGhlcndpc2UuCiAgICovCiAgcHJlZGljdChpbnB1dHMpIHsKICAgIGNvbnN0IHNpbmdsZSA9IGlzU2luZ2xlKGlucHV0cyk7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQogICAgY29uc3QgdHJhaW5NYXRyaXggPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CgogICAgLy8gd2VpZ2h0cyAoblRyYWluIMOXIG5JbnB1dCkgPSBL4oG7wrkgwrcgY292KHRyYWluLCBpbnB1dHMpLgogICAgbGV0IHdlaWdodHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICB3ZWlnaHRzID0gdGhpcy5jb3ZtYXRDaG9sZXNreS5zb2x2ZSh3ZWlnaHRzKTsKICAgIGNvbnN0IG1lYW4gPSB0aGlzLl9tZWFuRnJvbVdlaWdodHMod2VpZ2h0cywgaW5wdXRzTWF0cml4KTsKICAgIHJldHVybiBmcm9tVmVjdG9yKG1lYW4sIHNpbmdsZSk7CiAgfQoKICAvKioKICAgKiBQcmVkaWN0cyB0aGUgdmFyaWFuY2Ugb2YgdGhlIEdhdXNzaWFuIHByb2Nlc3MgZm9yIGVhY2ggcm93IG9mIGBpbnB1dHNgCiAgICogKGBtb2QucnM6MjQ4YCkuCiAgICoKICAgKiBGb3JtdWxhIChkaWFnb25hbCBvZik6CiAgICogICBjb3YoaW5wdXQsaW5wdXQpIOKIkiBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt2Nvdih0cmFpbixpbnB1dCkKICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge251bWJlcnxudW1iZXJbXX0KICAgKi8KICBwcmVkaWN0X3ZhcmlhbmNlKGlucHV0cykgewogICAgY29uc3Qgc2luZ2xlID0gaXNTaW5nbGUoaW5wdXRzKTsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KGlucHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4WzBdLmxlbmd0aCAhPT0gdGhpcy50cmFpbmluZ0lucHV0cy5uY29scykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5uY29scygpICgke2lucHV0c01hdHJpeFswXS5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfaW5wdXRzLm5jb2xzKCkgKCR7dGhpcy50cmFpbmluZ0lucHV0cy5uY29sc30pYCk7CiAgICB9CiAgICBjb25zdCB0cmFpbk1hdHJpeCA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKCiAgICAvLyBjb3ZfdHJhaW5faW5wdXRzIChuVHJhaW4gw5cgbklucHV0KS4KICAgIGNvbnN0IGNvdlRyYWluSW5wdXRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgodHJhaW5NYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwoKICAgIC8vIGtsID0gTOKBu8K5IMK3IGNvdl90cmFpbl9pbnB1dHMgIChzb2x2ZSBMwrdrbCA9IGNvdl90cmFpbl9pbnB1dHMpLgogICAgY29uc3Qga2wgPSBzb2x2ZUxvd2VyVHJpKHRoaXMuY292bWF0Q2hvbGVza3kubCgpLCBjb3ZUcmFpbklucHV0cyk7CgogICAgLy8gdmFyaWFuY2VbaV0gPSBrZXJuZWwoaW5wdXThtaIsaW5wdXThtaIpIOKIkiDigJZjb2x1bW4gaSBvZiBrbOKAlsKyLgogICAgY29uc3QgbklucHV0ID0gaW5wdXRzTWF0cml4Lmxlbmd0aDsKICAgIGNvbnN0IHZhcmlhbmNlcyA9IG5ldyBBcnJheShuSW5wdXQpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSW5wdXQ7IGkrKykgewogICAgICBjb25zdCBiYXNlQ292ID0gdGhpcy5rZXJuZWwua2VybmVsKGlucHV0c01hdHJpeFtpXSwgaW5wdXRzTWF0cml4W2ldKTsKICAgICAgY29uc3QgcHJlZGljdGVkQ292ID0gY29sdW1uTm9ybVNxdWFyZWQoa2wsIGkpOwogICAgICB2YXJpYW5jZXNbaV0gPSBiYXNlQ292IC0gcHJlZGljdGVkQ292OwogICAgfQogICAgcmV0dXJuIGZyb21WZWN0b3IodmFyaWFuY2VzLCBzaW5nbGUpOwogIH0KCiAgLyoqCiAgICogUHJlZGljdHMgYm90aCB0aGUgbWVhbiBhbmQgdGhlIHZhcmlhbmNlIGZvciBlYWNoIHJvdyBvZiBgaW5wdXRzYAogICAqIChgbW9kLnJzOjI5MGApLiBGYXN0ZXIgdGhhbiBjYWxsaW5nIGBwcmVkaWN0YCBhbmQgYHByZWRpY3RfdmFyaWFuY2VgCiAgICogc2VwYXJhdGVseS4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge1tudW1iZXJ8bnVtYmVyW10sIG51bWJlcnxudW1iZXJbXV19IGBbbWVhbiwgdmFyaWFuY2VdYC4KICAgKi8KICBwcmVkaWN0X21lYW5fdmFyaWFuY2UoaW5wdXRzKSB7CiAgICBjb25zdCBzaW5nbGUgPSBpc1NpbmdsZShpbnB1dHMpOwogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgIC8vIGNvdl90cmFpbl9pbnB1dHMgKG5UcmFpbiDDlyBuSW5wdXQpOyAgd2VpZ2h0cyA9IEvigbvCuSDCtyBjb3ZfdHJhaW5faW5wdXRzLgogICAgY29uc3QgY292VHJhaW5JbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICBjb25zdCB3ZWlnaHRzID0gdGhpcy5jb3ZtYXRDaG9sZXNreS5zb2x2ZShjb3ZUcmFpbklucHV0cyk7CgogICAgLy8gLS0tLS0gbWVhbiAtLS0tLQogICAgY29uc3QgbWVhblZlYyA9IHRoaXMuX21lYW5Gcm9tV2VpZ2h0cyh3ZWlnaHRzLCBpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgbWVhbiA9IGZyb21WZWN0b3IobWVhblZlYywgc2luZ2xlKTsKCiAgICAvLyAtLS0tLSB2YXJpYW5jZSAtLS0tLQogICAgLy8gdmFyaWFuY2VbaV0gPSBrZXJuZWwoaW5wdXThtaIsaW5wdXThtaIpIOKIkiAoY29sdW1uIGkgb2YgY292X3RyYWluX2lucHV0cynCtyhjb2x1bW4gaSBvZiB3ZWlnaHRzKS4KICAgIGNvbnN0IG5JbnB1dCA9IGlucHV0c01hdHJpeC5sZW5ndGg7CiAgICBjb25zdCB2YXJpYW5jZXMgPSBuZXcgQXJyYXkobklucHV0KTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbklucHV0OyBpKyspIHsKICAgICAgY29uc3QgYmFzZUNvdiA9IHRoaXMua2VybmVsLmtlcm5lbChpbnB1dHNNYXRyaXhbaV0sIGlucHV0c01hdHJpeFtpXSk7CiAgICAgIGNvbnN0IHByZWRpY3RlZENvdiA9IGNvbHVtbkRvdChjb3ZUcmFpbklucHV0cywgd2VpZ2h0cywgaSk7CiAgICAgIHZhcmlhbmNlc1tpXSA9IGJhc2VDb3YgLSBwcmVkaWN0ZWRDb3Y7CiAgICB9CiAgICBjb25zdCB2YXJpYW5jZSA9IGZyb21WZWN0b3IodmFyaWFuY2VzLCBzaW5nbGUpOwogICAgcmV0dXJuIFttZWFuLCB2YXJpYW5jZV07CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBmdWxsIGNvdmFyaWFuY2UgbWF0cml4IGZvciB0aGUgcm93cyBvZiBgaW5wdXRzYCAoYG1vZC5yczozMjlgKS4KICAgKgogICAqIEZvcm11bGE6CiAgICogICBjb3YoaW5wdXQsaW5wdXQpIOKIkiBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt2Nvdih0cmFpbixpbnB1dCkKICAgKgogICAqIEFMV0FZUyByZXR1cm5zIGEgYG51bWJlcltdW11gIG1hdHJpeCAobmV2ZXIgc2NhbGFyaXNlZCDigJQgbWF0Y2hlcyBSdXN0IHdoaWNoCiAgICogYWx3YXlzIHJldHVybnMgYSBgRE1hdHJpeGApLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcmV0dXJucyB7bnVtYmVyW11bXX0gKG5JbnB1dCDDlyBuSW5wdXQpCiAgICovCiAgcHJlZGljdF9jb3ZhcmlhbmNlKGlucHV0cykgewogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwogICAgY29uc3QgY292VHJhaW5JbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICBjb25zdCBjb3ZJbnB1dHNJbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeChpbnB1dHNNYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwoKICAgIC8vIGtsID0gTOKBu8K5IMK3IGNvdl90cmFpbl9pbnB1dHMuCiAgICBjb25zdCBrbCA9IHNvbHZlTG93ZXJUcmkodGhpcy5jb3ZtYXRDaG9sZXNreS5sKCksIGNvdlRyYWluSW5wdXRzKTsKCiAgICAvLyByZXN1bHQgPSBjb3ZfaW5wdXRzX2lucHV0cyDiiJIga2zhtYDCt2tsICAgKG1hdGNoZXMgZ2VtbV90cigtMSwga2wsIGtsLCAxKSkuCiAgICBjb25zdCBrbHRfa2wgPSBtYXRNdWwodHJhbnNwb3NlKGtsKSwga2wpOwogICAgcmV0dXJuIG1hdFN1Yihjb3ZJbnB1dHNJbnB1dHMsIGtsdF9rbCk7CiAgfQoKICAvKioKICAgKiBQcm9kdWNlcyBhIG11bHRpdmFyaWF0ZSBHYXVzc2lhbiB0aGF0IGNhbiBiZSBzYW1wbGVkIGF0IHRoZSBpbnB1dCBwb2ludHMKICAgKiAoYG1vZC5yczozNzFgKS4KICAgKgogICAqIENvdmFyaWFuY2U6CiAgICogICBjb3YoaW5wdXQsaW5wdXQpIOKIkiBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt2Nvdih0cmFpbixpbnB1dCkKICAgKiBNZWFuOgogICAqICAgcHJpb3IgKyBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt291dHB1dAogICAqCiAgICogVGhlIHJldHVybmVkIHtAbGluayBNdWx0aXZhcmlhdGVOb3JtYWx9IGhhcyBhIGAuc2FtcGxlKHJuZylgIG1ldGhvZCB3aGVyZQogICAqIGBybmdgIGlzIGEgYCgpID0+IG51bWJlciDiiIggWzAsMSlgIChlLmcuIGZyb20gYG11bGJlcnJ5MzJgKS4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge011bHRpdmFyaWF0ZU5vcm1hbH0KICAgKi8KICBzYW1wbGVfYXQoaW5wdXRzKSB7CiAgICBjb25zdCBzaW5nbGUgPSBpc1NpbmdsZShpbnB1dHMpOwogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgIC8vIHdlaWdodHMgPSBL4oG7wrkgwrcgY292KHRyYWluLCBpbnB1dHMpLgogICAgY29uc3QgY292VHJhaW5JbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICBjb25zdCB3ZWlnaHRzID0gdGhpcy5jb3ZtYXRDaG9sZXNreS5zb2x2ZShjb3ZUcmFpbklucHV0cyk7CgogICAgLy8gY292ID0gY292KGlucHV0LGlucHV0KSDiiJIgY292X3RyYWluX2lucHV0c+G1gMK3d2VpZ2h0cyAgKGdlbW1fdHIoLTEsIGNvdlRyYWluSW5wdXRzLCB3ZWlnaHRzLCAxKSkuCiAgICBjb25zdCBjb3ZJbnB1dHNJbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeChpbnB1dHNNYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwogICAgY29uc3QgY3RfdyA9IG1hdE11bCh0cmFuc3Bvc2UoY292VHJhaW5JbnB1dHMpLCB3ZWlnaHRzKTsKICAgIGNvbnN0IGNvdiA9IG1hdFN1Yihjb3ZJbnB1dHNJbnB1dHMsIGN0X3cpOwoKICAgIC8vIG1lYW4gPSBwcmlvciArIHdlaWdodHPhtYDCt3RyYWluaW5nT3V0cHV0cy4KICAgIGNvbnN0IG1lYW4gPSB0aGlzLl9tZWFuRnJvbVdlaWdodHMod2VpZ2h0cywgaW5wdXRzTWF0cml4KTsKICAgIHJldHVybiBuZXcgTXVsdGl2YXJpYXRlTm9ybWFsKG1lYW4sIGNvdiwgc2luZ2xlKTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBGSVQKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIEZpdHMgdGhlIHJlcXVlc3RlZCBwYXJhbWV0ZXJzIGFuZCByZXRyYWlucyB0aGUgbW9kZWwgKGBtb2QucnM6NDA2YCkuCiAgICoKICAgKiBOb2lzZSBhbmQga2VybmVsIHBhcmFtZXRlcnMgYXJlIGZpdHRlZCBieSBncmFkaWVudCBhc2NlbnQgKEFEQU0pIG9uIHRoZQogICAqIG1hcmdpbmFsIGxvZy1saWtlbGlob29kLiBSdW5zIGZvciBhdCBtb3N0IGBtYXhJdGVyYCBpdGVyYXRpb25zLCBzdG9wcGluZwogICAqIGVhcmx5IHdoZW4gYWxsIGdyYWRpZW50cyBhcmUgYmVsb3cgYGNvbnZlcmdlbmNlRnJhY3Rpb25gwrdwYXJhbSBvciBhZnRlcgogICAqIGBtYXhUaW1lYC4KICAgKgogICAqIEBwYXJhbSB7Ym9vbGVhbn0gZml0UHJpb3IgICAgICAgICAgICAgIGZpdCB0aGUgcHJpb3IgdG8gdGhlIGRhdGEuCiAgICogQHBhcmFtIHtib29sZWFufSBmaXRLZXJuZWwgICAgICAgICAgICAgZml0IHRoZSBrZXJuZWwgKGFuZCBub2lzZSkgcGFyYW1ldGVycy4KICAgKiBAcGFyYW0ge251bWJlcn0gIG1heEl0ZXIgICAgICAgICAgICAgICBtYXggZ3JhZGllbnQtYXNjZW50IGl0ZXJhdGlvbnMuCiAgICogQHBhcmFtIHtudW1iZXJ9ICBjb252ZXJnZW5jZUZyYWN0aW9uICAgcmVsYXRpdmUgY29udmVyZ2VuY2UgdGhyZXNob2xkLgogICAqIEBwYXJhbSB7bnVtYmVyfSBbbWF4VGltZT0zNjAwMDAwXSAgICAgIG1heCBmaXR0aW5nIHRpbWUgaW4gTUlMTElTRUNPTkRTCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFJ1c3QgdXNlcyBjaHJvbm86OkR1cmF0aW9uIHNlY29uZHMpLgogICAqLwogIGZpdF9wYXJhbWV0ZXJzKGZpdFByaW9yLCBmaXRLZXJuZWwsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUgPSBERUZBVUxUX01BWF9USU1FX01TKSB7CiAgICBpZiAoZml0UHJpb3IpIHsKICAgICAgY29uc3QgaW5wdXRzID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgICAgLy8gUmVjb3ZlciB0aGUgb3JpZ2luYWwgKHJhdykgb3V0cHV0czogcmVzaWR1YWwgKyBwcmlvcl9vbGQoaW5wdXRzKS4KICAgICAgY29uc3QgcmVzaWR1YWxPbGQgPSB0aGlzLnRyYWluaW5nT3V0cHV0cy5hc1ZlY3RvcigpOwogICAgICBjb25zdCBwcmlvck9sZCA9IHRoaXMucHJpb3IucHJpb3IoaW5wdXRzKTsKICAgICAgY29uc3Qgb3JpZ2luYWxPdXRwdXRzID0gbmV3IEFycmF5KHJlc2lkdWFsT2xkLmxlbmd0aCk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzaWR1YWxPbGQubGVuZ3RoOyBpKyspIHsKICAgICAgICBvcmlnaW5hbE91dHB1dHNbaV0gPSByZXNpZHVhbE9sZFtpXSArIHByaW9yT2xkW2ldOwogICAgICB9CgogICAgICAvLyBSZWZpdCB0aGUgcHJpb3Igb24gdGhlIHJhdyBvdXRwdXRzLgogICAgICB0aGlzLnByaW9yLmZpdChpbnB1dHMsIG9yaWdpbmFsT3V0cHV0cyk7CgogICAgICAvLyBSZS1yZXNpZHVhbGlzZSBhZ2FpbnN0IHRoZSBuZXcgcHJpb3IgYW5kIHN0b3JlIGJhY2suCiAgICAgIGNvbnN0IHByaW9yTmV3ID0gdGhpcy5wcmlvci5wcmlvcihpbnB1dHMpOwogICAgICBjb25zdCByZXNpZHVhbE5ldyA9IG5ldyBBcnJheShvcmlnaW5hbE91dHB1dHMubGVuZ3RoKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmlnaW5hbE91dHB1dHMubGVuZ3RoOyBpKyspIHsKICAgICAgICByZXNpZHVhbE5ld1tpXSA9IG9yaWdpbmFsT3V0cHV0c1tpXSAtIHByaW9yTmV3W2ldOwogICAgICB9CiAgICAgIHRoaXMudHJhaW5pbmdPdXRwdXRzLmFzc2lnbihyZXNpZHVhbE5ldyk7CgogICAgICAvLyBJZiB0aGUga2VybmVsIGlzIE5PVCBiZWluZyBmaXR0ZWQsIHJldHJhaW4gdGhlIGNvdmFyaWFuY2UgQ2hvbGVza3kKICAgICAgLy8gZnJvbSBzY3JhdGNoICh0aGUgcmVzaWR1YWxzIGNoYW5nZWQpLiBXaGVuIGZpdEtlcm5lbCBpcyB0cnVlIHRoZQogICAgICAvLyBvcHRpbWl6ZXIgcmVidWlsZHMgaXQgYW55d2F5LgogICAgICBpZiAoIWZpdEtlcm5lbCkgewogICAgICAgIHRoaXMuY292bWF0Q2hvbGVza3kgPSBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoaW5wdXRzLCB0aGlzLmtlcm5lbCwgdGhpcy5ub2lzZSwgdGhpcy5jaG9sZXNreUVwc2lsb24pOwogICAgICB9CiAgICB9CiAgICBpZiAoZml0S2VybmVsKSB7CiAgICAgIGlmICh0aGlzLmtlcm5lbC5pc1NjYWxhYmxlKCkpIHsKICAgICAgICBzY2FsZWRPcHRpbWl6ZVBhcmFtZXRlcnModGhpcywgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb3B0aW1pemVQYXJhbWV0ZXJzKHRoaXMsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpOwogICAgICB9CiAgICB9CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gSU5URVJOQUwgSEVMUEVSUwogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogQ29tcHV0ZXMgdGhlIHBvc3RlcmlvciBtZWFuIGBwcmlvciArIHdlaWdodHPhtYDCt3RyYWluaW5nT3V0cHV0c2AsIGkuZS4KICAgKiBgbWVhbltpXSA9IHByaW9yKGlucHV0cylbaV0gKyDOo190IHdlaWdodHNbdF1baV3Ct3RyYWluaW5nT3V0cHV0c1t0XWAuCiAgICoKICAgKiBUaGlzIHJlcHJvZHVjZXMgbmFsZ2VicmEgYHByaW9yLmdlbW1fdHIoMSwgd2VpZ2h0cywgdHJhaW5pbmdPdXRwdXRzLCAxKWAsCiAgICogd2hlcmUgYHdlaWdodHNgIGlzIChuVHJhaW4gw5cgbklucHV0KSwgYHRyYWluaW5nT3V0cHV0c2AgaXMgdGhlIHJlc2lkdWFsCiAgICogdmVjdG9yIChsZW5ndGggblRyYWluKSwgYW5kIHRoZSByZXN1bHQgaGFzIGxlbmd0aCBuSW5wdXQuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdW119IHdlaWdodHMgICAgICAoblRyYWluIMOXIG5JbnB1dCkKICAgKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0c01hdHJpeCAobklucHV0IMOXIGQpCiAgICogQHJldHVybnMge251bWJlcltdfSBwb3N0ZXJpb3IgbWVhbiAobGVuZ3RoIG5JbnB1dCksIHByaW9yIGFscmVhZHkgYWRkZWQuCiAgICogQHByaXZhdGUKICAgKi8KICBfbWVhbkZyb21XZWlnaHRzKHdlaWdodHMsIGlucHV0c01hdHJpeCkgewogICAgY29uc3QgbklucHV0ID0gaW5wdXRzTWF0cml4Lmxlbmd0aDsKICAgIGNvbnN0IG5UcmFpbiA9IHdlaWdodHMubGVuZ3RoOwogICAgY29uc3Qgb3V0cHV0cyA9IHRoaXMudHJhaW5pbmdPdXRwdXRzLmFzVmVjdG9yKCk7IC8vIHJlc2lkdWFsCiAgICBjb25zdCBwcmlvclZlYyA9IHRoaXMucHJpb3IucHJpb3IoaW5wdXRzTWF0cml4KTsKICAgIGNvbnN0IG1lYW4gPSBuZXcgQXJyYXkobklucHV0KTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbklucHV0OyBpKyspIHsKICAgICAgbGV0IHMgPSBwcmlvclZlY1tpXTsKICAgICAgZm9yIChsZXQgdCA9IDA7IHQgPCBuVHJhaW47IHQrKykgewogICAgICAgIHMgKz0gd2VpZ2h0c1t0XVtpXSAqIG91dHB1dHNbdF07CiAgICAgIH0KICAgICAgbWVhbltpXSA9IHM7CiAgICB9CiAgICByZXR1cm4gbWVhbjsKICB9Cn0KCi8vIE1peGluIHRoZSBvcHRpbWl6ZXIgZnJlZS1mdW5jdGlvbnMgb250byB0aGUgcHJvdG90eXBlIHNvIHRoZXkgYXJlIGFsc28KLy8gcmVhY2hhYmxlIGFzIG1ldGhvZHMgKGUuZy4gYGdwLm9wdGltaXplUGFyYW1ldGVycyguLi4pYCkuIGBmaXRfcGFyYW1ldGVyc2AKLy8gYWJvdmUgY2FsbHMgdGhlIGltcG9ydGVkIGZyZWUgZnVuY3Rpb25zIGRpcmVjdGx5OyB0aGVzZSBhbGlhc2VzIGp1c3Qga2VlcCB0aGUKLy8gc3VyZmFjZSBjb25zaXN0ZW50IHdpdGggUE9SVF9TUEVDIMKnNyAoImltcG9ydCB0aGVuIGNhbGwgYXMgbWV0aG9kcyIpLgpHYXVzc2lhblByb2Nlc3MucHJvdG90eXBlLm9wdGltaXplUGFyYW1ldGVycyA9IGZ1bmN0aW9uIChtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKSB7CiAgcmV0dXJuIG9wdGltaXplUGFyYW1ldGVycyh0aGlzLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKTsKfTsKR2F1c3NpYW5Qcm9jZXNzLnByb3RvdHlwZS5zY2FsZWRPcHRpbWl6ZVBhcmFtZXRlcnMgPSBmdW5jdGlvbiAobWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSkgewogIHJldHVybiBzY2FsZWRPcHRpbWl6ZVBhcmFtZXRlcnModGhpcywgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSk7Cn07CkdhdXNzaWFuUHJvY2Vzcy5wcm90b3R5cGUuZ3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QgPSBmdW5jdGlvbiAoKSB7CiAgcmV0dXJuIGdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKHRoaXMpOwp9OwpHYXVzc2lhblByb2Nlc3MucHJvdG90eXBlLnNjYWxlZEdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kID0gZnVuY3Rpb24gKCkgewogIHJldHVybiBzY2FsZWRHcmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZCh0aGlzKTsKfTsKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gR2F1c3NpYW5Qcm9jZXNzQnVpbGRlcgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQnVpbGRlciB0byBzZXQgdGhlIHBhcmFtZXRlcnMgb2YgYSBHYXVzc2lhbiBwcm9jZXNzIChgYnVpbGRlci5yc2ApLgogKgogKiBDaGFpbmFibGUgc2V0dGVycyBjdWxtaW5hdGluZyBpbiBgdHJhaW4oKWAuIFByb2R1Y2VkIGJ5CiAqIGBHYXVzc2lhblByb2Nlc3MuYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpYC4KICoKICogRGVmYXVsdHMgKGBidWlsZGVyLnJzOjY2YCk6CiAqICAgLSBjb25zdGFudCBwcmlvciAoMCB1bmxlc3MgZml0dGVkKQogKiAgIC0gYSBHYXVzc2lhbiBrZXJuZWwKICogICAtIG5vaXNlID0gMTAlIG9mIHRoZSBvdXRwdXQgc3RhbmRhcmQgZGV2aWF0aW9uCiAqICAgLSBkb2VzIG5vdCBmaXQgYW55IHBhcmFtZXRlcnMKICogICAtIGZpdCBydW5zIGZvciDiiaQgMTAwIGl0ZXJhdGlvbnMgLyAxIGhvdXIgdW5sZXNzIGFsbCBncmFkaWVudHMgYXJlIGJlbG93IDUlLgogKgogKiBTZXR0ZXJzIG11dGF0ZSBhbmQgcmV0dXJuIGB0aGlzYCAoUnVzdCByZXR1cm5zIGEgbmV3IHR5cGVkIGJ1aWxkZXI7IGZvciBKUyB3ZQogKiBrZWVwIGEgc2luZ2xlIG11dGFibGUgYnVpbGRlciDigJQgYmVoYXZpb3VyIGlzIGlkZW50aWNhbCBmb3IgdGhlIGZsdWVudCBBUEkpLgogKi8KY2xhc3MgR2F1c3NpYW5Qcm9jZXNzQnVpbGRlciB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSB0cmFpbmluZ0lucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSAgICAgdHJhaW5pbmdPdXRwdXRzCiAgICovCiAgY29uc3RydWN0b3IodHJhaW5pbmdJbnB1dHMsIHRyYWluaW5nT3V0cHV0cykgewogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgodHJhaW5pbmdJbnB1dHMpOwogICAgY29uc3Qgb3V0cHV0c1ZlY3RvciA9IHRvVmVjdG9yKHRyYWluaW5nT3V0cHV0cyk7CgogICAgLyoqIEB0eXBlIHtudW1iZXJbXVtdfSAqLwogICAgdGhpcy50cmFpbmluZ0lucHV0cyA9IGlucHV0c01hdHJpeDsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW119ICovCiAgICB0aGlzLnRyYWluaW5nT3V0cHV0cyA9IG91dHB1dHNWZWN0b3I7CgogICAgLy8gRGVmYXVsdCBwcmlvcjogQ29uc3RhbnRQcmlvcigwKSAoZGltIGlzIGlnbm9yZWQgYnkgQ29uc3RhbnRQcmlvcikuCiAgICAvKiogQHR5cGUge29iamVjdH0gKi8KICAgIHRoaXMucHJpb3IgPSBDb25zdGFudFByaW9yLmRlZmF1bHQoaW5wdXRzTWF0cml4Lmxlbmd0aCA9PT0gMCA/IDAgOiBpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoKTsKICAgIC8vIERlZmF1bHQga2VybmVsOiBHYXVzc2lhbiAvIFNxdWFyZWRFeHAgd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMuCiAgICAvKiogQHR5cGUge29iamVjdH0gKi8KICAgIHRoaXMua2VybmVsID0gbmV3IEdhdXNzaWFuKCk7CiAgICAvLyBEZWZhdWx0IG5vaXNlOiAxMCUgb2YgdGhlIG91dHB1dCBzdGFuZGFyZCBkZXZpYXRpb24uCiAgICAvLyAgIHJvd192YXJpYW5jZShvdXRwdXRzKVswXSA9IM6jKHnhtaLiiJLIsynCsi9OICAoZGl2aWRlIGJ5IE4g4oCUIHNlZSBmaXRBbXBsaXR1ZGVWYXIpLgogICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovCiAgICB0aGlzLm5vaXNlID0gMC4xICogTWF0aC5zcXJ0KGZpdEFtcGxpdHVkZVZhcihvdXRwdXRzVmVjdG9yKSk7CiAgICAvKiogQHR5cGUge251bWJlcnxudWxsfSAqLwogICAgdGhpcy5jaG9sZXNreUVwc2lsb24gPSBudWxsOwoKICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi8KICAgIHRoaXMuc2hvdWxkRml0S2VybmVsID0gZmFsc2U7CiAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovCiAgICB0aGlzLnNob3VsZEZpdFByaW9yID0gZmFsc2U7CgogICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovCiAgICB0aGlzLm1heEl0ZXIgPSAxMDA7CiAgICAvKiogQHR5cGUge251bWJlcn0gKi8KICAgIHRoaXMuY29udmVyZ2VuY2VGcmFjdGlvbiA9IDAuMDU7CiAgICAvKiogQHR5cGUge251bWJlcn0gbWF4IGZpdHRpbmcgdGltZSBpbiBtaWxsaXNlY29uZHMgKi8KICAgIHRoaXMubWF4VGltZSA9IERFRkFVTFRfTUFYX1RJTUVfTVM7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gU0VUVEVSUyAoY2hhaW5hYmxlKQogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogU2V0cyBhIG5ldyBwcmlvci4KICAgKiBAcGFyYW0ge29iamVjdH0gcHJpb3IKICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBzZXRQcmlvcihwcmlvcikgewogICAgdGhpcy5wcmlvciA9IHByaW9yOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBTZXRzIHRoZSBub2lzZSBwYXJhbWV0ZXIgKHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgb3V0cHV0IG5vaXNlKS4KICAgKiBAcGFyYW0ge251bWJlcn0gbm9pc2UgKOKJpSAwKQogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIHNldE5vaXNlKG5vaXNlKSB7CiAgICBpZiAoIShub2lzZSA+PSAwKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBub2lzZSBwYXJhbWV0ZXIgc2hvdWxkIGJlIG5vbi1uZWdhdGl2ZSBidXQgd2UgdHJpZWQgdG8gc2V0IGl0IHRvICR7bm9pc2V9YCk7CiAgICB9CiAgICB0aGlzLm5vaXNlID0gbm9pc2U7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIENoYW5nZXMgdGhlIGtlcm5lbCBvZiB0aGUgR2F1c3NpYW4gcHJvY2Vzcy4KICAgKiBAcGFyYW0ge29iamVjdH0ga2VybmVsCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgc2V0S2VybmVsKGtlcm5lbCkgewogICAgdGhpcy5rZXJuZWwgPSBrZXJuZWw7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFNldHMgdGhlIENob2xlc2t5IGVwc2lsb24uIFdoZW4gYSBzdHJpY3RseSBwb3NpdGl2ZSB2YWx1ZSBpcyBnaXZlbiwgdGhlCiAgICogQ2hvbGVza3kgZGVjb21wb3NpdGlvbiBpcyBndWFyYW50ZWVkIHRvIHN1Y2NlZWQgKHRoZSB2YWx1ZSBpcyB1c2VkIGluCiAgICogcGxhY2Ugb2YgYSBub24tcG9zaXRpdmUgZGlhZ29uYWwgcGl2b3QpLiBgbnVsbGAgaWdub3JlcyBpdC4KICAgKiBAcGFyYW0ge251bWJlcnxudWxsfSBjaG9sZXNreUVwc2lsb24KICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBzZXRDaG9sZXNreUVwc2lsb24oY2hvbGVza3lFcHNpbG9uKSB7CiAgICB0aGlzLmNob2xlc2t5RXBzaWxvbiA9IGNob2xlc2t5RXBzaWxvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogTW9kaWZpZXMgdGhlIHN0b3BwaW5nIGNyaXRlcmlhIG9mIHRoZSBncmFkaWVudCBkZXNjZW50IHVzZWQgdG8gZml0IHRoZQogICAqIG5vaXNlIGFuZCBrZXJuZWwgcGFyYW1ldGVycy4KICAgKiBAcGFyYW0ge251bWJlcn0gbWF4SXRlcgogICAqIEBwYXJhbSB7bnVtYmVyfSBjb252ZXJnZW5jZUZyYWN0aW9uCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgc2V0Rml0UGFyYW1ldGVycyhtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uKSB7CiAgICB0aGlzLm1heEl0ZXIgPSBtYXhJdGVyOwogICAgdGhpcy5jb252ZXJnZW5jZUZyYWN0aW9uID0gY29udmVyZ2VuY2VGcmFjdGlvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQXNrcyBmb3IgdGhlIGtlcm5lbCBwYXJhbWV0ZXJzIHRvIGJlIGZpdHRlZCBvbiB0aGUgdHJhaW5pbmcgZGF0YSAoYXBwbGllZAogICAqIHdoZW4gYHRyYWluKClgIGlzIGNhbGxlZCkuCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgZml0S2VybmVsKCkgewogICAgdGhpcy5zaG91bGRGaXRLZXJuZWwgPSB0cnVlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBc2tzIGZvciB0aGUgcHJpb3IgdG8gYmUgZml0dGVkIG9uIHRoZSB0cmFpbmluZyBkYXRhIChhcHBsaWVkIHdoZW4KICAgKiBgdHJhaW4oKWAgaXMgY2FsbGVkKS4KICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBmaXRQcmlvcigpIHsKICAgIHRoaXMuc2hvdWxkRml0UHJpb3IgPSB0cnVlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gVFJBSU4KICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFRyYWlucyB0aGUgR2F1c3NpYW4gcHJvY2VzcywgZml0dGluZyB0aGUgcGFyYW1ldGVycyBpZiByZXF1ZXN0ZWQKICAgKiAoYGJ1aWxkZXIucnM6MTg5YCkuCiAgICoKICAgKiBTdGVwczoKICAgKiAgIDEuIGlmIGBzaG91bGRGaXRLZXJuZWxgIOKGkiBga2VybmVsLmhldXJpc3RpY0ZpdChpbnB1dHMsIG91dHB1dHMpYCB1c2luZyB0aGUKICAgKiAgICAgIFJBVyBvdXRwdXRzICh0aGUgYnVpbGRlciBoYXMgbm90IHN1YnRyYWN0ZWQgdGhlIHByaW9yIHlldCkuCiAgICogICAyLiBjb25zdHJ1Y3QgdGhlIEdhdXNzaWFuUHJvY2Vzcy4KICAgKiAgIDMuIGBncC5maXRfcGFyYW1ldGVycyhzaG91bGRGaXRQcmlvciwgc2hvdWxkRml0S2VybmVsLCDigKYpYC4KICAgKgogICAqIEByZXR1cm5zIHtHYXVzc2lhblByb2Nlc3N9CiAgICovCiAgdHJhaW4oKSB7CiAgICAvLyAxLiBLZXJuZWwgaGV1cmlzdGljIGZpdCAodXNlcyByYXcgb3V0cHV0cykuCiAgICBpZiAodGhpcy5zaG91bGRGaXRLZXJuZWwpIHsKICAgICAgdGhpcy5rZXJuZWwuaGV1cmlzdGljRml0KHRoaXMudHJhaW5pbmdJbnB1dHMsIHRoaXMudHJhaW5pbmdPdXRwdXRzKTsKICAgIH0KCiAgICAvLyAyLiBCdWlsZCB0aGUgR1AgKHRoaXMgcmVzaWR1YWxpc2VzIHRoZSBvdXRwdXRzIGFuZCBidWlsZHMgdGhlIENob2xlc2t5KS4KICAgIGNvbnN0IGdwID0gbmV3IEdhdXNzaWFuUHJvY2Vzcyh0aGlzLnByaW9yLCB0aGlzLmtlcm5lbCwgdGhpcy5ub2lzZSwgdGhpcy5jaG9sZXNreUVwc2lsb24sIHRoaXMudHJhaW5pbmdJbnB1dHMsIHRoaXMudHJhaW5pbmdPdXRwdXRzKTsKCiAgICAvLyAzLiBGaXQgb24gdGhlIHRyYWluaW5nIGRhdGEsIGlmIHJlcXVlc3RlZC4KICAgIGdwLmZpdF9wYXJhbWV0ZXJzKHRoaXMuc2hvdWxkRml0UHJpb3IsIHRoaXMuc2hvdWxkRml0S2VybmVsLCB0aGlzLm1heEl0ZXIsIHRoaXMuY29udmVyZ2VuY2VGcmFjdGlvbiwgdGhpcy5tYXhUaW1lKTsKICAgIHJldHVybiBncDsKICB9Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gTE9DQUwgQ09MVU1OIEhFTFBFUlMKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIFNxdWFyZWQgRXVjbGlkZWFuIG5vcm0gb2YgY29sdW1uIGBjYCBvZiBtYXRyaXggYE1gIChudW1iZXJbXVtdKS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBNCiAqIEBwYXJhbSB7bnVtYmVyfSBjCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBjb2x1bW5Ob3JtU3F1YXJlZChNLCBjKSB7CiAgbGV0IHMgPSAwOwogIGZvciAobGV0IHIgPSAwOyByIDwgTS5sZW5ndGg7IHIrKykgewogICAgY29uc3QgdiA9IE1bcl1bY107CiAgICBzICs9IHYgKiB2OwogIH0KICByZXR1cm4gczsKfQoKLyoqCiAqIERvdCBwcm9kdWN0IG9mIGNvbHVtbiBgY2Agb2YgQSB3aXRoIGNvbHVtbiBgY2Agb2YgQiAoYm90aCBudW1iZXJbXVtdKS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQgogKiBAcGFyYW0ge251bWJlcn0gYwogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gY29sdW1uRG90KEEsIEIsIGMpIHsKICBsZXQgcyA9IDA7CiAgZm9yIChsZXQgciA9IDA7IHIgPCBBLmxlbmd0aDsgcisrKSB7CiAgICBzICs9IEFbcl1bY10gKiBCW3JdW2NdOwogIH0KICByZXR1cm4gczsKfQoKLyoqDQogKiDlhYvliKnph5Hms5UoS3JpZ2luZynlhaflpJbmj5Lpu57mlbjlgLwNCiAqDQogKiDlhYvliKnph5Hms5XoqIjnrpfoiIflr6bpmpvpgYvnrpfnk7bpoLjllY/poYzlj6/oqbPopos6IGh0dHBzOi8vZ2l0aHViLmNvbS9sdmlzZWkvd2ViLWRldmVsb3Blci1yZXNvdXJjZXMvYmxvYi9tYXN0ZXIvd2ViYXNzZW1ibHkva3JpZ2luZy5tZA0KICoNCiAqIOiLpeaYr05vZGUuanPnq6/kvb/nlKjpoIjmm7Tpq5joqIjnrpfpgJ/luqbvvIzlj6/kvb/nlKh3LWtyaWdpbmc6IGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWtyaWdpbmcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9pbnRlcnAyS3JpZ2luZy50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzU3JjIOi8uOWFpeS6jOe2reW6p+aomeWKoOingOa4rOaVuOaTmum7numZo+WIl++8jOeCult7eDp4MSx5OnkxLHo6ejF9LHt4OngyLHk6eTIsejp6Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIlw0KICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHBzVGFyIOi8uOWFpeS6jOe2reW6p+aomem7numZo+WIl+aIlum7nueJqeS7tu+8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiX77yM5oiWe3g6eDEseTp5MX3pu57nianku7YNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tuS5i3jmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7bkuYt55qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlaPSd6J10g6Ly45YWl6bue54mp5Lu25LmLeuashOS9jeWtl+S4su+8jOeCuuingOa4rOWAvO+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2NhbGU9MV0g6Ly45YWl5q2j6KaP5YyW56+E5ZyN5pW45YC877yM5Zug6JmV55CG5aSa6YKK5b2i5pmC5pyJ5pW45YC85a656Kix6Kqk5beu77yM5pWF6aCI6YCa6YGO57iu5pS+5YC85Z+f5L6G5rib5bCR5ZWP6aGM77yM6aCQ6KitMeaYr+ato+imj+WMljDoh7Mx5LmL6ZaT77yM5L2/55Soc2NhbGVYWeWJh+aYr+ato+imj+WMlueCujDoh7NzY2FsZVhZ5LmL6ZaT77yM6aCQ6KitMQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQubWV0aG9kPSdmcmllZHJpY2gnXSDovLjlhaXlvoznq6/lvJXmk47lrZfkuLLvvIzlj6/pgbgnZnJpZWRyaWNoJyhHYXVzc2lhbiBQcm9jZXNzIFJlZ3Jlc3Npb27vvIzmoLjlh73mlbjvvIxrcmlnaW5nLWZyaWVkcmljaCnjgIEnaW52YWxsJyjntpPlhbhPcmRpbmFyeSBLcmlnaW5n77yM5Y2K6K6K55Ww5ZyW5pOs5ZCI77yMa3JpZ2luZy1pbnZhbGwva3JpZ2luZy5tanMp77yM6aCQ6KitJ2ZyaWVkcmljaCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0Lm1vZGVsPSdleHBvbmVudGlhbCddIOi8uOWFpeaTrOWQiOaooeW8j+Wtl+S4su+8jG1ldGhvZD0naW52YWxsJ+aZguWPr+mBuCdleHBvbmVudGlhbCfjgIEnZ2F1c3NpYW4n44CBJ3NwaGVyaWNhbCfvvJttZXRob2Q9J2ZyaWVkcmljaCfmmYInZ2F1c3NpYW4n5bCN5oeJU3F1YXJlZEV4cOOAgeWFtumkmCjlkKtzcGhlcmljYWwp5bCN5oeJRXhwb25lbnRpYWzvvIzpoJDoqK0nZXhwb25lbnRpYWwnDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zaWdtYTI9MF0g6Ly45YWl6Ieq5YuV5pOs5ZCI5Y+D5pW4c2lnbWEy5pW45YC877yM5YOFbWV0aG9kPSdpbnZhbGwn5pmC5pyJ5pWI77yM6aCQ6KitMA0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuYWxwaGE9MTAwXSDovLjlhaXoh6rli5Xmk6zlkIjlj4PmlbhhbHBoYeaVuOWAvO+8jOWDhW1ldGhvZD0naW52YWxsJ+aZguacieaViO+8jOmgkOiorTEwMA0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQubHM9MC41XSDovLjlhaVmcmllZHJpY2jmoLjlh73mlbhsZW5ndGhzY2FsZeaVuOWAvCjlsI3mh4nmraPopo/ljJblvozlgLzln58p77yM5YOFbWV0aG9kPSdmcmllZHJpY2gn5pmC5pyJ5pWI77yM6aCQ6KitMC41DQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5ub2lzZT0wLjAxXSDovLjlhaVmcmllZHJpY2jop4DmuKzlmarpn7PmqJnmupblt64o5bCN5oeJ5q2j6KaP5YyW5b6M5YC85Z+fKe+8jOWDhW1ldGhvZD0nZnJpZWRyaWNoJ+aZguacieaViO+8jOmgkOiorTAuMDENCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC5yZXR1cm5XaXRoVmFyaW9ncmFtPWZhbHNlXSDovLjlhaXmmK/lkKblm57lgrPmk6zlkIjljYrorornlbDmlbjntZDmnpzluIPmnpflgLzvvIxtZXRob2Q9J2ZyaWVkcmljaCfmmYJ2YXJpb2dyYW3lm57lgrNudWxs77yM6aCQ6KitZmFsc2UNCiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IOWbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpeS9v+eUqHJldHVybldpdGhWYXJpb2dyYW09dHJ1ZeWJh+WbnuWCs+eJqeS7tuizh+ioiu+8jOiLpeeZvOeUn+mMr+iqpOWJh+WbnuWCs+mMr+iqpOioiuaBr+eJqeS7tg0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCBwDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNSwgejogOTQuOTQ5MjU4OTg3ODQ1MjcgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI4MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyODMsIHk6IDIwNSwgejogMTE3LjE0ODk2MzEwNjk1MTQ3IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAxMTYwLA0KICogICAgIHk6IDM4MCwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDExNjAsIHk6IDM4MCwgejogODQuOTgzMTQ2NzIwMDUzMzQgfQ0KICoNCiAqIHBzID0gW3sgYTogMjQzLCBiOiAyMDYsIGM6IDk1IH0sIHsgYTogMjMzLCBiOiAyMjUsIGM6IDE0NiB9LCB7IGE6IDIxLCBiOiAzMjUsIGM6IDIyIH0sIHsgYTogOTUzLCBiOiAyOCwgYzogMjIzIH0sIHsgYTogMTA5MiwgYjogMjkwLCBjOiAzOSB9LCB7IGE6IDc0NCwgYjogMjAwLCBjOiAxOTEgfSwgeyBhOiAxNzQsIGI6IDMsIGM6IDIyIH0sIHsgYTogNTM3LCBiOiAzNjgsIGM6IDI0OSB9LCB7IGE6IDExNTEsIGI6IDM3MSwgYzogODYgfSwgeyBhOiA4MTQsIGI6IDI1MiwgYzogMTI1IH1dDQogKiBwID0gew0KICogICAgIGE6IDI0MywNCiAqICAgICBiOiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHAsIHsga2V5WDogJ2EnLCBrZXlZOiAnYicsIGtleVo6ICdjJyB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgYTogMjQzLCBiOiAyMDUsIGM6IDk0Ljk0OTI1ODk4Nzg0NTI3IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IFsNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI0MywNCiAqICAgICAgICAgeTogMjA1LA0KICogICAgIH0sDQogKiAgICAgew0KICogICAgICAgICB4OiAyODMsDQogKiAgICAgICAgIHk6IDIwNSwNCiAqICAgICB9LA0KICogXQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNSwgejogOTQuOTQ5MjU4OTg3ODQ1MjcgfSwNCiAqIC8vICAgeyB4OiAyODMsIHk6IDIwNSwgejogMTE3LjE0ODk2MzEwNjk1MTQ3IH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwLCB7IHNjYWxlOiAxMDAwLCBtZXRob2Q6ICdpbnZhbGwnIH0pIC8vc2NhbGUtcm9idXN054K6aW52YWxs5bCI5bGsLCBmcmllZHJpY2jlm7rlrpprZXJuZWzpnZ5zY2FsZS1yb2J1c3QNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA1LCB6OiA5NC44ODQ3OTk0ODQxODg3OCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCwgeyBtb2RlbDogJ2dhdXNzaWFuJyB9KSAvL2ZyaWVkcmljaOm7mOiqjSwgZ2F1c3NpYW7lsI3mh4lTcXVhcmVkRXhw5qC4DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNSwgejogMTE4LjkwNTgyNTAwNzQ3OTgzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwLCB7IHNpZ21hMjogMC4wMDEsIGFscGhhOiA3MCwgbWV0aG9kOiAnaW52YWxsJyB9KSAvL3NpZ21hMi9hbHBoYeeCumludmFsbOWNiuiuiueVsOWcluaTrOWQiOWPg+aVuCwgZnJpZWRyaWNo5LiN6YGp55SoDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNSwgejogOTAuODg3MDI5NDkyNzYzNDMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHAsIHsgcmV0dXJuV2l0aFZhcmlvZ3JhbTogdHJ1ZSwgbWV0aG9kOiAnaW52YWxsJyB9KSAvL3ZhcmlvZ3JhbeeCumludmFsbOWwiOWxrCwgZnJpZWRyaWNo5Zue5YKzbnVsbA0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsNCiAqIC8vICAgcmVzdWx0OiB7IHg6IDI0MywgeTogMjA1LCB6OiA5NC44ODQ3OTk0ODQxODcyMSB9LA0KICogLy8gICB2YXJpb2dyYW06IHsNCiAqIC8vICAgICB0OiBbDQogKiAvLyAgICAgICAwLjMyMTU4NTkwMzA4MzcwMDQ0LA0KICogLy8gICAgICAgMC41NDYyNTU1MDY2MDc5Mjk1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODg1NDYyNTU1MDY2MDc5MywNCiAqIC8vICAgICAgIDAuMDc0ODg5ODY3ODQxNDA5NjksDQogKiAvLyAgICAgICAwLjc0NDQ5MzM5MjA3MDQ4NDYsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuMjgxOTM4MzI1OTkxMTg5NDUsDQogKiAvLyAgICAgICAwLjQ1Mzc0NDQ5MzM5MjA3MDQ2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICB4OiBbDQogKiAvLyAgICAgICAwLjE5NjQ2MDE3Njk5MTE1MDQ1LA0KICogLy8gICAgICAgMC4xODc2MTA2MTk0NjkwMjY1NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjgyNDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjk0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuNjM5ODIzMDA4ODQ5NTU3NiwNCiAqIC8vICAgICAgIDAuMTM1Mzk4MjMwMDg4NDk1NTgsDQogKiAvLyAgICAgICAwLjQ1NjYzNzE2ODE0MTU5Mjk0LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNzAxNzY5OTExNTA0NDI0OA0KICogLy8gICAgIF0sDQogKiAvLyAgICAgeTogWw0KICogLy8gICAgICAgMC41MTY4MTQxNTkyOTIwMzU0LA0KICogLy8gICAgICAgMC41MzM2MjgzMTg1ODQwNzA4LA0KICogLy8gICAgICAgMC42MjIxMjM4OTM4MDUzMDk3LA0KICogLy8gICAgICAgMC4zNTkyOTIwMzUzOTgyMzAwNywNCiAqIC8vICAgICAgIDAuNTkxMTUwNDQyNDc3ODc2MSwNCiAqIC8vICAgICAgIDAuNTExNTA0NDI0Nzc4NzYxLA0KICogLy8gICAgICAgMC4zMzcxNjgxNDE1OTI5MjAzNiwNCiAqIC8vICAgICAgIDAuNjYwMTc2OTkxMTUwNDQyNSwNCiAqIC8vICAgICAgIDAuNjYyODMxODU4NDA3MDc5NywNCiAqIC8vICAgICAgIDAuNTU3NTIyMTIzODkzODA1Mw0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbnVnZ2V0OiAwLjMzNTI4NTM0OTIzNDI4MTQ0LA0KICogLy8gICAgIHJhbmdlOiAwLjk4MTgyNzQyMDQxMjA0ODgsDQogKiAvLyAgICAgc2lsbDogMC40NTg0NTgwMzMzNDQzMDc1LA0KICogLy8gICAgIEE6IDAuMzMzMzMzMzMzMzMzMzMzMywNCiAqIC8vICAgICBuOiAxMCwNCiAqIC8vICAgICBtb2RlbDogW0Z1bmN0aW9uOiBrcmlnaW5nX3ZhcmlvZ3JhbV9leHBvbmVudGlhbF0sDQogKiAvLyAgICAgc3ZwZDogeyBkYXRhOiBbQXJyYXldLCBiYXJzOiBbQXJyYXldIH0sDQogKiAvLyAgICAgSzogWw0KICogLy8gICAgICAgICAgLTc1Ljg1MTcwMDQxNzUyNDUsICAgICAgIDY3LjkyNTcyMjkyMzQ4NCwgLTAuMTYzMzU4NDEwMzY5NjQ2NzcsDQogKiAvLyAgICAgICAgMC4yNDEzMTUxODk3ODI3MDg3NywgIC0wLjA0MjM0MjQ2ODY1MDQ4NzMyLCAgIDAuODc3MDUxODM5NjMyODkxMiwNCiAqIC8vICAgICAgICAgIDUuNjE2OTYwMzYyMTcwMjc5LCAgICAgMS42MjE2NTk2Mzc0NDAyMjcsIDAuMDI3ODg4MDAxNjUxODk0NjM1LA0KICogLy8gICAgICAgLTAuMjE0MTU4NTM0MTY2NTI4MDMsICAgICA2Ny45MjU3MjI5MjM0ODQwMiwgICAtNzUuNjE3ODY0Nzg4MjQ4NjgsDQogKiAvLyAgICAgICAgICA1LjQxMzIzMjA3OTcyNzA2NCwgICAwLjA0OTA2OTQzNDM4Mzg1OTU4LCAgMC4wMzY3OTExMzIyOTM0ODQ2NSwNCiAqIC8vICAgICAgIC0wLjExODQ3MTM5MzUyNjk4Njc3LCAgICAwLjMxNDIwMTI3NjcyOTc5MTcsICAgMS45NTMxMDc4ODU0NDMwMDI0LA0KICogLy8gICAgICAgIDAuMTQyMTYzNzc4NTQwNTUzNDMsIC0wLjAyNjUwMzEwNDY3MjUyNTE3NCwgICAtMC4xNjMzNTg0MTAzNjk2NTEsDQogKiAvLyAgICAgICAgICA1LjQxMzIzMjA3OTcyNzA2NywgICAtMTAuMzQxMDg4NzQxNjAyNDc1LCAgICAwLjcwNzY5MDI1NjQxNTIwNSwNCiAqIC8vICAgICAgICAgMC4yNzE3MjU5NDc3NDgxMzc1LCAgICAtMC4wMzI3NTEzMzgzMjc4MTgsICAgMi40MDIxNTEwNDY3NzM0NDA2LA0KICogLy8gICAgICAgICAxLjEwMzk1MjkzMDMyMDQ5NTgsICAgIDAuOTM0MzI0MTE5OTYyNjcxMSwgIDAuMTc1OTM5MTA2NzcxOTk1NTMsDQogKiAvLyAgICAgICAgMC4yNDEzMTUxODk3ODI2ODgyMywgICAwLjA0OTA2OTQzNDM4Mzg4NDUzLCAgIDAuNzA3NjkwMjU2NDE1MjAwNiwNCiAqIC8vICAgICAgICAtMTEuMTk1ODk1ODA5MzMyODE4LCAgICAzLjYzMTgzMjY3NjcxNjgyNjcsICAgMy4wOTM1Mzg2NTA4ODg3MDM1LA0KICogLy8gICAgICAgICAxLjA0NTE1NTM0OTk1NjgxMzYsICAgMC4wNzY4MTExNTE1OTAyNTE5OCwgICAwLjU1MDA1MjA5ODEyNTM0MTYsDQogKiAvLyAgICAgICAgICAyLjE3NjkyODIwNzcxMDA0OCwgIC0wLjA0MjM0MjQ2ODY1MDQ5MDU1LCAgMC4wMzY3OTExMzIyOTM0ODU3OCwNCiAqIC8vICAgICAgICAwLjI3MTcyNTk0Nzc0ODEzODEzLCAgICAzLjYzMTgzMjY3NjcxNjgxODgsICAtMjEuODMzOTkxODMzMzk3NTI2LA0KICogLy8gICAgICAgIC0wLjM3MDM1NDQ1NjcwMzE3ODQsICAgIDAuMTYzMTk0MDc5NzA4NjgxNCwgICAwLjE0Nzg0ODUyODUzMDIxMjEsDQogKiAvLyAgICAgICAgIDE0LjU5MjY2MTE1MzY0NjM0OSwgICAgIDMuNTI5NjQwNzU5NjYwOTQ5LCAgICAwLjg3NzA1MTgzOTYzMjg4NCwNCiAqIC8vICAgICAgIC0wLjExODQ3MTM5MzUyNjk3MTExLCAtMC4wMzI3NTEzMzgzMjc4MTk2ODYsICAgMy4wOTM1Mzg2NTA4ODg2OTg2LA0KICogLy8gICAgICAgLTAuMzcwMzU0NDU2NzAzMTgwNzMsICAgLTIzLjQyODM4NTA1NzgwMzY5NSwgICAwLjgzNDY5MDkwNzU5ODQ5NTIsDQogKiAvLyAgICAgICAgICAzLjY4MzgwMDQxNTQ4NTc3OCwgIC0wLjA3MDk0NTI4NjU5OTY4MTUyLCAgIDE1LjYzMDgzNDc4MjczNTcyMiwNCiAqIC8vICAgICAgICAgIDUuNjE2OTYwMzYyMTcwMjM4LCAgIDAuMzE0MjAxMjc2NzI5ODMyNTYsICAgMi40MDIxNTEwNDY3NzM0Mzk3LA0KICogLy8gICAgICAgICAgMS4wNDUxNTUzNDk5NTY4MTUsICAgMC4xNjMxOTQwNzk3MDg2ODUyNywgICAwLjgzNDY5MDkwNzU5ODQ5MjMsDQogKiAvLyAgICAgICAgIC0xMS4xNTk2NzY0MzU3NDcyOCwgICAwLjQ3OTgwNTA1NzI3NjIzOTA3LCAgIDAuNzUyNTExOTYzOTg2OTQ3MywNCiAqIC8vICAgICAgICAtMC4wMzk5MDIwMjE2MjYxMzg0LCAgICAxLjYyMTY1OTYzNzQ0MDI3MzksICAgMS45NTMxMDc4ODU0NDI5NTMzLA0KICogLy8gICAgICAgICAxLjEwMzk1MjkzMDMyMDQ5NjIsICAgMC4wNzY4MTExNTE1OTAyNDk2MiwgICAwLjE0Nzg0ODUyODUzMDIwMTMsDQogKiAvLyAgICAgICAgIDMuNjgzODAwNDE1NDg1NzkzNSwgICAgICAwLjQ3OTgwNTA1NzI3NjI0LCAgLTExLjU5NDU1NTkzMDc1MzgzNSwNCiAqIC8vICAgICAgICAgMC45MjM3Mjg0MjE0MTQwMjI2LCAgICAxLjg5NDc4NTk3NzIyMjMzMDgsIDAuMDI3ODg4MDAxNjUxOTE3Mzc3LA0KICogLy8gICAgICAgIDAuMTQyMTYzNzc4NTQwNTM0NzIsICAgIDAuOTM0MzI0MTE5OTYyNjczMiwgICAwLjU1MDA1MjA5ODEyNTM0NzYsDQogKiAvLyAgICAgICAgIDE0LjU5MjY2MTE1MzY0NjM0NywgICAtMC4wNzA5NDUyODY1OTk2NzM1LCAgIDAuNzUyNTExOTYzOTg2OTQ4NiwNCiAqIC8vICAgICAgICAgMC45MjM3Mjg0MjE0MTQwMTExLCAgIC0xOC4yNTEyMzAyNDU2NTMzMTgsICAgIDAuODM3OTU5NjkzMzkxODA5LA0KICogLy8gICAgICAgLTAuMjE0MTU4NTM0MTY2NTQ2OTMsIC0wLjAyNjUwMzEwNDY3MjUxNzg3NCwgICAwLjE3NTkzOTEwNjc3MTk5ODksDQogKiAvLyAgICAgICAgICAyLjE3NjkyODIwNzcxMDA1MywgICAgIDMuNTI5NjQwNzU5NjYwOTUyLCAgIDE1LjYzMDgzNDc4MjczNTcwNCwNCiAqIC8vICAgICAgIC0wLjAzOTkwMjAyMTYyNjEzNzQ0LCAgICAgMS44OTQ3ODU5NzcyMjIzNDMsICAgMC44Mzc5NTk2OTMzOTE4MTQ4LA0KICogLy8gICAgICAgICAtMjMuODkyMDQwMTcxNDUyODENCiAqIC8vICAgICBdLA0KICogLy8gICAgIE06IFsNCiAqIC8vICAgICAgIDE1LjEwNzc3NTUyODE3MzgwMiwNCiAqIC8vICAgICAgIC0xNy41MjM1NTMxNjQwMjQzNywNCiAqIC8vICAgICAgIDQuOTc0Mjc5NzY3NjY4ODI5LA0KICogLy8gICAgICAgLTYuMDE0MzcwODM4NjI4MzU5LA0KICogLy8gICAgICAgNy4xNzUwOTUyOTQ3ODk0MDIsDQogKiAvLyAgICAgICAtMy43NTcyNjU3MzM5ODA3MTgzLA0KICogLy8gICAgICAgNC4yMTA5MjA1MjExNTc3ODgsDQogKiAvLyAgICAgICAtNi4wNjQzMjMxNDM4NjMwMTMsDQogKiAvLyAgICAgICAtMi4yMjgwNzI0NDUyOTUyNDg3LA0KICogLy8gICAgICAgNS4wMzU3ODUzODU1NDkxMTcNCiAqIC8vICAgICBdDQogKiAvLyAgIH0NCiAqIC8vIH0NCiAqDQogKi8KZnVuY3Rpb24gaW50ZXJwMktyaWdpbmcocHNTcmMsIHBzVGFyLCBvcHQgPSB7fSkgewogIC8vY2hlY2sgcHNTcmMKICBpZiAoIWlzZWFycihwc1NyYykpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzU3JjIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXknCiAgICB9OwogIH0KCiAgLy9jaGVjayBwc1RhcgogIGlmICghaXNlb2JqKHBzVGFyKSAmJiAhaXNlYXJyKHBzVGFyKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNUYXIgaXMgbm90IGFuIGVmZmVjdGl2ZSBvYmplY3Qgb3IgYXJyYXknCiAgICB9OwogIH0KCiAgLy9pc09uZQogIGxldCBpc09uZSA9IGlzZW9iaihwc1Rhcik7CiAgaWYgKGlzT25lKSB7CiAgICBwc1RhciA9IFtwc1Rhcl07CiAgfQoKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleVoKICBsZXQga2V5WiA9IGdldChvcHQsICdrZXlaJyk7CiAgaWYgKCFpc2VzdHIoa2V5WikpIHsKICAgIGtleVogPSAneic7CiAgfQoKICAvL3NjYWxlCiAgbGV0IHNjYWxlID0gZ2V0KG9wdCwgJ3NjYWxlJyk7CiAgaWYgKCFpc251bShzY2FsZSkpIHsKICAgIHNjYWxlID0gMTsKICB9CiAgc2NhbGUgPSBjZGJsKHNjYWxlKTsKCiAgLy9tZXRob2QKICBsZXQgbWV0aG9kID0gZ2V0KG9wdCwgJ21ldGhvZCcpOwogIGlmIChtZXRob2QgIT09ICdmcmllZHJpY2gnICYmIG1ldGhvZCAhPT0gJ2ludmFsbCcpIHsKICAgIG1ldGhvZCA9ICdmcmllZHJpY2gnOwogIH0KCiAgLy9rcmlnaW5nTW9kZWwKICBsZXQga3JpZ2luZ01vZGVsID0gZ2V0KG9wdCwgJ21vZGVsJyk7CiAgaWYgKGtyaWdpbmdNb2RlbCAhPT0gJ2V4cG9uZW50aWFsJyAmJiBrcmlnaW5nTW9kZWwgIT09ICdnYXVzc2lhbicgJiYga3JpZ2luZ01vZGVsICE9PSAnc3BoZXJpY2FsJykgewogICAga3JpZ2luZ01vZGVsID0gJ2V4cG9uZW50aWFsJzsKICB9CgogIC8va3JpZ2luZ1NpZ21hMgogIGxldCBrcmlnaW5nU2lnbWEyID0gZ2V0KG9wdCwgJ3NpZ21hMicpOwogIGlmICghaXNudW0oa3JpZ2luZ1NpZ21hMikpIHsKICAgIGtyaWdpbmdTaWdtYTIgPSAwOwogIH0KICBrcmlnaW5nU2lnbWEyID0gY2RibChrcmlnaW5nU2lnbWEyKTsKCiAgLy9rcmlnaW5nQWxwaGEKICBsZXQga3JpZ2luZ0FscGhhID0gZ2V0KG9wdCwgJ2FscGhhJyk7CiAgaWYgKCFpc251bShrcmlnaW5nQWxwaGEpKSB7CiAgICBrcmlnaW5nQWxwaGEgPSAxMDA7CiAgfQogIGtyaWdpbmdBbHBoYSA9IGNkYmwoa3JpZ2luZ0FscGhhKTsKCiAgLy9scywgZnJpZWRyaWNo5qC45Ye95pW4bGVuZ3Roc2NhbGUKICBsZXQgbHMgPSBnZXQob3B0LCAnbHMnKTsKICBpZiAoIWlzbnVtKGxzKSkgewogICAgbHMgPSAwLjU7CiAgfQogIGxzID0gY2RibChscyk7CgogIC8vbm9pc2UsIGZyaWVkcmljaOingOa4rOWZqumfs+aomea6luW3rgogIGxldCBub2lzZSA9IGdldChvcHQsICdub2lzZScpOwogIGlmICghaXNudW0obm9pc2UpKSB7CiAgICBub2lzZSA9IDAuMDE7CiAgfQogIG5vaXNlID0gY2RibChub2lzZSk7CgogIC8vcmV0dXJuV2l0aFZhcmlvZ3JhbQogIGxldCByZXR1cm5XaXRoVmFyaW9ncmFtID0gZ2V0KG9wdCwgJ3JldHVybldpdGhWYXJpb2dyYW0nKTsKICBpZiAoIWlzYm9sKHJldHVybldpdGhWYXJpb2dyYW0pKSB7CiAgICByZXR1cm5XaXRoVmFyaW9ncmFtID0gZmFsc2U7CiAgfQogIC8vIGNvbnNvbGUubG9nKCdyZXR1cm5XaXRoVmFyaW9ncmFtJywgcmV0dXJuV2l0aFZhcmlvZ3JhbSkKCiAgLy9wdHNYWVp0b0FycgogIHBzU3JjID0gcHRzWFladG9BcnIocHNTcmMsIG9wdCk7CgogIC8vY2hlY2sgcHNTcmMKICBpZiAoc2l6ZShwc1NyYykgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzU3JjIGhhcyBubyBlZmZlY3RpdmUgZGF0YScKICAgIH07CiAgfQogIC8vIGNvbnNvbGUubG9nKCdwdHNYWVp0b0FyciBwc1NyYycsIHBzU3JjKQoKICAvL3B0c1hZdG9BcnIKICBwc1RhciA9IHB0c1hZdG9BcnIocHNUYXIsIG9wdCk7CgogIC8vY2hlY2sgcHNUYXIKICBpZiAoc2l6ZShwc1RhcikgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzVGFyIGhhcyBubyBlZmZlY3RpdmUgZGF0YScKICAgIH07CiAgfQogIC8vIGNvbnNvbGUubG9nKCdwdHNYWXRvQXJyIHBzVGFyJywgcHNUYXIpCgogIC8vaW50ZXJwMk5vcm1hbGl6ZQogIGxldCBpdG5tID0gaW50ZXJwMk5vcm1hbGl6ZShwc1NyYywgewogICAgc2NhbGUKICB9KTsKICBwc1NyYyA9IGl0bm0ucHM7IC8v6KSH5a+r5q2j6KaP5YyW5pW45pOaCiAgbGV0IG52ID0gaXRubS5udjsKICBsZXQgaW52ID0gaXRubS5pbnY7CgogIC8va3BLbm93bgogIGxldCBrcEtub3duID0ge307CiAgZm9yRWFjaChwc1NyYywgdiA9PiB7CiAgICBsZXQgayA9IGAke3YueH0tJHt2Lnl9YDsgLy/lt7LntpPooqvmraPopo/ljJboh7N4LHkKICAgIGtwS25vd25ba10gPSB2Lno7IC8v5bey57aT6KKr5q2j6KaP5YyW6IezeCx5LHoKICB9KTsKCiAgLy92YXJpb2dyYW0sIHByZWRpY3Q6IOS+nW1ldGhvZOWIh+aPm+W+jOerr+W8leaTjgogIGxldCB2YXJpb2dyYW0gPSBudWxsOyAvL2ZyaWVkcmljaOeEoeWNiuiuiueVsOWcluamguW/tSwg5Zue5YKz5pmC57at5oyBbnVsbAogIGxldCBwcmVkaWN0OyAvLyhueCwgbnkpID0+IG56CiAgaWYgKG1ldGhvZCA9PT0gJ2ZyaWVkcmljaCcpIHsKICAgIC8vaW5wdXRzLCBvdXRwdXRzICjlt7LmraPopo/ljJYpCiAgICBsZXQgaW5wdXRzID0gW107CiAgICBsZXQgb3V0cHV0cyA9IFtdOwogICAgZm9yRWFjaChwc1NyYywgdiA9PiB7CiAgICAgIGlucHV0cy5wdXNoKFt2LngsIHYueV0pOwogICAgICBvdXRwdXRzLnB1c2godi56KTsKICAgIH0pOwoKICAgIC8va2VybmVsLCBtb2RlbOWwjeaHieaguOWHveaVuDogZ2F1c3NpYW4tPlNxdWFyZWRFeHAsIOWFtumkmCjlkKtzcGhlcmljYWwpLT5FeHBvbmVudGlhbAogICAgbGV0IGtlcm5lbDsKICAgIGlmIChrcmlnaW5nTW9kZWwgPT09ICdnYXVzc2lhbicpIHsKICAgICAga2VybmVsID0gbmV3IFNxdWFyZWRFeHAobHMsIDEpOwogICAgfSBlbHNlIHsKICAgICAga2VybmVsID0gbmV3IEV4cG9uZW50aWFsKGxzLCAxKTsKICAgIH0KCiAgICAvL2dwLCDlm7rlrpprZXJuZWzkuI3lgZpBREFN5YSq5YyWKOizh+aWmeW3suato+imj+WMliwg5Zu65a6abGVuZ3Roc2NhbGXljbPlkIjnkIYpCiAgICBsZXQgZ3AgPSBHYXVzc2lhblByb2Nlc3MuYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpLnNldEtlcm5lbChrZXJuZWwpLnNldE5vaXNlKG5vaXNlKS50cmFpbigpOwoKICAgIC8vcHJlZGljdAogICAgcHJlZGljdCA9IChueCwgbnkpID0+IGdwLnByZWRpY3QoW254LCBueV0pOwogIH0gZWxzZSB7CiAgICAvL3gsIHksIHQKICAgIGxldCB4ID0gW107CiAgICBsZXQgeSA9IFtdOwogICAgbGV0IHQgPSBbXTsKICAgIGZvckVhY2gocHNTcmMsIHYgPT4gewogICAgICB4LnB1c2godi54KTsKICAgICAgeS5wdXNoKHYueSk7CiAgICAgIHQucHVzaCh2LnopOwogICAgfSk7CgogICAgLy92YXJpb2dyYW0KICAgIHZhcmlvZ3JhbSA9IGtyaWdpbmcudHJhaW4odCwgeCwgeSwga3JpZ2luZ01vZGVsLCBrcmlnaW5nU2lnbWEyLCBrcmlnaW5nQWxwaGEpOwogICAgLy8gY29uc29sZS5sb2coJ3ZhcmlvZ3JhbScsIHZhcmlvZ3JhbSkKCiAgICAvL3ByZWRpY3QKICAgIHByZWRpY3QgPSAobngsIG55KSA9PiBrcmlnaW5nLnByZWRpY3QobngsIG55LCB2YXJpb2dyYW0pOwogIH0KCiAgLy9rcGR0CiAgbGV0IGtwZHQgPSAobngsIG55KSA9PiB7CiAgICAvL2NoZWNrCiAgICBsZXQgayA9IGAke254fS0ke255fWA7IC8v5bey57aT6KKr5q2j6KaP5YyW6IezeCx5CiAgICBpZiAoaGFza2V5KGtwS25vd24sIGspKSB7CiAgICAgIHJldHVybiBrcEtub3duW2tdOwogICAgfQoKICAgIC8vcHJlZGljdAogICAgbGV0IG56ID0gcHJlZGljdChueCwgbnkpOwoKICAgIC8vc2F2ZQogICAga3BLbm93bltrXSA9IG56OwogICAgcmV0dXJuIG56OwogIH07CgogIC8vaXR2CiAgbGV0IGl0diA9IHAgPT4gewogICAgLy94LCBueAogICAgbGV0IHggPSBwLng7CiAgICBsZXQgbnggPSBudih4LCAneCcpOwogICAgaWYgKCFpc051bWJlcihueCkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG54WyR7bnh9XWApOyAvL3gseemgkOacn+mDveaYr+acieWAvAogICAgfQoKICAgIC8veSwgbnkKICAgIGxldCB5ID0gcC55OwogICAgbGV0IG55ID0gbnYoeSwgJ3knKTsKICAgIGlmICghaXNOdW1iZXIobnkpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBueVske255fV1gKTsgLy94LHnpoJDmnJ/pg73mmK/mnInlgLwKICAgIH0KCiAgICAvL256LCB6CiAgICBsZXQgbnogPSBrcGR0KG54LCBueSk7CiAgICBsZXQgeiA9IGludihueiwgJ3onKTsKICAgIGlmICghaXNOdW1iZXIoeikpIHsKICAgICAgeiA9IG51bGw7IC8veumgiOaUr+aPtOWPr+iDveeEoeazleWFp+aPkgogICAgfQoKICAgIC8vIGNvbnNvbGUubG9nKCd4JywgeCwgJ3knLCB5LCAneicsIHopCiAgICAvLyBjb25zb2xlLmxvZygnbngnLCBueCwgJ255JywgbnksICdueicsIG56KQoKICAgIC8vcgogICAgbGV0IHIgPSB7CiAgICAgIFtrZXlYXTogeCwKICAgICAgW2tleVldOiB5LAogICAgICBba2V5Wl06IHoKICAgIH07CiAgICByZXR1cm4gcjsKICB9OwoKICAvL3IKICBsZXQgcjsKICBpZiAoaXNPbmUpIHsKICAgIGxldCBwID0gcHNUYXJbMF07CiAgICByID0gaXR2KHApOwogIH0gZWxzZSB7CiAgICByID0gW107CiAgICBmb3JFYWNoKHBzVGFyLCBwID0+IHsKICAgICAgci5wdXNoKGl0dihwKSk7CiAgICB9KTsKICB9CgogIC8vcmV0dXJuV2l0aFZhcmlvZ3JhbQogIGlmIChyZXR1cm5XaXRoVmFyaW9ncmFtKSB7CiAgICByID0gewogICAgICByZXN1bHQ6IHIsCiAgICAgIHZhcmlvZ3JhbQogICAgfTsKICB9CiAgcmV0dXJuIHI7Cn0KCi8qKg0KICog6Yed5bCN5LiN6KaP5YmH5LqM57at5pW45pOa6YCy6KGM5oyH5a6a5YWn5o+S6bue5pW45YC8DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvaW50ZXJwMi50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzU3JjIOi8uOWFpem7numZo+WIl++8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiXDQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gcHNUYXIg6Ly45YWl6bue6Zmj5YiX5oiW6bue54mp5Lu277yM54K6W3t4OngxLHk6eTF9LHt4OngyLHk6eTJ9LC4uLl3pu57nianku7bkuYvpmaPliJfvvIzmiJZ7eDp4MSx5Onkxfem7nueJqeS7tg0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlYPSd4J10g6Ly45YWl6bue54mp5Lu25LmLeOW6p+aomeashOS9jeWtl+S4su+8jOmgkOiorSd4Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neSddIOi8uOWFpem7nueJqeS7tuS5i3nluqfmqJnmrITkvY3lrZfkuLLvvIzpoJDoqK0neScNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVo9J3onXSDovLjlhaXpu57nianku7bkuYt65bqn5qiZ5oiW5YC85qyE5L2N5a2X5Liy77yM6aCQ6KitJ3onDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zY2FsZT0xXSDovLjlhaXmraPopo/ljJbnr4TlnI3mlbjlgLzvvIzlm6DomZXnkIblpJrpgorlvaLmmYLmnInmlbjlgLzlrrnoqLHoqqTlt67vvIzmlYXpoIjpgJrpgY7nuK7mlL7lgLzln5/kvobmuJvlsJHllY/poYzvvIzpoJDoqK0x5piv5q2j6KaP5YyWMOiHszHkuYvplpPvvIzkvb/nlKhzY2FsZVhZ5YmH5piv5q2j6KaP5YyW54K6MOiHs3NjYWxlWFnkuYvplpPvvIzpoJDoqK0xDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5tZXRob2Q9J25hdHVyYWxOZWlnaGJvciddIOi8uOWFpeWFp+aPkuaWueazleWtl+S4su+8jOWPr+mBuCduYXR1cmFsTmVpZ2hib3In44CBJ2tyaWdpbmcn77yM6aCQ6KitJ25hdHVyYWxOZWlnaGJvcifvvJttZXRob2Q9J2tyaWdpbmcn5pmC5ZG85Y+raW50ZXJwMktyaWdpbmfkuKblm7rlrprkvb/nlKjlhbZmcmllZHJpY2jlvJXmk44o57aTaW50ZXJwMueEoeazlemBuOeUqGludmFsbOW8leaTjikNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0Lm1vZGVsPSdleHBvbmVudGlhbCddIOi8uOWFpeiLpW1ldGhvZD0na3JpZ2luZyfmmYLkuYvmoLjlh73mlbjlsI3mh4nmqKHlvI/lrZfkuLLvvIwnZ2F1c3NpYW4n5bCN5oeJU3F1YXJlZEV4cOOAgeWFtumkmCjlkKsnZXhwb25lbnRpYWwn44CBJ3NwaGVyaWNhbCcp5bCN5oeJRXhwb25lbnRpYWzvvIzpoJDoqK0nZXhwb25lbnRpYWwnDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5scz0wLjVdIOi8uOWFpeiLpW1ldGhvZD0na3JpZ2luZyfmmYLkuYtmcmllZHJpY2jmoLjlh73mlbhsZW5ndGhzY2FsZeaVuOWAvCjlsI3mh4nmraPopo/ljJblvozlgLzln58p77yM6aCQ6KitMC41DQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5ub2lzZT0wLjAxXSDovLjlhaXoi6VtZXRob2Q9J2tyaWdpbmcn5pmC5LmLZnJpZWRyaWNo6KeA5ris5Zmq6Z+z5qiZ5rqW5beuKOWwjeaHieato+imj+WMluW+jOWAvOWfnynvvIzpoJDoqK0wLjAxDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zaWdtYTI9MF0gKOWDheiIimludmFsbOW8leaTjuS5i+WNiuiuiueVsOWcluaTrOWQiOWPg+aVuO+8jOWboGludGVycDLkuYtrcmlnaW5n5Zu65a6a6LWwZnJpZWRyaWNo5pWF5LiN55Sf5pWIKSDovLjlhaXoh6rli5Xmk6zlkIjlj4PmlbhzaWdtYTLmlbjlgLzvvIzpoJDoqK0wDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5hbHBoYT0xMDBdICjlg4XoiIppbnZhbGzlvJXmk47kuYvljYrorornlbDlnJbmk6zlkIjlj4PmlbjvvIzlm6BpbnRlcnAy5LmLa3JpZ2luZ+WbuuWumui1sGZyaWVkcmljaOaVheS4jeeUn+aViCkg6Ly45YWl6Ieq5YuV5pOs5ZCI5Y+D5pW4YWxwaGHmlbjlgLzvvIzpoJDoqK0xMDANCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC5yZXR1cm5XaXRoVmFyaW9ncmFtPWZhbHNlXSAo5YOF6IiKaW52YWxs5byV5pOO5Y+D5pW477yM5ZugaW50ZXJwMuS5i2tyaWdpbmflm7rlrprotbBmcmllZHJpY2jmlYXkuI3nlJ/mlYjvvIxmcmllZHJpY2jnhKHljYrorornlbDlnJYpIOi8uOWFpeaYr+WQpuWbnuWCs+aTrOWQiOWNiuiuiueVsOaVuOe1kOaenOW4g+ael+WAvO+8jOmgkOiorWZhbHNlDQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQudXNlU3luYz1mYWxzZV0g6Ly45YWl5piv5ZCm5L2/55So5ZCM5q2l5Ye95pW45biD5p6X5YC877yM6aCQ6KitZmFsc2UNCiAqIEByZXR1cm5zIHtQcm9taXNlfEFycmF5fE9iamVjdH0g5Zue5YKzUHJvbWlzZeaIlum7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpXVzZVN5bmM9ZmFsc2XliYflm57lgrNQcm9taXNl77yMcmVzb2x2ZeeCuuWbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jHJlamVjdOeCuuWkseaVl+ioiuaBr++8jOiLpXVzZVN5bmM9dHJ1ZeWJh+WbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpeeZvOeUn+mMr+iqpOWJh+WbnuWCs+mMr+iqpOioiuaBr+eJqeS7tg0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCBwDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjgzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjgzLCB5OiAyMDcsIHo6IDExNC40MzA0MDQyMTk1MTkwOCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTE2MCwNCiAqICAgICB5OiAzODAsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDExNjAsIHk6IDM4MCwgejogbnVsbCB9DQogKg0KICogcHMgPSBbeyBhOiAyNDMsIGI6IDIwNiwgYzogOTUgfSwgeyBhOiAyMzMsIGI6IDIyNSwgYzogMTQ2IH0sIHsgYTogMjEsIGI6IDMyNSwgYzogMjIgfSwgeyBhOiA5NTMsIGI6IDI4LCBjOiAyMjMgfSwgeyBhOiAxMDkyLCBiOiAyOTAsIGM6IDM5IH0sIHsgYTogNzQ0LCBiOiAyMDAsIGM6IDE5MSB9LCB7IGE6IDE3NCwgYjogMywgYzogMjIgfSwgeyBhOiA1MzcsIGI6IDM2OCwgYzogMjQ5IH0sIHsgYTogMTE1MSwgYjogMzcxLCBjOiA4NiB9LCB7IGE6IDgxNCwgYjogMjUyLCBjOiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgYTogMjQzLA0KICogICAgIGI6IDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwLCB7IGtleVg6ICdhJywga2V5WTogJ2InLCBrZXlaOiAnYycgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IGE6IDI0MywgYjogMjA3LCBjOiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSBbDQogKiAgICAgew0KICogICAgICAgICB4OiAyNDMsDQogKiAgICAgICAgIHk6IDIwNywNCiAqICAgICB9LA0KICogICAgIHsNCiAqICAgICAgICAgeDogMjgzLA0KICogICAgICAgICB5OiAyMDcsDQogKiAgICAgfSwNCiAqIF0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfSwNCiAqIC8vICAgeyB4OiAyODMsIHk6IDIwNywgejogMTE0LjQzMDQwNDIxOTUxOTA4IH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHAsIHsgbWV0aG9kOiAna3JpZ2luZycgfSkgLy9tZXRob2Q9J2tyaWdpbmcn6LWwaW50ZXJwMktyaWdpbmcsIOm7mOiqjWZyaWVkcmljaOW8leaTjg0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjQ5ODQ2MjM1MTA4MTIzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDAuMDAwMjQzLCB5OiAwLjAwMDIwNiwgejogOTUgfSwgeyB4OiAwLjAwMDIzMywgeTogMC4wMDAyMjUsIHo6IDE0NiB9LCB7IHg6IDAuMDAwMDIxLCB5OiAwLjAwMDMyNSwgejogMjIgfSwgeyB4OiAwLjAwMDk1MywgeTogMC4wMDAwMjgsIHo6IDIyMyB9LCB7IHg6IDAuMDAxMDkyLCB5OiAwLjAwMDI5LCB6OiAzOSB9LCB7IHg6IDAuMDAwNzQ0LCB5OiAwLjAwMDIwMCwgejogMTkxIH0sIHsgeDogMC4wMDAxNzQsIHk6IDAuMDAwMDAzLCB6OiAyMiB9LCB7IHg6IDAuMDAwNTM3LCB5OiAwLjAwMDM2OCwgejogMjQ5IH0sIHsgeDogMC4wMDExNTEsIHk6IDAuMDAwMzcxLCB6OiA4NiB9LCB7IHg6IDAuMDAwODE0LCB5OiAwLjAwMDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDAuMDAwMjQzLA0KICogICAgIHk6IDAuMDAwMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAwLjAwMDI0MywgeTogMC4wMDAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2NzggfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCwgeyBzY2FsZTogMTAwMCB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODU1IH0NCiAqDQogKiAvL2ZvciBpbnRlcnAyLndrLnVtZC5qcw0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyKHBzLCBwLCB7IHVzZVN5bmM6IHRydWUgfSkgLy/kvb/nlKhpbnRlcnAyLndrLnVtZC5qc+WJh+S4jeaUr+aPtHN5bmPmqKHlvI8NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICovCmZ1bmN0aW9uIGludGVycDIocHNTcmMsIHBzVGFyLCBvcHQgPSB7fSkgewogIC8vbWV0aG9kCiAgbGV0IG1ldGhvZCA9IGdldChvcHQsICdtZXRob2QnKTsKICBpZiAobWV0aG9kICE9PSAnbmF0dXJhbE5laWdoYm9yJyAmJiBtZXRob2QgIT09ICdrcmlnaW5nJykgewogICAgbWV0aG9kID0gJ25hdHVyYWxOZWlnaGJvcic7CiAgfQoKICAvL3VzZVN5bmMKICBsZXQgdXNlU3luYyA9IGdldChvcHQsICd1c2VTeW5jJyk7CiAgaWYgKCFpc2JvbCh1c2VTeW5jKSkgewogICAgdXNlU3luYyA9IGZhbHNlOwogIH0KCiAgLy9fc3luYwogIGxldCBfc3luYyA9ICgpID0+IHsKICAgIGxldCByID0gbnVsbDsKICAgIHRyeSB7CiAgICAgIGlmIChtZXRob2QgPT09ICduYXR1cmFsTmVpZ2hib3InKSB7CiAgICAgICAgciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHNTcmMsIHBzVGFyLCBvcHQpOwogICAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PT0gJ2tyaWdpbmcnKSB7CiAgICAgICAgciA9IGludGVycDJLcmlnaW5nKHBzU3JjLCBwc1Rhciwgb3B0KTsKICAgICAgfQogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIHIgPSB7CiAgICAgICAgZXJyOiBlcnIudG9TdHJpbmcoKQogICAgICB9OwogICAgfQogICAgcmV0dXJuIHI7CiAgfTsKCiAgLy9fYXN5bmMKICBsZXQgX2FzeW5jID0gYXN5bmMgKCkgPT4gewogICAgbGV0IHIgPSBudWxsOwogICAgdHJ5IHsKICAgICAgciA9IF9zeW5jKCk7CiAgICAgIGxldCBlcnIgPSBnZXQociwgJ2VycicpOwogICAgICBpZiAoaXNlc3RyKGVycikpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gcjsKICAgICAgfQogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIGNvbnNvbGUubG9nKGVycik7CiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIudG9TdHJpbmcoKSk7CiAgICB9CiAgfTsKICBpZiAodXNlU3luYykgewogICAgcmV0dXJuIF9zeW5jKCk7CiAgfSBlbHNlIHsKICAgIHJldHVybiBfYXN5bmMoKTsKICB9Cn0KCgoKbGV0IGluc3RhbmNlID0gbnVsbApmdW5jdGlvbiBpbml0KGlucHV0KXsKCiAgICAvL2luaXQKICAgIGxldCByCiAgICAKICAgICAgICByID0gewogICAgICAgICAgICBtYWluOiBpbnRlcnAyCiAgICAgICAgfQogICAgICAgIAoKICAgIC8vb24KICAgIAoKICAgIC8vc2F2ZQogICAgaW5zdGFuY2UgPSByCgp9CgpmdW5jdGlvbiBzZW5kTWVzc2FnZShkYXRhKSB7CiAgICAKICAgICAgICBwYXJlbnRQb3J0LnBvc3RNZXNzYWdlKGRhdGEpCiAgICAgICAgCn0KCmFzeW5jIGZ1bmN0aW9uIHJ1bihkYXRhKSB7CiAgICAvLyBjb25zb2xlLmxvZygnaW5uZXIgd29ya2VyIHJ1bicsZGF0YSkKCiAgICAvL21vZGUKICAgIGxldCBtb2RlID0gZGF0YS5tb2RlCgogICAgLy9jaGVjawogICAgaWYobW9kZSAhPT0gJ2luaXQnICYmIG1vZGUgIT09ICdjYWxsJyl7CiAgICAgICAgcmV0dXJuCiAgICB9CgogICAgLy9pbml0CiAgICBpZihtb2RlID09PSAnaW5pdCcpewogICAgICAgIAogICAgICAgIHRyeXsKCiAgICAgICAgICAgIC8vdHlwZQogICAgICAgICAgICBsZXQgdHlwZSA9IGRhdGEudHlwZQoKICAgICAgICAgICAgLy9pbnB1dAogICAgICAgICAgICBsZXQgaW5wdXQgPSBkYXRhLmlucHV0CiAgICAKICAgICAgICAgICAgLy9pbnN0YW5jZQogICAgICAgICAgICBpZih0eXBlID09PSAnZnVuY3Rpb24nKXsKICAgICAgICAgICAgICAgIGluaXQoLi4uaW5wdXQpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZih0eXBlID09PSAnb2JqZWN0Jyl7CiAgICAgICAgICAgICAgICBpbnN0YW5jZSA9IGludGVycDIKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgY2F0Y2goZXJyKXsKICAgICAgICAKICAgICAgICAgICAgLy9zZW5kTWVzc2FnZQogICAgICAgICAgICBsZXQgcmVzID0gewogICAgICAgICAgICAgICAgbW9kZTogJ2VtaXQnLAogICAgICAgICAgICAgICAgZXZOYW1lOiAnZXJyb3InLAogICAgICAgICAgICAgICAgbXNnOiBlcnIsCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VuZE1lc3NhZ2UocmVzKQoKICAgICAgICB9CiAgICAgICAgICAgIAogICAgfQoKICAgIC8vY2hlY2sKICAgIGlmKG1vZGUgPT09ICdjYWxsJyl7CiAgICAgICAgbGV0IHN0YXRlID0gJycKICAgICAgICBsZXQgbXNnID0gbnVsbAoKICAgICAgICB0cnl7CgogICAgICAgICAgICAvL2Z1bgogICAgICAgICAgICBsZXQgZnVuID0gaW5zdGFuY2VbZGF0YS5mdW5dCgogICAgICAgICAgICAvL2lucHV0CiAgICAgICAgICAgIGxldCBpbnB1dCA9IGRhdGEuaW5wdXQKCiAgICAgICAgICAgIC8vZXhlYwogICAgICAgICAgICBhd2FpdCBmdW4oLi4uaW5wdXQpCiAgICAgICAgICAgICAgICAudGhlbigoc3VjKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU9J3N1Y2Nlc3MnCiAgICAgICAgICAgICAgICAgICAgbXNnPXN1YwogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU9J2Vycm9yJwogICAgICAgICAgICAgICAgICAgIG1zZz1lcnIKICAgICAgICAgICAgICAgIH0pCgogICAgICAgIH0KICAgICAgICBjYXRjaChlcnIpewogICAgICAgICAgICBzdGF0ZSA9ICdlcnJvcicKICAgICAgICAgICAgbXNnID0gZXJyCiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vc2VuZE1lc3NhZ2UKICAgICAgICBsZXQgcmVzID0gewogICAgICAgICAgICBtb2RlOiAncmV0dXJuJywKICAgICAgICAgICAgaWQ6IGRhdGEuaWQsCiAgICAgICAgICAgIGZ1bjogZGF0YS5mdW4sCiAgICAgICAgICAgIHN0YXRlLAogICAgICAgICAgICBtc2csCiAgICAgICAgfQogICAgICAgIHNlbmRNZXNzYWdlKHJlcykKCiAgICB9Cgp9CgpmdW5jdGlvbiByZWN2TWVzc2FnZShkYXRhKSB7CiAgICAvLyBjb25zb2xlLmxvZygnaW5uZXIgd29ya2VyIHJlY3Y6JywgZGF0YSkKCiAgICAvL2RhdGFSZWN2CiAgICBsZXQgZGF0YVJlY3YgPSBkYXRhCgogICAgLy9ydW4KICAgIHJ1bihkYXRhUmVjdikKCn0KCgogICAgICAgIHBhcmVudFBvcnQub24oJ21lc3NhZ2UnLCByZWN2TWVzc2FnZSkKICAgICAgICAKCnRyeXsKCiAgICAvL+WDheS7pXVuY2F1Z2h0RXhjZXB0aW9uTW9uaXRvcuiomOmMhCwg5LiN5Y+v6Ki75YaKdW5jYXVnaHRFeGNlcHRpb27oiId1bmhhbmRsZWRSZWplY3Rpb27nm6Pogb06CiAgICAvL+aWvHdvcmtlcuWFp+iou+WGiuatpOS6jOebo+iBveacg+mYu+atok5vZGXpoJDoqK3nmoR3b3JrZXLntYLmraLooYzngrosIOS9v3dvcmtlcuW0qea9sOW+jOS7jeWtmOa0u+epuui9iSwKICAgIC8v5aSW5bGk5pS25LiN5YiwZXJyb3IvZXhpdOS6i+S7tiwgcGVuZGluZyBwcm9taXNl5rC45LmF5oe4572uLCDkuJTlrZjmtLvmrq3lsY13b3JrZXLmnIPku6Tlrr/kuLvnqIvluo/nhKHms5XpgIDlh7o7CiAgICAvL+enu+mZpOW+jHdvcmtlcuS+nemgkOioreihjOeCuuatu+S6oSwgZXJyb3Lkuovku7blgrPoh7PlpJblsaQsIOeUseWkluWxpOaVtOaJuXJlamVjdCBwZW5kaW5nCiAgICAvLyBwcm9jZXNzLm9uKCd1bmhhbmRsZWRSZWplY3Rpb24nLCAoZXJyKSA9PiB7CiAgICAvLyAgICAgY29uc29sZS5sb2coJ2lubmVyOnVuaGFuZGxlZFJlamVjdGlvbicsIGVycikKICAgIC8vIH0pCiAgICAvLyBwcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIChlcnIpID0+IHsKICAgIC8vICAgICBjb25zb2xlLmxvZygnaW5uZXI6dW5jYXVnaHRFeGNlcHRpb24nLCBlcnIpCiAgICAvLyB9KQogICAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb25Nb25pdG9yJywgKGVycikgPT4gewogICAgICAgIGNvbnNvbGUubG9nKCdpbm5lcjp1bmNhdWdodEV4Y2VwdGlvbk1vbml0b3InLCBlcnIpCiAgICB9KQoKfQpjYXRjaChlcnIpe30KCg==`;//code
|
|
140
140
|
let code=b642str(codeB64);function wrapWorker(){//evem
|
|
141
141
|
let ev=evem();//pendings, 呼叫中promise登記表; bDead, worker已死標記(死後呼叫立即reject); bTerminated, 由terminate()主動中止標記(exit事件不視為異常)
|
|
142
142
|
let pendings={};let bDead=false;let bTerminated=false;function emitError(err){//先整批reject pending: 錯誤發生時呼叫端不得永久懸置(pending promise之settle僅靠worker回傳return訊息, worker崩潰即永無回音)
|
|
@@ -186,12 +186,12 @@
|
|
|
186
186
|
// process.on('uncaughtException', (err) => {
|
|
187
187
|
// console.log('outer:uncaughtException', err)
|
|
188
188
|
// })
|
|
189
|
-
process.on('uncaughtExceptionMonitor',err=>{console.log('outer:uncaughtExceptionMonitor',err);});}catch(err){}var ww$1=ww;return ww$1;});})(
|
|
189
|
+
process.on('uncaughtExceptionMonitor',err=>{console.log('outer:uncaughtExceptionMonitor',err);});}catch(err){}var ww$1=ww;return ww$1;});})(tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlINw);var nw = tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlINwExports;
|
|
190
190
|
|
|
191
|
-
var
|
|
192
|
-
var
|
|
193
|
-
get exports(){ return
|
|
194
|
-
set exports(v){
|
|
191
|
+
var tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlIWwExports = {};
|
|
192
|
+
var tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlIWw = {
|
|
193
|
+
get exports(){ return tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlIWwExports; },
|
|
194
|
+
set exports(v){ tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlIWwExports = v; },
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
(function(module,exports){(function(global,factory){module.exports=factory();})(commonjsGlobal,function(){/**
|
|
@@ -391,7 +391,7 @@
|
|
|
391
391
|
// return window.atob(b64) //瀏覽器端執行使用 atob 或 decodeURIComponent(atob()) 或 unescape(decodeURIComponent(atob('ooxx'))) 無法解Buffer轉出的b64, 因這只能解由瀏覽器對應的函數產生b64
|
|
392
392
|
}//codeShow
|
|
393
393
|
//codeB64, 此處需提供worker執行程式碼, 因有特殊符號轉譯困難, 故需先轉base64再使用
|
|
394
|
-
let codeB64=`CgoKJ3VzZSBzdHJpY3QnOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQXJyYXkoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNBcnJheSgnYWJjJyk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNBcnJheShfLm5vb3ApOwogKiAvLyA9PiBmYWxzZQogKi8KdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5Owp2YXIgaXNBcnJheSQxID0gaXNBcnJheTsKCi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovCnZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwgJiYgZ2xvYmFsLk9iamVjdCA9PT0gT2JqZWN0ICYmIGdsb2JhbDsKdmFyIGZyZWVHbG9iYWwkMSA9IGZyZWVHbG9iYWw7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqLwp2YXIgZnJlZVNlbGYgPSB0eXBlb2Ygc2VsZiA9PSAnb2JqZWN0JyAmJiBzZWxmICYmIHNlbGYuT2JqZWN0ID09PSBPYmplY3QgJiYgc2VsZjsKCi8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqLwp2YXIgcm9vdCA9IGZyZWVHbG9iYWwkMSB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpOwp2YXIgcm9vdCQxID0gcm9vdDsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgU3ltYm9sID0gcm9vdCQxLlN5bWJvbDsKdmFyIFN5bWJvbCQxID0gU3ltYm9sOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kYiA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDggPSBvYmplY3RQcm90byRiLmhhc093blByb3BlcnR5OwoKLyoqCiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUKICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpCiAqIG9mIHZhbHVlcy4KICovCnZhciBuYXRpdmVPYmplY3RUb1N0cmluZyQxID0gb2JqZWN0UHJvdG8kYi50b1N0cmluZzsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3ltVG9TdHJpbmdUYWckMSA9IFN5bWJvbCQxID8gU3ltYm9sJDEudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJhdyBgdG9TdHJpbmdUYWdgLgogKi8KZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7CiAgdmFyIGlzT3duID0gaGFzT3duUHJvcGVydHkkOC5jYWxsKHZhbHVlLCBzeW1Ub1N0cmluZ1RhZyQxKSwKICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnJDFdOwogIHRyeSB7CiAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXSA9IHVuZGVmaW5lZDsKICAgIHZhciB1bm1hc2tlZCA9IHRydWU7CiAgfSBjYXRjaCAoZSkge30KICB2YXIgcmVzdWx0ID0gbmF0aXZlT2JqZWN0VG9TdHJpbmckMS5jYWxsKHZhbHVlKTsKICBpZiAodW5tYXNrZWQpIHsKICAgIGlmIChpc093bikgewogICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXSA9IHRhZzsKICAgIH0gZWxzZSB7CiAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kYSA9IE9iamVjdC5wcm90b3R5cGU7CgovKioKICogVXNlZCB0byByZXNvbHZlIHRoZQogKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZykKICogb2YgdmFsdWVzLgogKi8KdmFyIG5hdGl2ZU9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8kYS50b1N0cmluZzsKCi8qKgogKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy4KICovCmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7CiAgcmV0dXJuIG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBudWxsVGFnID0gJ1tvYmplY3QgTnVsbF0nLAogIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nOwoKLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovCnZhciBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCQxID8gU3ltYm9sJDEudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldFRhZ2Agd2l0aG91dCBmYWxsYmFja3MgZm9yIGJ1Z2d5IGVudmlyb25tZW50cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuCiAqLwpmdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7CiAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkVGFnIDogbnVsbFRhZzsKICB9CiAgcmV0dXJuIHN5bVRvU3RyaW5nVGFnICYmIHN5bVRvU3RyaW5nVGFnIGluIE9iamVjdCh2YWx1ZSkgPyBnZXRSYXdUYWcodmFsdWUpIDogb2JqZWN0VG9TdHJpbmcodmFsdWUpOwp9CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgCiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgIm9iamVjdCIuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzT2JqZWN0TGlrZSh7fSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzT2JqZWN0TGlrZShudWxsKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JzsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgc3ltYm9sVGFnJDEgPSAnW29iamVjdCBTeW1ib2xdJzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3ltYm9sLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNTeW1ib2woU3ltYm9sLml0ZXJhdG9yKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzU3ltYm9sKCdhYmMnKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHN5bWJvbFRhZyQxOwp9CgovKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovCnZhciByZUlzRGVlcFByb3AgPSAvXC58XFsoPzpbXltcXV0qfChbIiddKSg/Oig/IVwxKVteXFxdfFxcLikqP1wxKVxdLywKICByZUlzUGxhaW5Qcm9wID0gL15cdyokLzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUgYW5kIG5vdCBhIHByb3BlcnR5IHBhdGguCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHsKICBpZiAoaXNBcnJheSQxKHZhbHVlKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKICBpZiAodHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nIHx8IHZhbHVlID09IG51bGwgfHwgaXNTeW1ib2wodmFsdWUpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgcmV0dXJuIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkgfHwgIXJlSXNEZWVwUHJvcC50ZXN0KHZhbHVlKSB8fCBvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiBPYmplY3Qob2JqZWN0KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZQogKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpCiAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYCkKICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzT2JqZWN0KHt9KTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdChfLm5vb3ApOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNPYmplY3QobnVsbCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkgewogIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlOwogIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGFzeW5jVGFnID0gJ1tvYmplY3QgQXN5bmNGdW5jdGlvbl0nLAogIGZ1bmNUYWckMSA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsCiAgZ2VuVGFnID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJywKICBwcm94eVRhZyA9ICdbb2JqZWN0IFByb3h5XSc7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzRnVuY3Rpb24oXyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0Z1bmN0aW9uKC9hYmMvKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHsKICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3IKICAvLyBpbiBTYWZhcmkgOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheXMgYW5kIG90aGVyIGNvbnN0cnVjdG9ycy4KICB2YXIgdGFnID0gYmFzZUdldFRhZyh2YWx1ZSk7CiAgcmV0dXJuIHRhZyA9PSBmdW5jVGFnJDEgfHwgdGFnID09IGdlblRhZyB8fCB0YWcgPT0gYXN5bmNUYWcgfHwgdGFnID09IHByb3h5VGFnOwp9CgovKiogVXNlZCB0byBkZXRlY3Qgb3ZlcnJlYWNoaW5nIGNvcmUtanMgc2hpbXMuICovCnZhciBjb3JlSnNEYXRhID0gcm9vdCQxWydfX2NvcmUtanNfc2hhcmVkX18nXTsKdmFyIGNvcmVKc0RhdGEkMSA9IGNvcmVKc0RhdGE7CgovKiogVXNlZCB0byBkZXRlY3QgbWV0aG9kcyBtYXNxdWVyYWRpbmcgYXMgbmF0aXZlLiAqLwp2YXIgbWFza1NyY0tleSA9IGZ1bmN0aW9uICgpIHsKICB2YXIgdWlkID0gL1teLl0rJC8uZXhlYyhjb3JlSnNEYXRhJDEgJiYgY29yZUpzRGF0YSQxLmtleXMgJiYgY29yZUpzRGF0YSQxLmtleXMuSUVfUFJPVE8gfHwgJycpOwogIHJldHVybiB1aWQgPyAnU3ltYm9sKHNyYylfMS4nICsgdWlkIDogJyc7Cn0oKTsKCi8qKgogKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBpdHMgc291cmNlIG1hc2tlZC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc01hc2tlZChmdW5jKSB7CiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiBtYXNrU3JjS2V5IGluIGZ1bmM7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIGZ1bmNQcm90byQxID0gRnVuY3Rpb24ucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqLwp2YXIgZnVuY1RvU3RyaW5nJDEgPSBmdW5jUHJvdG8kMS50b1N0cmluZzsKCi8qKgogKiBDb252ZXJ0cyBgZnVuY2AgdG8gaXRzIHNvdXJjZSBjb2RlLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzb3VyY2UgY29kZS4KICovCmZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHsKICBpZiAoZnVuYyAhPSBudWxsKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gZnVuY1RvU3RyaW5nJDEuY2FsbChmdW5jKTsKICAgIH0gY2F0Y2ggKGUpIHt9CiAgICB0cnkgewogICAgICByZXR1cm4gZnVuYyArICcnOwogICAgfSBjYXRjaCAoZSkge30KICB9CiAgcmV0dXJuICcnOwp9CgovKioKICogVXNlZCB0byBtYXRjaCBgUmVnRXhwYAogKiBbc3ludGF4IGNoYXJhY3RlcnNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXBhdHRlcm5zKS4KICovCnZhciByZVJlZ0V4cENoYXIgPSAvW1xcXiQuKis/KClbXF17fXxdL2c7CgovKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSkuICovCnZhciByZUlzSG9zdEN0b3IgPSAvXlxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXF0kLzsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZSwKICBvYmplY3RQcm90byQ5ID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi8KdmFyIGZ1bmNUb1N0cmluZyA9IGZ1bmNQcm90by50b1N0cmluZzsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkNyA9IG9iamVjdFByb3RvJDkuaGFzT3duUHJvcGVydHk7CgovKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqLwp2YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgKyBmdW5jVG9TdHJpbmcuY2FsbChoYXNPd25Qcm9wZXJ0eSQ3KS5yZXBsYWNlKHJlUmVnRXhwQ2hhciwgJ1xcJCYnKS5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcKCl8IGZvciAuKz8oPz1cXFxdKS9nLCAnJDEuKj8nKSArICckJyk7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNOYXRpdmVgIHdpdGhvdXQgYmFkIHNoaW0gY2hlY2tzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sCiAqICBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNOYXRpdmUodmFsdWUpIHsKICBpZiAoIWlzT2JqZWN0KHZhbHVlKSB8fCBpc01hc2tlZCh2YWx1ZSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIHBhdHRlcm4gPSBpc0Z1bmN0aW9uKHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3I7CiAgcmV0dXJuIHBhdHRlcm4udGVzdCh0b1NvdXJjZSh2YWx1ZSkpOwp9CgovKioKICogR2V0cyB0aGUgdmFsdWUgYXQgYGtleWAgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlLgogKi8KZnVuY3Rpb24gZ2V0VmFsdWUob2JqZWN0LCBrZXkpIHsKICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTsKfQoKLyoqCiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIG1ldGhvZCB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC4KICovCmZ1bmN0aW9uIGdldE5hdGl2ZShvYmplY3QsIGtleSkgewogIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTsKICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkOwp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBuYXRpdmVDcmVhdGUgPSBnZXROYXRpdmUoT2JqZWN0LCAnY3JlYXRlJyk7CnZhciBuYXRpdmVDcmVhdGUkMSA9IG5hdGl2ZUNyZWF0ZTsKCi8qKgogKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBoYXNoLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBjbGVhcgogKiBAbWVtYmVyT2YgSGFzaAogKi8KZnVuY3Rpb24gaGFzaENsZWFyKCkgewogIHRoaXMuX19kYXRhX18gPSBuYXRpdmVDcmVhdGUkMSA/IG5hdGl2ZUNyZWF0ZSQxKG51bGwpIDoge307CiAgdGhpcy5zaXplID0gMDsKfQoKLyoqCiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBoYXNoLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIEhhc2gKICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gbW9kaWZ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzaERlbGV0ZShrZXkpIHsKICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldOwogIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDsKICByZXR1cm4gcmVzdWx0Owp9CgovKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovCnZhciBIQVNIX1VOREVGSU5FRCQyID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kOCA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDYgPSBvYmplY3RQcm90byQ4Lmhhc093blByb3BlcnR5OwoKLyoqCiAqIEdldHMgdGhlIGhhc2ggdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIEhhc2gKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS4KICovCmZ1bmN0aW9uIGhhc2hHZXQoa2V5KSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fOwogIGlmIChuYXRpdmVDcmVhdGUkMSkgewogICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTsKICAgIHJldHVybiByZXN1bHQgPT09IEhBU0hfVU5ERUZJTkVEJDIgPyB1bmRlZmluZWQgOiByZXN1bHQ7CiAgfQogIHJldHVybiBoYXNPd25Qcm9wZXJ0eSQ2LmNhbGwoZGF0YSwga2V5KSA/IGRhdGFba2V5XSA6IHVuZGVmaW5lZDsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNyA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDUgPSBvYmplY3RQcm90byQ3Lmhhc093blByb3BlcnR5OwoKLyoqCiAqIENoZWNrcyBpZiBhIGhhc2ggdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBoYXNoSGFzKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXzsKICByZXR1cm4gbmF0aXZlQ3JlYXRlJDEgPyBkYXRhW2tleV0gIT09IHVuZGVmaW5lZCA6IGhhc093blByb3BlcnR5JDUuY2FsbChkYXRhLCBrZXkpOwp9CgovKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovCnZhciBIQVNIX1VOREVGSU5FRCQxID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nOwoKLyoqCiAqIFNldHMgdGhlIGhhc2ggYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LgogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGhhc2ggaW5zdGFuY2UuCiAqLwpmdW5jdGlvbiBoYXNoU2V0KGtleSwgdmFsdWUpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187CiAgdGhpcy5zaXplICs9IHRoaXMuaGFzKGtleSkgPyAwIDogMTsKICBkYXRhW2tleV0gPSBuYXRpdmVDcmVhdGUkMSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gSEFTSF9VTkRFRklORUQkMSA6IHZhbHVlOwogIHJldHVybiB0aGlzOwp9CgovKioKICogQ3JlYXRlcyBhIGhhc2ggb2JqZWN0LgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBIYXNoKGVudHJpZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDsKICB0aGlzLmNsZWFyKCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdOwogICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTsKICB9Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC4KSGFzaC5wcm90b3R5cGUuY2xlYXIgPSBoYXNoQ2xlYXI7Ckhhc2gucHJvdG90eXBlWydkZWxldGUnXSA9IGhhc2hEZWxldGU7Ckhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7Ckhhc2gucHJvdG90eXBlLmhhcyA9IGhhc2hIYXM7Ckhhc2gucHJvdG90eXBlLnNldCA9IGhhc2hTZXQ7CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS4KICoKICogQHByaXZhdGUKICogQG5hbWUgY2xlYXIKICogQG1lbWJlck9mIExpc3RDYWNoZQogKi8KZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7CiAgdGhpcy5fX2RhdGFfXyA9IFtdOwogIHRoaXMuc2l6ZSA9IDA7Cn0KCi8qKgogKiBQZXJmb3JtcyBhCiAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pCiAqIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBlcXVpdmFsZW50LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLgogKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEgfTsKICogdmFyIG90aGVyID0geyAnYSc6IDEgfTsKICoKICogXy5lcShvYmplY3QsIG9iamVjdCk7CiAqIC8vID0+IHRydWUKICoKICogXy5lcShvYmplY3QsIG90aGVyKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5lcSgnYScsICdhJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5lcSgnYScsIE9iamVjdCgnYScpKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5lcShOYU4sIE5hTik7CiAqIC8vID0+IHRydWUKICovCmZ1bmN0aW9uIGVxKHZhbHVlLCBvdGhlcikgewogIHJldHVybiB2YWx1ZSA9PT0gb3RoZXIgfHwgdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjsKfQoKLyoqCiAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBga2V5YCBpcyBmb3VuZCBpbiBgYXJyYXlgIG9mIGtleS12YWx1ZSBwYWlycy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuCiAqIEBwYXJhbSB7Kn0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC4KICovCmZ1bmN0aW9uIGFzc29jSW5kZXhPZihhcnJheSwga2V5KSB7CiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsKICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgIGlmIChlcShhcnJheVtsZW5ndGhdWzBdLCBrZXkpKSB7CiAgICAgIHJldHVybiBsZW5ndGg7CiAgICB9CiAgfQogIHJldHVybiAtMTsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3BsaWNlID0gYXJyYXlQcm90by5zcGxpY2U7CgovKioKICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGxpc3QgY2FjaGUuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGRlbGV0ZQogKiBAbWVtYmVyT2YgTGlzdENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLAogICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTsKICBpZiAoaW5kZXggPCAwKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHZhciBsYXN0SW5kZXggPSBkYXRhLmxlbmd0aCAtIDE7CiAgaWYgKGluZGV4ID09IGxhc3RJbmRleCkgewogICAgZGF0YS5wb3AoKTsKICB9IGVsc2UgewogICAgc3BsaWNlLmNhbGwoZGF0YSwgaW5kZXgsIDEpOwogIH0KICAtLXRoaXMuc2l6ZTsKICByZXR1cm4gdHJ1ZTsKfQoKLyoqCiAqIEdldHMgdGhlIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7CiAgcmV0dXJuIGluZGV4IDwgMCA/IHVuZGVmaW5lZCA6IGRhdGFbaW5kZXhdWzFdOwp9CgovKioKICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBoYXMKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlSGFzKGtleSkgewogIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xOwp9CgovKioKICogU2V0cyB0aGUgbGlzdCBjYWNoZSBga2V5YCB0byBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBzZXQKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlU2V0KGtleSwgdmFsdWUpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sCiAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpOwogIGlmIChpbmRleCA8IDApIHsKICAgICsrdGhpcy5zaXplOwogICAgZGF0YS5wdXNoKFtrZXksIHZhbHVlXSk7CiAgfSBlbHNlIHsKICAgIGRhdGFbaW5kZXhdWzFdID0gdmFsdWU7CiAgfQogIHJldHVybiB0aGlzOwp9CgovKioKICogQ3JlYXRlcyBhbiBsaXN0IGNhY2hlIG9iamVjdC4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDsKICB0aGlzLmNsZWFyKCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdOwogICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTsKICB9Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBMaXN0Q2FjaGVgLgpMaXN0Q2FjaGUucHJvdG90eXBlLmNsZWFyID0gbGlzdENhY2hlQ2xlYXI7Ckxpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlOwpMaXN0Q2FjaGUucHJvdG90eXBlLmdldCA9IGxpc3RDYWNoZUdldDsKTGlzdENhY2hlLnByb3RvdHlwZS5oYXMgPSBsaXN0Q2FjaGVIYXM7Ckxpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0OwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgTWFwID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ01hcCcpOwp2YXIgTWFwJDEgPSBNYXA7CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbWFwLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBjbGVhcgogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICovCmZ1bmN0aW9uIG1hcENhY2hlQ2xlYXIoKSB7CiAgdGhpcy5zaXplID0gMDsKICB0aGlzLl9fZGF0YV9fID0gewogICAgJ2hhc2gnOiBuZXcgSGFzaCgpLAogICAgJ21hcCc6IG5ldyAoTWFwJDEgfHwgTGlzdENhY2hlKSgpLAogICAgJ3N0cmluZyc6IG5ldyBIYXNoKCkKICB9Owp9CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHVzZSBhcyB1bmlxdWUgb2JqZWN0IGtleS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc0tleWFibGUodmFsdWUpIHsKICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKICByZXR1cm4gdHlwZSA9PSAnc3RyaW5nJyB8fCB0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicgPyB2YWx1ZSAhPT0gJ19fcHJvdG9fXycgOiB2YWx1ZSA9PT0gbnVsbDsKfQoKLyoqCiAqIEdldHMgdGhlIGRhdGEgZm9yIGBtYXBgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gbWFwIFRoZSBtYXAgdG8gcXVlcnkuCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXAgZGF0YS4KICovCmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHsKICB2YXIgZGF0YSA9IG1hcC5fX2RhdGFfXzsKICByZXR1cm4gaXNLZXlhYmxlKGtleSkgPyBkYXRhW3R5cGVvZiBrZXkgPT0gJ3N0cmluZycgPyAnc3RyaW5nJyA6ICdoYXNoJ10gOiBkYXRhLm1hcDsKfQoKLyoqCiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGRlbGV0ZQogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIG1hcENhY2hlRGVsZXRlKGtleSkgewogIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7CiAgdGhpcy5zaXplIC09IHJlc3VsdCA/IDEgOiAwOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBHZXRzIHRoZSBtYXAgdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIE1hcENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZUdldChrZXkpIHsKICByZXR1cm4gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLmdldChrZXkpOwp9CgovKioKICogQ2hlY2tzIGlmIGEgbWFwIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGhhcwogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIG1hcENhY2hlSGFzKGtleSkgewogIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuaGFzKGtleSk7Cn0KCi8qKgogKiBTZXRzIHRoZSBtYXAgYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBNYXBDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZVNldChrZXksIHZhbHVlKSB7CiAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksCiAgICBzaXplID0gZGF0YS5zaXplOwogIGRhdGEuc2V0KGtleSwgdmFsdWUpOwogIHRoaXMuc2l6ZSArPSBkYXRhLnNpemUgPT0gc2l6ZSA/IDAgOiAxOwogIHJldHVybiB0aGlzOwp9CgovKioKICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CiAgdGhpcy5jbGVhcigpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTsKICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7CiAgfQp9CgovLyBBZGQgbWV0aG9kcyB0byBgTWFwQ2FjaGVgLgpNYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyOwpNYXBDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbWFwQ2FjaGVEZWxldGU7Ck1hcENhY2hlLnByb3RvdHlwZS5nZXQgPSBtYXBDYWNoZUdldDsKTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzOwpNYXBDYWNoZS5wcm90b3R5cGUuc2V0ID0gbWFwQ2FjaGVTZXQ7CgovKiogRXJyb3IgbWVzc2FnZSBjb25zdGFudHMuICovCnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7CgovKioKICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgbWVtb2l6ZXMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuIElmIGByZXNvbHZlcmAgaXMKICogcHJvdmlkZWQsIGl0IGRldGVybWluZXMgdGhlIGNhY2hlIGtleSBmb3Igc3RvcmluZyB0aGUgcmVzdWx0IGJhc2VkIG9uIHRoZQogKiBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgZmlyc3QgYXJndW1lbnQKICogcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uIGlzIHVzZWQgYXMgdGhlIG1hcCBjYWNoZSBrZXkuIFRoZSBgZnVuY2AKICogaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24uCiAqCiAqICoqTm90ZToqKiBUaGUgY2FjaGUgaXMgZXhwb3NlZCBhcyB0aGUgYGNhY2hlYCBwcm9wZXJ0eSBvbiB0aGUgbWVtb2l6ZWQKICogZnVuY3Rpb24uIEl0cyBjcmVhdGlvbiBtYXkgYmUgY3VzdG9taXplZCBieSByZXBsYWNpbmcgdGhlIGBfLm1lbW9pemUuQ2FjaGVgCiAqIGNvbnN0cnVjdG9yIHdpdGggb25lIHdob3NlIGluc3RhbmNlcyBpbXBsZW1lbnQgdGhlCiAqIFtgTWFwYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcHJvcGVydGllcy1vZi10aGUtbWFwLXByb3RvdHlwZS1vYmplY3QpCiAqIG1ldGhvZCBpbnRlcmZhY2Ugb2YgYGNsZWFyYCwgYGRlbGV0ZWAsIGBnZXRgLCBgaGFzYCwgYW5kIGBzZXRgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgRnVuY3Rpb24KICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgb3V0cHV0IG1lbW9pemVkLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzb2x2ZXJdIFRoZSBmdW5jdGlvbiB0byByZXNvbHZlIHRoZSBjYWNoZSBrZXkuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG1lbW9pemVkIGZ1bmN0aW9uLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9OwogKiB2YXIgb3RoZXIgPSB7ICdjJzogMywgJ2QnOiA0IH07CiAqCiAqIHZhciB2YWx1ZXMgPSBfLm1lbW9pemUoXy52YWx1ZXMpOwogKiB2YWx1ZXMob2JqZWN0KTsKICogLy8gPT4gWzEsIDJdCiAqCiAqIHZhbHVlcyhvdGhlcik7CiAqIC8vID0+IFszLCA0XQogKgogKiBvYmplY3QuYSA9IDI7CiAqIHZhbHVlcyhvYmplY3QpOwogKiAvLyA9PiBbMSwgMl0KICoKICogLy8gTW9kaWZ5IHRoZSByZXN1bHQgY2FjaGUuCiAqIHZhbHVlcy5jYWNoZS5zZXQob2JqZWN0LCBbJ2EnLCAnYiddKTsKICogdmFsdWVzKG9iamVjdCk7CiAqIC8vID0+IFsnYScsICdiJ10KICoKICogLy8gUmVwbGFjZSBgXy5tZW1vaXplLkNhY2hlYC4KICogXy5tZW1vaXplLkNhY2hlID0gV2Vha01hcDsKICovCmZ1bmN0aW9uIG1lbW9pemUoZnVuYywgcmVzb2x2ZXIpIHsKICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJyB8fCByZXNvbHZlciAhPSBudWxsICYmIHR5cGVvZiByZXNvbHZlciAhPSAnZnVuY3Rpb24nKSB7CiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7CiAgfQogIHZhciBtZW1vaXplZCA9IGZ1bmN0aW9uICgpIHsKICAgIHZhciBhcmdzID0gYXJndW1lbnRzLAogICAgICBrZXkgPSByZXNvbHZlciA/IHJlc29sdmVyLmFwcGx5KHRoaXMsIGFyZ3MpIDogYXJnc1swXSwKICAgICAgY2FjaGUgPSBtZW1vaXplZC5jYWNoZTsKICAgIGlmIChjYWNoZS5oYXMoa2V5KSkgewogICAgICByZXR1cm4gY2FjaGUuZ2V0KGtleSk7CiAgICB9CiAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTsKICAgIG1lbW9pemVkLmNhY2hlID0gY2FjaGUuc2V0KGtleSwgcmVzdWx0KSB8fCBjYWNoZTsKICAgIHJldHVybiByZXN1bHQ7CiAgfTsKICBtZW1vaXplZC5jYWNoZSA9IG5ldyAobWVtb2l6ZS5DYWNoZSB8fCBNYXBDYWNoZSkoKTsKICByZXR1cm4gbWVtb2l6ZWQ7Cn0KCi8vIEV4cG9zZSBgTWFwQ2FjaGVgLgptZW1vaXplLkNhY2hlID0gTWFwQ2FjaGU7CgovKiogVXNlZCBhcyB0aGUgbWF4aW11bSBtZW1vaXplIGNhY2hlIHNpemUuICovCnZhciBNQVhfTUVNT0laRV9TSVpFID0gNTAwOwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tZW1vaXplYCB3aGljaCBjbGVhcnMgdGhlIG1lbW9pemVkIGZ1bmN0aW9uJ3MKICogY2FjaGUgd2hlbiBpdCBleGNlZWRzIGBNQVhfTUVNT0laRV9TSVpFYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgb3V0cHV0IG1lbW9pemVkLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIG1lbW9pemVDYXBwZWQoZnVuYykgewogIHZhciByZXN1bHQgPSBtZW1vaXplKGZ1bmMsIGZ1bmN0aW9uIChrZXkpIHsKICAgIGlmIChjYWNoZS5zaXplID09PSBNQVhfTUVNT0laRV9TSVpFKSB7CiAgICAgIGNhY2hlLmNsZWFyKCk7CiAgICB9CiAgICByZXR1cm4ga2V5OwogIH0pOwogIHZhciBjYWNoZSA9IHJlc3VsdC5jYWNoZTsKICByZXR1cm4gcmVzdWx0Owp9CgovKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovCnZhciByZVByb3BOYW1lID0gL1teLltcXV0rfFxbKD86KC0/XGQrKD86XC5cZCspPyl8KFsiJ10pKCg/Oig/IVwyKVteXFxdfFxcLikqPylcMilcXXwoPz0oPzpcLnxcW1xdKSg/OlwufFxbXF18JCkpL2c7CgovKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi8KdmFyIHJlRXNjYXBlQ2hhciA9IC9cXChcXCk/L2c7CgovKioKICogQ29udmVydHMgYHN0cmluZ2AgdG8gYSBwcm9wZXJ0eSBwYXRoIGFycmF5LgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LgogKi8KdmFyIHN0cmluZ1RvUGF0aCA9IG1lbW9pemVDYXBwZWQoZnVuY3Rpb24gKHN0cmluZykgewogIHZhciByZXN1bHQgPSBbXTsKICBpZiAoc3RyaW5nLmNoYXJDb2RlQXQoMCkgPT09IDQ2IC8qIC4gKi8pIHsKICAgIHJlc3VsdC5wdXNoKCcnKTsKICB9CiAgc3RyaW5nLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24gKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdWJTdHJpbmcpIHsKICAgIHJlc3VsdC5wdXNoKHF1b3RlID8gc3ViU3RyaW5nLnJlcGxhY2UocmVFc2NhcGVDaGFyLCAnJDEnKSA6IG51bWJlciB8fCBtYXRjaCk7CiAgfSk7CiAgcmV0dXJuIHJlc3VsdDsKfSk7CnZhciBzdHJpbmdUb1BhdGgkMSA9IHN0cmluZ1RvUGF0aDsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWFwYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUKICogc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuCiAqLwpmdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLAogICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBJTkZJTklUWSQyID0gMSAvIDA7CgovKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi8KdmFyIHN5bWJvbFByb3RvJDEgPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnByb3RvdHlwZSA6IHVuZGVmaW5lZCwKICBzeW1ib2xUb1N0cmluZyA9IHN5bWJvbFByb3RvJDEgPyBzeW1ib2xQcm90byQxLnRvU3RyaW5nIDogdW5kZWZpbmVkOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvU3RyaW5nYCB3aGljaCBkb2Vzbid0IGNvbnZlcnQgbnVsbGlzaAogKiB2YWx1ZXMgdG8gZW1wdHkgc3RyaW5ncy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RyaW5nLgogKi8KZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7CiAgLy8gRXhpdCBlYXJseSBmb3Igc3RyaW5ncyB0byBhdm9pZCBhIHBlcmZvcm1hbmNlIGhpdCBpbiBzb21lIGVudmlyb25tZW50cy4KICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKSB7CiAgICByZXR1cm4gdmFsdWU7CiAgfQogIGlmIChpc0FycmF5JDEodmFsdWUpKSB7CiAgICAvLyBSZWN1cnNpdmVseSBjb252ZXJ0IHZhbHVlcyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLgogICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCBiYXNlVG9TdHJpbmcpICsgJyc7CiAgfQogIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHsKICAgIHJldHVybiBzeW1ib2xUb1N0cmluZyA/IHN5bWJvbFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7CiAgfQogIHZhciByZXN1bHQgPSB2YWx1ZSArICcnOwogIHJldHVybiByZXN1bHQgPT0gJzAnICYmIDEgLyB2YWx1ZSA9PSAtSU5GSU5JVFkkMiA/ICctMCcgOiByZXN1bHQ7Cn0KCi8qKgogKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgZm9yIGBudWxsYAogKiBhbmQgYHVuZGVmaW5lZGAgdmFsdWVzLiBUaGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy4KICogQGV4YW1wbGUKICoKICogXy50b1N0cmluZyhudWxsKTsKICogLy8gPT4gJycKICoKICogXy50b1N0cmluZygtMCk7CiAqIC8vID0+ICctMCcKICoKICogXy50b1N0cmluZyhbMSwgMiwgM10pOwogKiAvLyA9PiAnMSwyLDMnCiAqLwpmdW5jdGlvbiB0b1N0cmluZyh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiBiYXNlVG9TdHJpbmcodmFsdWUpOwp9CgovKioKICogQ2FzdHMgYHZhbHVlYCB0byBhIHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LgogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNhc3QgcHJvcGVydHkgcGF0aCBhcnJheS4KICovCmZ1bmN0aW9uIGNhc3RQYXRoKHZhbHVlLCBvYmplY3QpIHsKICBpZiAoaXNBcnJheSQxKHZhbHVlKSkgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICByZXR1cm4gaXNLZXkodmFsdWUsIG9iamVjdCkgPyBbdmFsdWVdIDogc3RyaW5nVG9QYXRoJDEodG9TdHJpbmcodmFsdWUpKTsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBJTkZJTklUWSQxID0gMSAvIDA7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBrZXkgaWYgaXQncyBub3QgYSBzdHJpbmcgb3Igc3ltYm9sLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7c3RyaW5nfHN5bWJvbH0gUmV0dXJucyB0aGUga2V5LgogKi8KZnVuY3Rpb24gdG9LZXkodmFsdWUpIHsKICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IGlzU3ltYm9sKHZhbHVlKSkgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICB2YXIgcmVzdWx0ID0gdmFsdWUgKyAnJzsKICByZXR1cm4gcmVzdWx0ID09ICcwJyAmJiAxIC8gdmFsdWUgPT0gLUlORklOSVRZJDEgPyAnLTAnIDogcmVzdWx0Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZ2V0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZmF1bHQgdmFsdWVzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS4KICovCmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoKSB7CiAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7CiAgdmFyIGluZGV4ID0gMCwKICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoOwogIHdoaWxlIChvYmplY3QgIT0gbnVsbCAmJiBpbmRleCA8IGxlbmd0aCkgewogICAgb2JqZWN0ID0gb2JqZWN0W3RvS2V5KHBhdGhbaW5kZXgrK10pXTsKICB9CiAgcmV0dXJuIGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCA/IG9iamVjdCA6IHVuZGVmaW5lZDsKfQoKLyoqCiAqIEdldHMgdGhlIHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzCiAqIGB1bmRlZmluZWRgLCB0aGUgYGRlZmF1bHRWYWx1ZWAgaXMgcmV0dXJuZWQgaW4gaXRzIHBsYWNlLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAzLjcuMAogKiBAY2F0ZWdvcnkgT2JqZWN0CiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHBhcmFtIHsqfSBbZGVmYXVsdFZhbHVlXSBUaGUgdmFsdWUgcmV0dXJuZWQgZm9yIGB1bmRlZmluZWRgIHJlc29sdmVkIHZhbHVlcy4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9OwogKgogKiBfLmdldChvYmplY3QsICdhWzBdLmIuYycpOwogKiAvLyA9PiAzCiAqCiAqIF8uZ2V0KG9iamVjdCwgWydhJywgJzAnLCAnYicsICdjJ10pOwogKiAvLyA9PiAzCiAqCiAqIF8uZ2V0KG9iamVjdCwgJ2EuYi5jJywgJ2RlZmF1bHQnKTsKICogLy8gPT4gJ2RlZmF1bHQnCiAqLwpmdW5jdGlvbiBnZXQob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHsKICB2YXIgcmVzdWx0ID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7CiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdFZhbHVlIDogcmVzdWx0Owp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBib29sVGFnJDIgPSAnW29iamVjdCBCb29sZWFuXSc7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGJvb2xlYW4gcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYm9vbGVhbiwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQm9vbGVhbihmYWxzZSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0Jvb2xlYW4obnVsbCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0Jvb2xlYW4odmFsdWUpIHsKICByZXR1cm4gdmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09IGZhbHNlIHx8IGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYm9vbFRhZyQyOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCumJvb2xlYW4NCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2JvbC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNib2woZmFsc2UpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2JvbCh2KSB7CiAgcmV0dXJuIGlzQm9vbGVhbih2KTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrlrZfkuLINCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc3N0ci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIoMCkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyKCcwJykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIoJycpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc3N0cih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IFN0cmluZ10nOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuacieaViOWtl+S4sg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzZXN0ci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNlc3RyKCcxLjI1JykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNlc3RyKDEyNSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXN0cignJykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2VzdHIodikgewogIC8vY2hlY2sKICBpZiAoaXNzdHIodikpIHsKICAgIGlmICh2ICE9PSAnJykgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLgogKi8KZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICByZXR1cm4gYXJyYXk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgbWV0aG9kcyBsaWtlIGBfLmZvckluYCBhbmQgYF8uZm9yT3duYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkgewogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHsKICAgIHZhciBpbmRleCA9IC0xLAogICAgICBpdGVyYWJsZSA9IE9iamVjdChvYmplY3QpLAogICAgICBwcm9wcyA9IGtleXNGdW5jKG9iamVjdCksCiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDsKICAgIHdoaWxlIChsZW5ndGgtLSkgewogICAgICB2YXIga2V5ID0gcHJvcHNbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF07CiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgcmV0dXJuIG9iamVjdDsKICB9Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JPd25gIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYG9iamVjdGAKICogcHJvcGVydGllcyByZXR1cm5lZCBieSBga2V5c0Z1bmNgIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuCiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC4KICovCnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpOwp2YXIgYmFzZUZvciQxID0gYmFzZUZvcjsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50aW1lc2Agd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzCiAqIG9yIG1heCBhcnJheSBsZW5ndGggY2hlY2tzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHJlc3VsdHMuCiAqLwpmdW5jdGlvbiBiYXNlVGltZXMobiwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IEFycmF5KG4pOwogIHdoaWxlICgrK2luZGV4IDwgbikgewogICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgYXJnc1RhZyQyID0gJ1tvYmplY3QgQXJndW1lbnRzXSc7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNBcmd1bWVudHNgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LAogKi8KZnVuY3Rpb24gYmFzZUlzQXJndW1lbnRzKHZhbHVlKSB7CiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZyQyOwp9CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQ2ID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkNCA9IG9iamVjdFByb3RvJDYuaGFzT3duUHJvcGVydHk7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlJDEgPSBvYmplY3RQcm90byQ2LnByb3BlcnR5SXNFbnVtZXJhYmxlOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxpa2VseSBhbiBgYXJndW1lbnRzYCBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsCiAqICBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pOwogKiAvLyA9PiBmYWxzZQogKi8KdmFyIGlzQXJndW1lbnRzID0gYmFzZUlzQXJndW1lbnRzKGZ1bmN0aW9uICgpIHsKICByZXR1cm4gYXJndW1lbnRzOwp9KCkpID8gYmFzZUlzQXJndW1lbnRzIDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkkNC5jYWxsKHZhbHVlLCAnY2FsbGVlJykgJiYgIXByb3BlcnR5SXNFbnVtZXJhYmxlJDEuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpOwp9Owp2YXIgaXNBcmd1bWVudHMkMSA9IGlzQXJndW1lbnRzOwoKLyoqCiAqIFRoaXMgbWV0aG9kIHJldHVybnMgYGZhbHNlYC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4xMy4wCiAqIEBjYXRlZ29yeSBVdGlsCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8udGltZXMoMiwgXy5zdHViRmFsc2UpOwogKiAvLyA9PiBbZmFsc2UsIGZhbHNlXQogKi8KZnVuY3Rpb24gc3R1YkZhbHNlKCkgewogIHJldHVybiBmYWxzZTsKfQoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi8KdmFyIGZyZWVFeHBvcnRzJDEgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovCnZhciBmcmVlTW9kdWxlJDEgPSBmcmVlRXhwb3J0cyQxICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlOwoKLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi8KdmFyIG1vZHVsZUV4cG9ydHMkMSA9IGZyZWVNb2R1bGUkMSAmJiBmcmVlTW9kdWxlJDEuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHMkMTsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyQxID8gcm9vdCQxLkJ1ZmZlciA6IHVuZGVmaW5lZDsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi8KdmFyIG5hdGl2ZUlzQnVmZmVyID0gQnVmZmVyID8gQnVmZmVyLmlzQnVmZmVyIDogdW5kZWZpbmVkOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjMuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBidWZmZXIsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0J1ZmZlcihuZXcgQnVmZmVyKDIpKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQnVmZmVyKG5ldyBVaW50OEFycmF5KDIpKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc0J1ZmZlciA9IG5hdGl2ZUlzQnVmZmVyIHx8IHN0dWJGYWxzZTsKdmFyIGlzQnVmZmVyJDEgPSBpc0J1ZmZlcjsKCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgTUFYX1NBRkVfSU5URUdFUiQxID0gOTAwNzE5OTI1NDc0MDk5MTsKCi8qKiBVc2VkIHRvIGRldGVjdCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy4gKi8KdmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXGQqKSQvOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPU1BWF9TQUZFX0lOVEVHRVJdIFRoZSB1cHBlciBib3VuZHMgb2YgYSB2YWxpZCBpbmRleC4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNJbmRleCh2YWx1ZSwgbGVuZ3RoKSB7CiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyBNQVhfU0FGRV9JTlRFR0VSJDEgOiBsZW5ndGg7CiAgcmV0dXJuICEhbGVuZ3RoICYmICh0eXBlID09ICdudW1iZXInIHx8IHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGxlbmd0aC4KICoKICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24KICogW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvbGVuZ3RoKS4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgbGVuZ3RoLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNMZW5ndGgoMyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0xlbmd0aChOdW1iZXIuTUlOX1ZBTFVFKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5pc0xlbmd0aChJbmZpbml0eSk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNMZW5ndGgoJzMnKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzTGVuZ3RoKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGFyZ3NUYWckMSA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLAogIGFycmF5VGFnJDEgPSAnW29iamVjdCBBcnJheV0nLAogIGJvb2xUYWckMSA9ICdbb2JqZWN0IEJvb2xlYW5dJywKICBkYXRlVGFnJDEgPSAnW29iamVjdCBEYXRlXScsCiAgZXJyb3JUYWckMSA9ICdbb2JqZWN0IEVycm9yXScsCiAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsCiAgbWFwVGFnJDMgPSAnW29iamVjdCBNYXBdJywKICBudW1iZXJUYWckMiA9ICdbb2JqZWN0IE51bWJlcl0nLAogIG9iamVjdFRhZyQyID0gJ1tvYmplY3QgT2JqZWN0XScsCiAgcmVnZXhwVGFnJDEgPSAnW29iamVjdCBSZWdFeHBdJywKICBzZXRUYWckMyA9ICdbb2JqZWN0IFNldF0nLAogIHN0cmluZ1RhZyQyID0gJ1tvYmplY3QgU3RyaW5nXScsCiAgd2Vha01hcFRhZyQxID0gJ1tvYmplY3QgV2Vha01hcF0nOwp2YXIgYXJyYXlCdWZmZXJUYWckMSA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsCiAgZGF0YVZpZXdUYWckMiA9ICdbb2JqZWN0IERhdGFWaWV3XScsCiAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLAogIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJywKICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsCiAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsCiAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsCiAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsCiAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJywKICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLAogIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7CgovKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovCnZhciB0eXBlZEFycmF5VGFncyA9IHt9Owp0eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlOwp0eXBlZEFycmF5VGFnc1thcmdzVGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWckMV0gPSB0eXBlZEFycmF5VGFnc1thcnJheUJ1ZmZlclRhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tkYXRhVmlld1RhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW2RhdGVUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tlcnJvclRhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnJDNdID0gdHlwZWRBcnJheVRhZ3NbbnVtYmVyVGFnJDJdID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnJDJdID0gdHlwZWRBcnJheVRhZ3NbcmVnZXhwVGFnJDFdID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnJDNdID0gdHlwZWRBcnJheVRhZ3Nbc3RyaW5nVGFnJDJdID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZyQxXSA9IGZhbHNlOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzVHlwZWRBcnJheWAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHR5cGVkIGFycmF5LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNUeXBlZEFycmF5KHZhbHVlKSB7CiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW2Jhc2VHZXRUYWcodmFsdWUpXTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuYXJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0b3JpbmcgbWV0YWRhdGEuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNhcCBhcmd1bWVudHMgZm9yLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlVW5hcnkoZnVuYykgewogIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHsKICAgIHJldHVybiBmdW5jKHZhbHVlKTsKICB9Owp9CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqLwp2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovCnZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7CgovKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqLwp2YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0czsKCi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgcHJvY2Vzc2AgZnJvbSBOb2RlLmpzLiAqLwp2YXIgZnJlZVByb2Nlc3MgPSBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwkMS5wcm9jZXNzOwoKLyoqIFVzZWQgdG8gYWNjZXNzIGZhc3RlciBOb2RlLmpzIGhlbHBlcnMuICovCnZhciBub2RlVXRpbCA9IGZ1bmN0aW9uICgpIHsKICB0cnkgewogICAgLy8gVXNlIGB1dGlsLnR5cGVzYCBmb3IgTm9kZS5qcyAxMCsuCiAgICB2YXIgdHlwZXMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUucmVxdWlyZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUoJ3V0aWwnKS50eXBlczsKICAgIGlmICh0eXBlcykgewogICAgICByZXR1cm4gdHlwZXM7CiAgICB9CgogICAgLy8gTGVnYWN5IGBwcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKWAgZm9yIE5vZGUuanMgPCAxMC4KICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTsKICB9IGNhdGNoIChlKSB7fQp9KCk7CnZhciBub2RlVXRpbCQxID0gbm9kZVV0aWw7CgovKiBOb2RlLmpzIGhlbHBlciByZWZlcmVuY2VzLiAqLwp2YXIgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsJDEgJiYgbm9kZVV0aWwkMS5pc1R5cGVkQXJyYXk7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAzLjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc1R5cGVkQXJyYXkoW10pOwogKiAvLyA9PiBmYWxzZQogKi8KdmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5Owp2YXIgaXNUeXBlZEFycmF5JDEgPSBpc1R5cGVkQXJyYXk7CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQ1ID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkMyA9IG9iamVjdFByb3RvJDUuaGFzT3duUHJvcGVydHk7CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiB0aGUgYXJyYXktbGlrZSBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS4KICogQHBhcmFtIHtib29sZWFufSBpbmhlcml0ZWQgU3BlY2lmeSByZXR1cm5pbmcgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVzLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLgogKi8KZnVuY3Rpb24gYXJyYXlMaWtlS2V5cyh2YWx1ZSwgaW5oZXJpdGVkKSB7CiAgdmFyIGlzQXJyID0gaXNBcnJheSQxKHZhbHVlKSwKICAgIGlzQXJnID0gIWlzQXJyICYmIGlzQXJndW1lbnRzJDEodmFsdWUpLAogICAgaXNCdWZmID0gIWlzQXJyICYmICFpc0FyZyAmJiBpc0J1ZmZlciQxKHZhbHVlKSwKICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkkMSh2YWx1ZSksCiAgICBza2lwSW5kZXhlcyA9IGlzQXJyIHx8IGlzQXJnIHx8IGlzQnVmZiB8fCBpc1R5cGUsCiAgICByZXN1bHQgPSBza2lwSW5kZXhlcyA/IGJhc2VUaW1lcyh2YWx1ZS5sZW5ndGgsIFN0cmluZykgOiBbXSwKICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7CiAgZm9yICh2YXIga2V5IGluIHZhbHVlKSB7CiAgICBpZiAoKGluaGVyaXRlZCB8fCBoYXNPd25Qcm9wZXJ0eSQzLmNhbGwodmFsdWUsIGtleSkpICYmICEoc2tpcEluZGV4ZXMgJiYgKAogICAgLy8gU2FmYXJpIDkgaGFzIGVudW1lcmFibGUgYGFyZ3VtZW50cy5sZW5ndGhgIGluIHN0cmljdCBtb2RlLgogICAga2V5ID09ICdsZW5ndGgnIHx8CiAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy4KICAgIGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykgfHwKICAgIC8vIFBoYW50b21KUyAyIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIHR5cGVkIGFycmF5cy4KICAgIGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykgfHwKICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy4KICAgIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSkpIHsKICAgICAgcmVzdWx0LnB1c2goa2V5KTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNCA9IE9iamVjdC5wcm90b3R5cGU7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcHJvdG90eXBlLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkgewogIHZhciBDdG9yID0gdmFsdWUgJiYgdmFsdWUuY29uc3RydWN0b3IsCiAgICBwcm90byA9IHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgfHwgb2JqZWN0UHJvdG8kNDsKICByZXR1cm4gdmFsdWUgPT09IHByb3RvOwp9CgovKioKICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBUaGUgYXJndW1lbnQgdHJhbnNmb3JtLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIG92ZXJBcmcoZnVuYywgdHJhbnNmb3JtKSB7CiAgcmV0dXJuIGZ1bmN0aW9uIChhcmcpIHsKICAgIHJldHVybiBmdW5jKHRyYW5zZm9ybShhcmcpKTsKICB9Owp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovCnZhciBuYXRpdmVLZXlzID0gb3ZlckFyZyhPYmplY3Qua2V5cywgT2JqZWN0KTsKdmFyIG5hdGl2ZUtleXMkMSA9IG5hdGl2ZUtleXM7CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQzID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkMiA9IG9iamVjdFByb3RvJDMuaGFzT3duUHJvcGVydHk7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ua2V5c2Agd2hpY2ggZG9lc24ndCB0cmVhdCBzcGFyc2UgYXJyYXlzIGFzIGRlbnNlLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuCiAqLwpmdW5jdGlvbiBiYXNlS2V5cyhvYmplY3QpIHsKICBpZiAoIWlzUHJvdG90eXBlKG9iamVjdCkpIHsKICAgIHJldHVybiBuYXRpdmVLZXlzJDEob2JqZWN0KTsKICB9CiAgdmFyIHJlc3VsdCA9IFtdOwogIGZvciAodmFyIGtleSBpbiBPYmplY3Qob2JqZWN0KSkgewogICAgaWYgKGhhc093blByb3BlcnR5JDIuY2FsbChvYmplY3QsIGtleSkgJiYga2V5ICE9ICdjb25zdHJ1Y3RvcicpIHsKICAgICAgcmVzdWx0LnB1c2goa2V5KTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UuIEEgdmFsdWUgaXMgY29uc2lkZXJlZCBhcnJheS1saWtlIGlmIGl0J3MKICogbm90IGEgZnVuY3Rpb24gYW5kIGhhcyBhIGB2YWx1ZS5sZW5ndGhgIHRoYXQncyBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiBvcgogKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQXJyYXlMaWtlKFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5TGlrZShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQXJyYXlMaWtlKCdhYmMnKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQXJyYXlMaWtlKF8ubm9vcCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0FycmF5TGlrZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgIWlzRnVuY3Rpb24odmFsdWUpOwp9CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuCiAqCiAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLiBTZWUgdGhlCiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cykKICogZm9yIG1vcmUgZGV0YWlscy4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IE9iamVjdAogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuCiAqIEBleGFtcGxlCiAqCiAqIGZ1bmN0aW9uIEZvbygpIHsKICogICB0aGlzLmEgPSAxOwogKiAgIHRoaXMuYiA9IDI7CiAqIH0KICoKICogRm9vLnByb3RvdHlwZS5jID0gMzsKICoKICogXy5rZXlzKG5ldyBGb28pOwogKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpCiAqCiAqIF8ua2V5cygnaGknKTsKICogLy8gPT4gWycwJywgJzEnXQogKi8KZnVuY3Rpb24ga2V5cyhvYmplY3QpIHsKICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JPd25gIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC4KICovCmZ1bmN0aW9uIGJhc2VGb3JPd24ob2JqZWN0LCBpdGVyYXRlZSkgewogIHJldHVybiBvYmplY3QgJiYgYmFzZUZvciQxKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpOwp9CgovKioKICogQ3JlYXRlcyBhIGBiYXNlRWFjaGAgb3IgYGJhc2VFYWNoUmlnaHRgIGZ1bmN0aW9uLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi4KICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7CiAgcmV0dXJuIGZ1bmN0aW9uIChjb2xsZWN0aW9uLCBpdGVyYXRlZSkgewogICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkgewogICAgICByZXR1cm4gY29sbGVjdGlvbjsKICAgIH0KICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHsKICAgICAgcmV0dXJuIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTsKICAgIH0KICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aCwKICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMSwKICAgICAgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7CiAgICB3aGlsZSAoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpIHsKICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2luZGV4XSwgaW5kZXgsIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGNvbGxlY3Rpb247CiAgfTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC4KICovCnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pOwp2YXIgYmFzZUVhY2gkMSA9IGJhc2VFYWNoOwoKLyoqCiAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGl0IHJlY2VpdmVzLgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS4KICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07CiAqCiAqIGNvbnNvbGUubG9nKF8uaWRlbnRpdHkob2JqZWN0KSA9PT0gb2JqZWN0KTsKICogLy8gPT4gdHJ1ZQogKi8KZnVuY3Rpb24gaWRlbnRpdHkkMSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZTsKfQoKLyoqCiAqIENhc3RzIGB2YWx1ZWAgdG8gYGlkZW50aXR5YCBpZiBpdCdzIG5vdCBhIGZ1bmN0aW9uLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgY2FzdCBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGNhc3RGdW5jdGlvbih2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogaWRlbnRpdHkkMTsKfQoKLyoqCiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggZWxlbWVudC4KICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS4KICogSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLgogKgogKiAqKk5vdGU6KiogQXMgd2l0aCBvdGhlciAiQ29sbGVjdGlvbnMiIG1ldGhvZHMsIG9iamVjdHMgd2l0aCBhICJsZW5ndGgiCiAqIHByb3BlcnR5IGFyZSBpdGVyYXRlZCBsaWtlIGFycmF5cy4gVG8gYXZvaWQgdGhpcyBiZWhhdmlvciB1c2UgYF8uZm9ySW5gCiAqIG9yIGBfLmZvck93bmAgZm9yIG9iamVjdCBpdGVyYXRpb24uCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBhbGlhcyBlYWNoCiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLgogKiBAc2VlIF8uZm9yRWFjaFJpZ2h0CiAqIEBleGFtcGxlCiAqCiAqIF8uZm9yRWFjaChbMSwgMl0sIGZ1bmN0aW9uKHZhbHVlKSB7CiAqICAgY29uc29sZS5sb2codmFsdWUpOwogKiB9KTsKICogLy8gPT4gTG9ncyBgMWAgdGhlbiBgMmAuCiAqCiAqIF8uZm9yRWFjaCh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHsKICogICBjb25zb2xlLmxvZyhrZXkpOwogKiB9KTsKICogLy8gPT4gTG9ncyAnYScgdGhlbiAnYicgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkuCiAqLwpmdW5jdGlvbiBmb3JFYWNoKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7CiAgdmFyIGZ1bmMgPSBpc0FycmF5JDEoY29sbGVjdGlvbikgPyBhcnJheUVhY2ggOiBiYXNlRWFjaCQxOwogIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGNhc3RGdW5jdGlvbihpdGVyYXRlZSkpOwp9CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgc3RhY2suCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGNsZWFyCiAqIEBtZW1iZXJPZiBTdGFjawogKi8KZnVuY3Rpb24gc3RhY2tDbGVhcigpIHsKICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZSgpOwogIHRoaXMuc2l6ZSA9IDA7Cn0KCi8qKgogKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgc3RhY2suCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGRlbGV0ZQogKiBAbWVtYmVyT2YgU3RhY2sKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIHN0YWNrRGVsZXRlKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7CiAgdGhpcy5zaXplID0gZGF0YS5zaXplOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGdldAogKiBAbWVtYmVyT2YgU3RhY2sKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS4KICovCmZ1bmN0aW9uIHN0YWNrR2V0KGtleSkgewogIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpOwp9CgovKioKICogQ2hlY2tzIGlmIGEgc3RhY2sgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBTdGFjawogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gc3RhY2tIYXMoa2V5KSB7CiAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKGtleSk7Cn0KCi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqLwp2YXIgTEFSR0VfQVJSQVlfU0laRSA9IDIwMDsKCi8qKgogKiBTZXRzIHRoZSBzdGFjayBga2V5YCB0byBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBzZXQKICogQG1lbWJlck9mIFN0YWNrCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LgogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIHN0YWNrIGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gc3RhY2tTZXQoa2V5LCB2YWx1ZSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXzsKICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkgewogICAgdmFyIHBhaXJzID0gZGF0YS5fX2RhdGFfXzsKICAgIGlmICghTWFwJDEgfHwgcGFpcnMubGVuZ3RoIDwgTEFSR0VfQVJSQVlfU0laRSAtIDEpIHsKICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pOwogICAgICB0aGlzLnNpemUgPSArK2RhdGEuc2l6ZTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBkYXRhID0gdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZShwYWlycyk7CiAgfQogIGRhdGEuc2V0KGtleSwgdmFsdWUpOwogIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYSBzdGFjayBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBTdGFjayhlbnRyaWVzKSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZShlbnRyaWVzKTsKICB0aGlzLnNpemUgPSBkYXRhLnNpemU7Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBTdGFja2AuClN0YWNrLnByb3RvdHlwZS5jbGVhciA9IHN0YWNrQ2xlYXI7ClN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTsKU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0OwpTdGFjay5wcm90b3R5cGUuaGFzID0gc3RhY2tIYXM7ClN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDsKCi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi8KdmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nOwoKLyoqCiAqIEFkZHMgYHZhbHVlYCB0byB0aGUgYXJyYXkgY2FjaGUuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGFkZAogKiBAbWVtYmVyT2YgU2V0Q2FjaGUKICogQGFsaWFzIHB1c2gKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2FjaGUuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gc2V0Q2FjaGVBZGQodmFsdWUpIHsKICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpOwogIHJldHVybiB0aGlzOwp9CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBoYXMKICogQG1lbWJlck9mIFNldENhY2hlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBzZXRDYWNoZUhhcyh2YWx1ZSkgewogIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyh2YWx1ZSk7Cn0KCi8qKgogKgogKiBDcmVhdGVzIGFuIGFycmF5IGNhY2hlIG9iamVjdCB0byBzdG9yZSB1bmlxdWUgdmFsdWVzLgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS4KICovCmZ1bmN0aW9uIFNldENhY2hlKHZhbHVlcykgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gdmFsdWVzID09IG51bGwgPyAwIDogdmFsdWVzLmxlbmd0aDsKICB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlKCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHRoaXMuYWRkKHZhbHVlc1tpbmRleF0pOwogIH0KfQoKLy8gQWRkIG1ldGhvZHMgdG8gYFNldENhY2hlYC4KU2V0Q2FjaGUucHJvdG90eXBlLmFkZCA9IFNldENhY2hlLnByb3RvdHlwZS5wdXNoID0gc2V0Q2FjaGVBZGQ7ClNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhczsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlCiAqIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjaywKICogIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGFycmF5U29tZShhcnJheSwgcHJlZGljYXRlKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIGBjYWNoZWAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IGNhY2hlIFRoZSBjYWNoZSB0byBxdWVyeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGNhY2hlSGFzKGNhY2hlLCBrZXkpIHsKICByZXR1cm4gY2FjaGUuaGFzKGtleSk7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNSA9IDEsCiAgQ09NUEFSRV9VTk9SREVSRURfRkxBRyQzID0gMjsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yCiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLgogKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy4KICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuCiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBhcnJheWAgYW5kIGBvdGhlcmAgb2JqZWN0cy4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykgewogIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNSwKICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCwKICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aDsKICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzUGFydGlhbCAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuCiAgdmFyIGFyclN0YWNrZWQgPSBzdGFjay5nZXQoYXJyYXkpOwogIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTsKICBpZiAoYXJyU3RhY2tlZCAmJiBvdGhTdGFja2VkKSB7CiAgICByZXR1cm4gYXJyU3RhY2tlZCA9PSBvdGhlciAmJiBvdGhTdGFja2VkID09IGFycmF5OwogIH0KICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IHRydWUsCiAgICBzZWVuID0gYml0bWFzayAmIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMyA/IG5ldyBTZXRDYWNoZSgpIDogdW5kZWZpbmVkOwogIHN0YWNrLnNldChhcnJheSwgb3RoZXIpOwogIHN0YWNrLnNldChvdGhlciwgYXJyYXkpOwoKICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuCiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHsKICAgIHZhciBhcnJWYWx1ZSA9IGFycmF5W2luZGV4XSwKICAgICAgb3RoVmFsdWUgPSBvdGhlcltpbmRleF07CiAgICBpZiAoY3VzdG9taXplcikgewogICAgICB2YXIgY29tcGFyZWQgPSBpc1BhcnRpYWwgPyBjdXN0b21pemVyKG90aFZhbHVlLCBhcnJWYWx1ZSwgaW5kZXgsIG90aGVyLCBhcnJheSwgc3RhY2spIDogY3VzdG9taXplcihhcnJWYWx1ZSwgb3RoVmFsdWUsIGluZGV4LCBhcnJheSwgb3RoZXIsIHN0YWNrKTsKICAgIH0KICAgIGlmIChjb21wYXJlZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIGlmIChjb21wYXJlZCkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICBpZiAoc2VlbikgewogICAgICBpZiAoIWFycmF5U29tZShvdGhlciwgZnVuY3Rpb24gKG90aFZhbHVlLCBvdGhJbmRleCkgewogICAgICAgIGlmICghY2FjaGVIYXMoc2Vlbiwgb3RoSW5kZXgpICYmIChhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spKSkgewogICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7CiAgICAgICAgfQogICAgICB9KSkgewogICAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9IGVsc2UgaWYgKCEoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHsKICAgICAgcmVzdWx0ID0gZmFsc2U7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBzdGFja1snZGVsZXRlJ10oYXJyYXkpOwogIHN0YWNrWydkZWxldGUnXShvdGhlcik7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovCnZhciBVaW50OEFycmF5ID0gcm9vdCQxLlVpbnQ4QXJyYXk7CnZhciBVaW50OEFycmF5JDEgPSBVaW50OEFycmF5OwoKLyoqCiAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy4KICovCmZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSBBcnJheShtYXAuc2l6ZSk7CiAgbWFwLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHsKICAgIHJlc3VsdFsrK2luZGV4XSA9IFtrZXksIHZhbHVlXTsKICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ29udmVydHMgYHNldGAgdG8gYW4gYXJyYXkgb2YgaXRzIHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgdmFsdWVzLgogKi8KZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IEFycmF5KHNldC5zaXplKTsKICBzZXQuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHsKICAgIHJlc3VsdFsrK2luZGV4XSA9IHZhbHVlOwogIH0pOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNCA9IDEsCiAgQ09NUEFSRV9VTk9SREVSRURfRkxBRyQyID0gMjsKCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsCiAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJywKICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsCiAgbWFwVGFnJDIgPSAnW29iamVjdCBNYXBdJywKICBudW1iZXJUYWckMSA9ICdbb2JqZWN0IE51bWJlcl0nLAogIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLAogIHNldFRhZyQyID0gJ1tvYmplY3QgU2V0XScsCiAgc3RyaW5nVGFnJDEgPSAnW29iamVjdCBTdHJpbmddJywKICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJzsKdmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJywKICBkYXRhVmlld1RhZyQxID0gJ1tvYmplY3QgRGF0YVZpZXddJzsKCi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqLwp2YXIgc3ltYm9sUHJvdG8gPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnByb3RvdHlwZSA6IHVuZGVmaW5lZCwKICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkOwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2YKICogdGhlIHNhbWUgYHRvU3RyaW5nVGFnYC4KICoKICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZgogKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgdGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7CiAgc3dpdGNoICh0YWcpIHsKICAgIGNhc2UgZGF0YVZpZXdUYWckMToKICAgICAgaWYgKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGggfHwgb2JqZWN0LmJ5dGVPZmZzZXQgIT0gb3RoZXIuYnl0ZU9mZnNldCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBvYmplY3QgPSBvYmplY3QuYnVmZmVyOwogICAgICBvdGhlciA9IG90aGVyLmJ1ZmZlcjsKICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6CiAgICAgIGlmIChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoIHx8ICFlcXVhbEZ1bmMobmV3IFVpbnQ4QXJyYXkkMShvYmplY3QpLCBuZXcgVWludDhBcnJheSQxKG90aGVyKSkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGJvb2xUYWc6CiAgICBjYXNlIGRhdGVUYWc6CiAgICBjYXNlIG51bWJlclRhZyQxOgogICAgICAvLyBDb2VyY2UgYm9vbGVhbnMgdG8gYDFgIG9yIGAwYCBhbmQgZGF0ZXMgdG8gbWlsbGlzZWNvbmRzLgogICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLgogICAgICByZXR1cm4gZXEoK29iamVjdCwgK290aGVyKTsKICAgIGNhc2UgZXJyb3JUYWc6CiAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7CiAgICBjYXNlIHJlZ2V4cFRhZzoKICAgIGNhc2Ugc3RyaW5nVGFnJDE6CiAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MsIHByaW1pdGl2ZXMgYW5kIG9iamVjdHMsCiAgICAgIC8vIGFzIGVxdWFsLiBTZWUgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXJlZ2V4cC5wcm90b3R5cGUudG9zdHJpbmcKICAgICAgLy8gZm9yIG1vcmUgZGV0YWlscy4KICAgICAgcmV0dXJuIG9iamVjdCA9PSBvdGhlciArICcnOwogICAgY2FzZSBtYXBUYWckMjoKICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5OwogICAgY2FzZSBzZXRUYWckMjoKICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyQ0OwogICAgICBjb252ZXJ0IHx8IChjb252ZXJ0ID0gc2V0VG9BcnJheSk7CiAgICAgIGlmIChvYmplY3Quc2l6ZSAhPSBvdGhlci5zaXplICYmICFpc1BhcnRpYWwpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgLy8gQXNzdW1lIGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLgogICAgICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldChvYmplY3QpOwogICAgICBpZiAoc3RhY2tlZCkgewogICAgICAgIHJldHVybiBzdGFja2VkID09IG90aGVyOwogICAgICB9CiAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRyQyOwoKICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICAgIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTsKICAgICAgdmFyIHJlc3VsdCA9IGVxdWFsQXJyYXlzKGNvbnZlcnQob2JqZWN0KSwgY29udmVydChvdGhlciksIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spOwogICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIGNhc2Ugc3ltYm9sVGFnOgogICAgICBpZiAoc3ltYm9sVmFsdWVPZikgewogICAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mLmNhbGwob2JqZWN0KSA9PSBzeW1ib2xWYWx1ZU9mLmNhbGwob3RoZXIpOwogICAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIEFwcGVuZHMgdGhlIGVsZW1lbnRzIG9mIGB2YWx1ZXNgIHRvIGBhcnJheWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuCiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuCiAqLwpmdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCwKICAgIG9mZnNldCA9IGFycmF5Lmxlbmd0aDsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgYXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gdmFsdWVzW2luZGV4XTsKICB9CiAgcmV0dXJuIGFycmF5Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldEFsbEtleXNgIGFuZCBgZ2V0QWxsS2V5c0luYCB3aGljaCB1c2VzCiAqIGBrZXlzRnVuY2AgYW5kIGBzeW1ib2xzRnVuY2AgdG8gZ2V0IHRoZSBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIGFuZAogKiBzeW1ib2xzIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHN5bWJvbHNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIHN5bWJvbHMgb2YgYG9iamVjdGAuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuCiAqLwpmdW5jdGlvbiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXNGdW5jLCBzeW1ib2xzRnVuYykgewogIHZhciByZXN1bHQgPSBrZXlzRnVuYyhvYmplY3QpOwogIHJldHVybiBpc0FycmF5JDEob2JqZWN0KSA/IHJlc3VsdCA6IGFycmF5UHVzaChyZXN1bHQsIHN5bWJvbHNGdW5jKG9iamVjdCkpOwp9CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZpbHRlcmAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yCiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LgogKi8KZnVuY3Rpb24gYXJyYXlGaWx0ZXIoYXJyYXksIHByZWRpY2F0ZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsCiAgICByZXNJbmRleCA9IDAsCiAgICByZXN1bHQgPSBbXTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdOwogICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGFycmF5KSkgewogICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgYXJyYXkuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMTMuMAogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBlbXB0eSBhcnJheS4KICogQGV4YW1wbGUKICoKICogdmFyIGFycmF5cyA9IF8udGltZXMoMiwgXy5zdHViQXJyYXkpOwogKgogKiBjb25zb2xlLmxvZyhhcnJheXMpOwogKiAvLyA9PiBbW10sIFtdXQogKgogKiBjb25zb2xlLmxvZyhhcnJheXNbMF0gPT09IGFycmF5c1sxXSk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBzdHViQXJyYXkoKSB7CiAgcmV0dXJuIFtdOwp9CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQyID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90byQyLnByb3BlcnR5SXNFbnVtZXJhYmxlOwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqLwp2YXIgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHN5bWJvbHMuCiAqLwp2YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24gKG9iamVjdCkgewogIGlmIChvYmplY3QgPT0gbnVsbCkgewogICAgcmV0dXJuIFtdOwogIH0KICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTsKICByZXR1cm4gYXJyYXlGaWx0ZXIobmF0aXZlR2V0U3ltYm9scyhvYmplY3QpLCBmdW5jdGlvbiAoc3ltYm9sKSB7CiAgICByZXR1cm4gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmplY3QsIHN5bWJvbCk7CiAgfSk7Cn07CnZhciBnZXRTeW1ib2xzJDEgPSBnZXRTeW1ib2xzOwoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy4KICovCmZ1bmN0aW9uIGdldEFsbEtleXMob2JqZWN0KSB7CiAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5cywgZ2V0U3ltYm9scyQxKTsKfQoKLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovCnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyQzID0gMTsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDEgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQxID0gb2JqZWN0UHJvdG8kMS5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvcgogKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy4KICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuCiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHsKICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHJDMsCiAgICBvYmpQcm9wcyA9IGdldEFsbEtleXMob2JqZWN0KSwKICAgIG9iakxlbmd0aCA9IG9ialByb3BzLmxlbmd0aCwKICAgIG90aFByb3BzID0gZ2V0QWxsS2V5cyhvdGhlciksCiAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7CiAgaWYgKG9iakxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIWlzUGFydGlhbCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgaW5kZXggPSBvYmpMZW5ndGg7CiAgd2hpbGUgKGluZGV4LS0pIHsKICAgIHZhciBrZXkgPSBvYmpQcm9wc1tpbmRleF07CiAgICBpZiAoIShpc1BhcnRpYWwgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eSQxLmNhbGwob3RoZXIsIGtleSkpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgLy8gQ2hlY2sgdGhhdCBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC4KICB2YXIgb2JqU3RhY2tlZCA9IHN0YWNrLmdldChvYmplY3QpOwogIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTsKICBpZiAob2JqU3RhY2tlZCAmJiBvdGhTdGFja2VkKSB7CiAgICByZXR1cm4gb2JqU3RhY2tlZCA9PSBvdGhlciAmJiBvdGhTdGFja2VkID09IG9iamVjdDsKICB9CiAgdmFyIHJlc3VsdCA9IHRydWU7CiAgc3RhY2suc2V0KG9iamVjdCwgb3RoZXIpOwogIHN0YWNrLnNldChvdGhlciwgb2JqZWN0KTsKICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7CiAgd2hpbGUgKCsraW5kZXggPCBvYmpMZW5ndGgpIHsKICAgIGtleSA9IG9ialByb3BzW2luZGV4XTsKICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLAogICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07CiAgICBpZiAoY3VzdG9taXplcikgewogICAgICB2YXIgY29tcGFyZWQgPSBpc1BhcnRpYWwgPyBjdXN0b21pemVyKG90aFZhbHVlLCBvYmpWYWx1ZSwga2V5LCBvdGhlciwgb2JqZWN0LCBzdGFjaykgOiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSwga2V5LCBvYmplY3QsIG90aGVyLCBzdGFjayk7CiAgICB9CiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS4KICAgIGlmICghKGNvbXBhcmVkID09PSB1bmRlZmluZWQgPyBvYmpWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spIDogY29tcGFyZWQpKSB7CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTsKICB9CiAgaWYgKHJlc3VsdCAmJiAhc2tpcEN0b3IpIHsKICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLAogICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7CgogICAgLy8gTm9uIGBPYmplY3RgIG9iamVjdCBpbnN0YW5jZXMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1YWwuCiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmICdjb25zdHJ1Y3RvcicgaW4gb2JqZWN0ICYmICdjb25zdHJ1Y3RvcicgaW4gb3RoZXIgJiYgISh0eXBlb2Ygb2JqQ3RvciA9PSAnZnVuY3Rpb24nICYmIG9iakN0b3IgaW5zdGFuY2VvZiBvYmpDdG9yICYmIHR5cGVvZiBvdGhDdG9yID09ICdmdW5jdGlvbicgJiYgb3RoQ3RvciBpbnN0YW5jZW9mIG90aEN0b3IpKSB7CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgfQogIH0KICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTsKICBzdGFja1snZGVsZXRlJ10ob3RoZXIpOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi8KdmFyIERhdGFWaWV3ID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ0RhdGFWaWV3Jyk7CnZhciBEYXRhVmlldyQxID0gRGF0YVZpZXc7CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBQcm9taXNlJDEgPSBnZXROYXRpdmUocm9vdCQxLCAnUHJvbWlzZScpOwp2YXIgUHJvbWlzZSQyID0gUHJvbWlzZSQxOwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgU2V0ID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ1NldCcpOwp2YXIgU2V0JDEgPSBTZXQ7CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ1dlYWtNYXAnKTsKdmFyIFdlYWtNYXAkMSA9IFdlYWtNYXA7CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBtYXBUYWckMSA9ICdbb2JqZWN0IE1hcF0nLAogIG9iamVjdFRhZyQxID0gJ1tvYmplY3QgT2JqZWN0XScsCiAgcHJvbWlzZVRhZyA9ICdbb2JqZWN0IFByb21pc2VdJywKICBzZXRUYWckMSA9ICdbb2JqZWN0IFNldF0nLAogIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7CnZhciBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7CgovKiogVXNlZCB0byBkZXRlY3QgbWFwcywgc2V0cywgYW5kIHdlYWttYXBzLiAqLwp2YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXckMSksCiAgbWFwQ3RvclN0cmluZyA9IHRvU291cmNlKE1hcCQxKSwKICBwcm9taXNlQ3RvclN0cmluZyA9IHRvU291cmNlKFByb21pc2UkMiksCiAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCQxKSwKICB3ZWFrTWFwQ3RvclN0cmluZyA9IHRvU291cmNlKFdlYWtNYXAkMSk7CgovKioKICogR2V0cyB0aGUgYHRvU3RyaW5nVGFnYCBvZiBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC4KICovCnZhciBnZXRUYWcgPSBiYXNlR2V0VGFnOwoKLy8gRmFsbGJhY2sgZm9yIGRhdGEgdmlld3MsIG1hcHMsIHNldHMsIGFuZCB3ZWFrIG1hcHMgaW4gSUUgMTEgYW5kIHByb21pc2VzIGluIE5vZGUuanMgPCA2LgppZiAoRGF0YVZpZXckMSAmJiBnZXRUYWcobmV3IERhdGFWaWV3JDEobmV3IEFycmF5QnVmZmVyKDEpKSkgIT0gZGF0YVZpZXdUYWcgfHwgTWFwJDEgJiYgZ2V0VGFnKG5ldyBNYXAkMSgpKSAhPSBtYXBUYWckMSB8fCBQcm9taXNlJDIgJiYgZ2V0VGFnKFByb21pc2UkMi5yZXNvbHZlKCkpICE9IHByb21pc2VUYWcgfHwgU2V0JDEgJiYgZ2V0VGFnKG5ldyBTZXQkMSgpKSAhPSBzZXRUYWckMSB8fCBXZWFrTWFwJDEgJiYgZ2V0VGFnKG5ldyBXZWFrTWFwJDEoKSkgIT0gd2Vha01hcFRhZykgewogIGdldFRhZyA9IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgdmFyIHJlc3VsdCA9IGJhc2VHZXRUYWcodmFsdWUpLAogICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyQxID8gdmFsdWUuY29uc3RydWN0b3IgOiB1bmRlZmluZWQsCiAgICAgIGN0b3JTdHJpbmcgPSBDdG9yID8gdG9Tb3VyY2UoQ3RvcikgOiAnJzsKICAgIGlmIChjdG9yU3RyaW5nKSB7CiAgICAgIHN3aXRjaCAoY3RvclN0cmluZykgewogICAgICAgIGNhc2UgZGF0YVZpZXdDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIGRhdGFWaWV3VGFnOwogICAgICAgIGNhc2UgbWFwQ3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBtYXBUYWckMTsKICAgICAgICBjYXNlIHByb21pc2VDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIHByb21pc2VUYWc7CiAgICAgICAgY2FzZSBzZXRDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIHNldFRhZyQxOwogICAgICAgIGNhc2Ugd2Vha01hcEN0b3JTdHJpbmc6CiAgICAgICAgICByZXR1cm4gd2Vha01hcFRhZzsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9Owp9CnZhciBnZXRUYWckMSA9IGdldFRhZzsKCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckMiA9IDE7CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsCiAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLAogIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5OwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXMKICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhcgogKiByZWZlcmVuY2VzIHRvIGJlIGNvbXBhcmVkLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHsKICB2YXIgb2JqSXNBcnIgPSBpc0FycmF5JDEob2JqZWN0KSwKICAgIG90aElzQXJyID0gaXNBcnJheSQxKG90aGVyKSwKICAgIG9ialRhZyA9IG9iaklzQXJyID8gYXJyYXlUYWcgOiBnZXRUYWckMShvYmplY3QpLAogICAgb3RoVGFnID0gb3RoSXNBcnIgPyBhcnJheVRhZyA6IGdldFRhZyQxKG90aGVyKTsKICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZzsKICBvdGhUYWcgPSBvdGhUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG90aFRhZzsKICB2YXIgb2JqSXNPYmogPSBvYmpUYWcgPT0gb2JqZWN0VGFnLAogICAgb3RoSXNPYmogPSBvdGhUYWcgPT0gb2JqZWN0VGFnLAogICAgaXNTYW1lVGFnID0gb2JqVGFnID09IG90aFRhZzsKICBpZiAoaXNTYW1lVGFnICYmIGlzQnVmZmVyJDEob2JqZWN0KSkgewogICAgaWYgKCFpc0J1ZmZlciQxKG90aGVyKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBvYmpJc0FyciA9IHRydWU7CiAgICBvYmpJc09iaiA9IGZhbHNlOwogIH0KICBpZiAoaXNTYW1lVGFnICYmICFvYmpJc09iaikgewogICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKCkpOwogICAgcmV0dXJuIG9iaklzQXJyIHx8IGlzVHlwZWRBcnJheSQxKG9iamVjdCkgPyBlcXVhbEFycmF5cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTsKICB9CiAgaWYgKCEoYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHJDIpKSB7CiAgICB2YXIgb2JqSXNXcmFwcGVkID0gb2JqSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsICdfX3dyYXBwZWRfXycpLAogICAgICBvdGhJc1dyYXBwZWQgPSBvdGhJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCAnX193cmFwcGVkX18nKTsKICAgIGlmIChvYmpJc1dyYXBwZWQgfHwgb3RoSXNXcmFwcGVkKSB7CiAgICAgIHZhciBvYmpVbndyYXBwZWQgPSBvYmpJc1dyYXBwZWQgPyBvYmplY3QudmFsdWUoKSA6IG9iamVjdCwKICAgICAgICBvdGhVbndyYXBwZWQgPSBvdGhJc1dyYXBwZWQgPyBvdGhlci52YWx1ZSgpIDogb3RoZXI7CiAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjaygpKTsKICAgICAgcmV0dXJuIGVxdWFsRnVuYyhvYmpVbndyYXBwZWQsIG90aFVud3JhcHBlZCwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spOwogICAgfQogIH0KICBpZiAoIWlzU2FtZVRhZykgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2soKSk7CiAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzRXF1YWxgIHdoaWNoIHN1cHBvcnRzIHBhcnRpYWwgY29tcGFyaXNvbnMKICogYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHtib29sZWFufSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLgogKiAgMSAtIFVub3JkZXJlZCBjb21wYXJpc29uCiAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgYW5kIGBvdGhlcmAgb2JqZWN0cy4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGJhc2VJc0VxdWFsKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spIHsKICBpZiAodmFsdWUgPT09IG90aGVyKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAhaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkgewogICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7CiAgfQogIHJldHVybiBiYXNlSXNFcXVhbERlZXAodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBiYXNlSXNFcXVhbCwgc3RhY2spOwp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDEgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMSA9IDI7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC4KICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC4KICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyB0byBtYXRjaC4KICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBpcyBhIG1hdGNoLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhLCBjdXN0b21pemVyKSB7CiAgdmFyIGluZGV4ID0gbWF0Y2hEYXRhLmxlbmd0aCwKICAgIGxlbmd0aCA9IGluZGV4LAogICAgbm9DdXN0b21pemVyID0gIWN1c3RvbWl6ZXI7CiAgaWYgKG9iamVjdCA9PSBudWxsKSB7CiAgICByZXR1cm4gIWxlbmd0aDsKICB9CiAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7CiAgd2hpbGUgKGluZGV4LS0pIHsKICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTsKICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSA/IGRhdGFbMV0gIT09IG9iamVjdFtkYXRhWzBdXSA6ICEoZGF0YVswXSBpbiBvYmplY3QpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdOwogICAgdmFyIGtleSA9IGRhdGFbMF0sCiAgICAgIG9ialZhbHVlID0gb2JqZWN0W2tleV0sCiAgICAgIHNyY1ZhbHVlID0gZGF0YVsxXTsKICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkgewogICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YXIgc3RhY2sgPSBuZXcgU3RhY2soKTsKICAgICAgaWYgKGN1c3RvbWl6ZXIpIHsKICAgICAgICB2YXIgcmVzdWx0ID0gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKTsKICAgICAgfQogICAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZCA/IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgQ09NUEFSRV9QQVJUSUFMX0ZMQUckMSB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMSwgY3VzdG9taXplciwgc3RhY2spIDogcmVzdWx0KSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gdHJ1ZTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0CiAqICBlcXVhbGl0eSBjb21wYXJpc29ucywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7CiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSAmJiAhaXNPYmplY3QodmFsdWUpOwp9CgovKioKICogR2V0cyB0aGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLgogKi8KZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkgewogIHZhciByZXN1bHQgPSBrZXlzKG9iamVjdCksCiAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoOwogIHdoaWxlIChsZW5ndGgtLSkgewogICAgdmFyIGtleSA9IHJlc3VsdFtsZW5ndGhdLAogICAgICB2YWx1ZSA9IG9iamVjdFtrZXldOwogICAgcmVzdWx0W2xlbmd0aF0gPSBba2V5LCB2YWx1ZSwgaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKV07CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYG1hdGNoZXNQcm9wZXJ0eWAgZm9yIHNvdXJjZSB2YWx1ZXMgc3VpdGFibGUKICogZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUoa2V5LCBzcmNWYWx1ZSkgewogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0KSB7CiAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZSAmJiAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCBrZXkgaW4gT2JqZWN0KG9iamVjdCkpOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzYCB3aGljaCBkb2Vzbid0IGNsb25lIGBzb3VyY2VgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7CiAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpOwogIGlmIChtYXRjaERhdGEubGVuZ3RoID09IDEgJiYgbWF0Y2hEYXRhWzBdWzJdKSB7CiAgICByZXR1cm4gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUobWF0Y2hEYXRhWzBdWzBdLCBtYXRjaERhdGFbMF1bMV0pOwogIH0KICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBtYXRjaERhdGEpOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5oYXNJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSGFzSW4ob2JqZWN0LCBrZXkpIHsKICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYga2V5IGluIE9iamVjdChvYmplY3QpOwp9CgovKioKICogQ2hlY2tzIGlmIGBwYXRoYCBleGlzdHMgb24gYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suCiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrIHByb3BlcnRpZXMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgaGFzRnVuYykgewogIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpOwogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gcGF0aC5sZW5ndGgsCiAgICByZXN1bHQgPSBmYWxzZTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKTsKICAgIGlmICghKHJlc3VsdCA9IG9iamVjdCAhPSBudWxsICYmIGhhc0Z1bmMob2JqZWN0LCBrZXkpKSkgewogICAgICBicmVhazsKICAgIH0KICAgIG9iamVjdCA9IG9iamVjdFtrZXldOwogIH0KICBpZiAocmVzdWx0IHx8ICsraW5kZXggIT0gbGVuZ3RoKSB7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICBsZW5ndGggPSBvYmplY3QgPT0gbnVsbCA/IDAgOiBvYmplY3QubGVuZ3RoOwogIHJldHVybiAhIWxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpICYmIChpc0FycmF5JDEob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyQxKG9iamVjdCkpOwp9CgovKioKICogQ2hlY2tzIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgb2YgYG9iamVjdGAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBPYmplY3QKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IF8uY3JlYXRlKHsgJ2EnOiBfLmNyZWF0ZSh7ICdiJzogMiB9KSB9KTsKICoKICogXy5oYXNJbihvYmplY3QsICdhJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5oYXNJbihvYmplY3QsICdhLmInKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmhhc0luKG9iamVjdCwgWydhJywgJ2InXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5oYXNJbihvYmplY3QsICdiJyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBoYXNJbihvYmplY3QsIHBhdGgpIHsKICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzUGF0aChvYmplY3QsIHBhdGgsIGJhc2VIYXNJbik7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lc24ndCBjbG9uZSBgc3JjVmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VNYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHsKICBpZiAoaXNLZXkocGF0aCkgJiYgaXNTdHJpY3RDb21wYXJhYmxlKHNyY1ZhbHVlKSkgewogICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKHRvS2V5KHBhdGgpLCBzcmNWYWx1ZSk7CiAgfQogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0KSB7CiAgICB2YXIgb2JqVmFsdWUgPSBnZXQob2JqZWN0LCBwYXRoKTsKICAgIHJldHVybiBvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmIG9ialZhbHVlID09PSBzcmNWYWx1ZSA/IGhhc0luKG9iamVjdCwgcGF0aCkgOiBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIENPTVBBUkVfUEFSVElBTF9GTEFHIHwgQ09NUEFSRV9VTk9SREVSRURfRkxBRyk7CiAgfTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07CiAgfTsKfQoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVByb3BlcnR5YCB3aGljaCBzdXBwb3J0cyBkZWVwIHBhdGhzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eURlZXAocGF0aCkgewogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0KSB7CiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgpOwogIH07Cn0KCi8qKgogKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDIuNC4wCiAqIEBjYXRlZ29yeSBVdGlsCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0cyA9IFsKICogICB7ICdhJzogeyAnYic6IDIgfSB9LAogKiAgIHsgJ2EnOiB7ICdiJzogMSB9IH0KICogXTsKICoKICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iJykpOwogKiAvLyA9PiBbMiwgMV0KICoKICogXy5tYXAoXy5zb3J0Qnkob2JqZWN0cywgXy5wcm9wZXJ0eShbJ2EnLCAnYiddKSksICdhLmInKTsKICogLy8gPT4gWzEsIDJdCiAqLwpmdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7CiAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHRvS2V5KHBhdGgpKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pdGVyYXRlZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gW3ZhbHVlPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGFuIGl0ZXJhdGVlLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGl0ZXJhdGVlLgogKi8KZnVuY3Rpb24gYmFzZUl0ZXJhdGVlKHZhbHVlKSB7CiAgLy8gRG9uJ3Qgc3RvcmUgdGhlIGB0eXBlb2ZgIHJlc3VsdCBpbiBhIHZhcmlhYmxlIHRvIGF2b2lkIGEgSklUIGJ1ZyBpbiBTYWZhcmkgOS4KICAvLyBTZWUgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE1NjAzNCBmb3IgbW9yZSBkZXRhaWxzLgogIGlmICh0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJykgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgcmV0dXJuIGlkZW50aXR5JDE7CiAgfQogIGlmICh0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpIHsKICAgIHJldHVybiBpc0FycmF5JDEodmFsdWUpID8gYmFzZU1hdGNoZXNQcm9wZXJ0eSh2YWx1ZVswXSwgdmFsdWVbMV0pIDogYmFzZU1hdGNoZXModmFsdWUpOwogIH0KICByZXR1cm4gcHJvcGVydHkodmFsdWUpOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWFwYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LgogKi8KZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTsKICBiYXNlRWFjaCQxKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7CiAgICByZXN1bHRbKytpbmRleF0gPSBpdGVyYXRlZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKTsKICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB2YWx1ZXMgYnkgcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIHRocnUKICogYGl0ZXJhdGVlYC4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6CiAqICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS4KICoKICogTWFueSBsb2Rhc2ggbWV0aG9kcyBhcmUgZ3VhcmRlZCB0byB3b3JrIGFzIGl0ZXJhdGVlcyBmb3IgbWV0aG9kcyBsaWtlCiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLgogKgogKiBUaGUgZ3VhcmRlZCBtZXRob2RzIGFyZToKICogYGFyeWAsIGBjaHVua2AsIGBjdXJyeWAsIGBjdXJyeVJpZ2h0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGV2ZXJ5YCwKICogYGZpbGxgLCBgaW52ZXJ0YCwgYHBhcnNlSW50YCwgYHJhbmRvbWAsIGByYW5nZWAsIGByYW5nZVJpZ2h0YCwgYHJlcGVhdGAsCiAqIGBzYW1wbGVTaXplYCwgYHNsaWNlYCwgYHNvbWVgLCBgc29ydEJ5YCwgYHNwbGl0YCwgYHRha2VgLCBgdGFrZVJpZ2h0YCwKICogYHRlbXBsYXRlYCwgYHRyaW1gLCBgdHJpbUVuZGAsIGB0cmltU3RhcnRgLCBhbmQgYHdvcmRzYAogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbgogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuCiAqIEBleGFtcGxlCiAqCiAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7CiAqICAgcmV0dXJuIG4gKiBuOwogKiB9CiAqCiAqIF8ubWFwKFs0LCA4XSwgc3F1YXJlKTsKICogLy8gPT4gWzE2LCA2NF0KICoKICogXy5tYXAoeyAnYSc6IDQsICdiJzogOCB9LCBzcXVhcmUpOwogKiAvLyA9PiBbMTYsIDY0XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKQogKgogKiB2YXIgdXNlcnMgPSBbCiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sCiAqICAgeyAndXNlcic6ICdmcmVkJyB9CiAqIF07CiAqCiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLgogKiBfLm1hcCh1c2VycywgJ3VzZXInKTsKICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddCiAqLwpmdW5jdGlvbiBtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHsKICB2YXIgZnVuYyA9IGlzQXJyYXkkMShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDsKICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBiYXNlSXRlcmF0ZWUoaXRlcmF0ZWUpKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnN1bWAgYW5kIGBfLnN1bUJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yCiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS4KICovCmZ1bmN0aW9uIGJhc2VTdW0oYXJyYXksIGl0ZXJhdGVlKSB7CiAgdmFyIHJlc3VsdCwKICAgIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBjdXJyZW50ID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdKTsKICAgIGlmIChjdXJyZW50ICE9PSB1bmRlZmluZWQpIHsKICAgICAgcmVzdWx0ID0gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBjdXJyZW50IDogcmVzdWx0ICsgY3VycmVudDsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENvbXB1dGVzIHRoZSBzdW0gb2YgdGhlIHZhbHVlcyBpbiBgYXJyYXlgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAzLjQuMAogKiBAY2F0ZWdvcnkgTWF0aAogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uCiAqIEBleGFtcGxlCiAqCiAqIF8uc3VtKFs0LCAyLCA4LCA2XSk7CiAqIC8vID0+IDIwCiAqLwpmdW5jdGlvbiBzdW0kMShhcnJheSkgewogIHJldHVybiBhcnJheSAmJiBhcnJheS5sZW5ndGggPyBiYXNlU3VtKGFycmF5LCBpZGVudGl0eSQxKSA6IDA7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3RyaW5nYCBwcmltaXRpdmUgb3Igb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzdHJpbmcsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc1N0cmluZygnYWJjJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc1N0cmluZygxKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCAhaXNBcnJheSQxKHZhbHVlKSAmJiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHN0cmluZ1RhZzsKfQoKLyoqCiAqIEdldHMgdGhlIHNpemUgb2YgYW4gQVNDSUkgYHN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS4KICovCnZhciBhc2NpaVNpemUgPSBiYXNlUHJvcGVydHkoJ2xlbmd0aCcpOwp2YXIgYXNjaWlTaXplJDEgPSBhc2NpaVNpemU7CgovKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2hhcmFjdGVyIGNsYXNzZXMuICovCnZhciByc0FzdHJhbFJhbmdlJDEgPSAnXFx1ZDgwMC1cXHVkZmZmJywKICByc0NvbWJvTWFya3NSYW5nZSQxID0gJ1xcdTAzMDAtXFx1MDM2ZicsCiAgcmVDb21ib0hhbGZNYXJrc1JhbmdlJDEgPSAnXFx1ZmUyMC1cXHVmZTJmJywKICByc0NvbWJvU3ltYm9sc1JhbmdlJDEgPSAnXFx1MjBkMC1cXHUyMGZmJywKICByc0NvbWJvUmFuZ2UkMSA9IHJzQ29tYm9NYXJrc1JhbmdlJDEgKyByZUNvbWJvSGFsZk1hcmtzUmFuZ2UkMSArIHJzQ29tYm9TeW1ib2xzUmFuZ2UkMSwKICByc1ZhclJhbmdlJDEgPSAnXFx1ZmUwZVxcdWZlMGYnOwoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNhcHR1cmUgZ3JvdXBzLiAqLwp2YXIgcnNaV0okMSA9ICdcXHUyMDBkJzsKCi8qKiBVc2VkIHRvIGRldGVjdCBzdHJpbmdzIHdpdGggW3plcm8td2lkdGggam9pbmVycyBvciBjb2RlIHBvaW50cyBmcm9tIHRoZSBhc3RyYWwgcGxhbmVzXShodHRwOi8vZWV2LmVlL2Jsb2cvMjAxNS8wOS8xMi9kYXJrLWNvcm5lcnMtb2YtdW5pY29kZS8pLiAqLwp2YXIgcmVIYXNVbmljb2RlID0gUmVnRXhwKCdbJyArIHJzWldKJDEgKyByc0FzdHJhbFJhbmdlJDEgKyByc0NvbWJvUmFuZ2UkMSArIHJzVmFyUmFuZ2UkMSArICddJyk7CgovKioKICogQ2hlY2tzIGlmIGBzdHJpbmdgIGNvbnRhaW5zIFVuaWNvZGUgc3ltYm9scy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHN5bWJvbCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzVW5pY29kZShzdHJpbmcpIHsKICByZXR1cm4gcmVIYXNVbmljb2RlLnRlc3Qoc3RyaW5nKTsKfQoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNoYXJhY3RlciBjbGFzc2VzLiAqLwp2YXIgcnNBc3RyYWxSYW5nZSA9ICdcXHVkODAwLVxcdWRmZmYnLAogIHJzQ29tYm9NYXJrc1JhbmdlID0gJ1xcdTAzMDAtXFx1MDM2ZicsCiAgcmVDb21ib0hhbGZNYXJrc1JhbmdlID0gJ1xcdWZlMjAtXFx1ZmUyZicsCiAgcnNDb21ib1N5bWJvbHNSYW5nZSA9ICdcXHUyMGQwLVxcdTIwZmYnLAogIHJzQ29tYm9SYW5nZSA9IHJzQ29tYm9NYXJrc1JhbmdlICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlICsgcnNDb21ib1N5bWJvbHNSYW5nZSwKICByc1ZhclJhbmdlID0gJ1xcdWZlMGVcXHVmZTBmJzsKCi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi8KdmFyIHJzQXN0cmFsID0gJ1snICsgcnNBc3RyYWxSYW5nZSArICddJywKICByc0NvbWJvID0gJ1snICsgcnNDb21ib1JhbmdlICsgJ10nLAogIHJzRml0eiA9ICdcXHVkODNjW1xcdWRmZmItXFx1ZGZmZl0nLAogIHJzTW9kaWZpZXIgPSAnKD86JyArIHJzQ29tYm8gKyAnfCcgKyByc0ZpdHogKyAnKScsCiAgcnNOb25Bc3RyYWwgPSAnW14nICsgcnNBc3RyYWxSYW5nZSArICddJywKICByc1JlZ2lvbmFsID0gJyg/OlxcdWQ4M2NbXFx1ZGRlNi1cXHVkZGZmXSl7Mn0nLAogIHJzU3VyclBhaXIgPSAnW1xcdWQ4MDAtXFx1ZGJmZl1bXFx1ZGMwMC1cXHVkZmZmXScsCiAgcnNaV0ogPSAnXFx1MjAwZCc7CgovKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgcmVnZXhlcy4gKi8KdmFyIHJlT3B0TW9kID0gcnNNb2RpZmllciArICc/JywKICByc09wdFZhciA9ICdbJyArIHJzVmFyUmFuZ2UgKyAnXT8nLAogIHJzT3B0Sm9pbiA9ICcoPzonICsgcnNaV0ogKyAnKD86JyArIFtyc05vbkFzdHJhbCwgcnNSZWdpb25hbCwgcnNTdXJyUGFpcl0uam9pbignfCcpICsgJyknICsgcnNPcHRWYXIgKyByZU9wdE1vZCArICcpKicsCiAgcnNTZXEgPSByc09wdFZhciArIHJlT3B0TW9kICsgcnNPcHRKb2luLAogIHJzU3ltYm9sID0gJyg/OicgKyBbcnNOb25Bc3RyYWwgKyByc0NvbWJvICsgJz8nLCByc0NvbWJvLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyLCByc0FzdHJhbF0uam9pbignfCcpICsgJyknOwoKLyoqIFVzZWQgdG8gbWF0Y2ggW3N0cmluZyBzeW1ib2xzXShodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC11bmljb2RlKS4gKi8KdmFyIHJlVW5pY29kZSA9IFJlZ0V4cChyc0ZpdHogKyAnKD89JyArIHJzRml0eiArICcpfCcgKyByc1N5bWJvbCArIHJzU2VxLCAnZycpOwoKLyoqCiAqIEdldHMgdGhlIHNpemUgb2YgYSBVbmljb2RlIGBzdHJpbmdgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuCiAqLwpmdW5jdGlvbiB1bmljb2RlU2l6ZShzdHJpbmcpIHsKICB2YXIgcmVzdWx0ID0gcmVVbmljb2RlLmxhc3RJbmRleCA9IDA7CiAgd2hpbGUgKHJlVW5pY29kZS50ZXN0KHN0cmluZykpIHsKICAgICsrcmVzdWx0OwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogR2V0cyB0aGUgbnVtYmVyIG9mIHN5bWJvbHMgaW4gYHN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS4KICovCmZ1bmN0aW9uIHN0cmluZ1NpemUoc3RyaW5nKSB7CiAgcmV0dXJuIGhhc1VuaWNvZGUoc3RyaW5nKSA/IHVuaWNvZGVTaXplKHN0cmluZykgOiBhc2NpaVNpemUkMShzdHJpbmcpOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBtYXBUYWcgPSAnW29iamVjdCBNYXBdJywKICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJzsKCi8qKgogKiBHZXRzIHRoZSBzaXplIG9mIGBjb2xsZWN0aW9uYCBieSByZXR1cm5pbmcgaXRzIGxlbmd0aCBmb3IgYXJyYXktbGlrZQogKiB2YWx1ZXMgb3IgdGhlIG51bWJlciBvZiBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBmb3Igb2JqZWN0cy4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IENvbGxlY3Rpb24KICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbGxlY3Rpb24gc2l6ZS4KICogQGV4YW1wbGUKICoKICogXy5zaXplKFsxLCAyLCAzXSk7CiAqIC8vID0+IDMKICoKICogXy5zaXplKHsgJ2EnOiAxLCAnYic6IDIgfSk7CiAqIC8vID0+IDIKICoKICogXy5zaXplKCdwZWJibGVzJyk7CiAqIC8vID0+IDcKICovCmZ1bmN0aW9uIHNpemUoY29sbGVjdGlvbikgewogIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHsKICAgIHJldHVybiAwOwogIH0KICBpZiAoaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHsKICAgIHJldHVybiBpc1N0cmluZyhjb2xsZWN0aW9uKSA/IHN0cmluZ1NpemUoY29sbGVjdGlvbikgOiBjb2xsZWN0aW9uLmxlbmd0aDsKICB9CiAgdmFyIHRhZyA9IGdldFRhZyQxKGNvbGxlY3Rpb24pOwogIGlmICh0YWcgPT0gbWFwVGFnIHx8IHRhZyA9PSBzZXRUYWcpIHsKICAgIHJldHVybiBjb2xsZWN0aW9uLnNpemU7CiAgfQogIHJldHVybiBiYXNlS2V5cyhjb2xsZWN0aW9uKS5sZW5ndGg7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTnVtYmVyYCBwcmltaXRpdmUgb3Igb2JqZWN0LgogKgogKiAqKk5vdGU6KiogVG8gZXhjbHVkZSBgSW5maW5pdHlgLCBgLUluZmluaXR5YCwgYW5kIGBOYU5gLCB3aGljaCBhcmUKICogY2xhc3NpZmllZCBhcyBudW1iZXJzLCB1c2UgdGhlIGBfLmlzRmluaXRlYCBtZXRob2QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG51bWJlciwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzTnVtYmVyKDMpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNOdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc051bWJlcihJbmZpbml0eSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc051bWJlcignMycpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNOdW1iZXIodmFsdWUpIHsKICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInIHx8IGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gbnVtYmVyVGFnOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuueJqeS7tg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzb2JqLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc29iaih7fSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNvYmooeyBhOiAxMjMgfSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzb2JqKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgT2JqZWN0XSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pyJ5pWI54mp5Lu2DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNvYmoudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZW9iaih7fSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZW9iaih7IGE6IDEyMyB9KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNlb2JqKHYpIHsKICBpZiAoaXNvYmoodikpIHsKICAgIGZvciAobGV0IGsgaW4gdikgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuumZo+WIlw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzYXJyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2FycihbXSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNhcnIoW3t9XSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzYXJyKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgQXJyYXldJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrp1bmRlZmluZWQNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc3VuZGVmaW5lZC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXN1bmRlZmluZWQodW5kZWZpbmVkKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXN1bmRlZmluZWQodikgewogIGxldCBjID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpOwogIHJldHVybiBjID09PSAnW29iamVjdCBVbmRlZmluZWRdJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrpudWxsDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNudWxsLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bGwobnVsbCkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzbnVsbCh2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IE51bGxdJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnqbrnianku7YNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc29iajAudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzb2JqMCh7fSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNvYmowKHsgYTogMTIzIH0pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKi8KZnVuY3Rpb24gaXNvYmowKHYpIHsKICBpZiAoaXNvYmoodikpIHsKICAgIGZvciAobGV0IGsgaW4gdikgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuepuuWtl+S4sg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzc3RyMC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIwKCcnKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc3N0cjAoJzAnKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIwKCdhYmMxMjUnKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzc3RyMCh2KSB7CiAgaWYgKGlzc3RyKHYpKSB7CiAgICBpZiAodiA9PT0gJycpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnhKHlhaflrrnpmaPliJcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2FycjAudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzYXJyKFtdKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2Fycihbe31dKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzYXJyMCh2KSB7CiAgaWYgKGlzYXJyKHYpKSB7CiAgICBpZiAodi5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLy8gaW1wb3J0IGlzTmFOIGZyb20gJ2xvZGFzaC1lcy9pc05hTi5qcycKCi8qKg0KICog5Yik5pa35piv5ZCm54K6TmFODQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNuYW4udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbmFuKE5hTikpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzbmFuKHYpIHsKICAvLyByZXR1cm4gaXNOYU4odikKICByZXR1cm4gdiAhPT0gdjsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrlu6PnvqnnhKHmlYgNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2VyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKCcxMmE1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoJycpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoW10pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoW3t9XSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoWycnXSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoe30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIobnVsbCkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNlcih1bmRlZmluZWQpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoTmFOKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNlcih2KSB7CiAgaWYgKGlzdW5kZWZpbmVkKHYpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKGlzbnVsbCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc29iajAodikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICBpZiAoaXNzdHIwKHYpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKGlzYXJyMCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc25hbih2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrmnInmlYjpmaPliJfvvIzplbfluqboh7PlsJHlpKfmlrznrYnmlrwx77yM5ZCE5YWD57Sg6Iez5bCR55qG54K65pyJ5pWIDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNlYXJyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VhcnIoW3t9XSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZWFycihbeyBhOiAxMjMgfV0pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2VhcnIodikgewogIC8vY2hlY2sKICBpZiAoIWlzYXJyKHYpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICAvL2NoZWNrIGxlbmd0aAogIGlmICh2Lmxlbmd0aCA9PT0gMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy9jaGVjayBsZW5ndGg9MQogIGlmICh2Lmxlbmd0aCA9PT0gMSkgewogICAgaWYgKGlzZXIodlswXSkpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogIH0KICByZXR1cm4gdHJ1ZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrmlbjlrZcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc25ici50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNuYnIoMS4yNSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNuYnIoJzEuMjUnKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzbmJyKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgTnVtYmVyXSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pW45a2XDQogKg0KICog5rOo5oSP77ya5pys5Ye95byP5LiN5pSv5o+0QmlnSW5077yMdHlwZW9mIEJpZ0ludOWAvOeCuidiaWdpbnQn6ICM6Z2eJ251bWJlcifmlYVpc25icuWIpOWumueCumZhbHNl44CCDQogKiBCaWdJbnToiIdOdW1iZXLlnKhKU+eCuuS6kuS4jeebuOWuueeahOeul+ihk+WfnyhgMW4gKyAxYOOAgWBNYXRoLmZsb29yKDFuKWAg55qG5pOyVHlwZUVycm9yKe+8jA0KICog6ICMaXNudW3nmoTpmrHlkKvlpZHntITmmK/jgIzpgJrpgY7lvozlj6/lgZpOdW1iZXLnrpfooZPpgYvnrpfjgI3vvIx3c2VtaeWFp+mAvjYw6JmVY2FsbHNpdGXkvp3os7TmraTlpZHntIQNCiAqICjlpoJhcnJNYXgvYXJyTWluL3JvdW5kL3JhbmRvbVJhbmdl562JKe+8jOiLpeaUvuWvrGlzbnVt6KqNQmlnSW505bCH5bCO6Ie06YCZ5LqbY2FsbHNpdGXln7fooYzmnJ/pjK/oqqTjgIINCiAqIOatpOioreioiOiIh2xvZGFzaCBgXy5pc051bWJlcmAg5bCHQmlnSW505o6S6Zmk55qE6JmV55CG5LiA6Ie044CCQmlnSW506KuL5Y+m5L2c542o56uL5Yik5pa344CCDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNudW0udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKDApKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKDEuMjUpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKCctMTI1JykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNudW0oMTIzbikpDQogKiAvLyA9PiBmYWxzZSAoQmlnSW505LiN6KKr6KaW54K65pW45a2XLCDoqbPopovkuIrmlrnoqqrmmI4pDQogKg0KICovCmZ1bmN0aW9uIGlzbnVtKHYpIHsKICBsZXQgYiA9IGZhbHNlOwogIGlmIChpc2VzdHIodikpIHsKICAgIGIgPSAhaXNOYU4oTnVtYmVyKHYpKTsKICB9IGVsc2UgaWYgKGlzbmJyKHYpKSB7CiAgICAvL+azqOaEj05hTueCuk51bWJlciwg5pWFaXNuYnLlm57lgrN0cnVlCiAgICBpZiAoaXNuYW4odikpIHsKICAgICAgcmV0dXJuIGZhbHNlOyAvL+atpOiZleWIpOWumueCuuacieaViOaVuOWtlywg5pWFTmFO6aCI5YmU6ZmkCiAgICB9IGVsc2UgewogICAgICBiID0gdHJ1ZTsKICAgIH0KICB9CiAgcmV0dXJuIGI7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65Ye95pW4DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNmdW4udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZnVuKCcxLjI1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZnVuKGZ1bmN0aW9uKCkge30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2Z1bih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScgfHwgYyA9PT0gJ1tvYmplY3QgQXN5bmNGdW5jdGlvbl0nOwp9CgovKiogVXNlZCB0byBtYXRjaCBhIHNpbmdsZSB3aGl0ZXNwYWNlIGNoYXJhY3Rlci4gKi8KdmFyIHJlV2hpdGVzcGFjZSA9IC9ccy87CgovKioKICogVXNlZCBieSBgXy50cmltYCBhbmQgYF8udHJpbUVuZGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZQogKiBjaGFyYWN0ZXIgb2YgYHN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIuCiAqLwpmdW5jdGlvbiB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSB7CiAgdmFyIGluZGV4ID0gc3RyaW5nLmxlbmd0aDsKICB3aGlsZSAoaW5kZXgtLSAmJiByZVdoaXRlc3BhY2UudGVzdChzdHJpbmcuY2hhckF0KGluZGV4KSkpIHt9CiAgcmV0dXJuIGluZGV4Owp9CgovKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIHdoaXRlc3BhY2UuICovCnZhciByZVRyaW1TdGFydCA9IC9eXHMrLzsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50cmltYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHRyaW0uCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHRyaW1tZWQgc3RyaW5nLgogKi8KZnVuY3Rpb24gYmFzZVRyaW0oc3RyaW5nKSB7CiAgcmV0dXJuIHN0cmluZyA/IHN0cmluZy5zbGljZSgwLCB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSArIDEpLnJlcGxhY2UocmVUcmltU3RhcnQsICcnKSA6IHN0cmluZzsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBOQU4kMSA9IDAgLyAwOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi8KdmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTsKCi8qKiBVc2VkIHRvIGRldGVjdCBiaW5hcnkgc3RyaW5nIHZhbHVlcy4gKi8KdmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7CgovKiogVXNlZCB0byBkZXRlY3Qgb2N0YWwgc3RyaW5nIHZhbHVlcy4gKi8KdmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7CgovKiogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgd2l0aG91dCBhIGRlcGVuZGVuY3kgb24gYHJvb3RgLiAqLwp2YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLgogKiBAZXhhbXBsZQogKgogKiBfLnRvTnVtYmVyKDMuMik7CiAqIC8vID0+IDMuMgogKgogKiBfLnRvTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpOwogKiAvLyA9PiA1ZS0zMjQKICoKICogXy50b051bWJlcihJbmZpbml0eSk7CiAqIC8vID0+IEluZmluaXR5CiAqCiAqIF8udG9OdW1iZXIoJzMuMicpOwogKiAvLyA9PiAzLjIKICovCmZ1bmN0aW9uIHRvTnVtYmVyKHZhbHVlKSB7CiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7CiAgICByZXR1cm4gTkFOJDE7CiAgfQogIGlmIChpc09iamVjdCh2YWx1ZSkpIHsKICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTsKICAgIHZhbHVlID0gaXNPYmplY3Qob3RoZXIpID8gb3RoZXIgKyAnJyA6IG90aGVyOwogIH0KICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7CiAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6ICt2YWx1ZTsKICB9CiAgdmFsdWUgPSBiYXNlVHJpbSh2YWx1ZSk7CiAgdmFyIGlzQmluYXJ5ID0gcmVJc0JpbmFyeS50ZXN0KHZhbHVlKTsKICByZXR1cm4gaXNCaW5hcnkgfHwgcmVJc09jdGFsLnRlc3QodmFsdWUpID8gZnJlZVBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCBpc0JpbmFyeSA/IDIgOiA4KSA6IHJlSXNCYWRIZXgudGVzdCh2YWx1ZSkgPyBOQU4kMSA6ICt2YWx1ZTsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBJTkZJTklUWSA9IDEgLyAwLAogIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDg7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMTIuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgbnVtYmVyLgogKiBAZXhhbXBsZQogKgogKiBfLnRvRmluaXRlKDMuMik7CiAqIC8vID0+IDMuMgogKgogKiBfLnRvRmluaXRlKE51bWJlci5NSU5fVkFMVUUpOwogKiAvLyA9PiA1ZS0zMjQKICoKICogXy50b0Zpbml0ZShJbmZpbml0eSk7CiAqIC8vID0+IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4CiAqCiAqIF8udG9GaW5pdGUoJzMuMicpOwogKiAvLyA9PiAzLjIKICovCmZ1bmN0aW9uIHRvRmluaXRlKHZhbHVlKSB7CiAgaWYgKCF2YWx1ZSkgewogICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwOwogIH0KICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTsKICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHsKICAgIHZhciBzaWduID0gdmFsdWUgPCAwID8gLTEgOiAxOwogICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjsKICB9CiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDsKfQoKLyoqDQogKiDmlbjlrZfmiJblrZfkuLLovYnmta7pu57mlbgNCiAqIOiLpei8uOWFpemdnuaVuOWtl+WJh+WbnuWCszANCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9jZGJsLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHtOdW1iZXJ8U3RyaW5nfSB2IOi8uOWFpeaVuOWtl+aIluWtl+S4sg0KICogQHJldHVybnMge051bWJlcn0g5Zue5YKz5pW45a2XDQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGNkYmwoJzI1JykpDQogKiAvLyA9PiAyNQ0KICoNCiAqLwpmdW5jdGlvbiBjZGJsKHYpIHsKICAvL2NoZWNrCiAgaWYgKCFpc251bSh2KSkgewogICAgcmV0dXJuIDA7CiAgfQogIGxldCByID0gdG9GaW5pdGUodik7CiAgcmV0dXJuIHI7Cn0KCi8qKg0KICog5Yik5pa354mp5Lu25piv5ZCm5pyJa2V55bGs5oCnDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaGFza2V5LnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHtPYmplY3R9IG9iaiDovLjlhaXnianku7YNCiAqIEBwYXJhbSB7U3RyaW5nfSBrZXkg6Ly45YWl6KaB5p+l5om+55qEa2V55a2X5LiyDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGhhc2tleSh7IGE6IDEyMywgYjogJ3h5eicsIGM6ICc0NW9wJywgZDogbnVsbCB9LCAnYScpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBoYXNrZXkob2JqLCBrZXkpIHsKICAvL2NoZWNrCiAgaWYgKCFpc29iaihvYmopKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIGlmICghaXNlc3RyKGtleSkgJiYgIWlzbnVtKGtleSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgcmV0dXJuIGtleSBpbiBvYmo7Cn0KCi8qKg0KICog5o+Q5Y+W6bue6Zmj5YiX5YWn5LmL6bueWzAsMV3miJZ7eCx5feaIluaMh+WumumNteWAvOaIkOeCuum7nnt4LHl954mp5Lu26Zmj5YiXDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvcHRzWFl0b0Fyci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzIOi8uOWFpem7numZo+WIl++8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiX77yM5oiWW1t4MSx5MV0sW3gyLHkyXSwuLi5d6bue5bqn5qiZ6Zmj5YiX5LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7Z45bqn5qiZ6Y215a2X5Liy77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu2eeW6p+aomemNteWtl+S4su+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5SW5kPSdpbmQnXSDovLjlhaXpu57nianku7bmjIfmqJnpjbXlrZfkuLLvvIzpoJDoqK0naW5kJw0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnJldHVybk9iakFycmF5PXRydWVdIOi8uOWFpeaYr+WQpuWbnuWCs+eJqeS7tumZo+WIl++8jOiLpXRydWXku6Pooajlm57lgrPpu57ngrrnianku7Z7eCx5feS5i+mZo+WIl++8jOiLpWZhbHNl5Zue5YKz6bue6Zmj5YiXW3gseV3kuYvpmaPliJfvvIzpoJDoqK10cnVlDQogKiBAcmV0dXJucyB7QXJyYXl9IOWbnuWCs+m7numZo+WIlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCByDQogKg0KICogcHMgPSBbWzI0MywgMjA2XSwgWzIzMywgMjI1XSwgWzIxLCAzMjVdXQ0KICogciA9IHB0c1hZdG9BcnIocHMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7ICd4JzogMjQzLCAneSc6IDIwNiB9LCB7ICd4JzogMjMzLCAneSc6IDIyNSB9LCB7ICd4JzogMjEsICd5JzogMzI1IH1dDQogKiByID0gcHRzWFl0b0FycihwcykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDYsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCBpbmQ6IDEgfSwNCiAqIC8vICAgeyB4OiAyMSwgeTogMzI1LCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgJ2EnOiAyNDMsICdiJzogMjA2IH0sIHsgJ2EnOiAyMzMsICdiJzogMjI1IH0sIHsgJ2EnOiAyMSwgJ2InOiAzMjUgfV0NCiAqIHIgPSBwdHNYWXRvQXJyKHBzLCB7IGtleVg6ICdhJywga2V5WTogJ2InIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKi8KZnVuY3Rpb24gcHRzWFl0b0Fycihwcywgb3B0ID0ge30pIHsKICAvL+iLpeeEoeaVuOaTmuWbnuWCs+epuumZo+WIlwogIGlmIChzaXplKHBzKSA8PSAwKSB7CiAgICByZXR1cm4gW107CiAgfQoKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleUluZAogIGxldCBrZXlJbmQgPSBnZXQob3B0LCAna2V5SW5kJywgJycpOwogIGlmICghaXNlc3RyKGtleUluZCkpIHsKICAgIGtleUluZCA9ICdpbmQnOwogIH0KCiAgLy9yZXR1cm5PYmpBcnJheQogIGxldCByZXR1cm5PYmpBcnJheSA9IGdldChvcHQsICdyZXR1cm5PYmpBcnJheScpOwogIGlmICghaXNib2wocmV0dXJuT2JqQXJyYXkpKSB7CiAgICByZXR1cm5PYmpBcnJheSA9IHRydWU7CiAgfQoKICAvL3JzCiAgbGV0IHJzID0gW107CiAgZm9yRWFjaChwcywgKHYsIGspID0+IHsKICAgIGxldCB4ID0gbnVsbDsKICAgIGxldCB5ID0gbnVsbDsKICAgIGlmIChpc2Fycih2KSAmJiBzaXplKHYpID49IDIpIHsKICAgICAgeCA9IGdldCh2LCAwKTsKICAgICAgeSA9IGdldCh2LCAxKTsKICAgIH0gZWxzZSB7CiAgICAgIHggPSBnZXQodiwga2V5WCwgbnVsbCk7CiAgICAgIHkgPSBnZXQodiwga2V5WSwgbnVsbCk7CiAgICB9CiAgICBpZiAoaXNudW0oeCkgJiYgaXNudW0oeSkpIHsKICAgICAgeCA9IHRvTnVtYmVyKHgpOwogICAgICB5ID0gdG9OdW1iZXIoeSk7CiAgICAgIHJzLnB1c2goewogICAgICAgIHgsCiAgICAgICAgeSwKICAgICAgICBba2V5SW5kXTogawogICAgICB9KTsKICAgIH0KICB9KTsKCiAgLy9yZXR1cm5PYmpBcnJheQogIGlmICghcmV0dXJuT2JqQXJyYXkpIHsKICAgIHJzID0gbWFwKHJzLCB2ID0+IHsKICAgICAgcmV0dXJuIFt2LngsIHYueSwgdltrZXlJbmRdXTsKICAgIH0pOwogIH0KICByZXR1cm4gcnM7Cn0KCi8qKg0KICog5o+Q5Y+W6bue6Zmj5YiX5YWn5LmL6bueWzAsMSwyXeaIlnt4LHksen3miJbmjIflrprpjbXlgLzmiJDngrrpu557eCx5LHp954mp5Lu26Zmj5YiXDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvcHRzWFladG9BcnIudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwcyDovLjlhaXpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MSx6OnoxfSx7eDp4Mix5OnkyLHo6ejJ9LC4uLl3pu57nianku7bkuYvpmaPliJfvvIzmiJZbW3gxLHkxLHoxXSxbeDIseTIsejJdLC4uLl3pu57luqfmqJnpmaPliJfkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tnjluqfmqJnpjbXlrZfkuLLvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7Z55bqn5qiZ6Y215a2X5Liy77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd6J10g6Ly45YWl6bue54mp5Lu2euW6p+aomemNteWtl+S4su+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5SW5kPSdpbmQnXSDovLjlhaXpu57nianku7bmjIfmqJnpjbXlrZfkuLLvvIzpoJDoqK0naW5kJw0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnJldHVybk9iakFycmF5PXRydWVdIOi8uOWFpeaYr+WQpuWbnuWCs+eJqeS7tumZo+WIl++8jOiLpXRydWXku6Pooajlm57lgrPpu57ngrrnianku7Z7eCx5LHp95LmL6Zmj5YiX77yM6IulZmFsc2Xlm57lgrPpu57pmaPliJdbeCx5LHpd5LmL6Zmj5YiX77yM6aCQ6KitdHJ1ZQ0KICogQHJldHVybnMge0FycmF5fSDlm57lgrPpu557eCx5LHp96Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHINCiAqDQogKiBwcyA9IFtbMjQzLCAyMDYsIDk1XSwgWzIzMywgMjI1LCAxNDZdLCBbMjEsIDMyNSwgMjJdXQ0KICogciA9IHB0c1hZWnRvQXJyKHBzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNiwgejogOTUsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYsIGluZDogMSB9LA0KICogLy8gICB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyLCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgJ3gnOiAyNDMsICd5JzogMjA2LCAneic6IDk1IH0sIHsgJ3gnOiAyMzMsICd5JzogMjI1LCAneic6IDE0NiB9LCB7ICd4JzogMjEsICd5JzogMzI1LCAneic6IDIyIH1dDQogKiByID0gcHRzWFladG9BcnIocHMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCB6OiA5NSwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgejogMjIsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyAnYSc6IDI0MywgJ2InOiAyMDYsICdjJzogOTUgfSwgeyAnYSc6IDIzMywgJ2InOiAyMjUsICdjJzogMTQ2IH0sIHsgJ2EnOiAyMSwgJ2InOiAzMjUsICdjJzogMjIgfV0NCiAqIHIgPSBwdHNYWVp0b0FycihwcywgeyBrZXlYOiAnYScsIGtleVk6ICdiJywga2V5WjogJ2MnIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCB6OiA5NSwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgejogMjIsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICovCmZ1bmN0aW9uIHB0c1hZWnRvQXJyKHBzLCBvcHQgPSB7fSkgewogIC8v6Iul54Sh5pW45pOa5Zue5YKz56m66Zmj5YiXCiAgaWYgKHNpemUocHMpIDw9IDApIHsKICAgIHJldHVybiBbXTsKICB9CgogIC8va2V5WAogIGxldCBrZXlYID0gZ2V0KG9wdCwgJ2tleVgnKTsKICBpZiAoIWlzZXN0cihrZXlYKSkgewogICAga2V5WCA9ICd4JzsKICB9CgogIC8va2V5WQogIGxldCBrZXlZID0gZ2V0KG9wdCwgJ2tleVknKTsKICBpZiAoIWlzZXN0cihrZXlZKSkgewogICAga2V5WSA9ICd5JzsKICB9CgogIC8va2V5WgogIGxldCBrZXlaID0gZ2V0KG9wdCwgJ2tleVonLCAnJyk7CiAgaWYgKCFpc2VzdHIoa2V5WikpIHsKICAgIGtleVogPSAneic7CiAgfQoKICAvL2tleUluZAogIGxldCBrZXlJbmQgPSBnZXQob3B0LCAna2V5SW5kJywgJycpOwogIGlmICghaXNlc3RyKGtleUluZCkpIHsKICAgIGtleUluZCA9ICdpbmQnOwogIH0KCiAgLy9yZXR1cm5PYmpBcnJheQogIGxldCByZXR1cm5PYmpBcnJheSA9IGdldChvcHQsICdyZXR1cm5PYmpBcnJheScpOwogIGlmICghaXNib2wocmV0dXJuT2JqQXJyYXkpKSB7CiAgICByZXR1cm5PYmpBcnJheSA9IHRydWU7CiAgfQoKICAvL3JzCiAgbGV0IHJzID0gW107CiAgZm9yRWFjaChwcywgKHYsIGspID0+IHsKICAgIGxldCB4ID0gbnVsbDsKICAgIGxldCB5ID0gbnVsbDsKICAgIGxldCB6ID0gbnVsbDsKICAgIGlmIChpc2Fycih2KSAmJiBzaXplKHYpID49IDMpIHsKICAgICAgeCA9IGdldCh2LCAwKTsKICAgICAgeSA9IGdldCh2LCAxKTsKICAgICAgeiA9IGdldCh2LCAyKTsKICAgIH0gZWxzZSB7CiAgICAgIHggPSBnZXQodiwga2V5WCwgbnVsbCk7CiAgICAgIHkgPSBnZXQodiwga2V5WSwgbnVsbCk7CiAgICAgIHogPSBnZXQodiwga2V5WiwgbnVsbCk7CiAgICB9CiAgICBpZiAoaXNudW0oeCkgJiYgaXNudW0oeSkgJiYgaXNudW0oeikpIHsKICAgICAgeCA9IHRvTnVtYmVyKHgpOwogICAgICB5ID0gdG9OdW1iZXIoeSk7CiAgICAgIHogPSB0b051bWJlcih6KTsKICAgICAgcnMucHVzaCh7CiAgICAgICAgeCwKICAgICAgICB5LAogICAgICAgIHosCiAgICAgICAgW2tleUluZF06IGsKICAgICAgfSk7CiAgICB9CiAgfSk7CgogIC8vcmV0dXJuT2JqQXJyYXkKICBpZiAoIXJldHVybk9iakFycmF5KSB7CiAgICBycyA9IG1hcChycywgdiA9PiB7CiAgICAgIHJldHVybiBbdi54LCB2LnksIHYueiwgdltrZXlJbmRdXTsKICAgIH0pOwogIH0KICByZXR1cm4gcnM7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8ubWF4YCBhbmQgYF8ubWluYCB3aGljaCBhY2NlcHRzIGEKICogYGNvbXBhcmF0b3JgIHRvIGRldGVybWluZSB0aGUgZXh0cmVtdW0gdmFsdWUuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGNvbXBhcmF0b3IgdXNlZCB0byBjb21wYXJlIHZhbHVlcy4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGV4dHJlbXVtIHZhbHVlLgogKi8KZnVuY3Rpb24gYmFzZUV4dHJlbXVtKGFycmF5LCBpdGVyYXRlZSwgY29tcGFyYXRvcikgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sCiAgICAgIGN1cnJlbnQgPSBpdGVyYXRlZSh2YWx1ZSk7CiAgICBpZiAoY3VycmVudCAhPSBudWxsICYmIChjb21wdXRlZCA9PT0gdW5kZWZpbmVkID8gY3VycmVudCA9PT0gY3VycmVudCAmJiAhaXNTeW1ib2woY3VycmVudCkgOiBjb21wYXJhdG9yKGN1cnJlbnQsIGNvbXB1dGVkKSkpIHsKICAgICAgdmFyIGNvbXB1dGVkID0gY3VycmVudCwKICAgICAgICByZXN1bHQgPSB2YWx1ZTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmx0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBgb3RoZXJgLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUx0KHZhbHVlLCBvdGhlcikgewogIHJldHVybiB2YWx1ZSA8IG90aGVyOwp9CgovKioKICogQ29tcHV0ZXMgdGhlIG1pbmltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksCiAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgTWF0aAogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZS4KICogQGV4YW1wbGUKICoKICogXy5taW4oWzQsIDIsIDgsIDZdKTsKICogLy8gPT4gMgogKgogKiBfLm1pbihbXSk7CiAqIC8vID0+IHVuZGVmaW5lZAogKi8KZnVuY3Rpb24gbWluKGFycmF5KSB7CiAgcmV0dXJuIGFycmF5ICYmIGFycmF5Lmxlbmd0aCA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHkkMSwgYmFzZUx0KSA6IHVuZGVmaW5lZDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmd0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUd0KHZhbHVlLCBvdGhlcikgewogIHJldHVybiB2YWx1ZSA+IG90aGVyOwp9CgovKioKICogQ29tcHV0ZXMgdGhlIG1heGltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksCiAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgTWF0aAogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZS4KICogQGV4YW1wbGUKICoKICogXy5tYXgoWzQsIDIsIDgsIDZdKTsKICogLy8gPT4gOAogKgogKiBfLm1heChbXSk7CiAqIC8vID0+IHVuZGVmaW5lZAogKi8KZnVuY3Rpb24gbWF4KGFycmF5KSB7CiAgcmV0dXJuIGFycmF5ICYmIGFycmF5Lmxlbmd0aCA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHkkMSwgYmFzZUd0KSA6IHVuZGVmaW5lZDsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbHRlcmAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS4KICovCmZ1bmN0aW9uIGJhc2VGaWx0ZXIoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7CiAgdmFyIHJlc3VsdCA9IFtdOwogIGJhc2VFYWNoJDEoY29sbGVjdGlvbiwgZnVuY3Rpb24gKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikgewogICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pKSB7CiAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTsKICAgIH0KICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyBhbiBhcnJheSBvZiBhbGwgZWxlbWVudHMKICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0aHJlZQogKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS4KICoKICogKipOb3RlOioqIFVubGlrZSBgXy5yZW1vdmVgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbgogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuCiAqIEBzZWUgXy5yZWplY3QKICogQGV4YW1wbGUKICoKICogdmFyIHVzZXJzID0gWwogKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LAogKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfQogKiBdOwogKgogKiBfLmZpbHRlcih1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ10KICoKICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC4KICogXy5maWx0ZXIodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXQogKgogKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuCiAqIF8uZmlsdGVyKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7CiAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddCiAqCiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLgogKiBfLmZpbHRlcih1c2VycywgJ2FjdGl2ZScpOwogKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddCiAqCiAqIC8vIENvbWJpbmluZyBzZXZlcmFsIHByZWRpY2F0ZXMgdXNpbmcgYF8ub3ZlckV2ZXJ5YCBvciBgXy5vdmVyU29tZWAuCiAqIF8uZmlsdGVyKHVzZXJzLCBfLm92ZXJTb21lKFt7ICdhZ2UnOiAzNiB9LCBbJ2FnZScsIDQwXV0pKTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ2Jhcm5leSddCiAqLwpmdW5jdGlvbiBmaWx0ZXIoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7CiAgdmFyIGZ1bmMgPSBpc0FycmF5JDEoY29sbGVjdGlvbikgPyBhcnJheUZpbHRlciA6IGJhc2VGaWx0ZXI7CiAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgYmFzZUl0ZXJhdGVlKHByZWRpY2F0ZSkpOwp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovCnZhciBuYXRpdmVDZWlsID0gTWF0aC5jZWlsLAogIG5hdGl2ZU1heCA9IE1hdGgubWF4OwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJhbmdlYCBhbmQgYF8ucmFuZ2VSaWdodGAgd2hpY2ggZG9lc24ndAogKiBjb2VyY2UgYXJndW1lbnRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS4KICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS4KICogQHBhcmFtIHtudW1iZXJ9IHN0ZXAgVGhlIHZhbHVlIHRvIGluY3JlbWVudCBvciBkZWNyZW1lbnQgYnkuCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuCiAqLwpmdW5jdGlvbiBiYXNlUmFuZ2Uoc3RhcnQsIGVuZCwgc3RlcCwgZnJvbVJpZ2h0KSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBuYXRpdmVNYXgobmF0aXZlQ2VpbCgoZW5kIC0gc3RhcnQpIC8gKHN0ZXAgfHwgMSkpLCAwKSwKICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7CiAgd2hpbGUgKGxlbmd0aC0tKSB7CiAgICByZXN1bHRbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF0gPSBzdGFydDsKICAgIHN0YXJ0ICs9IHN0ZXA7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBDaGVja3MgaWYgdGhlIGdpdmVuIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgdmFsdWUgYXJndW1lbnQuCiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuCiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLAogKiAgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHsKICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7CiAgaWYgKHR5cGUgPT0gJ251bWJlcicgPyBpc0FycmF5TGlrZShvYmplY3QpICYmIGlzSW5kZXgoaW5kZXgsIG9iamVjdC5sZW5ndGgpIDogdHlwZSA9PSAnc3RyaW5nJyAmJiBpbmRleCBpbiBvYmplY3QpIHsKICAgIHJldHVybiBlcShvYmplY3RbaW5kZXhdLCB2YWx1ZSk7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIENyZWF0ZXMgYSBgXy5yYW5nZWAgb3IgYF8ucmFuZ2VSaWdodGAgZnVuY3Rpb24uCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByYW5nZSBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGNyZWF0ZVJhbmdlKGZyb21SaWdodCkgewogIHJldHVybiBmdW5jdGlvbiAoc3RhcnQsIGVuZCwgc3RlcCkgewogICAgaWYgKHN0ZXAgJiYgdHlwZW9mIHN0ZXAgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoc3RhcnQsIGVuZCwgc3RlcCkpIHsKICAgICAgZW5kID0gc3RlcCA9IHVuZGVmaW5lZDsKICAgIH0KICAgIC8vIEVuc3VyZSB0aGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC4KICAgIHN0YXJ0ID0gdG9GaW5pdGUoc3RhcnQpOwogICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIGVuZCA9IHN0YXJ0OwogICAgICBzdGFydCA9IDA7CiAgICB9IGVsc2UgewogICAgICBlbmQgPSB0b0Zpbml0ZShlbmQpOwogICAgfQogICAgc3RlcCA9IHN0ZXAgPT09IHVuZGVmaW5lZCA/IHN0YXJ0IDwgZW5kID8gMSA6IC0xIDogdG9GaW5pdGUoc3RlcCk7CiAgICByZXR1cm4gYmFzZVJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXAsIGZyb21SaWdodCk7CiAgfTsKfQoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbnVtYmVycyAocG9zaXRpdmUgYW5kL29yIG5lZ2F0aXZlKSBwcm9ncmVzc2luZyBmcm9tCiAqIGBzdGFydGAgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC4gQSBzdGVwIG9mIGAtMWAgaXMgdXNlZCBpZiBhIG5lZ2F0aXZlCiAqIGBzdGFydGAgaXMgc3BlY2lmaWVkIHdpdGhvdXQgYW4gYGVuZGAgb3IgYHN0ZXBgLiBJZiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkLAogKiBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuCiAqCiAqICoqTm90ZToqKiBKYXZhU2NyaXB0IGZvbGxvd3MgdGhlIElFRUUtNzU0IHN0YW5kYXJkIGZvciByZXNvbHZpbmcKICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IFV0aWwKICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLgogKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLgogKiBAcGFyYW0ge251bWJlcn0gW3N0ZXA9MV0gVGhlIHZhbHVlIHRvIGluY3JlbWVudCBvciBkZWNyZW1lbnQgYnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy4KICogQHNlZSBfLmluUmFuZ2UsIF8ucmFuZ2VSaWdodAogKiBAZXhhbXBsZQogKgogKiBfLnJhbmdlKDQpOwogKiAvLyA9PiBbMCwgMSwgMiwgM10KICoKICogXy5yYW5nZSgtNCk7CiAqIC8vID0+IFswLCAtMSwgLTIsIC0zXQogKgogKiBfLnJhbmdlKDEsIDUpOwogKiAvLyA9PiBbMSwgMiwgMywgNF0KICoKICogXy5yYW5nZSgwLCAyMCwgNSk7CiAqIC8vID0+IFswLCA1LCAxMCwgMTVdCiAqCiAqIF8ucmFuZ2UoMCwgLTQsIC0xKTsKICogLy8gPT4gWzAsIC0xLCAtMiwgLTNdCiAqCiAqIF8ucmFuZ2UoMSwgNCwgMCk7CiAqIC8vID0+IFsxLCAxLCAxXQogKgogKiBfLnJhbmdlKDApOwogKiAvLyA9PiBbXQogKi8KdmFyIHJhbmdlID0gY3JlYXRlUmFuZ2UoKTsKdmFyIHJhbmdlJDEgPSByYW5nZTsKCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgTkFOID0gMCAvIDA7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWVhbmAgYW5kIGBfLm1lYW5CeWAgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLgogKi8KZnVuY3Rpb24gYmFzZU1lYW4oYXJyYXksIGl0ZXJhdGVlKSB7CiAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoOwogIHJldHVybiBsZW5ndGggPyBiYXNlU3VtKGFycmF5LCBpdGVyYXRlZSkgLyBsZW5ndGggOiBOQU47Cn0KCi8qKgogKiBDb21wdXRlcyB0aGUgbWVhbiBvZiB0aGUgdmFsdWVzIGluIGBhcnJheWAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBNYXRoCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG1lYW4uCiAqIEBleGFtcGxlCiAqCiAqIF8ubWVhbihbNCwgMiwgOCwgNl0pOwogKiAvLyA9PiA1CiAqLwpmdW5jdGlvbiBtZWFuKGFycmF5KSB7CiAgcmV0dXJuIGJhc2VNZWFuKGFycmF5LCBpZGVudGl0eSQxKTsKfQoKZnVuY3Rpb24gbm9ybWFsaXplQXJyYXlDb3JlKGFycikgewogIC8vY2hlY2sgcHNTcmMKICBpZiAoIWlzZWFycihhcnIpKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdhcnIgaXMgbm90IGFuIGVmZmVjdGl2ZSBhcnJheScKICAgIH07CiAgfQoKICAvL3YwCiAgbGV0IHYwID0gZ2V0KGFyciwgMCk7CgogIC8vbgogIGxldCBuID0gMDsgLy8xZCBhcnJheQogIGlmIChpc2VhcnIodjApKSB7CiAgICBuID0gc2l6ZSh2MCk7IC8vbmQgYXJyYXkKICB9CgogIC8vZWFycgogIGxldCBlYXJyID0gW107CiAgaWYgKG4gPT09IDApIHsKICAgIGVhcnIgPSBmaWx0ZXIoYXJyLCBpc251bSk7CiAgICBlYXJyID0gbWFwKGVhcnIsIGNkYmwpOwogIH0gZWxzZSB7CiAgICBmb3JFYWNoKGFyciwgdnMgPT4gewogICAgICAvL2IKICAgICAgbGV0IGIgPSB0cnVlOwogICAgICBsZXQgY3MgPSBbXTsKICAgICAgZm9yRWFjaChyYW5nZSQxKG4pLCBpID0+IHsKICAgICAgICAvL3YKICAgICAgICBsZXQgdiA9IGdldCh2cywgaSk7CgogICAgICAgIC8vY2hlY2sKICAgICAgICBpZiAoIWlzbnVtKHYpKSB7CiAgICAgICAgICBiID0gZmFsc2U7CiAgICAgICAgICAvL+i3s+WHuuaPm+S4i+S4gOWAiwogICAgICAgIH0KCiAgICAgICAgLy9wdXNoCiAgICAgICAgY3MucHVzaChjZGJsKHYpKTsKICAgICAgfSk7CgogICAgICAvL2NoZWNrCiAgICAgIGlmIChiKSB7CiAgICAgICAgZWFyci5wdXNoKGNzKTsKICAgICAgfQogICAgfSk7CiAgfQoKICAvL2NoZWNrCiAgaWYgKHNpemUoZWFycikgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ2FyciBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KCiAgLy9zdGEKICBsZXQgc3RhID0gYXJyID0+IHsKICAgIGxldCBybWluID0gbWluKGFycik7CiAgICBsZXQgcm1heCA9IG1heChhcnIpOwogICAgcmV0dXJuIHsKICAgICAgbWluOiBybWluLAogICAgICBtYXg6IHJtYXgsCiAgICAgIHJhbmdlOiBybWF4IC0gcm1pbiwKICAgICAgbWlkOiAocm1heCArIHJtaW4pIC8gMiwKICAgICAgYXZnOiBtZWFuKGFycikKICAgIH07CiAgfTsKCiAgLy9ubWFycgogIGxldCBubWFyciA9IChhcnIsIHJtaW4sIHJtYXgsIHJybmcpID0+IHsKICAgIHJldHVybiBtYXAoYXJyLCB2ID0+IHsKICAgICAgcmV0dXJuICh2IC0gcm1pbikgLyBycm5nOwogICAgfSk7CiAgfTsKCiAgLy9ubQogIGxldCBubSA9IGFyciA9PiB7CiAgICBsZXQgcyA9IHN0YShhcnIpOwogICAgbGV0IGFycnQgPSBubWFycihhcnIsIHMubWluLCBzLm1heCwgcy5yYW5nZSk7CiAgICByZXR1cm4gewogICAgICBhcnI6IGFycnQsCiAgICAgIC4uLnMKICAgIH07CiAgfTsKCiAgLy9yCiAgbGV0IHIgPSBudWxsOwogIGlmIChuID09PSAwKSB7CiAgICByID0gbm0oZWFycik7CiAgfSBlbHNlIHsKICAgIHIgPSBtYXAocmFuZ2UkMShuKSwgaSA9PiB7CiAgICAgIGxldCBlYXJydCA9IG1hcChlYXJyLCBpKTsKICAgICAgcmV0dXJuIG5tKGVhcnJ0KTsKICAgIH0pOwogIH0KICByZXR1cm4gcjsKfQoKLyoqDQogKiDph53lsI3kuIDntq3miJbkuozntq3pmaPliJfmraPopo/ljJYNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9ub3JtYWxpemVBcnJheS50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IGFyciDovLjlhaXos4fmlpnpmaPliJfvvIzngrpbeDEseDIsLi4uXeS5i+S4gOe2remZo+WIl++8jOaIlltbeDEseTFdLFt4Mix5Ml0sLi4uXeS5i+S6jOe2remZo+WIlw0KICogQHJldHVybnMge0FycmF5fE9iamVjdH0g5Zue5YKz5q2j6KaP5YyW5pW45pOa5LmL54mp5Lu25oiW6Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBhcnINCiAqIGxldCByDQogKg0KICogYXJyID0gWw0KICogICAgIFsyNDMsIDIwNiwgOTVdLA0KICogICAgIFsyMzMsIDIyNSwgMTQ2XSwNCiAqICAgICBbMjEsIDMyNSwgMjJdLA0KICogICAgIFs5NTMsIDI4LCAyMjNdLA0KICogICAgIFsxMDkyLCAyOTAsIDM5XSwNCiAqICAgICBbNzQ0LCAyMDAsIDE5MV0sDQogKiAgICAgWzE3NCwgMywgMjJdLA0KICogICAgIFs1MzcsIDM2OCwgMjQ5XSwNCiAqICAgICBbMTE1MSwgMzcxLCA4Nl0sDQogKiAgICAgWzgxNCwgMjUyLCAxMjVdDQogKiBdDQogKiByID0gbm9ybWFsaXplQXJyYXkoYXJyKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC4xOTY0NjAxNzY5OTExNTA0NSwNCiAqIC8vICAgICAgIDAuMTg3NjEwNjE5NDY5MDI2NTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44MjQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgICAgMC45NDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjYzOTgyMzAwODg0OTU1NzYsDQogKiAvLyAgICAgICAwLjEzNTM5ODIzMDA4ODQ5NTU4LA0KICogLy8gICAgICAgMC40NTY2MzcxNjgxNDE1OTI5NCwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjcwMTc2OTkxMTUwNDQyNDgNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMjEsDQogKiAvLyAgICAgbWF4OiAxMTUxLA0KICogLy8gICAgIHJhbmdlOiAxMTMwLA0KICogLy8gICAgIGF2ZzogNTk2LjINCiAqIC8vICAgfSwNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC41NTE2MzA0MzQ3ODI2MDg2LA0KICogLy8gICAgICAgMC42MDMyNjA4Njk1NjUyMTc0LA0KICogLy8gICAgICAgMC44NzUsDQogKiAvLyAgICAgICAwLjA2NzkzNDc4MjYwODY5NTY1LA0KICogLy8gICAgICAgMC43Nzk4OTEzMDQzNDc4MjYsDQogKiAvLyAgICAgICAwLjUzNTMyNjA4Njk1NjUyMTcsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC45OTE4NDc4MjYwODY5NTY1LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNjc2NjMwNDM0NzgyNjA4Ng0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAzLA0KICogLy8gICAgIG1heDogMzcxLA0KICogLy8gICAgIHJhbmdlOiAzNjgsDQogKiAvLyAgICAgYXZnOiAyMjYuOA0KICogLy8gICB9LA0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjMyMTU4NTkwMzA4MzcwMDQ0LA0KICogLy8gICAgICAgMC41NDYyNTU1MDY2MDc5Mjk1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODg1NDYyNTU1MDY2MDc5MywNCiAqIC8vICAgICAgIDAuMDc0ODg5ODY3ODQxNDA5NjksDQogKiAvLyAgICAgICAwLjc0NDQ5MzM5MjA3MDQ4NDYsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuMjgxOTM4MzI1OTkxMTg5NDUsDQogKiAvLyAgICAgICAwLjQ1Mzc0NDQ5MzM5MjA3MDQ2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDIyLA0KICogLy8gICAgIG1heDogMjQ5LA0KICogLy8gICAgIHJhbmdlOiAyMjcsDQogKiAvLyAgICAgYXZnOiAxMTkuOA0KICogLy8gICB9DQogKiAvLyBdDQogKg0KICogYXJyID0gWw0KICogICAgIDI0MywgMjMzLCAyMSwNCiAqICAgICA5NTMsIDEwOTIsIDc0NCwNCiAqICAgICAxNzQsIDUzNywgMTE1MSwNCiAqICAgICA4MTQNCiAqIF0NCiAqIHIgPSBub3JtYWxpemVBcnJheShhcnIpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gew0KICogLy8gICBhcnI6IFsNCiAqIC8vICAgICAwLjE5NjQ2MDE3Njk5MTE1MDQ1LA0KICogLy8gICAgIDAuMTg3NjEwNjE5NDY5MDI2NTUsDQogKiAvLyAgICAgMCwNCiAqIC8vICAgICAwLjgyNDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgMC45NDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgMC42Mzk4MjMwMDg4NDk1NTc2LA0KICogLy8gICAgIDAuMTM1Mzk4MjMwMDg4NDk1NTgsDQogKiAvLyAgICAgMC40NTY2MzcxNjgxNDE1OTI5NCwNCiAqIC8vICAgICAxLA0KICogLy8gICAgIDAuNzAxNzY5OTExNTA0NDI0OA0KICogLy8gICBdLA0KICogLy8gICBtaW46IDIxLA0KICogLy8gICBtYXg6IDExNTEsDQogKiAvLyAgIHJhbmdlOiAxMTMwLA0KICogLy8gICBhdmc6IDU5Ni4yDQogKiAvLyB9DQogKg0KICogYXJyID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiByID0gbm9ybWFsaXplQXJyYXkoYXJyLCBbJ3gnLCAneScsICd6J10pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjE5NjQ2MDE3Njk5MTE1MDQ1LA0KICogLy8gICAgICAgMC4xODc2MTA2MTk0NjkwMjY1NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjgyNDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjk0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuNjM5ODIzMDA4ODQ5NTU3NiwNCiAqIC8vICAgICAgIDAuMTM1Mzk4MjMwMDg4NDk1NTgsDQogKiAvLyAgICAgICAwLjQ1NjYzNzE2ODE0MTU5Mjk0LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNzAxNzY5OTExNTA0NDI0OA0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAyMSwNCiAqIC8vICAgICBtYXg6IDExNTEsDQogKiAvLyAgICAgcmFuZ2U6IDExMzAsDQogKiAvLyAgICAgYXZnOiA1OTYuMg0KICogLy8gICB9LA0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjU1MTYzMDQzNDc4MjYwODYsDQogKiAvLyAgICAgICAwLjYwMzI2MDg2OTU2NTIxNzQsDQogKiAvLyAgICAgICAwLjg3NSwNCiAqIC8vICAgICAgIDAuMDY3OTM0NzgyNjA4Njk1NjUsDQogKiAvLyAgICAgICAwLjc3OTg5MTMwNDM0NzgyNiwNCiAqIC8vICAgICAgIDAuNTM1MzI2MDg2OTU2NTIxNywNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjk5MTg0NzgyNjA4Njk1NjUsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC42NzY2MzA0MzQ3ODI2MDg2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDMsDQogKiAvLyAgICAgbWF4OiAzNzEsDQogKiAvLyAgICAgcmFuZ2U6IDM2OCwNCiAqIC8vICAgICBhdmc6IDIyNi44DQogKiAvLyAgIH0sDQogKiAvLyAgIHsNCiAqIC8vICAgICBhcnI6IFsNCiAqIC8vICAgICAgIDAuMzIxNTg1OTAzMDgzNzAwNDQsDQogKiAvLyAgICAgICAwLjU0NjI1NTUwNjYwNzkyOTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44ODU0NjI1NTUwNjYwNzkzLA0KICogLy8gICAgICAgMC4wNzQ4ODk4Njc4NDE0MDk2OSwNCiAqIC8vICAgICAgIDAuNzQ0NDkzMzkyMDcwNDg0NiwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC4yODE5MzgzMjU5OTExODk0NSwNCiAqIC8vICAgICAgIDAuNDUzNzQ0NDkzMzkyMDcwNDYNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMjIsDQogKiAvLyAgICAgbWF4OiAyNDksDQogKiAvLyAgICAgcmFuZ2U6IDIyNywNCiAqIC8vICAgICBhdmc6IDExOS44DQogKiAvLyAgIH0NCiAqIC8vIF0NCiAqDQogKi8KZnVuY3Rpb24gbm9ybWFsaXplQXJyYXkoYXJyLCBrZXlzID0gW10pIHsKICAvL2NoZWNrIHBzU3JjCiAgaWYgKCFpc2VhcnIoYXJyKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAnYXJyIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXknCiAgICB9OwogIH0KCiAgLy9rZXlzCiAgaWYgKHNpemUoa2V5cykgPiAwKSB7CiAgICAvL2NoZWNrCiAgICBsZXQgdjAgPSBnZXQoYXJyLCAwKTsKICAgIGlmICghaXNlb2JqKHYwKSkgewogICAgICByZXR1cm4gewogICAgICAgIGVycjogJ2FyciBpcyBub3QgYW4gZWZmZWN0aXZlIGFycmF5IG9mIG9iamVjdHMnCiAgICAgIH07CiAgICB9CgogICAgLy9hcnJ0LCDmj5Dlj5bmjIflrpprZXlzCiAgICBsZXQgYXJydCA9IFtdOwogICAgZm9yRWFjaChhcnIsIGR0ID0+IHsKICAgICAgbGV0IGNzID0gW107CiAgICAgIGZvckVhY2goa2V5cywgayA9PiB7CiAgICAgICAgY3MucHVzaChnZXQoZHQsIGssICcnKSk7CiAgICAgIH0pOwogICAgICBhcnJ0LnB1c2goY3MpOwogICAgfSk7CgogICAgLy9zYXZlCiAgICBhcnIgPSBhcnJ0OwogIH0KCiAgLy9ub3JtYWxpemVBcnJheUNvcmUKICBsZXQgciA9IG5vcm1hbGl6ZUFycmF5Q29yZShhcnIpOwogIHJldHVybiByOwp9CgovKioNCiAqIOWFp+aPkueUqOato+imj+WMluaVuOaTmg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ludGVycDJOb3JtYWxpemUudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwcyDovLjlhaXkuozntq3luqfmqJnliqDop4DmuKzmlbjmk5rpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MSx6OnoxfSx7eDp4Mix5OnkyLHo6ejJ9LC4uLl3pu57nianku7bkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tuS5i3jmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7bkuYt55qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlaPSd6J10g6Ly45YWl6bue54mp5Lu25LmLeuashOS9jeWtl+S4su+8jOeCuuingOa4rOWAvO+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5SW5kPSdpbmQnXSDovLjlhaXpu57nianku7bkuYtpbmTmrITkvY3lrZfkuLLvvIzmraPopo/ljJblvozlj6/lj43mn6Xljp/lp4vmlbjmk5rkuYvmjIfmqJnvvIzpoJDoqK0naW5kJw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2NhbGU9MV0g6Ly45YWl5q2j6KaP5YyW56+E5ZyN5pW45YC877yM5Zug6JmV55CG5aSa6YKK5b2i5pmC5pyJ5pW45YC85a656Kix6Kqk5beu77yM5pWF6aCI6YCa6YGO57iu5pS+5YC85Z+f5L6G5rib5bCR5ZWP6aGM77yM6aCQ6KitMeaYr+ato+imj+WMljDoh7Mx5LmL6ZaT77yM5L2/55Soc2NhbGVYWeWJh+aYr+ato+imj+WMlueCujDoh7NzY2FsZVhZ5LmL6ZaT77yM6aCQ6KitMQ0KICogQHJldHVybnMge09iamVjdH0g5Zue5YKz5q2j6KaP5YyW5pW45pOa54mp5Lu2DQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHINCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogciA9IGludGVycDJOb3JtYWxpemUocHMpDQogKiBkZWxldGUgci5udg0KICogZGVsZXRlIHIuaW52DQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IHsicHMiOlt7IngiOjAuMTk2NDYwMTc2OTkxMTUwNDUsInkiOjAuNTE2ODE0MTU5MjkyMDM1NCwieiI6MC4zMjE1ODU5MDMwODM3MDA0NCwiaW5kIjpudWxsfSx7IngiOjAuMTg3NjEwNjE5NDY5MDI2NTUsInkiOjAuNTMzNjI4MzE4NTg0MDcwOCwieiI6MC41NDYyNTU1MDY2MDc5Mjk1LCJpbmQiOm51bGx9LHsieCI6MCwieSI6MC42MjIxMjM4OTM4MDUzMDk3LCJ6IjowLCJpbmQiOm51bGx9LHsieCI6MC44MjQ3Nzg3NjEwNjE5NDY5LCJ5IjowLjM1OTI5MjAzNTM5ODIzMDA3LCJ6IjowLjg4NTQ2MjU1NTA2NjA3OTMsImluZCI6bnVsbH0seyJ4IjowLjk0Nzc4NzYxMDYxOTQ2OSwieSI6MC41OTExNTA0NDI0Nzc4NzYxLCJ6IjowLjA3NDg4OTg2Nzg0MTQwOTY5LCJpbmQiOm51bGx9LHsieCI6MC42Mzk4MjMwMDg4NDk1NTc2LCJ5IjowLjUxMTUwNDQyNDc3ODc2MSwieiI6MC43NDQ0OTMzOTIwNzA0ODQ2LCJpbmQiOm51bGx9LHsieCI6MC4xMzUzOTgyMzAwODg0OTU1OCwieSI6MC4zMzcxNjgxNDE1OTI5MjAzNiwieiI6MCwiaW5kIjpudWxsfSx7IngiOjAuNDU2NjM3MTY4MTQxNTkyOTQsInkiOjAuNjYwMTc2OTkxMTUwNDQyNSwieiI6MSwiaW5kIjpudWxsfSx7IngiOjEsInkiOjAuNjYyODMxODU4NDA3MDc5NywieiI6MC4yODE5MzgzMjU5OTExODk0NSwiaW5kIjpudWxsfSx7IngiOjAuNzAxNzY5OTExNTA0NDI0OCwieSI6MC41NTc1MjIxMjM4OTM4MDUzLCJ6IjowLjQ1Mzc0NDQ5MzM5MjA3MDQ2LCJpbmQiOm51bGx9XSwicHNNaW5NYXgiOnsieG1pbiI6MCwieG1heCI6MSwieW1pbiI6MC4zMzcxNjgxNDE1OTI5MjAzNiwieW1heCI6MC42NjI4MzE4NTg0MDcwNzk3LCJ6bWluIjowLCJ6bWF4IjoxfSwic3QiOnsieCI6eyJtaW4iOjIxLCJtYXgiOjExNTEsInJhbmdlIjoxMTMwfSwieSI6eyJtaW4iOi0zNzgsIm1heCI6NzUyLCJyYW5nZSI6MTEzMH0sInoiOnsibWluIjoyMiwibWF4IjoyNDksInJhbmdlIjoyMjd9fX0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogciA9IGludGVycDJOb3JtYWxpemUocHMsIHsgc2NhbGU6IDEwMCB9KQ0KICogZGVsZXRlIHIubnYNCiAqIGRlbGV0ZSByLmludg0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiB7InBzIjpbeyJ4IjoxOS42NDYwMTc2OTkxMTUwNDUsInkiOjUxLjY4MTQxNTkyOTIwMzU0NiwieiI6MzIuMTU4NTkwMzA4MzcwMDQ0LCJpbmQiOm51bGx9LHsieCI6MTguNzYxMDYxOTQ2OTAyNjU0LCJ5Ijo1My4zNjI4MzE4NTg0MDcwOCwieiI6NTQuNjI1NTUwNjYwNzkyOTUsImluZCI6bnVsbH0seyJ4IjowLCJ5Ijo2Mi4yMTIzODkzODA1MzA5NywieiI6MCwiaW5kIjpudWxsfSx7IngiOjgyLjQ3Nzg3NjEwNjE5NDY5LCJ5IjozNS45MjkyMDM1Mzk4MjMwMSwieiI6ODguNTQ2MjU1NTA2NjA3OTMsImluZCI6bnVsbH0seyJ4Ijo5NC43Nzg3NjEwNjE5NDY5MSwieSI6NTkuMTE1MDQ0MjQ3Nzg3NjEsInoiOjcuNDg4OTg2Nzg0MTQwOTY5LCJpbmQiOm51bGx9LHsieCI6NjMuOTgyMzAwODg0OTU1NzU1LCJ5Ijo1MS4xNTA0NDI0Nzc4NzYxLCJ6Ijo3NC40NDkzMzkyMDcwNDg0NSwiaW5kIjpudWxsfSx7IngiOjEzLjUzOTgyMzAwODg0OTU1OCwieSI6MzMuNzE2ODE0MTU5MjkyMDM1LCJ6IjowLCJpbmQiOm51bGx9LHsieCI6NDUuNjYzNzE2ODE0MTU5Mjk0LCJ5Ijo2Ni4wMTc2OTkxMTUwNDQyNSwieiI6MTAwLCJpbmQiOm51bGx9LHsieCI6MTAwLCJ5Ijo2Ni4yODMxODU4NDA3MDc5NywieiI6MjguMTkzODMyNTk5MTE4OTQ1LCJpbmQiOm51bGx9LHsieCI6NzAuMTc2OTkxMTUwNDQyNDgsInkiOjU1Ljc1MjIxMjM4OTM4MDUzLCJ6Ijo0NS4zNzQ0NDkzMzkyMDcwNSwiaW5kIjpudWxsfV0sInBzTWluTWF4Ijp7InhtaW4iOjAsInhtYXgiOjEwMCwieW1pbiI6MzMuNzE2ODE0MTU5MjkyMDM1LCJ5bWF4Ijo2Ni4yODMxODU4NDA3MDc5Nywiem1pbiI6MCwiem1heCI6MTAwfSwic3QiOnsieCI6eyJtaW4iOjIxLCJtYXgiOjExNTEsInJhbmdlIjoxMTMwfSwieSI6eyJtaW4iOi0zNzgsIm1heCI6NzUyLCJyYW5nZSI6MTEzMH0sInoiOnsibWluIjoyMiwibWF4IjoyNDksInJhbmdlIjoyMjd9fX0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSwgaW5kOiAxMDEgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2LCBpbmQ6IDEwMiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyLCBpbmQ6IDEwMyB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMywgaW5kOiAxMDQgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5LCBpbmQ6IDEwNSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEsIGluZDogMTA2IH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiwgaW5kOiAxMDcgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5LCBpbmQ6IDEwOCB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYsIGluZDogMTA5IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSwgaW5kOiAxMTAgfV0NCiAqIHIgPSBpbnRlcnAyTm9ybWFsaXplKHBzLCB7IGtleUluZDogJ2luZCcgfSkNCiAqIGRlbGV0ZSByLm52DQogKiBkZWxldGUgci5pbnYNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4geyJwcyI6W3sieCI6MC4xOTY0NjAxNzY5OTExNTA0NSwieSI6MC41MTY4MTQxNTkyOTIwMzU0LCJ6IjowLjMyMTU4NTkwMzA4MzcwMDQ0LCJpbmQiOjEwMX0seyJ4IjowLjE4NzYxMDYxOTQ2OTAyNjU1LCJ5IjowLjUzMzYyODMxODU4NDA3MDgsInoiOjAuNTQ2MjU1NTA2NjA3OTI5NSwiaW5kIjoxMDJ9LHsieCI6MCwieSI6MC42MjIxMjM4OTM4MDUzMDk3LCJ6IjowLCJpbmQiOjEwM30seyJ4IjowLjgyNDc3ODc2MTA2MTk0NjksInkiOjAuMzU5MjkyMDM1Mzk4MjMwMDcsInoiOjAuODg1NDYyNTU1MDY2MDc5MywiaW5kIjoxMDR9LHsieCI6MC45NDc3ODc2MTA2MTk0NjksInkiOjAuNTkxMTUwNDQyNDc3ODc2MSwieiI6MC4wNzQ4ODk4Njc4NDE0MDk2OSwiaW5kIjoxMDV9LHsieCI6MC42Mzk4MjMwMDg4NDk1NTc2LCJ5IjowLjUxMTUwNDQyNDc3ODc2MSwieiI6MC43NDQ0OTMzOTIwNzA0ODQ2LCJpbmQiOjEwNn0seyJ4IjowLjEzNTM5ODIzMDA4ODQ5NTU4LCJ5IjowLjMzNzE2ODE0MTU5MjkyMDM2LCJ6IjowLCJpbmQiOjEwN30seyJ4IjowLjQ1NjYzNzE2ODE0MTU5Mjk0LCJ5IjowLjY2MDE3Njk5MTE1MDQ0MjUsInoiOjEsImluZCI6MTA4fSx7IngiOjEsInkiOjAuNjYyODMxODU4NDA3MDc5NywieiI6MC4yODE5MzgzMjU5OTExODk0NSwiaW5kIjoxMDl9LHsieCI6MC43MDE3Njk5MTE1MDQ0MjQ4LCJ5IjowLjU1NzUyMjEyMzg5MzgwNTMsInoiOjAuNDUzNzQ0NDkzMzkyMDcwNDYsImluZCI6MTEwfV0sInBzTWluTWF4Ijp7InhtaW4iOjAsInhtYXgiOjEsInltaW4iOjAuMzM3MTY4MTQxNTkyOTIwMzYsInltYXgiOjAuNjYyODMxODU4NDA3MDc5Nywiem1pbiI6MCwiem1heCI6MX0sInN0Ijp7IngiOnsibWluIjoyMSwibWF4IjoxMTUxLCJyYW5nZSI6MTEzMH0sInkiOnsibWluIjotMzc4LCJtYXgiOjc1MiwicmFuZ2UiOjExMzB9LCJ6Ijp7Im1pbiI6MjIsIm1heCI6MjQ5LCJyYW5nZSI6MjI3fX19DQogKg0KICovCmZ1bmN0aW9uIGludGVycDJOb3JtYWxpemUocHMsIG9wdCA9IHt9KSB7CiAgLy9rZXlYCiAgbGV0IGtleVggPSBnZXQob3B0LCAna2V5WCcpOwogIGlmICghaXNlc3RyKGtleVgpKSB7CiAgICBrZXlYID0gJ3gnOwogIH0KCiAgLy9rZXlZCiAgbGV0IGtleVkgPSBnZXQob3B0LCAna2V5WScpOwogIGlmICghaXNlc3RyKGtleVkpKSB7CiAgICBrZXlZID0gJ3knOwogIH0KCiAgLy9rZXlaCiAgbGV0IGtleVogPSBnZXQob3B0LCAna2V5WicsICcnKTsKICBpZiAoIWlzZXN0cihrZXlaKSkgewogICAga2V5WiA9ICd6JzsKICB9CgogIC8va2V5SW5kCiAgbGV0IGtleUluZCA9IGdldChvcHQsICdrZXlJbmQnLCAnJyk7CiAgaWYgKCFpc2VzdHIoa2V5SW5kKSkgewogICAga2V5SW5kID0gJ2luZCc7CiAgfQoKICAvL3NjYWxlCiAgbGV0IHNjYWxlID0gZ2V0KG9wdCwgJ3NjYWxlJyk7CiAgaWYgKCFpc251bShzY2FsZSkpIHsKICAgIHNjYWxlID0gMTsKICB9CiAgc2NhbGUgPSBjZGJsKHNjYWxlKTsKICBpZiAoc2NhbGUgPD0gMCkgewogICAgdGhyb3cgbmV3IEVycm9yKGBzY2FsZSBuZWVkID49IDBgKTsKICB9CiAgLy8gY29uc29sZS5sb2coJ3NjYWxlJywgc2NhbGUpCgogIC8vbngsIG55LCBuegogIGxldCBueCA9IG5vcm1hbGl6ZUFycmF5KG1hcChwcywga2V5WCkpOwogIGxldCBueSA9IG5vcm1hbGl6ZUFycmF5KG1hcChwcywga2V5WSkpOwogIGxldCBueiA9IG5vcm1hbGl6ZUFycmF5KG1hcChwcywga2V5WikpOwogIC8vIGNvbnNvbGUubG9nKCdueCcsIG54KQogIC8vIGNvbnNvbGUubG9nKCdueScsIG55KQogIC8vIGNvbnNvbGUubG9nKCdueicsIG56KQoKICAvL3JhbmdlWFkKICBsZXQgcmFuZ2VYWSA9IE1hdGgubWF4KG54LnJhbmdlLCBueS5yYW5nZSk7CgogIC8vcmFuZ2VYWUhhbGYKICBsZXQgcmFuZ2VYWUhhbGYgPSByYW5nZVhZIC8gMjsKCiAgLy9zdCwgeCx55L2/55So5ZCM57ay5qC85bC65a+457iu5pS+CiAgbGV0IHN0ID0gewogICAgeDogewogICAgICBtaW46IG54Lm1pZCAtIHJhbmdlWFlIYWxmLAogICAgICBtYXg6IG54Lm1pZCArIHJhbmdlWFlIYWxmLAogICAgICByYW5nZTogcmFuZ2VYWQogICAgfSwKICAgIHk6IHsKICAgICAgbWluOiBueS5taWQgLSByYW5nZVhZSGFsZiwKICAgICAgbWF4OiBueS5taWQgKyByYW5nZVhZSGFsZiwKICAgICAgcmFuZ2U6IHJhbmdlWFkKICAgIH0sCiAgICB6OiB7CiAgICAgIG1pbjogbnoubWluLAogICAgICBtYXg6IG56Lm1heCwKICAgICAgcmFuZ2U6IG56LnJhbmdlCiAgICB9CiAgfTsKICAvLyBjb25zb2xlLmxvZygnc3QnLCBzdCkKCiAgLy9udgogIGxldCBudiA9ICh2LCBkaXIpID0+IHsKICAgIGlmICghaXNOdW1iZXIodikpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZiAoc3RbZGlyXS5yYW5nZSA8PSAwKSB7CiAgICAgIHJldHVybiB2OwogICAgfQogICAgcmV0dXJuICh2IC0gc3RbZGlyXS5taW4pIC8gc3RbZGlyXS5yYW5nZSAqIHNjYWxlOwogIH07CgogIC8vaW52CiAgbGV0IGludiA9IChpdiwgZGlyKSA9PiB7CiAgICBpZiAoIWlzTnVtYmVyKGl2KSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGlmIChzY2FsZSA8PSAwKSB7CiAgICAgIHJldHVybiBpdjsKICAgIH0KICAgIHJldHVybiBpdiAvIHNjYWxlICogc3RbZGlyXS5yYW5nZSArIHN0W2Rpcl0ubWluOwogIH07CgogIC8vbm9ybWFsaXplIHBzCiAgcHMgPSBtYXAocHMsIHYgPT4gewogICAgbGV0IHggPSBudih2W2tleVhdLCAneCcpOwogICAgbGV0IHkgPSBudih2W2tleVldLCAneScpOwogICAgbGV0IHogPSBudih2W2tleVpdLCAneicpOwogICAgbGV0IGluZCA9IGdldCh2LCBrZXlJbmQsIG51bGwpOwogICAgcmV0dXJuIHsKICAgICAgW2tleVhdOiB4LAogICAgICBba2V5WV06IHksCiAgICAgIFtrZXlaXTogeiwKICAgICAgW2tleUluZF06IGluZAogICAgfTsKICB9KTsKICAvLyBjb25zb2xlLmxvZygnbm9ybWFsaXplIHBzJywgcHMpCgogIC8vcHNNaW5NYXgKICBsZXQgcHN4ID0gbWFwKHBzLCBrZXlYKTsKICBsZXQgcHN4TWluID0gbWluKHBzeCk7CiAgbGV0IHBzeE1heCA9IG1heChwc3gpOwogIGxldCBwc3kgPSBtYXAocHMsIGtleVkpOwogIGxldCBwc3lNaW4gPSBtaW4ocHN5KTsKICBsZXQgcHN5TWF4ID0gbWF4KHBzeSk7CiAgbGV0IHBzeiA9IG1hcChwcywga2V5Wik7CiAgbGV0IHBzek1pbiA9IG1pbihwc3opOwogIGxldCBwc3pNYXggPSBtYXgocHN6KTsKICBsZXQgcHNNaW5NYXggPSB7CiAgICB4bWluOiBwc3hNaW4sCiAgICB4bWF4OiBwc3hNYXgsCiAgICB5bWluOiBwc3lNaW4sCiAgICB5bWF4OiBwc3lNYXgsCiAgICB6bWluOiBwc3pNaW4sCiAgICB6bWF4OiBwc3pNYXgKICB9OwogIHJldHVybiB7CiAgICBwcywKICAgIHBzTWluTWF4LAogICAgc3QsCiAgICBudiwKICAgIGludgogIH07Cn0KCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3ByZWFkYWJsZVN5bWJvbCA9IFN5bWJvbCQxID8gU3ltYm9sJDEuaXNDb25jYXRTcHJlYWRhYmxlIDogdW5kZWZpbmVkOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgZmxhdHRlbmFibGUgYGFyZ3VtZW50c2Agb2JqZWN0IG9yIGFycmF5LgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZmxhdHRlbmFibGUsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzRmxhdHRlbmFibGUodmFsdWUpIHsKICByZXR1cm4gaXNBcnJheSQxKHZhbHVlKSB8fCBpc0FyZ3VtZW50cyQxKHZhbHVlKSB8fCAhIShzcHJlYWRhYmxlU3ltYm9sICYmIHZhbHVlICYmIHZhbHVlW3NwcmVhZGFibGVTeW1ib2xdKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZsYXR0ZW5gIHdpdGggc3VwcG9ydCBmb3IgcmVzdHJpY3RpbmcgZmxhdHRlbmluZy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uCiAqIEBwYXJhbSB7bnVtYmVyfSBkZXB0aCBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGguCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3ByZWRpY2F0ZT1pc0ZsYXR0ZW5hYmxlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcGFyYW0ge2Jvb2xlYW59IFtpc1N0cmljdF0gUmVzdHJpY3QgdG8gdmFsdWVzIHRoYXQgcGFzcyBgcHJlZGljYXRlYCBjaGVja3MuCiAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHQ9W11dIFRoZSBpbml0aWFsIHJlc3VsdCB2YWx1ZS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LgogKi8KZnVuY3Rpb24gYmFzZUZsYXR0ZW4oYXJyYXksIGRlcHRoLCBwcmVkaWNhdGUsIGlzU3RyaWN0LCByZXN1bHQpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsKICBwcmVkaWNhdGUgfHwgKHByZWRpY2F0ZSA9IGlzRmxhdHRlbmFibGUpOwogIHJlc3VsdCB8fCAocmVzdWx0ID0gW10pOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07CiAgICBpZiAoZGVwdGggPiAwICYmIHByZWRpY2F0ZSh2YWx1ZSkpIHsKICAgICAgaWYgKGRlcHRoID4gMSkgewogICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGZsYXR0ZW4gYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGRlcHRoIC0gMSwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcnJheVB1c2gocmVzdWx0LCB2YWx1ZSk7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoIWlzU3RyaWN0KSB7CiAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IHZhbHVlOwogICAgfQogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgQXJyYXkKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS4KICogQGV4YW1wbGUKICoKICogXy5mbGF0dGVuKFsxLCBbMiwgWzMsIFs0XV0sIDVdXSk7CiAqIC8vID0+IFsxLCAyLCBbMywgWzRdXSwgNV0KICovCmZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHsKICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7CiAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCAxKSA6IFtdOwp9CgovKioNCiAqIOioiOeul+aVuOaTmuWFp+m7nueJqeS7tua3seW6pg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2dldFBvaW50RGVwdGgudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge09iamVjdH0gcCDovLjlhaXpu57luqfmqJnnianku7YNCiAqIEByZXR1cm5zIHtJbnRlZ2VyfSDlm57lgrPmt7HluqbmlbTmlbgNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHANCiAqIGxldCByDQogKg0KICogdHJ5IHsNCiAqICAgICBwID0gW1tbW1sxLCAyLjVdLCBbMS4xLCAyLjNdXV1dXQ0KICogICAgIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiB9DQogKiBjYXRjaCAoZXJyKSB7DQogKiAgICAgciA9IGVyci5tZXNzYWdlDQogKiB9DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gaW52YWxpZCBwW1tbW1tbMSwyLjVdLFsxLjEsMi4zXV1dXV1dDQogKg0KICogcCA9IFtbW1sxLCAyLjVdLCBbMS4xLCAyLjNdXV1dDQogKiByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDMNCiAqDQogKiBwID0gW1tbWzEsIDIuNV1dXV0NCiAqIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMw0KICoNCiAqIHAgPSBbW1sxLCAyLjVdXV0NCiAqIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMg0KICoNCiAqIHAgPSBbWzEsIDIuNV1dDQogKiByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDENCiAqDQogKiB0cnkgew0KICogICAgIHAgPSBbeyB4OiAxLCB5OiAyLjUgfV0NCiAqICAgICByID0gZ2V0UG9pbnREZXB0aChwKQ0KICogfQ0KICogY2F0Y2ggKGVycikgew0KICogICAgIHIgPSBlcnIubWVzc2FnZQ0KICogfQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IGludmFsaWQgcFtbeyJ4IjoxLCJ5IjoyLjV9XV0NCiAqDQogKi8KZnVuY3Rpb24gZ2V0UG9pbnREZXB0aChwKSB7CiAgbGV0IHYxID0gZ2V0KHAsICcwJywgbnVsbCk7CiAgbGV0IGlwMSA9IHNpemUodjEpOwogIGxldCB0MSA9IGlzTnVtYmVyKHYxKTsKICBsZXQgdjIgPSBnZXQocCwgJzAuMCcsIG51bGwpOwogIGxldCBpcDIgPSBzaXplKHYyKTsKICBsZXQgdDIgPSBpc051bWJlcih2Mik7CiAgbGV0IHYzID0gZ2V0KHAsICcwLjAuMCcsIG51bGwpOwogIGxldCBpcDMgPSBzaXplKHYzKTsKICBsZXQgdDMgPSBpc051bWJlcih2Myk7CiAgbGV0IHY0ID0gZ2V0KHAsICcwLjAuMC4wJywgbnVsbCk7CiAgLy8gbGV0IGlwNCA9IHNpemUodjQpCiAgbGV0IHQ0ID0gaXNOdW1iZXIodjQpOwogIGlmIChpcDMgPT09IDIgJiYgdDQpIHsKICAgIHJldHVybiAzOwogIH0KICBpZiAoaXAyID09PSAyICYmIHQzKSB7CiAgICByZXR1cm4gMjsKICB9CiAgaWYgKGlwMSA9PT0gMiAmJiB0MikgewogICAgcmV0dXJuIDE7CiAgfQogIGlmIChpcDEgPT09IDAgJiYgdDEpIHsKICAgIHJldHVybiAwOwogIH0KICAvLyBjb25zb2xlLmxvZygndjEnLCB2MSwgJ2lwMScsIGlwMSwgJ3QyJywgdDIpCiAgLy8gY29uc29sZS5sb2coJ3YyJywgdjIsICdpcDInLCBpcDIsICd0MycsIHQzKQogIC8vIGNvbnNvbGUubG9nKCd2MycsIHYzLCAnaXAzJywgaXAzLCAndDQnLCB0NCkKICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgcFske0pTT04uc3RyaW5naWZ5KHApfV1gKTsKfQoKLyoqDQogKiDovYnmj5tSaW5nU3RyaW5n44CBcG9seWdvbuOAgU11bHRpUG9seWdvbuaIkOeCulBvbHlnb24NCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC90b1BvbHlnb24udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSB2IOi8uOWFpeizh+aWmemZo+WIlw0KICogQHJldHVybnMge0FycmF5fSDlm57lgrPos4fmlpnpmaPliJcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHJzDQogKiBsZXQgcg0KICoNCiAqIHJzID0gWyAvL3JpbmdTdHJpbmcNCiAqICAgICBbMCwgMF0sDQogKiAgICAgWzEwMCwgMF0sDQogKiAgICAgWzEwMCwgMV0sDQogKiAgICAgWzAsIDFdLA0KICogICAgIFswLCAwXSwgLy/plonlkIgNCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdLFswLDBdXV0NCiAqDQogKiBycyA9IFsgLy9yaW5nU3RyaW5nDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXV0NCiAqDQogKiBycyA9IFsgLy9wb2x5Z29uDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXV0NCiAqDQogKiBycyA9IFsgLy9wb2x5Z29uDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gdG9Qb2x5Z29uKHJzKQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxMCwwXSxbMTAsMV0sWzAsMV1dXQ0KICoNCiAqIHJzID0gWyAvL3BvbHlnb24NCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXSwNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwLCAwXSwNCiAqICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXSxbWzAsMF0sWzEwLDBdLFsxMCwxXSxbMCwxXV1dDQogKg0KICogcnMgPSBbIC8vbXVsdGlQb2x5Z29uDQogKiAgICAgWw0KICogICAgICAgICBbDQogKiAgICAgICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICAgICAgWzAsIDFdLA0KICogICAgICAgICBdLA0KICogICAgICAgICBbDQogKiAgICAgICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgICAgICBbMTAsIDBdLA0KICogICAgICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgICAgIFswLCAxXSwNCiAqICAgICAgICAgXQ0KICogICAgIF0NCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwMCwwXSxbMTAwLDFdLFswLDFdXSxbWzAsMF0sWzEwLDBdLFsxMCwxXSxbMCwxXV1dDQogKg0KICovCmZ1bmN0aW9uIHRvUG9seWdvbih2KSB7CiAgbGV0IGQgPSBnZXRQb2ludERlcHRoKHYpOwogIGlmIChkID09PSAzKSB7CiAgICByZXR1cm4gZmxhdHRlbih2KTsKICB9IGVsc2UgaWYgKGQgPT09IDIpIHsKICAgIHJldHVybiB2OwogIH0gZWxzZSBpZiAoZCA9PT0gMSkgewogICAgcmV0dXJuIFt2XTsKICB9IGVsc2UgaWYgKGQgPT09IDApIHsKICAgIHJldHVybiBbXTsKICB9CiAgcmV0dXJuIHY7Cn0KCi8qKg0KICog6KiI566XUmluZ1N0cmluZ+mdouepjQ0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2dldEFyZWFSaW5nU3RyaW5nLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcnMg6Ly45YWlUmluZ1N0cmluZ+izh+aWmemZo+WIl++8jOeCultbeDEseTFdLFt4Mix5Ml0sLi4uXeani+aIkOS5i+mZo+WIlw0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQudXNlQWJzPXRydWVdIOi8uOWFpemdouepjeaYr+WQpuWPlue1leWwjeWAvO+8jOmgkOiorXRydWUNCiAqIEByZXR1cm5zIHtOdW1iZXJ9IOWbnuWCs+mdouepjeaVuOWtlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcnMNCiAqIGxldCByDQogKg0KICogcnMgPSBbDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqICAgICBbMCwgMF0sIC8v6ZaJ5ZCIDQogKiBdDQogKiByID0gZ2V0QXJlYVJpbmdTdHJpbmcocnMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTAwDQogKg0KICogcnMgPSBbDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqIF0NCiAqIHIgPSBnZXRBcmVhUmluZ1N0cmluZyhycykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMDANCiAqDQogKiBycyA9IFsNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IGdldEFyZWFSaW5nU3RyaW5nKHJzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDANCiAqDQogKi8KZnVuY3Rpb24gZ2V0QXJlYVJpbmdTdHJpbmcocnMsIG9wdCA9IHt9KSB7CiAgLy91c2VBYnMKICBsZXQgdXNlQWJzID0gZ2V0KG9wdCwgJ3VzZUFicycpOwogIGlmICghaXNib2wodXNlQWJzKSkgewogICAgdXNlQWJzID0gdHJ1ZTsKICB9CgogIC8vY2hlY2sKICBpZiAoIWlzZWFycihycykpIHsKICAgIHJldHVybiAwOwogIH0KCiAgLy9lcnMKICBsZXQgZXJzID0gW107CiAgZm9yRWFjaChycywgdiA9PiB7CiAgICBpZiAoc2l6ZSh2KSA9PT0gMikgewogICAgICBpZiAoaXNudW0odlswXSkgJiYgaXNudW0odlsxXSkpIHsKICAgICAgICBlcnMucHVzaChbY2RibCh2WzBdKSwgY2RibCh2WzFdKV0pOwogICAgICB9CiAgICB9CiAgfSk7CgogIC8vY2hlY2sKICBpZiAoIWlzZWFycihlcnMpKSB7CiAgICByZXR1cm4gMDsKICB9CgogIC8vYXJlYQogIGxldCBpID0gLTE7CiAgbGV0IG4gPSBzaXplKGVycyk7CiAgbGV0IGE7CiAgbGV0IGIgPSBlcnNbbiAtIDFdOwogIGxldCBhcmVhID0gMDsKICB3aGlsZSAoKytpIDwgbikgewogICAgYSA9IGI7CiAgICBiID0gZXJzW2ldOwogICAgYXJlYSArPSBhWzFdICogYlswXSAtIGFbMF0gKiBiWzFdOwogIH0KICBsZXQgciA9IGFyZWEgLyAyOwoKICAvL3VzZUFicwogIGlmICh1c2VBYnMpIHsKICAgIHIgPSBNYXRoLmFicyhyKTsKICB9CiAgcmV0dXJuIHI7Cn0KCi8vIGltcG9ydCBnZXQgZnJvbSAnbG9kYXNoLWVzL2dldC5qcycKCi8qKg0KICog6KiI566XUG9seWdvbumdouepjQ0KICog5b6X6KaB6ICD5oWu5aSa5Y2A5Z+f44CB5YmU6Zmk5Y2A5Z+f5LmL57WE5ZCIOiBodHRwOi8vZXNyaS5naXRodWIuaW8vZ2VvbWV0cnktYXBpLWphdmEvZG9jL1BvbHlnb24uaHRtbA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2dldEFyZWFQb2x5Z29uLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcGcg6Ly45YWlUG9seWdvbuizh+aWmemZo+WIl++8jOeCultbW3gxLHkxXSxbeDIseTJdLC4uLl1d5qeL5oiQ5LmL6Zmj5YiXDQogKiBAcmV0dXJucyB7TnVtYmVyfSDlm57lgrPpnaLnqY3mlbjlrZcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBnDQogKiBsZXQgcg0KICoNCiAqIHBnID0gWw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiAgICAgWzAsIDBdLCAvL+mWieWQiA0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDEwMA0KICoNCiAqIHBnID0gWw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTAwDQogKg0KICogcGcgPSBbDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMDANCiAqDQogKiBwZyA9IFsNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwLCAwXSwNCiAqICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMA0KICoNCiAqIHBnID0gWw0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdLA0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAsIDBdLA0KICogICAgICAgICBbMTAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDkwDQogKg0KICogcGcgPSBbDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0sDQogKiAgICAgWyAvL+esrCAyIFJpbmdTdHJpbmcg6IiH56ysIDEgUmluZ1N0cmluZyDkuI3ph43nloosIOS9hnBvbHlnb27nrKwx5YCL54K65Li76KaB5Y2ALCDlhbblvozngrrliZTpmaTljYAsIOatpOeCuuacieWVj+mhjOWkmumCiuW9og0KICogICAgICAgICBbMjAwLCAwXSwNCiAqICAgICAgICAgWzIxMCwgMF0sDQogKiAgICAgICAgIFsyMTAsIDFdLA0KICogICAgICAgICBbMjAwLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gOTAsIOWvpumam+eCujExMA0KICoNCiAqLwpmdW5jdGlvbiBnZXRBcmVhUG9seWdvbihwZywgb3B0ID0ge30pIHsKICAvLyAvL2Vwc2lsb24KICAvLyBsZXQgZXBzaWxvbiA9IGdldChvcHQsICdlcHNpbG9uJywgMC4wMDAwMDAwMDAwMDEpCgogIC8vY2hlY2sKICBpZiAoIWlzZWFycihwZykpIHsKICAgIHJldHVybiAwOwogIH0KCiAgLy90b1BvbHlnb24KICBwZyA9IHRvUG9seWdvbihwZyk7CiAgLy8gY29uc29sZS5sb2coJ3RvUG9seWdvbiBwZycsIHBnKQoKICAvL3IKICBsZXQgciA9IDA7CiAgZm9yRWFjaChwZywgKHYsIGspID0+IHsKICAgIC8vcG9seWdvbueCuuWkmuWAi+WkmumCiuW9oue1hOaIkCwg56ysMeWAi+eCuuS4u+imgeWNgCwg5LmL5b6M54K65YmU6Zmk5Y2ACiAgICBsZXQgYSA9IGdldEFyZWFSaW5nU3RyaW5nKHYpOwogICAgaWYgKGsgPT09IDApIHsKICAgICAgciA9IGE7CiAgICB9IGVsc2UgewogICAgICByIC09IGE7CiAgICB9CiAgfSk7CgogIC8vY2hlY2sKICBpZiAociA8IDApIHsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gcjsKfQoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyB1c2VkIHN0cmljdGx5IGZvciBsb2dnaW5nIHRoZSBwcm9jZXNzaW5nIG9mIHRoZSBhbGdvcml0aG0uLi4gb25seSB1c2VmdWwgaWYgeW91IGludGVuZCBvbgovLyBsb29raW5nIHVuZGVyIHRoZSBjb3ZlcnMgKGZvciBwcmV0dHkgVUkncyBvciBkZWJ1Z2dpbmcpCi8vCgpmdW5jdGlvbiBCdWlsZExvZyQxKCkgewogIHZhciBteTsKICB2YXIgbmV4dFNlZ21lbnRJZCA9IDA7CiAgdmFyIGN1clZlcnQgPSBmYWxzZTsKICBmdW5jdGlvbiBwdXNoKHR5cGUsIGRhdGEpIHsKICAgIG15Lmxpc3QucHVzaCh7CiAgICAgIHR5cGU6IHR5cGUsCiAgICAgIGRhdGE6IGRhdGEgPyBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGRhdGEpKSA6IHZvaWQgMAogICAgfSk7CiAgICByZXR1cm4gbXk7CiAgfQogIG15ID0gewogICAgbGlzdDogW10sCiAgICBzZWdtZW50SWQ6IGZ1bmN0aW9uICgpIHsKICAgICAgcmV0dXJuIG5leHRTZWdtZW50SWQrKzsKICAgIH0sCiAgICBjaGVja0ludGVyc2VjdGlvbjogZnVuY3Rpb24gKHNlZzEsIHNlZzIpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoZWNrJywgewogICAgICAgIHNlZzE6IHNlZzEsCiAgICAgICAgc2VnMjogc2VnMgogICAgICB9KTsKICAgIH0sCiAgICBzZWdtZW50Q2hvcDogZnVuY3Rpb24gKHNlZywgZW5kKSB7CiAgICAgIHB1c2goJ2Rpdl9zZWcnLCB7CiAgICAgICAgc2VnOiBzZWcsCiAgICAgICAgcHQ6IGVuZAogICAgICB9KTsKICAgICAgcmV0dXJuIHB1c2goJ2Nob3AnLCB7CiAgICAgICAgc2VnOiBzZWcsCiAgICAgICAgcHQ6IGVuZAogICAgICB9KTsKICAgIH0sCiAgICBzdGF0dXNSZW1vdmU6IGZ1bmN0aW9uIChzZWcpIHsKICAgICAgcmV0dXJuIHB1c2goJ3BvcF9zZWcnLCB7CiAgICAgICAgc2VnOiBzZWcKICAgICAgfSk7CiAgICB9LAogICAgc2VnbWVudFVwZGF0ZTogZnVuY3Rpb24gKHNlZykgewogICAgICByZXR1cm4gcHVzaCgnc2VnX3VwZGF0ZScsIHsKICAgICAgICBzZWc6IHNlZwogICAgICB9KTsKICAgIH0sCiAgICBzZWdtZW50TmV3OiBmdW5jdGlvbiAoc2VnLCBwcmltYXJ5KSB7CiAgICAgIHJldHVybiBwdXNoKCduZXdfc2VnJywgewogICAgICAgIHNlZzogc2VnLAogICAgICAgIHByaW1hcnk6IHByaW1hcnkKICAgICAgfSk7CiAgICB9LAogICAgc2VnbWVudFJlbW92ZTogZnVuY3Rpb24gKHNlZykgewogICAgICByZXR1cm4gcHVzaCgncmVtX3NlZycsIHsKICAgICAgICBzZWc6IHNlZwogICAgICB9KTsKICAgIH0sCiAgICB0ZW1wU3RhdHVzOiBmdW5jdGlvbiAoc2VnLCBhYm92ZSwgYmVsb3cpIHsKICAgICAgcmV0dXJuIHB1c2goJ3RlbXBfc3RhdHVzJywgewogICAgICAgIHNlZzogc2VnLAogICAgICAgIGFib3ZlOiBhYm92ZSwKICAgICAgICBiZWxvdzogYmVsb3cKICAgICAgfSk7CiAgICB9LAogICAgcmV3aW5kOiBmdW5jdGlvbiAoc2VnKSB7CiAgICAgIHJldHVybiBwdXNoKCdyZXdpbmQnLCB7CiAgICAgICAgc2VnOiBzZWcKICAgICAgfSk7CiAgICB9LAogICAgc3RhdHVzOiBmdW5jdGlvbiAoc2VnLCBhYm92ZSwgYmVsb3cpIHsKICAgICAgcmV0dXJuIHB1c2goJ3N0YXR1cycsIHsKICAgICAgICBzZWc6IHNlZywKICAgICAgICBhYm92ZTogYWJvdmUsCiAgICAgICAgYmVsb3c6IGJlbG93CiAgICAgIH0pOwogICAgfSwKICAgIHZlcnQ6IGZ1bmN0aW9uICh4KSB7CiAgICAgIGlmICh4ID09PSBjdXJWZXJ0KSByZXR1cm4gbXk7CiAgICAgIGN1clZlcnQgPSB4OwogICAgICByZXR1cm4gcHVzaCgndmVydCcsIHsKICAgICAgICB4OiB4CiAgICAgIH0pOwogICAgfSwKICAgIGxvZzogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJykgZGF0YSA9IEpTT04uc3RyaW5naWZ5KGRhdGEsIGZhbHNlLCAnICAnKTsKICAgICAgcmV0dXJuIHB1c2goJ2xvZycsIHsKICAgICAgICB0eHQ6IGRhdGEKICAgICAgfSk7CiAgICB9LAogICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgcmV0dXJuIHB1c2goJ3Jlc2V0Jyk7CiAgICB9LAogICAgc2VsZWN0ZWQ6IGZ1bmN0aW9uIChzZWdzKSB7CiAgICAgIHJldHVybiBwdXNoKCdzZWxlY3RlZCcsIHsKICAgICAgICBzZWdzOiBzZWdzCiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluU3RhcnQ6IGZ1bmN0aW9uIChzZWcpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX3N0YXJ0JywgewogICAgICAgIHNlZzogc2VnCiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluUmVtb3ZlSGVhZDogZnVuY3Rpb24gKGluZGV4LCBwdCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fcmVtX2hlYWQnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4LAogICAgICAgIHB0OiBwdAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpblJlbW92ZVRhaWw6IGZ1bmN0aW9uIChpbmRleCwgcHQpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX3JlbV90YWlsJywgewogICAgICAgIGluZGV4OiBpbmRleCwKICAgICAgICBwdDogcHQKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5OZXc6IGZ1bmN0aW9uIChwdDEsIHB0MikgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fbmV3JywgewogICAgICAgIHB0MTogcHQxLAogICAgICAgIHB0MjogcHQyCiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluTWF0Y2g6IGZ1bmN0aW9uIChpbmRleCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fbWF0Y2gnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluQ2xvc2U6IGZ1bmN0aW9uIChpbmRleCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fY2xvc2UnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluQWRkSGVhZDogZnVuY3Rpb24gKGluZGV4LCBwdCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fYWRkX2hlYWQnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4LAogICAgICAgIHB0OiBwdAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbkFkZFRhaWw6IGZ1bmN0aW9uIChpbmRleCwgcHQpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX2FkZF90YWlsJywgewogICAgICAgIGluZGV4OiBpbmRleCwKICAgICAgICBwdDogcHQKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5Db25uZWN0OiBmdW5jdGlvbiAoaW5kZXgxLCBpbmRleDIpIHsKICAgICAgcmV0dXJuIHB1c2goJ2NoYWluX2NvbicsIHsKICAgICAgICBpbmRleDE6IGluZGV4MSwKICAgICAgICBpbmRleDI6IGluZGV4MgogICAgICB9KTsKICAgIH0sCiAgICBjaGFpblJldmVyc2U6IGZ1bmN0aW9uIChpbmRleCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fcmV2JywgewogICAgICAgIGluZGV4OiBpbmRleAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbkpvaW46IGZ1bmN0aW9uIChpbmRleDEsIGluZGV4MikgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fam9pbicsIHsKICAgICAgICBpbmRleDE6IGluZGV4MSwKICAgICAgICBpbmRleDI6IGluZGV4MgogICAgICB9KTsKICAgIH0sCiAgICBkb25lOiBmdW5jdGlvbiAoKSB7CiAgICAgIHJldHVybiBwdXNoKCdkb25lJyk7CiAgICB9CiAgfTsKICByZXR1cm4gbXk7Cn0KdmFyIGJ1aWxkTG9nJDEgPSBCdWlsZExvZyQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyBwcm92aWRlcyB0aGUgcmF3IGNvbXB1dGF0aW9uIGZ1bmN0aW9ucyB0aGF0IHRha2VzIGVwc2lsb24gaW50byBhY2NvdW50Ci8vCi8vIHplcm8gaXMgZGVmaW5lZCB0byBiZSBiZXR3ZWVuICgtZXBzaWxvbiwgZXBzaWxvbikgZXhjbHVzaXZlCi8vCgpmdW5jdGlvbiBFcHNpbG9uJDEoZXBzKSB7CiAgaWYgKHR5cGVvZiBlcHMgIT09ICdudW1iZXInKSBlcHMgPSAwLjAwMDAwMDAwMDE7IC8vIHNhbmUgZGVmYXVsdD8gc3VyZSB3aHkgbm90CiAgdmFyIG15ID0gewogICAgZXBzaWxvbjogZnVuY3Rpb24gKHYpIHsKICAgICAgaWYgKHR5cGVvZiB2ID09PSAnbnVtYmVyJykgZXBzID0gdjsKICAgICAgcmV0dXJuIGVwczsKICAgIH0sCiAgICBwb2ludEFib3ZlT3JPbkxpbmU6IGZ1bmN0aW9uIChwdCwgbGVmdCwgcmlnaHQpIHsKICAgICAgdmFyIEF4ID0gbGVmdFswXTsKICAgICAgdmFyIEF5ID0gbGVmdFsxXTsKICAgICAgdmFyIEJ4ID0gcmlnaHRbMF07CiAgICAgIHZhciBCeSA9IHJpZ2h0WzFdOwogICAgICB2YXIgQ3ggPSBwdFswXTsKICAgICAgdmFyIEN5ID0gcHRbMV07CiAgICAgIHJldHVybiAoQnggLSBBeCkgKiAoQ3kgLSBBeSkgLSAoQnkgLSBBeSkgKiAoQ3ggLSBBeCkgPj0gLWVwczsKICAgIH0sCiAgICBwb2ludEJldHdlZW46IGZ1bmN0aW9uIChwLCBsZWZ0LCByaWdodCkgewogICAgICAvLyBwIG11c3QgYmUgY29sbGluZWFyIHdpdGggbGVmdC0+cmlnaHQKICAgICAgLy8gcmV0dXJucyBmYWxzZSBpZiBwID09IGxlZnQsIHAgPT0gcmlnaHQsIG9yIGxlZnQgPT0gcmlnaHQKICAgICAgdmFyIGRfcHlfbHkgPSBwWzFdIC0gbGVmdFsxXTsKICAgICAgdmFyIGRfcnhfbHggPSByaWdodFswXSAtIGxlZnRbMF07CiAgICAgIHZhciBkX3B4X2x4ID0gcFswXSAtIGxlZnRbMF07CiAgICAgIHZhciBkX3J5X2x5ID0gcmlnaHRbMV0gLSBsZWZ0WzFdOwogICAgICB2YXIgZG90ID0gZF9weF9seCAqIGRfcnhfbHggKyBkX3B5X2x5ICogZF9yeV9seTsKICAgICAgLy8gaWYgYGRvdGAgaXMgMCwgdGhlbiBgcGAgPT0gYGxlZnRgIG9yIGBsZWZ0YCA9PSBgcmlnaHRgIChyZWplY3QpCiAgICAgIC8vIGlmIGBkb3RgIGlzIGxlc3MgdGhhbiAwLCB0aGVuIGBwYCBpcyB0byB0aGUgbGVmdCBvZiBgbGVmdGAgKHJlamVjdCkKICAgICAgaWYgKGRvdCA8IGVwcykgcmV0dXJuIGZhbHNlOwogICAgICB2YXIgc3FsZW4gPSBkX3J4X2x4ICogZF9yeF9seCArIGRfcnlfbHkgKiBkX3J5X2x5OwogICAgICAvLyBpZiBgZG90YCA+IGBzcWxlbmAsIHRoZW4gYHBgIGlzIHRvIHRoZSByaWdodCBvZiBgcmlnaHRgIChyZWplY3QpCiAgICAgIC8vIHRoZXJlZm9yZSwgaWYgYGRvdCAtIHNxbGVuYCBpcyBncmVhdGVyIHRoYW4gMCwgdGhlbiBgcGAgaXMgdG8gdGhlIHJpZ2h0IG9mIGByaWdodGAgKHJlamVjdCkKICAgICAgaWYgKGRvdCAtIHNxbGVuID4gLWVwcykgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0sCiAgICBwb2ludHNTYW1lWDogZnVuY3Rpb24gKHAxLCBwMikgewogICAgICByZXR1cm4gTWF0aC5hYnMocDFbMF0gLSBwMlswXSkgPCBlcHM7CiAgICB9LAogICAgcG9pbnRzU2FtZVk6IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgICAgcmV0dXJuIE1hdGguYWJzKHAxWzFdIC0gcDJbMV0pIDwgZXBzOwogICAgfSwKICAgIHBvaW50c1NhbWU6IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgICAgcmV0dXJuIG15LnBvaW50c1NhbWVYKHAxLCBwMikgJiYgbXkucG9pbnRzU2FtZVkocDEsIHAyKTsKICAgIH0sCiAgICBwb2ludHNDb21wYXJlOiBmdW5jdGlvbiAocDEsIHAyKSB7CiAgICAgIC8vIHJldHVybnMgLTEgaWYgcDEgaXMgc21hbGxlciwgMSBpZiBwMiBpcyBzbWFsbGVyLCAwIGlmIGVxdWFsCiAgICAgIGlmIChteS5wb2ludHNTYW1lWChwMSwgcDIpKSByZXR1cm4gbXkucG9pbnRzU2FtZVkocDEsIHAyKSA/IDAgOiBwMVsxXSA8IHAyWzFdID8gLTEgOiAxOwogICAgICByZXR1cm4gcDFbMF0gPCBwMlswXSA/IC0xIDogMTsKICAgIH0sCiAgICBwb2ludHNDb2xsaW5lYXI6IGZ1bmN0aW9uIChwdDEsIHB0MiwgcHQzKSB7CiAgICAgIC8vIGRvZXMgcHQxLT5wdDItPnB0MyBtYWtlIGEgc3RyYWlnaHQgbGluZT8KICAgICAgLy8gZXNzZW50aWFsbHkgdGhpcyBpcyBqdXN0IGNoZWNraW5nIHRvIHNlZSBpZiB0aGUgc2xvcGUocHQxLT5wdDIpID09PSBzbG9wZShwdDItPnB0MykKICAgICAgLy8gaWYgc2xvcGVzIGFyZSBlcXVhbCwgdGhlbiB0aGV5IG11c3QgYmUgY29sbGluZWFyLCBiZWNhdXNlIHRoZXkgc2hhcmUgcHQyCiAgICAgIHZhciBkeDEgPSBwdDFbMF0gLSBwdDJbMF07CiAgICAgIHZhciBkeTEgPSBwdDFbMV0gLSBwdDJbMV07CiAgICAgIHZhciBkeDIgPSBwdDJbMF0gLSBwdDNbMF07CiAgICAgIHZhciBkeTIgPSBwdDJbMV0gLSBwdDNbMV07CiAgICAgIHJldHVybiBNYXRoLmFicyhkeDEgKiBkeTIgLSBkeDIgKiBkeTEpIDwgZXBzOwogICAgfSwKICAgIGxpbmVzSW50ZXJzZWN0OiBmdW5jdGlvbiAoYTAsIGExLCBiMCwgYjEpIHsKICAgICAgLy8gcmV0dXJucyBmYWxzZSBpZiB0aGUgbGluZXMgYXJlIGNvaW5jaWRlbnQgKGUuZy4sIHBhcmFsbGVsIG9yIG9uIHRvcCBvZiBlYWNoIG90aGVyKQogICAgICAvLwogICAgICAvLyByZXR1cm5zIGFuIG9iamVjdCBpZiB0aGUgbGluZXMgaW50ZXJzZWN0OgogICAgICAvLyAgIHsKICAgICAgLy8gICAgIHB0OiBbeCwgeV0sICAgIHdoZXJlIHRoZSBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYXQKICAgICAgLy8gICAgIGFsb25nQTogd2hlcmUgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGFsb25nIEEsCiAgICAgIC8vICAgICBhbG9uZ0I6IHdoZXJlIGludGVyc2VjdGlvbiBwb2ludCBpcyBhbG9uZyBCCiAgICAgIC8vICAgfQogICAgICAvLwogICAgICAvLyAgYWxvbmdBIGFuZCBhbG9uZ0Igd2lsbCBlYWNoIGJlIG9uZSBvZjogLTIsIC0xLCAwLCAxLCAyCiAgICAgIC8vCiAgICAgIC8vICB3aXRoIHRoZSBmb2xsb3dpbmcgbWVhbmluZzoKICAgICAgLy8KICAgICAgLy8gICAgLTIgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYmVmb3JlIHNlZ21lbnQncyBmaXJzdCBwb2ludAogICAgICAvLyAgICAtMSAgIGludGVyc2VjdGlvbiBwb2ludCBpcyBkaXJlY3RseSBvbiBzZWdtZW50J3MgZmlyc3QgcG9pbnQKICAgICAgLy8gICAgIDAgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYmV0d2VlbiBzZWdtZW50J3MgZmlyc3QgYW5kIHNlY29uZCBwb2ludHMgKGV4Y2x1c2l2ZSkKICAgICAgLy8gICAgIDEgICBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgZGlyZWN0bHkgb24gc2VnbWVudCdzIHNlY29uZCBwb2ludAogICAgICAvLyAgICAgMiAgIGludGVyc2VjdGlvbiBwb2ludCBpcyBhZnRlciBzZWdtZW50J3Mgc2Vjb25kIHBvaW50CiAgICAgIHZhciBhZHggPSBhMVswXSAtIGEwWzBdOwogICAgICB2YXIgYWR5ID0gYTFbMV0gLSBhMFsxXTsKICAgICAgdmFyIGJkeCA9IGIxWzBdIC0gYjBbMF07CiAgICAgIHZhciBiZHkgPSBiMVsxXSAtIGIwWzFdOwogICAgICB2YXIgYXhiID0gYWR4ICogYmR5IC0gYWR5ICogYmR4OwogICAgICBpZiAoTWF0aC5hYnMoYXhiKSA8IGVwcykgcmV0dXJuIGZhbHNlOyAvLyBsaW5lcyBhcmUgY29pbmNpZGVudAoKICAgICAgdmFyIGR4ID0gYTBbMF0gLSBiMFswXTsKICAgICAgdmFyIGR5ID0gYTBbMV0gLSBiMFsxXTsKICAgICAgdmFyIEEgPSAoYmR4ICogZHkgLSBiZHkgKiBkeCkgLyBheGI7CiAgICAgIHZhciBCID0gKGFkeCAqIGR5IC0gYWR5ICogZHgpIC8gYXhiOwogICAgICB2YXIgcmV0ID0gewogICAgICAgIGFsb25nQTogMCwKICAgICAgICBhbG9uZ0I6IDAsCiAgICAgICAgcHQ6IFthMFswXSArIEEgKiBhZHgsIGEwWzFdICsgQSAqIGFkeV0KICAgICAgfTsKCiAgICAgIC8vIGNhdGVnb3JpemUgd2hlcmUgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGFsb25nIEEgYW5kIEIKCiAgICAgIGlmIChBIDw9IC1lcHMpIHJldC5hbG9uZ0EgPSAtMjtlbHNlIGlmIChBIDwgZXBzKSByZXQuYWxvbmdBID0gLTE7ZWxzZSBpZiAoQSAtIDEgPD0gLWVwcykgcmV0LmFsb25nQSA9IDA7ZWxzZSBpZiAoQSAtIDEgPCBlcHMpIHJldC5hbG9uZ0EgPSAxO2Vsc2UgcmV0LmFsb25nQSA9IDI7CiAgICAgIGlmIChCIDw9IC1lcHMpIHJldC5hbG9uZ0IgPSAtMjtlbHNlIGlmIChCIDwgZXBzKSByZXQuYWxvbmdCID0gLTE7ZWxzZSBpZiAoQiAtIDEgPD0gLWVwcykgcmV0LmFsb25nQiA9IDA7ZWxzZSBpZiAoQiAtIDEgPCBlcHMpIHJldC5hbG9uZ0IgPSAxO2Vsc2UgcmV0LmFsb25nQiA9IDI7CiAgICAgIHJldHVybiByZXQ7CiAgICB9LAogICAgcG9pbnRJbnNpZGVSZWdpb246IGZ1bmN0aW9uIChwdCwgcmVnaW9uKSB7CiAgICAgIHZhciB4ID0gcHRbMF07CiAgICAgIHZhciB5ID0gcHRbMV07CiAgICAgIHZhciBsYXN0X3ggPSByZWdpb25bcmVnaW9uLmxlbmd0aCAtIDFdWzBdOwogICAgICB2YXIgbGFzdF95ID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXVsxXTsKICAgICAgdmFyIGluc2lkZSA9IGZhbHNlOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lvbi5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBjdXJyX3ggPSByZWdpb25baV1bMF07CiAgICAgICAgdmFyIGN1cnJfeSA9IHJlZ2lvbltpXVsxXTsKCiAgICAgICAgLy8gaWYgeSBpcyBiZXR3ZWVuIGN1cnJfeSBhbmQgbGFzdF95LCBhbmQKICAgICAgICAvLyB4IGlzIHRvIHRoZSByaWdodCBvZiB0aGUgYm91bmRhcnkgY3JlYXRlZCBieSB0aGUgbGluZQogICAgICAgIGlmIChjdXJyX3kgLSB5ID4gZXBzICE9IGxhc3RfeSAtIHkgPiBlcHMgJiYgKGxhc3RfeCAtIGN1cnJfeCkgKiAoeSAtIGN1cnJfeSkgLyAobGFzdF95IC0gY3Vycl95KSArIGN1cnJfeCAtIHggPiBlcHMpIGluc2lkZSA9ICFpbnNpZGU7CiAgICAgICAgbGFzdF94ID0gY3Vycl94OwogICAgICAgIGxhc3RfeSA9IGN1cnJfeTsKICAgICAgfQogICAgICByZXR1cm4gaW5zaWRlOwogICAgfQogIH07CiAgcmV0dXJuIG15Owp9CnZhciBlcHNpbG9uJDMgPSBFcHNpbG9uJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIHNpbXBsZSBsaW5rZWQgbGlzdCBpbXBsZW1lbnRhdGlvbiB0aGF0IGFsbG93cyB5b3UgdG8gdHJhdmVyc2UgZG93biBub2RlcyBhbmQgc2F2ZSBwb3NpdGlvbnMKLy8KCnZhciBMaW5rZWRMaXN0JDEgPSB7CiAgY3JlYXRlOiBmdW5jdGlvbiAoKSB7CiAgICB2YXIgbXkgPSB7CiAgICAgIHJvb3Q6IHsKICAgICAgICByb290OiB0cnVlLAogICAgICAgIG5leHQ6IG51bGwKICAgICAgfSwKICAgICAgZXhpc3RzOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgIGlmIChub2RlID09PSBudWxsIHx8IG5vZGUgPT09IG15LnJvb3QpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfSwKICAgICAgaXNFbXB0eTogZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBteS5yb290Lm5leHQgPT09IG51bGw7CiAgICAgIH0sCiAgICAgIGdldEhlYWQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gbXkucm9vdC5uZXh0OwogICAgICB9LAogICAgICBpbnNlcnRCZWZvcmU6IGZ1bmN0aW9uIChub2RlLCBjaGVjaykgewogICAgICAgIHZhciBsYXN0ID0gbXkucm9vdDsKICAgICAgICB2YXIgaGVyZSA9IG15LnJvb3QubmV4dDsKICAgICAgICB3aGlsZSAoaGVyZSAhPT0gbnVsbCkgewogICAgICAgICAgaWYgKGNoZWNrKGhlcmUpKSB7CiAgICAgICAgICAgIG5vZGUucHJldiA9IGhlcmUucHJldjsKICAgICAgICAgICAgbm9kZS5uZXh0ID0gaGVyZTsKICAgICAgICAgICAgaGVyZS5wcmV2Lm5leHQgPSBub2RlOwogICAgICAgICAgICBoZXJlLnByZXYgPSBub2RlOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgICBsYXN0ID0gaGVyZTsKICAgICAgICAgIGhlcmUgPSBoZXJlLm5leHQ7CiAgICAgICAgfQogICAgICAgIGxhc3QubmV4dCA9IG5vZGU7CiAgICAgICAgbm9kZS5wcmV2ID0gbGFzdDsKICAgICAgICBub2RlLm5leHQgPSBudWxsOwogICAgICB9LAogICAgICBmaW5kVHJhbnNpdGlvbjogZnVuY3Rpb24gKGNoZWNrKSB7CiAgICAgICAgdmFyIHByZXYgPSBteS5yb290OwogICAgICAgIHZhciBoZXJlID0gbXkucm9vdC5uZXh0OwogICAgICAgIHdoaWxlIChoZXJlICE9PSBudWxsKSB7CiAgICAgICAgICBpZiAoY2hlY2soaGVyZSkpIGJyZWFrOwogICAgICAgICAgcHJldiA9IGhlcmU7CiAgICAgICAgICBoZXJlID0gaGVyZS5uZXh0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gewogICAgICAgICAgYmVmb3JlOiBwcmV2ID09PSBteS5yb290ID8gbnVsbCA6IHByZXYsCiAgICAgICAgICBhZnRlcjogaGVyZSwKICAgICAgICAgIGluc2VydDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgbm9kZS5wcmV2ID0gcHJldjsKICAgICAgICAgICAgbm9kZS5uZXh0ID0gaGVyZTsKICAgICAgICAgICAgcHJldi5uZXh0ID0gbm9kZTsKICAgICAgICAgICAgaWYgKGhlcmUgIT09IG51bGwpIGhlcmUucHJldiA9IG5vZGU7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgIH0KICAgIH07CiAgICByZXR1cm4gbXk7CiAgfSwKICBub2RlOiBmdW5jdGlvbiAoZGF0YSkgewogICAgZGF0YS5wcmV2ID0gbnVsbDsKICAgIGRhdGEubmV4dCA9IG51bGw7CiAgICBkYXRhLnJlbW92ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgZGF0YS5wcmV2Lm5leHQgPSBkYXRhLm5leHQ7CiAgICAgIGlmIChkYXRhLm5leHQpIGRhdGEubmV4dC5wcmV2ID0gZGF0YS5wcmV2OwogICAgICBkYXRhLnByZXYgPSBudWxsOwogICAgICBkYXRhLm5leHQgPSBudWxsOwogICAgfTsKICAgIHJldHVybiBkYXRhOwogIH0KfTsKdmFyIGxpbmtlZExpc3QgPSBMaW5rZWRMaXN0JDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIHRoaXMgaXMgdGhlIGNvcmUgd29yay1ob3JzZQovLwoKdmFyIExpbmtlZExpc3QgPSBsaW5rZWRMaXN0OwpmdW5jdGlvbiBJbnRlcnNlY3RlciQxKHNlbGZJbnRlcnNlY3Rpb24sIGVwcywgYnVpbGRMb2cpIHsKICAvLyBzZWxmSW50ZXJzZWN0aW9uIGlzIHRydWUvZmFsc2UgZGVwZW5kaW5nIG9uIHRoZSBwaGFzZSBvZiB0aGUgb3ZlcmFsbCBhbGdvcml0aG0KCiAgLy8KICAvLyBzZWdtZW50IGNyZWF0aW9uCiAgLy8KCiAgZnVuY3Rpb24gc2VnbWVudE5ldyhzdGFydCwgZW5kKSB7CiAgICByZXR1cm4gewogICAgICBpZDogYnVpbGRMb2cgPyBidWlsZExvZy5zZWdtZW50SWQoKSA6IC0xLAogICAgICBzdGFydDogc3RhcnQsCiAgICAgIGVuZDogZW5kLAogICAgICBteUZpbGw6IHsKICAgICAgICBhYm92ZTogbnVsbCwKICAgICAgICAvLyBpcyB0aGVyZSBmaWxsIGFib3ZlIHVzPwogICAgICAgIGJlbG93OiBudWxsIC8vIGlzIHRoZXJlIGZpbGwgYmVsb3cgdXM/CiAgICAgIH0sCgogICAgICBvdGhlckZpbGw6IG51bGwKICAgIH07CiAgfQogIGZ1bmN0aW9uIHNlZ21lbnRDb3B5KHN0YXJ0LCBlbmQsIHNlZykgewogICAgcmV0dXJuIHsKICAgICAgaWQ6IGJ1aWxkTG9nID8gYnVpbGRMb2cuc2VnbWVudElkKCkgOiAtMSwKICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICBlbmQ6IGVuZCwKICAgICAgbXlGaWxsOiB7CiAgICAgICAgYWJvdmU6IHNlZy5teUZpbGwuYWJvdmUsCiAgICAgICAgYmVsb3c6IHNlZy5teUZpbGwuYmVsb3cKICAgICAgfSwKICAgICAgb3RoZXJGaWxsOiBudWxsCiAgICB9OwogIH0KCiAgLy8KICAvLyBldmVudCBsb2dpYwogIC8vCgogIHZhciBldmVudF9yb290ID0gTGlua2VkTGlzdC5jcmVhdGUoKTsKICBmdW5jdGlvbiBldmVudENvbXBhcmUocDFfaXNTdGFydCwgcDFfMSwgcDFfMiwgcDJfaXNTdGFydCwgcDJfMSwgcDJfMikgewogICAgLy8gY29tcGFyZSB0aGUgc2VsZWN0ZWQgcG9pbnRzIGZpcnN0CiAgICB2YXIgY29tcCA9IGVwcy5wb2ludHNDb21wYXJlKHAxXzEsIHAyXzEpOwogICAgaWYgKGNvbXAgIT09IDApIHJldHVybiBjb21wOwogICAgLy8gdGhlIHNlbGVjdGVkIHBvaW50cyBhcmUgdGhlIHNhbWUKCiAgICBpZiAoZXBzLnBvaW50c1NhbWUocDFfMiwgcDJfMikpCiAgICAgIC8vIGlmIHRoZSBub24tc2VsZWN0ZWQgcG9pbnRzIGFyZSB0aGUgc2FtZSB0b28uLi4KICAgICAgcmV0dXJuIDA7IC8vIHRoZW4gdGhlIHNlZ21lbnRzIGFyZSBlcXVhbAoKICAgIGlmIChwMV9pc1N0YXJ0ICE9PSBwMl9pc1N0YXJ0KQogICAgICAvLyBpZiBvbmUgaXMgYSBzdGFydCBhbmQgdGhlIG90aGVyIGlzbid0Li4uCiAgICAgIHJldHVybiBwMV9pc1N0YXJ0ID8gMSA6IC0xOyAvLyBmYXZvciB0aGUgb25lIHRoYXQgaXNuJ3QgdGhlIHN0YXJ0CgogICAgLy8gb3RoZXJ3aXNlLCB3ZSdsbCBoYXZlIHRvIGNhbGN1bGF0ZSB3aGljaCBvbmUgaXMgYmVsb3cgdGhlIG90aGVyIG1hbnVhbGx5CiAgICByZXR1cm4gZXBzLnBvaW50QWJvdmVPck9uTGluZShwMV8yLCBwMl9pc1N0YXJ0ID8gcDJfMSA6IHAyXzIsCiAgICAvLyBvcmRlciBtYXR0ZXJzCiAgICBwMl9pc1N0YXJ0ID8gcDJfMiA6IHAyXzEpID8gMSA6IC0xOwogIH0KICBmdW5jdGlvbiBldmVudEFkZChldiwgb3RoZXJfcHQpIHsKICAgIGV2ZW50X3Jvb3QuaW5zZXJ0QmVmb3JlKGV2LCBmdW5jdGlvbiAoaGVyZSkgewogICAgICAvLyBzaG91bGQgZXYgYmUgaW5zZXJ0ZWQgYmVmb3JlIGhlcmU/CiAgICAgIHZhciBjb21wID0gZXZlbnRDb21wYXJlKGV2LmlzU3RhcnQsIGV2LnB0LCBvdGhlcl9wdCwgaGVyZS5pc1N0YXJ0LCBoZXJlLnB0LCBoZXJlLm90aGVyLnB0KTsKICAgICAgcmV0dXJuIGNvbXAgPCAwOwogICAgfSk7CiAgfQogIGZ1bmN0aW9uIGV2ZW50QWRkU2VnbWVudFN0YXJ0KHNlZywgcHJpbWFyeSkgewogICAgdmFyIGV2X3N0YXJ0ID0gTGlua2VkTGlzdC5ub2RlKHsKICAgICAgaXNTdGFydDogdHJ1ZSwKICAgICAgcHQ6IHNlZy5zdGFydCwKICAgICAgc2VnOiBzZWcsCiAgICAgIHByaW1hcnk6IHByaW1hcnksCiAgICAgIG90aGVyOiBudWxsLAogICAgICBzdGF0dXM6IG51bGwKICAgIH0pOwogICAgZXZlbnRBZGQoZXZfc3RhcnQsIHNlZy5lbmQpOwogICAgcmV0dXJuIGV2X3N0YXJ0OwogIH0KICBmdW5jdGlvbiBldmVudEFkZFNlZ21lbnRFbmQoZXZfc3RhcnQsIHNlZywgcHJpbWFyeSkgewogICAgdmFyIGV2X2VuZCA9IExpbmtlZExpc3Qubm9kZSh7CiAgICAgIGlzU3RhcnQ6IGZhbHNlLAogICAgICBwdDogc2VnLmVuZCwKICAgICAgc2VnOiBzZWcsCiAgICAgIHByaW1hcnk6IHByaW1hcnksCiAgICAgIG90aGVyOiBldl9zdGFydCwKICAgICAgc3RhdHVzOiBudWxsCiAgICB9KTsKICAgIGV2X3N0YXJ0Lm90aGVyID0gZXZfZW5kOwogICAgZXZlbnRBZGQoZXZfZW5kLCBldl9zdGFydC5wdCk7CiAgfQogIGZ1bmN0aW9uIGV2ZW50QWRkU2VnbWVudChzZWcsIHByaW1hcnkpIHsKICAgIHZhciBldl9zdGFydCA9IGV2ZW50QWRkU2VnbWVudFN0YXJ0KHNlZywgcHJpbWFyeSk7CiAgICBldmVudEFkZFNlZ21lbnRFbmQoZXZfc3RhcnQsIHNlZywgcHJpbWFyeSk7CiAgICByZXR1cm4gZXZfc3RhcnQ7CiAgfQogIGZ1bmN0aW9uIGV2ZW50VXBkYXRlRW5kKGV2LCBlbmQpIHsKICAgIC8vIHNsaWRlcyBhbiBlbmQgYmFja3dhcmRzCiAgICAvLyAgIChzdGFydCktLS0tLS0tLS0tLS0oZW5kKSAgICB0bzoKICAgIC8vICAgKHN0YXJ0KS0tLShlbmQpCgogICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5zZWdtZW50Q2hvcChldi5zZWcsIGVuZCk7CiAgICBldi5vdGhlci5yZW1vdmUoKTsKICAgIGV2LnNlZy5lbmQgPSBlbmQ7CiAgICBldi5vdGhlci5wdCA9IGVuZDsKICAgIGV2ZW50QWRkKGV2Lm90aGVyLCBldi5wdCk7CiAgfQogIGZ1bmN0aW9uIGV2ZW50RGl2aWRlKGV2LCBwdCkgewogICAgdmFyIG5zID0gc2VnbWVudENvcHkocHQsIGV2LnNlZy5lbmQsIGV2LnNlZyk7CiAgICBldmVudFVwZGF0ZUVuZChldiwgcHQpOwogICAgcmV0dXJuIGV2ZW50QWRkU2VnbWVudChucywgZXYucHJpbWFyeSk7CiAgfQogIGZ1bmN0aW9uIGNhbGN1bGF0ZShwcmltYXJ5UG9seUludmVydGVkLCBzZWNvbmRhcnlQb2x5SW52ZXJ0ZWQpIHsKICAgIC8vIGlmIHNlbGZJbnRlcnNlY3Rpb24gaXMgdHJ1ZSB0aGVuIHRoZXJlIGlzIG5vIHNlY29uZGFyeSBwb2x5Z29uLCBzbyB0aGF0IGlzbid0IHVzZWQKCiAgICAvLwogICAgLy8gc3RhdHVzIGxvZ2ljCiAgICAvLwoKICAgIHZhciBzdGF0dXNfcm9vdCA9IExpbmtlZExpc3QuY3JlYXRlKCk7CiAgICBmdW5jdGlvbiBzdGF0dXNDb21wYXJlKGV2MSwgZXYyKSB7CiAgICAgIHZhciBhMSA9IGV2MS5zZWcuc3RhcnQ7CiAgICAgIHZhciBhMiA9IGV2MS5zZWcuZW5kOwogICAgICB2YXIgYjEgPSBldjIuc2VnLnN0YXJ0OwogICAgICB2YXIgYjIgPSBldjIuc2VnLmVuZDsKICAgICAgaWYgKGVwcy5wb2ludHNDb2xsaW5lYXIoYTEsIGIxLCBiMikpIHsKICAgICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcihhMiwgYjEsIGIyKSkgcmV0dXJuIDE7IC8vZXZlbnRDb21wYXJlKHRydWUsIGExLCBhMiwgdHJ1ZSwgYjEsIGIyKTsKICAgICAgICByZXR1cm4gZXBzLnBvaW50QWJvdmVPck9uTGluZShhMiwgYjEsIGIyKSA/IDEgOiAtMTsKICAgICAgfQogICAgICByZXR1cm4gZXBzLnBvaW50QWJvdmVPck9uTGluZShhMSwgYjEsIGIyKSA/IDEgOiAtMTsKICAgIH0KICAgIGZ1bmN0aW9uIHN0YXR1c0ZpbmRTdXJyb3VuZGluZyhldikgewogICAgICByZXR1cm4gc3RhdHVzX3Jvb3QuZmluZFRyYW5zaXRpb24oZnVuY3Rpb24gKGhlcmUpIHsKICAgICAgICB2YXIgY29tcCA9IHN0YXR1c0NvbXBhcmUoZXYsIGhlcmUuZXYpOwogICAgICAgIHJldHVybiBjb21wID4gMDsKICAgICAgfSk7CiAgICB9CiAgICBmdW5jdGlvbiBjaGVja0ludGVyc2VjdGlvbihldjEsIGV2MikgewogICAgICAvLyByZXR1cm5zIHRoZSBzZWdtZW50IGVxdWFsIHRvIGV2MSwgb3IgZmFsc2UgaWYgbm90aGluZyBlcXVhbAoKICAgICAgdmFyIHNlZzEgPSBldjEuc2VnOwogICAgICB2YXIgc2VnMiA9IGV2Mi5zZWc7CiAgICAgIHZhciBhMSA9IHNlZzEuc3RhcnQ7CiAgICAgIHZhciBhMiA9IHNlZzEuZW5kOwogICAgICB2YXIgYjEgPSBzZWcyLnN0YXJ0OwogICAgICB2YXIgYjIgPSBzZWcyLmVuZDsKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGVja0ludGVyc2VjdGlvbihzZWcxLCBzZWcyKTsKICAgICAgdmFyIGkgPSBlcHMubGluZXNJbnRlcnNlY3QoYTEsIGEyLCBiMSwgYjIpOwogICAgICBpZiAoaSA9PT0gZmFsc2UpIHsKICAgICAgICAvLyBzZWdtZW50cyBhcmUgcGFyYWxsZWwgb3IgY29pbmNpZGVudAoKICAgICAgICAvLyBpZiBwb2ludHMgYXJlbid0IGNvbGxpbmVhciwgdGhlbiB0aGUgc2VnbWVudHMgYXJlIHBhcmFsbGVsLCBzbyBubyBpbnRlcnNlY3Rpb25zCiAgICAgICAgaWYgKCFlcHMucG9pbnRzQ29sbGluZWFyKGExLCBhMiwgYjEpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgLy8gb3RoZXJ3aXNlLCBzZWdtZW50cyBhcmUgb24gdG9wIG9mIGVhY2ggb3RoZXIgc29tZWhvdyAoYWthIGNvaW5jaWRlbnQpCgogICAgICAgIGlmIChlcHMucG9pbnRzU2FtZShhMSwgYjIpIHx8IGVwcy5wb2ludHNTYW1lKGEyLCBiMSkpIHJldHVybiBmYWxzZTsgLy8gc2VnbWVudHMgdG91Y2ggYXQgZW5kcG9pbnRzLi4uIG5vIGludGVyc2VjdGlvbgoKICAgICAgICB2YXIgYTFfZXF1X2IxID0gZXBzLnBvaW50c1NhbWUoYTEsIGIxKTsKICAgICAgICB2YXIgYTJfZXF1X2IyID0gZXBzLnBvaW50c1NhbWUoYTIsIGIyKTsKICAgICAgICBpZiAoYTFfZXF1X2IxICYmIGEyX2VxdV9iMikgcmV0dXJuIGV2MjsgLy8gc2VnbWVudHMgYXJlIGV4YWN0bHkgZXF1YWwKCiAgICAgICAgdmFyIGExX2JldHdlZW4gPSAhYTFfZXF1X2IxICYmIGVwcy5wb2ludEJldHdlZW4oYTEsIGIxLCBiMik7CiAgICAgICAgdmFyIGEyX2JldHdlZW4gPSAhYTJfZXF1X2IyICYmIGVwcy5wb2ludEJldHdlZW4oYTIsIGIxLCBiMik7CgogICAgICAgIC8vIGhhbmR5IGZvciBkZWJ1Z2dpbmc6CiAgICAgICAgLy8gYnVpbGRMb2cubG9nKHsKICAgICAgICAvLwlhMV9lcXVfYjE6IGExX2VxdV9iMSwKICAgICAgICAvLwlhMl9lcXVfYjI6IGEyX2VxdV9iMiwKICAgICAgICAvLwlhMV9iZXR3ZWVuOiBhMV9iZXR3ZWVuLAogICAgICAgIC8vCWEyX2JldHdlZW46IGEyX2JldHdlZW4KICAgICAgICAvLyB9KTsKCiAgICAgICAgaWYgKGExX2VxdV9iMSkgewogICAgICAgICAgaWYgKGEyX2JldHdlZW4pIHsKICAgICAgICAgICAgLy8gIChhMSktLS0oYTIpCiAgICAgICAgICAgIC8vICAoYjEpLS0tLS0tLS0tLShiMikKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBhMik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyAgKGExKS0tLS0tLS0tLS0oYTIpCiAgICAgICAgICAgIC8vICAoYjEpLS0tKGIyKQogICAgICAgICAgICBldmVudERpdmlkZShldjEsIGIyKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBldjI7CiAgICAgICAgfSBlbHNlIGlmIChhMV9iZXR3ZWVuKSB7CiAgICAgICAgICBpZiAoIWEyX2VxdV9iMikgewogICAgICAgICAgICAvLyBtYWtlIGEyIGVxdWFsIHRvIGIyCiAgICAgICAgICAgIGlmIChhMl9iZXR3ZWVuKSB7CiAgICAgICAgICAgICAgLy8gICAgICAgICAoYTEpLS0tKGEyKQogICAgICAgICAgICAgIC8vICAoYjEpLS0tLS0tLS0tLS0tLS0tLS0oYjIpCiAgICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBhMik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgLy8gICAgICAgICAoYTEpLS0tLS0tLS0tLShhMikKICAgICAgICAgICAgICAvLyAgKGIxKS0tLS0tLS0tLS0oYjIpCiAgICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBiMik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICAvLyAgICAgICAgIChhMSktLS0oYTIpCiAgICAgICAgICAvLyAgKGIxKS0tLS0tLS0tLS0oYjIpCiAgICAgICAgICBldmVudERpdmlkZShldjIsIGExKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gb3RoZXJ3aXNlLCBsaW5lcyBpbnRlcnNlY3QgYXQgaS5wdCwgd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgYmV0d2VlbiB0aGUgZW5kcG9pbnRzCgogICAgICAgIC8vIGlzIEEgZGl2aWRlZCBiZXR3ZWVuIGl0cyBlbmRwb2ludHM/IChleGNsdXNpdmUpCiAgICAgICAgaWYgKGkuYWxvbmdBID09PSAwKSB7CiAgICAgICAgICBpZiAoaS5hbG9uZ0IgPT09IC0xKQogICAgICAgICAgICAvLyB5ZXMsIGF0IGV4YWN0bHkgYjEKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBiMSk7ZWxzZSBpZiAoaS5hbG9uZ0IgPT09IDApCiAgICAgICAgICAgIC8vIHllcywgc29tZXdoZXJlIGJldHdlZW4gQidzIGVuZHBvaW50cwogICAgICAgICAgICBldmVudERpdmlkZShldjEsIGkucHQpO2Vsc2UgaWYgKGkuYWxvbmdCID09PSAxKQogICAgICAgICAgICAvLyB5ZXMsIGF0IGV4YWN0bHkgYjIKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYxLCBiMik7CiAgICAgICAgfQoKICAgICAgICAvLyBpcyBCIGRpdmlkZWQgYmV0d2VlbiBpdHMgZW5kcG9pbnRzPyAoZXhjbHVzaXZlKQogICAgICAgIGlmIChpLmFsb25nQiA9PT0gMCkgewogICAgICAgICAgaWYgKGkuYWxvbmdBID09PSAtMSkKICAgICAgICAgICAgLy8geWVzLCBhdCBleGFjdGx5IGExCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgYTEpO2Vsc2UgaWYgKGkuYWxvbmdBID09PSAwKQogICAgICAgICAgICAvLyB5ZXMsIHNvbWV3aGVyZSBiZXR3ZWVuIEEncyBlbmRwb2ludHMgKGV4Y2x1c2l2ZSkKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBpLnB0KTtlbHNlIGlmIChpLmFsb25nQSA9PT0gMSkKICAgICAgICAgICAgLy8geWVzLCBhdCBleGFjdGx5IGEyCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgYTIpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8KICAgIC8vIG1haW4gZXZlbnQgbG9vcAogICAgLy8KICAgIHZhciBzZWdtZW50cyA9IFtdOwogICAgd2hpbGUgKCFldmVudF9yb290LmlzRW1wdHkoKSkgewogICAgICB2YXIgZXYgPSBldmVudF9yb290LmdldEhlYWQoKTsKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy52ZXJ0KGV2LnB0WzBdKTsKICAgICAgaWYgKGV2LmlzU3RhcnQpIHsKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnNlZ21lbnROZXcoZXYuc2VnLCBldi5wcmltYXJ5KTsKICAgICAgICB2YXIgc3Vycm91bmRpbmcgPSBzdGF0dXNGaW5kU3Vycm91bmRpbmcoZXYpOwogICAgICAgIHZhciBhYm92ZSA9IHN1cnJvdW5kaW5nLmJlZm9yZSA/IHN1cnJvdW5kaW5nLmJlZm9yZS5ldiA6IG51bGw7CiAgICAgICAgdmFyIGJlbG93ID0gc3Vycm91bmRpbmcuYWZ0ZXIgPyBzdXJyb3VuZGluZy5hZnRlci5ldiA6IG51bGw7CiAgICAgICAgaWYgKGJ1aWxkTG9nKSB7CiAgICAgICAgICBidWlsZExvZy50ZW1wU3RhdHVzKGV2LnNlZywgYWJvdmUgPyBhYm92ZS5zZWcgOiBmYWxzZSwgYmVsb3cgPyBiZWxvdy5zZWcgOiBmYWxzZSk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGNoZWNrQm90aEludGVyc2VjdGlvbnMoKSB7CiAgICAgICAgICBpZiAoYWJvdmUpIHsKICAgICAgICAgICAgdmFyIGV2ZSA9IGNoZWNrSW50ZXJzZWN0aW9uKGV2LCBhYm92ZSk7CiAgICAgICAgICAgIGlmIChldmUpIHJldHVybiBldmU7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoYmVsb3cpIHJldHVybiBjaGVja0ludGVyc2VjdGlvbihldiwgYmVsb3cpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICB2YXIgZXZlID0gY2hlY2tCb3RoSW50ZXJzZWN0aW9ucygpOwogICAgICAgIGlmIChldmUpIHsKICAgICAgICAgIC8vIGV2IGFuZCBldmUgYXJlIGVxdWFsCiAgICAgICAgICAvLyB3ZSdsbCBrZWVwIGV2ZSBhbmQgdGhyb3cgYXdheSBldgoKICAgICAgICAgIC8vIG1lcmdlIGV2LnNlZydzIGZpbGwgaW5mb3JtYXRpb24gaW50byBldmUuc2VnCgogICAgICAgICAgaWYgKHNlbGZJbnRlcnNlY3Rpb24pIHsKICAgICAgICAgICAgdmFyIHRvZ2dsZTsgLy8gYXJlIHdlIGEgdG9nZ2xpbmcgZWRnZT8KICAgICAgICAgICAgaWYgKGV2LnNlZy5teUZpbGwuYmVsb3cgPT09IG51bGwpIHRvZ2dsZSA9IHRydWU7ZWxzZSB0b2dnbGUgPSBldi5zZWcubXlGaWxsLmFib3ZlICE9PSBldi5zZWcubXlGaWxsLmJlbG93OwoKICAgICAgICAgICAgLy8gbWVyZ2UgdHdvIHNlZ21lbnRzIHRoYXQgYmVsb25nIHRvIHRoZSBzYW1lIHBvbHlnb24KICAgICAgICAgICAgLy8gdGhpbmsgb2YgdGhpcyBhcyBzYW5kd2ljaGluZyB0d28gc2VnbWVudHMgdG9nZXRoZXIsIHdoZXJlIGBldmUuc2VnYCBpcwogICAgICAgICAgICAvLyB0aGUgYm90dG9tIC0tIHRoaXMgd2lsbCBjYXVzZSB0aGUgYWJvdmUgZmlsbCBmbGFnIHRvIHRvZ2dsZQogICAgICAgICAgICBpZiAodG9nZ2xlKSBldmUuc2VnLm15RmlsbC5hYm92ZSA9ICFldmUuc2VnLm15RmlsbC5hYm92ZTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIG1lcmdlIHR3byBzZWdtZW50cyB0aGF0IGJlbG9uZyB0byBkaWZmZXJlbnQgcG9seWdvbnMKICAgICAgICAgICAgLy8gZWFjaCBzZWdtZW50IGhhcyBkaXN0aW5jdCBrbm93bGVkZ2UsIHNvIG5vIHNwZWNpYWwgbG9naWMgaXMgbmVlZGVkCiAgICAgICAgICAgIC8vIG5vdGUgdGhhdCB0aGlzIGNhbiBvbmx5IGhhcHBlbiBvbmNlIHBlciBzZWdtZW50IGluIHRoaXMgcGhhc2UsIGJlY2F1c2Ugd2UKICAgICAgICAgICAgLy8gYXJlIGd1YXJhbnRlZWQgdGhhdCBhbGwgc2VsZi1pbnRlcnNlY3Rpb25zIGFyZSBnb25lCiAgICAgICAgICAgIGV2ZS5zZWcub3RoZXJGaWxsID0gZXYuc2VnLm15RmlsbDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuc2VnbWVudFVwZGF0ZShldmUuc2VnKTsKICAgICAgICAgIGV2Lm90aGVyLnJlbW92ZSgpOwogICAgICAgICAgZXYucmVtb3ZlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChldmVudF9yb290LmdldEhlYWQoKSAhPT0gZXYpIHsKICAgICAgICAgIC8vIHNvbWV0aGluZyB3YXMgaW5zZXJ0ZWQgYmVmb3JlIHVzIGluIHRoZSBldmVudCBxdWV1ZSwgc28gbG9vcCBiYWNrIGFyb3VuZCBhbmQKICAgICAgICAgIC8vIHByb2Nlc3MgaXQgYmVmb3JlIGNvbnRpbnVpbmcKICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cucmV3aW5kKGV2LnNlZyk7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIC8vCiAgICAgICAgLy8gY2FsY3VsYXRlIGZpbGwgZmxhZ3MKICAgICAgICAvLwogICAgICAgIGlmIChzZWxmSW50ZXJzZWN0aW9uKSB7CiAgICAgICAgICB2YXIgdG9nZ2xlOyAvLyBhcmUgd2UgYSB0b2dnbGluZyBlZGdlPwogICAgICAgICAgaWYgKGV2LnNlZy5teUZpbGwuYmVsb3cgPT09IG51bGwpCiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBhIG5ldyBzZWdtZW50Li4uCiAgICAgICAgICAgIHRvZ2dsZSA9IHRydWU7IC8vIHRoZW4gd2UgdG9nZ2xlCiAgICAgICAgICBlbHNlCiAgICAgICAgICAgIC8vIHdlIGFyZSBhIHNlZ21lbnQgdGhhdCBoYXMgcHJldmlvdXMga25vd2xlZGdlIGZyb20gYSBkaXZpc2lvbgogICAgICAgICAgICB0b2dnbGUgPSBldi5zZWcubXlGaWxsLmFib3ZlICE9PSBldi5zZWcubXlGaWxsLmJlbG93OyAvLyBjYWxjdWxhdGUgdG9nZ2xlCgogICAgICAgICAgLy8gbmV4dCwgY2FsY3VsYXRlIHdoZXRoZXIgd2UgYXJlIGZpbGxlZCBiZWxvdyB1cwogICAgICAgICAgaWYgKCFiZWxvdykgewogICAgICAgICAgICAvLyBpZiBub3RoaW5nIGlzIGJlbG93IHVzLi4uCiAgICAgICAgICAgIC8vIHdlIGFyZSBmaWxsZWQgYmVsb3cgdXMgaWYgdGhlIHBvbHlnb24gaXMgaW52ZXJ0ZWQKICAgICAgICAgICAgZXYuc2VnLm15RmlsbC5iZWxvdyA9IHByaW1hcnlQb2x5SW52ZXJ0ZWQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBvdGhlcndpc2UsIHdlIGtub3cgdGhlIGFuc3dlciAtLSBpdCdzIHRoZSBzYW1lIGlmIHdoYXRldmVyIGlzIGJlbG93CiAgICAgICAgICAgIC8vIHVzIGlzIGZpbGxlZCBhYm92ZSBpdAogICAgICAgICAgICBldi5zZWcubXlGaWxsLmJlbG93ID0gYmVsb3cuc2VnLm15RmlsbC5hYm92ZTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBzaW5jZSBub3cgd2Uga25vdyBpZiB3ZSdyZSBmaWxsZWQgYmVsb3cgdXMsIHdlIGNhbiBjYWxjdWxhdGUgd2hldGhlcgogICAgICAgICAgLy8gd2UncmUgZmlsbGVkIGFib3ZlIHVzIGJ5IGFwcGx5aW5nIHRvZ2dsZSB0byB3aGF0ZXZlciBpcyBiZWxvdyB1cwogICAgICAgICAgaWYgKHRvZ2dsZSkgZXYuc2VnLm15RmlsbC5hYm92ZSA9ICFldi5zZWcubXlGaWxsLmJlbG93O2Vsc2UgZXYuc2VnLm15RmlsbC5hYm92ZSA9IGV2LnNlZy5teUZpbGwuYmVsb3c7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIG5vdyB3ZSBmaWxsIGluIGFueSBtaXNzaW5nIHRyYW5zaXRpb24gaW5mb3JtYXRpb24sIHNpbmNlIHdlIGFyZSBhbGwta25vd2luZwogICAgICAgICAgLy8gYXQgdGhpcyBwb2ludAoKICAgICAgICAgIGlmIChldi5zZWcub3RoZXJGaWxsID09PSBudWxsKSB7CiAgICAgICAgICAgIC8vIGlmIHdlIGRvbid0IGhhdmUgb3RoZXIgaW5mb3JtYXRpb24sIHRoZW4gd2UgbmVlZCB0byBmaWd1cmUgb3V0IGlmIHdlJ3JlCiAgICAgICAgICAgIC8vIGluc2lkZSB0aGUgb3RoZXIgcG9seWdvbgogICAgICAgICAgICB2YXIgaW5zaWRlOwogICAgICAgICAgICBpZiAoIWJlbG93KSB7CiAgICAgICAgICAgICAgLy8gaWYgbm90aGluZyBpcyBiZWxvdyB1cywgdGhlbiB3ZSdyZSBpbnNpZGUgaWYgdGhlIG90aGVyIHBvbHlnb24gaXMKICAgICAgICAgICAgICAvLyBpbnZlcnRlZAogICAgICAgICAgICAgIGluc2lkZSA9IGV2LnByaW1hcnkgPyBzZWNvbmRhcnlQb2x5SW52ZXJ0ZWQgOiBwcmltYXJ5UG9seUludmVydGVkOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgc29tZXRoaW5nIGlzIGJlbG93IHVzCiAgICAgICAgICAgICAgLy8gc28gY29weSB0aGUgYmVsb3cgc2VnbWVudCdzIG90aGVyIHBvbHlnb24ncyBhYm92ZQogICAgICAgICAgICAgIGlmIChldi5wcmltYXJ5ID09PSBiZWxvdy5wcmltYXJ5KSBpbnNpZGUgPSBiZWxvdy5zZWcub3RoZXJGaWxsLmFib3ZlO2Vsc2UgaW5zaWRlID0gYmVsb3cuc2VnLm15RmlsbC5hYm92ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBldi5zZWcub3RoZXJGaWxsID0gewogICAgICAgICAgICAgIGFib3ZlOiBpbnNpZGUsCiAgICAgICAgICAgICAgYmVsb3c6IGluc2lkZQogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoYnVpbGRMb2cpIHsKICAgICAgICAgIGJ1aWxkTG9nLnN0YXR1cyhldi5zZWcsIGFib3ZlID8gYWJvdmUuc2VnIDogZmFsc2UsIGJlbG93ID8gYmVsb3cuc2VnIDogZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gaW5zZXJ0IHRoZSBzdGF0dXMgYW5kIHJlbWVtYmVyIGl0IGZvciBsYXRlciByZW1vdmFsCiAgICAgICAgZXYub3RoZXIuc3RhdHVzID0gc3Vycm91bmRpbmcuaW5zZXJ0KExpbmtlZExpc3Qubm9kZSh7CiAgICAgICAgICBldjogZXYKICAgICAgICB9KSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIHN0ID0gZXYuc3RhdHVzOwogICAgICAgIGlmIChzdCA9PT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb2x5Qm9vbDogWmVyby1sZW5ndGggc2VnbWVudCBkZXRlY3RlZDsgeW91ciBlcHNpbG9uIGlzICcgKyAncHJvYmFibHkgdG9vIHNtYWxsIG9yIHRvbyBsYXJnZScpOwogICAgICAgIH0KCiAgICAgICAgLy8gcmVtb3ZpbmcgdGhlIHN0YXR1cyB3aWxsIGNyZWF0ZSB0d28gbmV3IGFkamFjZW50IGVkZ2VzLCBzbyB3ZSdsbCBuZWVkIHRvIGNoZWNrCiAgICAgICAgLy8gZm9yIHRob3NlCiAgICAgICAgaWYgKHN0YXR1c19yb290LmV4aXN0cyhzdC5wcmV2KSAmJiBzdGF0dXNfcm9vdC5leGlzdHMoc3QubmV4dCkpIGNoZWNrSW50ZXJzZWN0aW9uKHN0LnByZXYuZXYsIHN0Lm5leHQuZXYpOwogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuc3RhdHVzUmVtb3ZlKHN0LmV2LnNlZyk7CgogICAgICAgIC8vIHJlbW92ZSB0aGUgc3RhdHVzCiAgICAgICAgc3QucmVtb3ZlKCk7CgogICAgICAgIC8vIGlmIHdlJ3ZlIHJlYWNoZWQgdGhpcyBwb2ludCwgd2UndmUgY2FsY3VsYXRlZCBldmVyeXRoaW5nIHRoZXJlIGlzIHRvIGtub3csIHNvCiAgICAgICAgLy8gc2F2ZSB0aGUgc2VnbWVudCBmb3IgcmVwb3J0aW5nCiAgICAgICAgaWYgKCFldi5wcmltYXJ5KSB7CiAgICAgICAgICAvLyBtYWtlIHN1cmUgYHNlZy5teUZpbGxgIGFjdHVhbGx5IHBvaW50cyB0byB0aGUgcHJpbWFyeSBwb2x5Z29uIHRob3VnaAogICAgICAgICAgdmFyIHMgPSBldi5zZWcubXlGaWxsOwogICAgICAgICAgZXYuc2VnLm15RmlsbCA9IGV2LnNlZy5vdGhlckZpbGw7CiAgICAgICAgICBldi5zZWcub3RoZXJGaWxsID0gczsKICAgICAgICB9CiAgICAgICAgc2VnbWVudHMucHVzaChldi5zZWcpOwogICAgICB9CgogICAgICAvLyByZW1vdmUgdGhlIGV2ZW50IGFuZCBjb250aW51ZQogICAgICBldmVudF9yb290LmdldEhlYWQoKS5yZW1vdmUoKTsKICAgIH0KICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuZG9uZSgpOwogICAgcmV0dXJuIHNlZ21lbnRzOwogIH0KCiAgLy8gcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBBUEkgZGVwZW5kaW5nIG9uIHdoYXQgd2UncmUgZG9pbmcKICBpZiAoIXNlbGZJbnRlcnNlY3Rpb24pIHsKICAgIC8vIHBlcmZvcm1pbmcgY29tYmluYXRpb24gb2YgcG9seWdvbnMsIHNvIG9ubHkgZGVhbCB3aXRoIGFscmVhZHktcHJvY2Vzc2VkIHNlZ21lbnRzCiAgICByZXR1cm4gewogICAgICBjYWxjdWxhdGU6IGZ1bmN0aW9uIChzZWdtZW50czEsIGludmVydGVkMSwgc2VnbWVudHMyLCBpbnZlcnRlZDIpIHsKICAgICAgICAvLyBzZWdtZW50c1ggY29tZSBmcm9tIHRoZSBzZWxmLWludGVyc2VjdGlvbiBBUEksIG9yIHRoaXMgQVBJCiAgICAgICAgLy8gaW52ZXJ0ZWRYIGlzIHdoZXRoZXIgd2UgdHJlYXQgdGhhdCBsaXN0IG9mIHNlZ21lbnRzIGFzIGFuIGludmVydGVkIHBvbHlnb24gb3Igbm90CiAgICAgICAgLy8gcmV0dXJucyBzZWdtZW50cyB0aGF0IGNhbiBiZSB1c2VkIGZvciBmdXJ0aGVyIG9wZXJhdGlvbnMKICAgICAgICBzZWdtZW50czEuZm9yRWFjaChmdW5jdGlvbiAoc2VnKSB7CiAgICAgICAgICBldmVudEFkZFNlZ21lbnQoc2VnbWVudENvcHkoc2VnLnN0YXJ0LCBzZWcuZW5kLCBzZWcpLCB0cnVlKTsKICAgICAgICB9KTsKICAgICAgICBzZWdtZW50czIuZm9yRWFjaChmdW5jdGlvbiAoc2VnKSB7CiAgICAgICAgICBldmVudEFkZFNlZ21lbnQoc2VnbWVudENvcHkoc2VnLnN0YXJ0LCBzZWcuZW5kLCBzZWcpLCBmYWxzZSk7CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGNhbGN1bGF0ZShpbnZlcnRlZDEsIGludmVydGVkMik7CiAgICAgIH0KICAgIH07CiAgfQoKICAvLyBvdGhlcndpc2UsIHBlcmZvcm1pbmcgc2VsZi1pbnRlcnNlY3Rpb24sIHNvIGRlYWwgd2l0aCByZWdpb25zCiAgcmV0dXJuIHsKICAgIGFkZFJlZ2lvbjogZnVuY3Rpb24gKHJlZ2lvbikgewogICAgICAvLyByZWdpb25zIGFyZSBhIGxpc3Qgb2YgcG9pbnRzOgogICAgICAvLyAgWyBbMCwgMF0sIFsxMDAsIDBdLCBbNTAsIDEwMF0gXQogICAgICAvLyB5b3UgY2FuIGFkZCBtdWx0aXBsZSByZWdpb25zIGJlZm9yZSBydW5uaW5nIGNhbGN1bGF0ZQogICAgICB2YXIgcHQxOwogICAgICB2YXIgcHQyID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWdpb24ubGVuZ3RoOyBpKyspIHsKICAgICAgICBwdDEgPSBwdDI7CiAgICAgICAgcHQyID0gcmVnaW9uW2ldOwogICAgICAgIHZhciBmb3J3YXJkID0gZXBzLnBvaW50c0NvbXBhcmUocHQxLCBwdDIpOwogICAgICAgIGlmIChmb3J3YXJkID09PSAwKQogICAgICAgICAgLy8gcG9pbnRzIGFyZSBlcXVhbCwgc28gd2UgaGF2ZSBhIHplcm8tbGVuZ3RoIHNlZ21lbnQKICAgICAgICAgIGNvbnRpbnVlOyAvLyBqdXN0IHNraXAgaXQKCiAgICAgICAgZXZlbnRBZGRTZWdtZW50KHNlZ21lbnROZXcoZm9yd2FyZCA8IDAgPyBwdDEgOiBwdDIsIGZvcndhcmQgPCAwID8gcHQyIDogcHQxKSwgdHJ1ZSk7CiAgICAgIH0KICAgIH0sCiAgICBjYWxjdWxhdGU6IGZ1bmN0aW9uIChpbnZlcnRlZCkgewogICAgICAvLyBpcyB0aGUgcG9seWdvbiBpbnZlcnRlZD8KICAgICAgLy8gcmV0dXJucyBzZWdtZW50cwogICAgICByZXR1cm4gY2FsY3VsYXRlKGludmVydGVkLCBmYWxzZSk7CiAgICB9CiAgfTsKfQp2YXIgaW50ZXJzZWN0ZXIgPSBJbnRlcnNlY3RlciQxOwoKLy8gKGMpIENvcHlyaWdodCAyMDE2LCBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCi8vIE1JVCBMaWNlbnNlCi8vIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCgovLwovLyBjb252ZXJ0cyBhIGxpc3Qgb2Ygc2VnbWVudHMgaW50byBhIGxpc3Qgb2YgcmVnaW9ucywgd2hpbGUgYWxzbyByZW1vdmluZyB1bm5lY2Vzc2FyeSB2ZXJ0aWNpZXMKLy8KCmZ1bmN0aW9uIFNlZ21lbnRDaGFpbmVyJDEoc2VnbWVudHMsIGVwcywgYnVpbGRMb2cpIHsKICB2YXIgY2hhaW5zID0gW107CiAgdmFyIHJlZ2lvbnMgPSBbXTsKICBzZWdtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzZWcpIHsKICAgIHZhciBwdDEgPSBzZWcuc3RhcnQ7CiAgICB2YXIgcHQyID0gc2VnLmVuZDsKICAgIGlmIChlcHMucG9pbnRzU2FtZShwdDEsIHB0MikpIHsKICAgICAgY29uc29sZS53YXJuKCdQb2x5Qm9vbDogV2FybmluZzogWmVyby1sZW5ndGggc2VnbWVudCBkZXRlY3RlZDsgeW91ciBlcHNpbG9uIGlzICcgKyAncHJvYmFibHkgdG9vIHNtYWxsIG9yIHRvbyBsYXJnZScpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluU3RhcnQoc2VnKTsKCiAgICAvLyBzZWFyY2ggZm9yIHR3byBjaGFpbnMgdGhhdCB0aGlzIHNlZ21lbnQgbWF0Y2hlcwogICAgdmFyIGZpcnN0X21hdGNoID0gewogICAgICBpbmRleDogMCwKICAgICAgbWF0Y2hlc19oZWFkOiBmYWxzZSwKICAgICAgbWF0Y2hlc19wdDE6IGZhbHNlCiAgICB9OwogICAgdmFyIHNlY29uZF9tYXRjaCA9IHsKICAgICAgaW5kZXg6IDAsCiAgICAgIG1hdGNoZXNfaGVhZDogZmFsc2UsCiAgICAgIG1hdGNoZXNfcHQxOiBmYWxzZQogICAgfTsKICAgIHZhciBuZXh0X21hdGNoID0gZmlyc3RfbWF0Y2g7CiAgICBmdW5jdGlvbiBzZXRNYXRjaChpbmRleCwgbWF0Y2hlc19oZWFkLCBtYXRjaGVzX3B0MSkgewogICAgICAvLyByZXR1cm4gdHJ1ZSBpZiB3ZSd2ZSBtYXRjaGVkIHR3aWNlCiAgICAgIG5leHRfbWF0Y2guaW5kZXggPSBpbmRleDsKICAgICAgbmV4dF9tYXRjaC5tYXRjaGVzX2hlYWQgPSBtYXRjaGVzX2hlYWQ7CiAgICAgIG5leHRfbWF0Y2gubWF0Y2hlc19wdDEgPSBtYXRjaGVzX3B0MTsKICAgICAgaWYgKG5leHRfbWF0Y2ggPT09IGZpcnN0X21hdGNoKSB7CiAgICAgICAgbmV4dF9tYXRjaCA9IHNlY29uZF9tYXRjaDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbmV4dF9tYXRjaCA9IG51bGw7CiAgICAgIHJldHVybiB0cnVlOyAvLyB3ZSd2ZSBtYXRjaGVkIHR3aWNlLCB3ZSdyZSBkb25lIGhlcmUKICAgIH0KCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoYWlucy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgY2hhaW4gPSBjaGFpbnNbaV07CiAgICAgIHZhciBoZWFkID0gY2hhaW5bMF07CiAgICAgIGNoYWluWzFdOwogICAgICB2YXIgdGFpbCA9IGNoYWluW2NoYWluLmxlbmd0aCAtIDFdOwogICAgICBjaGFpbltjaGFpbi5sZW5ndGggLSAyXTsKICAgICAgaWYgKGVwcy5wb2ludHNTYW1lKGhlYWQsIHB0MSkpIHsKICAgICAgICBpZiAoc2V0TWF0Y2goaSwgdHJ1ZSwgdHJ1ZSkpIGJyZWFrOwogICAgICB9IGVsc2UgaWYgKGVwcy5wb2ludHNTYW1lKGhlYWQsIHB0MikpIHsKICAgICAgICBpZiAoc2V0TWF0Y2goaSwgdHJ1ZSwgZmFsc2UpKSBicmVhazsKICAgICAgfSBlbHNlIGlmIChlcHMucG9pbnRzU2FtZSh0YWlsLCBwdDEpKSB7CiAgICAgICAgaWYgKHNldE1hdGNoKGksIGZhbHNlLCB0cnVlKSkgYnJlYWs7CiAgICAgIH0gZWxzZSBpZiAoZXBzLnBvaW50c1NhbWUodGFpbCwgcHQyKSkgewogICAgICAgIGlmIChzZXRNYXRjaChpLCBmYWxzZSwgZmFsc2UpKSBicmVhazsKICAgICAgfQogICAgfQogICAgaWYgKG5leHRfbWF0Y2ggPT09IGZpcnN0X21hdGNoKSB7CiAgICAgIC8vIHdlIGRpZG4ndCBtYXRjaCBhbnl0aGluZywgc28gY3JlYXRlIGEgbmV3IGNoYWluCiAgICAgIGNoYWlucy5wdXNoKFtwdDEsIHB0Ml0pOwogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluTmV3KHB0MSwgcHQyKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKG5leHRfbWF0Y2ggPT09IHNlY29uZF9tYXRjaCkgewogICAgICAvLyB3ZSBtYXRjaGVkIGEgc2luZ2xlIGNoYWluCgogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluTWF0Y2goZmlyc3RfbWF0Y2guaW5kZXgpOwoKICAgICAgLy8gYWRkIHRoZSBvdGhlciBwb2ludCB0byB0aGUgYXBwb3JwcmlhdGUgZW5kLCBhbmQgY2hlY2sgdG8gc2VlIGlmIHdlJ3ZlIGNsb3NlZCB0aGUKICAgICAgLy8gY2hhaW4gaW50byBhIGxvb3AKCiAgICAgIHZhciBpbmRleCA9IGZpcnN0X21hdGNoLmluZGV4OwogICAgICB2YXIgcHQgPSBmaXJzdF9tYXRjaC5tYXRjaGVzX3B0MSA/IHB0MiA6IHB0MTsgLy8gaWYgd2UgbWF0Y2hlZCBwdDEsIHRoZW4gd2UgYWRkIHB0MiwgZXRjCiAgICAgIHZhciBhZGRUb0hlYWQgPSBmaXJzdF9tYXRjaC5tYXRjaGVzX2hlYWQ7IC8vIGlmIHdlIG1hdGNoZWQgYXQgaGVhZCwgdGhlbiBhZGQgdG8gdGhlIGhlYWQKCiAgICAgIHZhciBjaGFpbiA9IGNoYWluc1tpbmRleF07CiAgICAgIHZhciBncm93ID0gYWRkVG9IZWFkID8gY2hhaW5bMF0gOiBjaGFpbltjaGFpbi5sZW5ndGggLSAxXTsKICAgICAgdmFyIGdyb3cyID0gYWRkVG9IZWFkID8gY2hhaW5bMV0gOiBjaGFpbltjaGFpbi5sZW5ndGggLSAyXTsKICAgICAgdmFyIG9wcG8gPSBhZGRUb0hlYWQgPyBjaGFpbltjaGFpbi5sZW5ndGggLSAxXSA6IGNoYWluWzBdOwogICAgICB2YXIgb3BwbzIgPSBhZGRUb0hlYWQgPyBjaGFpbltjaGFpbi5sZW5ndGggLSAyXSA6IGNoYWluWzFdOwogICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcihncm93MiwgZ3JvdywgcHQpKSB7CiAgICAgICAgLy8gZ3JvdyBpc24ndCBuZWVkZWQgYmVjYXVzZSBpdCdzIGRpcmVjdGx5IGJldHdlZW4gZ3JvdzIgYW5kIHB0OgogICAgICAgIC8vIGdyb3cyIC0tLWdyb3ctLS0+IHB0CiAgICAgICAgaWYgKGFkZFRvSGVhZCkgewogICAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJlbW92ZUhlYWQoZmlyc3RfbWF0Y2guaW5kZXgsIHB0KTsKICAgICAgICAgIGNoYWluLnNoaWZ0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVUYWlsKGZpcnN0X21hdGNoLmluZGV4LCBwdCk7CiAgICAgICAgICBjaGFpbi5wb3AoKTsKICAgICAgICB9CiAgICAgICAgZ3JvdyA9IGdyb3cyOyAvLyBvbGQgZ3JvdyBpcyBnb25lLi4uIG5ldyBncm93IGlzIHdoYXQgZ3JvdzIgd2FzCiAgICAgIH0KCiAgICAgIGlmIChlcHMucG9pbnRzU2FtZShvcHBvLCBwdCkpIHsKICAgICAgICAvLyB3ZSdyZSBjbG9zaW5nIHRoZSBsb29wLCBzbyByZW1vdmUgY2hhaW4gZnJvbSBjaGFpbnMKICAgICAgICBjaGFpbnMuc3BsaWNlKGluZGV4LCAxKTsKICAgICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcihvcHBvMiwgb3BwbywgZ3JvdykpIHsKICAgICAgICAgIC8vIG9wcG8gaXNuJ3QgbmVlZGVkIGJlY2F1c2UgaXQncyBkaXJlY3RseSBiZXR3ZWVuIG9wcG8yIGFuZCBncm93OgogICAgICAgICAgLy8gb3BwbzIgLS0tb3Bwby0tLT5ncm93CiAgICAgICAgICBpZiAoYWRkVG9IZWFkKSB7CiAgICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVUYWlsKGZpcnN0X21hdGNoLmluZGV4LCBncm93KTsKICAgICAgICAgICAgY2hhaW4ucG9wKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlSGVhZChmaXJzdF9tYXRjaC5pbmRleCwgZ3Jvdyk7CiAgICAgICAgICAgIGNoYWluLnNoaWZ0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5DbG9zZShmaXJzdF9tYXRjaC5pbmRleCk7CgogICAgICAgIC8vIHdlIGhhdmUgYSBjbG9zZWQgY2hhaW4hCiAgICAgICAgcmVnaW9ucy5wdXNoKGNoYWluKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIC8vIG5vdCBjbG9zaW5nIGEgbG9vcCwgc28ganVzdCBhZGQgaXQgdG8gdGhlIGFwcG9ycHJpYXRlIHNpZGUKICAgICAgaWYgKGFkZFRvSGVhZCkgewogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5BZGRIZWFkKGZpcnN0X21hdGNoLmluZGV4LCBwdCk7CiAgICAgICAgY2hhaW4udW5zaGlmdChwdCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbkFkZFRhaWwoZmlyc3RfbWF0Y2guaW5kZXgsIHB0KTsKICAgICAgICBjaGFpbi5wdXNoKHB0KTsKICAgICAgfQogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gb3RoZXJ3aXNlLCB3ZSBtYXRjaGVkIHR3byBjaGFpbnMsIHNvIHdlIG5lZWQgdG8gY29tYmluZSB0aG9zZSBjaGFpbnMgdG9nZXRoZXIKCiAgICBmdW5jdGlvbiByZXZlcnNlQ2hhaW4oaW5kZXgpIHsKICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJldmVyc2UoaW5kZXgpOwogICAgICBjaGFpbnNbaW5kZXhdLnJldmVyc2UoKTsgLy8gZ2VlLCB0aGF0J3MgZWFzeQogICAgfQoKICAgIGZ1bmN0aW9uIGFwcGVuZENoYWluKGluZGV4MSwgaW5kZXgyKSB7CiAgICAgIC8vIGluZGV4MSBnZXRzIGluZGV4MiBhcHBlbmRlZCB0byBpdCwgYW5kIGluZGV4MiBpcyByZW1vdmVkCiAgICAgIHZhciBjaGFpbjEgPSBjaGFpbnNbaW5kZXgxXTsKICAgICAgdmFyIGNoYWluMiA9IGNoYWluc1tpbmRleDJdOwogICAgICB2YXIgdGFpbCA9IGNoYWluMVtjaGFpbjEubGVuZ3RoIC0gMV07CiAgICAgIHZhciB0YWlsMiA9IGNoYWluMVtjaGFpbjEubGVuZ3RoIC0gMl07CiAgICAgIHZhciBoZWFkID0gY2hhaW4yWzBdOwogICAgICB2YXIgaGVhZDIgPSBjaGFpbjJbMV07CiAgICAgIGlmIChlcHMucG9pbnRzQ29sbGluZWFyKHRhaWwyLCB0YWlsLCBoZWFkKSkgewogICAgICAgIC8vIHRhaWwgaXNuJ3QgbmVlZGVkIGJlY2F1c2UgaXQncyBkaXJlY3RseSBiZXR3ZWVuIHRhaWwyIGFuZCBoZWFkCiAgICAgICAgLy8gdGFpbDIgLS0tdGFpbC0tLT4gaGVhZAogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVUYWlsKGluZGV4MSwgdGFpbCk7CiAgICAgICAgY2hhaW4xLnBvcCgpOwogICAgICAgIHRhaWwgPSB0YWlsMjsgLy8gb2xkIHRhaWwgaXMgZ29uZS4uLiBuZXcgdGFpbCBpcyB3aGF0IHRhaWwyIHdhcwogICAgICB9CgogICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcih0YWlsLCBoZWFkLCBoZWFkMikpIHsKICAgICAgICAvLyBoZWFkIGlzbid0IG5lZWRlZCBiZWNhdXNlIGl0J3MgZGlyZWN0bHkgYmV0d2VlbiB0YWlsIGFuZCBoZWFkMgogICAgICAgIC8vIHRhaWwgLS0taGVhZC0tLT4gaGVhZDIKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlSGVhZChpbmRleDIsIGhlYWQpOwogICAgICAgIGNoYWluMi5zaGlmdCgpOwogICAgICB9CiAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5Kb2luKGluZGV4MSwgaW5kZXgyKTsKICAgICAgY2hhaW5zW2luZGV4MV0gPSBjaGFpbjEuY29uY2F0KGNoYWluMik7CiAgICAgIGNoYWlucy5zcGxpY2UoaW5kZXgyLCAxKTsKICAgIH0KICAgIHZhciBGID0gZmlyc3RfbWF0Y2guaW5kZXg7CiAgICB2YXIgUyA9IHNlY29uZF9tYXRjaC5pbmRleDsKICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5Db25uZWN0KEYsIFMpOwogICAgdmFyIHJldmVyc2VGID0gY2hhaW5zW0ZdLmxlbmd0aCA8IGNoYWluc1tTXS5sZW5ndGg7IC8vIHJldmVyc2UgdGhlIHNob3J0ZXIgY2hhaW4sIGlmIG5lZWRlZAogICAgaWYgKGZpcnN0X21hdGNoLm1hdGNoZXNfaGVhZCkgewogICAgICBpZiAoc2Vjb25kX21hdGNoLm1hdGNoZXNfaGVhZCkgewogICAgICAgIGlmIChyZXZlcnNlRikgewogICAgICAgICAgLy8gPDw8PCBGIDw8PDwgLS0tID4+Pj4gUyA+Pj4+CiAgICAgICAgICByZXZlcnNlQ2hhaW4oRik7CiAgICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPj4+PiBTID4+Pj4KICAgICAgICAgIGFwcGVuZENoYWluKEYsIFMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyA8PDw8IEYgPDw8PCAtLS0gPj4+PiBTID4+Pj4KICAgICAgICAgIHJldmVyc2VDaGFpbihTKTsKICAgICAgICAgIC8vIDw8PDwgRiA8PDw8IC0tLSA8PDw8IFMgPDw8PCAgIGxvZ2ljYWxseSBzYW1lIGFzOgogICAgICAgICAgLy8gPj4+PiBTID4+Pj4gLS0tID4+Pj4gRiA+Pj4+CiAgICAgICAgICBhcHBlbmRDaGFpbihTLCBGKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gPDw8PCBGIDw8PDwgLS0tIDw8PDwgUyA8PDw8ICAgbG9naWNhbGx5IHNhbWUgYXM6CiAgICAgICAgLy8gPj4+PiBTID4+Pj4gLS0tID4+Pj4gRiA+Pj4+CiAgICAgICAgYXBwZW5kQ2hhaW4oUywgRik7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGlmIChzZWNvbmRfbWF0Y2gubWF0Y2hlc19oZWFkKSB7CiAgICAgICAgLy8gPj4+PiBGID4+Pj4gLS0tID4+Pj4gUyA+Pj4+CiAgICAgICAgYXBwZW5kQ2hhaW4oRiwgUyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHJldmVyc2VGKSB7CiAgICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPDw8PCBTIDw8PDwKICAgICAgICAgIHJldmVyc2VDaGFpbihGKTsKICAgICAgICAgIC8vIDw8PDwgRiA8PDw8IC0tLSA8PDw8IFMgPDw8PCAgIGxvZ2ljYWxseSBzYW1lIGFzOgogICAgICAgICAgLy8gPj4+PiBTID4+Pj4gLS0tID4+Pj4gRiA+Pj4+CiAgICAgICAgICBhcHBlbmRDaGFpbihTLCBGKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gPj4+PiBGID4+Pj4gLS0tIDw8PDwgUyA8PDw8CiAgICAgICAgICByZXZlcnNlQ2hhaW4oUyk7CiAgICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPj4+PiBTID4+Pj4KICAgICAgICAgIGFwcGVuZENoYWluKEYsIFMpOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0pOwogIHJldHVybiByZWdpb25zOwp9CnZhciBzZWdtZW50Q2hhaW5lciA9IFNlZ21lbnRDaGFpbmVyJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIGZpbHRlciBhIGxpc3Qgb2Ygc2VnbWVudHMgYmFzZWQgb24gYm9vbGVhbiBvcGVyYXRpb25zCi8vCgpmdW5jdGlvbiBzZWxlY3Qoc2VnbWVudHMsIHNlbGVjdGlvbiwgYnVpbGRMb2cpIHsKICB2YXIgcmVzdWx0ID0gW107CiAgc2VnbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoc2VnKSB7CiAgICB2YXIgaW5kZXggPSAoc2VnLm15RmlsbC5hYm92ZSA/IDggOiAwKSArIChzZWcubXlGaWxsLmJlbG93ID8gNCA6IDApICsgKHNlZy5vdGhlckZpbGwgJiYgc2VnLm90aGVyRmlsbC5hYm92ZSA/IDIgOiAwKSArIChzZWcub3RoZXJGaWxsICYmIHNlZy5vdGhlckZpbGwuYmVsb3cgPyAxIDogMCk7CiAgICBpZiAoc2VsZWN0aW9uW2luZGV4XSAhPT0gMCkgewogICAgICAvLyBjb3B5IHRoZSBzZWdtZW50IHRvIHRoZSByZXN1bHRzLCB3aGlsZSBhbHNvIGNhbGN1bGF0aW5nIHRoZSBmaWxsIHN0YXR1cwogICAgICByZXN1bHQucHVzaCh7CiAgICAgICAgaWQ6IGJ1aWxkTG9nID8gYnVpbGRMb2cuc2VnbWVudElkKCkgOiAtMSwKICAgICAgICBzdGFydDogc2VnLnN0YXJ0LAogICAgICAgIGVuZDogc2VnLmVuZCwKICAgICAgICBteUZpbGw6IHsKICAgICAgICAgIGFib3ZlOiBzZWxlY3Rpb25baW5kZXhdID09PSAxLAogICAgICAgICAgLy8gMSBpZiBmaWxsZWQgYWJvdmUKICAgICAgICAgIGJlbG93OiBzZWxlY3Rpb25baW5kZXhdID09PSAyIC8vIDIgaWYgZmlsbGVkIGJlbG93CiAgICAgICAgfSwKCiAgICAgICAgb3RoZXJGaWxsOiBudWxsCiAgICAgIH0pOwogICAgfQogIH0pOwogIGlmIChidWlsZExvZykgYnVpbGRMb2cuc2VsZWN0ZWQocmVzdWx0KTsKICByZXR1cm4gcmVzdWx0Owp9CnZhciBTZWdtZW50U2VsZWN0b3IkMSA9IHsKICB1bmlvbjogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gcHJpbWFyeSB8IHNlY29uZGFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDIsIDEsIDAsIDIsIDIsIDAsIDAsIDEsIDAsIDEsIDAsIDAsIDAsIDAsIDBdLCBidWlsZExvZyk7CiAgfSwKICBpbnRlcnNlY3Q6IGZ1bmN0aW9uIChzZWdtZW50cywgYnVpbGRMb2cpIHsKICAgIC8vIHByaW1hcnkgJiBzZWNvbmRhcnkKICAgIC8vIGFib3ZlMSBiZWxvdzEgYWJvdmUyIGJlbG93MiAgICBLZWVwPyAgICAgICAgICAgICAgIFZhbHVlCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIHJldHVybiBzZWxlY3Qoc2VnbWVudHMsIFswLCAwLCAwLCAwLCAwLCAyLCAwLCAyLCAwLCAwLCAxLCAxLCAwLCAyLCAxLCAwXSwgYnVpbGRMb2cpOwogIH0sCiAgZGlmZmVyZW5jZTogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gcHJpbWFyeSAtIHNlY29uZGFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDAsIDAsIDAsIDIsIDAsIDIsIDAsIDEsIDEsIDAsIDAsIDAsIDEsIDIsIDBdLCBidWlsZExvZyk7CiAgfSwKICBkaWZmZXJlbmNlUmV2OiBmdW5jdGlvbiAoc2VnbWVudHMsIGJ1aWxkTG9nKSB7CiAgICAvLyBzZWNvbmRhcnkgLSBwcmltYXJ5CiAgICAvLyBhYm92ZTEgYmVsb3cxIGFib3ZlMiBiZWxvdzIgICAgS2VlcD8gICAgICAgICAgICAgICBWYWx1ZQogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICByZXR1cm4gc2VsZWN0KHNlZ21lbnRzLCBbMCwgMiwgMSwgMCwgMCwgMCwgMSwgMSwgMCwgMiwgMCwgMiwgMCwgMCwgMCwgMF0sIGJ1aWxkTG9nKTsKICB9LAogIHhvcjogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gcHJpbWFyeSBeIHNlY29uZGFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDIsIDEsIDAsIDIsIDAsIDAsIDEsIDEsIDAsIDAsIDIsIDAsIDEsIDIsIDBdLCBidWlsZExvZyk7CiAgfQp9Owp2YXIgc2VnbWVudFNlbGVjdG9yID0gU2VnbWVudFNlbGVjdG9yJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTcsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIGNvbnZlcnQgYmV0d2VlbiBQb2x5Qm9vbCBwb2x5Z29uIGZvcm1hdCBhbmQgR2VvSlNPTiBmb3JtYXRzIChQb2x5Z29uIGFuZCBNdWx0aVBvbHlnb24pCi8vCgp2YXIgR2VvSlNPTiQxID0gewogIC8vIGNvbnZlcnQgYSBHZW9KU09OIG9iamVjdCB0byBhIFBvbHlCb29sIHBvbHlnb24KICB0b1BvbHlnb246IGZ1bmN0aW9uIChQb2x5Qm9vbCwgZ2VvanNvbikgewogICAgLy8gY29udmVydHMgbGlzdCBvZiBMaW5lU3RyaW5nJ3MgdG8gc2VnbWVudHMKICAgIGZ1bmN0aW9uIEdlb1BvbHkoY29vcmRzKSB7CiAgICAgIC8vIGNoZWNrIGZvciBlbXB0eSBjb29yZHMKICAgICAgaWYgKGNvb3Jkcy5sZW5ndGggPD0gMCkgcmV0dXJuIFBvbHlCb29sLnNlZ21lbnRzKHsKICAgICAgICBpbnZlcnRlZDogZmFsc2UsCiAgICAgICAgcmVnaW9uczogW10KICAgICAgfSk7CgogICAgICAvLyBjb252ZXJ0IExpbmVTdHJpbmcgdG8gc2VnbWVudHMKICAgICAgZnVuY3Rpb24gTGluZVN0cmluZyhscykgewogICAgICAgIC8vIHJlbW92ZSB0YWlsIHdoaWNoIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBoZWFkCiAgICAgICAgdmFyIHJlZyA9IGxzLnNsaWNlKDAsIGxzLmxlbmd0aCAtIDEpOwogICAgICAgIHJldHVybiBQb2x5Qm9vbC5zZWdtZW50cyh7CiAgICAgICAgICBpbnZlcnRlZDogZmFsc2UsCiAgICAgICAgICByZWdpb25zOiBbcmVnXQogICAgICAgIH0pOwogICAgICB9CgogICAgICAvLyB0aGUgZmlyc3QgTGluZVN0cmluZyBpcyBjb25zaWRlcmVkIHRoZSBvdXRzaWRlCiAgICAgIHZhciBvdXQgPSBMaW5lU3RyaW5nKGNvb3Jkc1swXSk7CgogICAgICAvLyB0aGUgcmVzdCBvZiB0aGUgTGluZVN0cmluZ3MgYXJlIGNvbnNpZGVyZWQgaW50ZXJpb3IgaG9sZXMsIHNvIHN1YnRyYWN0IHRoZW0gZnJvbSB0aGUKICAgICAgLy8gY3VycmVudCByZXN1bHQKICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIG91dCA9IFBvbHlCb29sLnNlbGVjdERpZmZlcmVuY2UoUG9seUJvb2wuY29tYmluZShvdXQsIExpbmVTdHJpbmcoY29vcmRzW2ldKSkpOwogICAgICByZXR1cm4gb3V0OwogICAgfQogICAgaWYgKGdlb2pzb24udHlwZSA9PT0gJ1BvbHlnb24nKSB7CiAgICAgIC8vIHNpbmdsZSBwb2x5Z29uLCBzbyBqdXN0IGNvbnZlcnQgaXQgYW5kIHdlJ3JlIGRvbmUKICAgICAgcmV0dXJuIFBvbHlCb29sLnBvbHlnb24oR2VvUG9seShnZW9qc29uLmNvb3JkaW5hdGVzKSk7CiAgICB9IGVsc2UgaWYgKGdlb2pzb24udHlwZSA9PT0gJ011bHRpUG9seWdvbicpIHsKICAgICAgLy8gbXVsdGlwbGUgcG9seWdvbnMsIHNvIHVuaW9uIGFsbCB0aGUgcG9seWdvbnMgdG9nZXRoZXIKICAgICAgdmFyIG91dCA9IFBvbHlCb29sLnNlZ21lbnRzKHsKICAgICAgICBpbnZlcnRlZDogZmFsc2UsCiAgICAgICAgcmVnaW9uczogW10KICAgICAgfSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ2VvanNvbi5jb29yZGluYXRlcy5sZW5ndGg7IGkrKykgb3V0ID0gUG9seUJvb2wuc2VsZWN0VW5pb24oUG9seUJvb2wuY29tYmluZShvdXQsIEdlb1BvbHkoZ2VvanNvbi5jb29yZGluYXRlc1tpXSkpKTsKICAgICAgcmV0dXJuIFBvbHlCb29sLnBvbHlnb24ob3V0KTsKICAgIH0KICAgIHRocm93IG5ldyBFcnJvcignUG9seUJvb2w6IENhbm5vdCBjb252ZXJ0IEdlb0pTT04gb2JqZWN0IHRvIFBvbHlCb29sIHBvbHlnb24nKTsKICB9LAogIC8vIGNvbnZlcnQgYSBQb2x5Qm9vbCBwb2x5Z29uIHRvIGEgR2VvSlNPTiBvYmplY3QKICBmcm9tUG9seWdvbjogZnVuY3Rpb24gKFBvbHlCb29sLCBlcHMsIHBvbHkpIHsKICAgIC8vIG1ha2Ugc3VyZSBvdXQgcG9seWdvbiBpcyBjbGVhbgogICAgcG9seSA9IFBvbHlCb29sLnBvbHlnb24oUG9seUJvb2wuc2VnbWVudHMocG9seSkpOwoKICAgIC8vIHRlc3QgaWYgcjEgaXMgaW5zaWRlIHIyCiAgICBmdW5jdGlvbiByZWdpb25JbnNpZGVSZWdpb24ocjEsIHIyKSB7CiAgICAgIC8vIHdlJ3JlIGd1YXJhbnRlZWQgbm8gbGluZXMgaW50ZXJzZWN0IChiZWNhdXNlIHRoZSBwb2x5Z29uIGlzIGNsZWFuKSwgYnV0IGEgdmVydGV4CiAgICAgIC8vIGNvdWxkIGJlIG9uIHRoZSBlZGdlIC0tIHNvIHdlIGp1c3QgYXZlcmFnZSBwdFswXSBhbmQgcHRbMV0gdG8gcHJvZHVjZSBhIHBvaW50IG9uIHRoZQogICAgICAvLyBlZGdlIG9mIHRoZSBmaXJzdCBsaW5lLCB3aGljaCBjYW5ub3QgYmUgb24gYW4gZWRnZQogICAgICByZXR1cm4gZXBzLnBvaW50SW5zaWRlUmVnaW9uKFsocjFbMF1bMF0gKyByMVsxXVswXSkgKiAwLjUsIChyMVswXVsxXSArIHIxWzFdWzFdKSAqIDAuNV0sIHIyKTsKICAgIH0KCiAgICAvLyBjYWxjdWxhdGUgaW5zaWRlIGhlaXJhcmNoeQogICAgLy8KICAgIC8vICBfX19fX19fX19fX19fX19fX19fX18gICBfX19fX19fICAgIHJvb3RzIC0+IEEgICAgICAgLT4gRgogICAgLy8gfCAgICAgICAgICBBICAgICAgICAgIHwgfCAgIEYgICB8ICAgICAgICAgICAgfCAgICAgICAgICB8CiAgICAvLyB8ICBfX19fX19fICAgX19fX19fXyAgfCB8ICBfX18gIHwgICAgICAgICAgICArLS0gQiAgICAgICstLSBHCiAgICAvLyB8IHwgICBCICAgfCB8ICAgQyAgIHwgfCB8IHwgICB8IHwgICAgICAgICAgICB8ICAgfAogICAgLy8gfCB8ICBfX18gIHwgfCAgX19fICB8IHwgfCB8ICAgfCB8ICAgICAgICAgICAgfCAgICstLSBECiAgICAvLyB8IHwgfCBEIHwgfCB8IHwgRSB8IHwgfCB8IHwgRyB8IHwgICAgICAgICAgICB8CiAgICAvLyB8IHwgfF9fX3wgfCB8IHxfX198IHwgfCB8IHwgICB8IHwgICAgICAgICAgICArLS0gQwogICAgLy8gfCB8X19fX19fX3wgfF9fX19fX198IHwgfCB8X19ffCB8ICAgICAgICAgICAgICAgIHwKICAgIC8vIHxfX19fX19fX19fX19fX19fX19fX198IHxfX19fX19ffCAgICAgICAgICAgICAgICArLS0gRQoKICAgIGZ1bmN0aW9uIG5ld05vZGUocmVnaW9uKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgcmVnaW9uOiByZWdpb24sCiAgICAgICAgY2hpbGRyZW46IFtdCiAgICAgIH07CiAgICB9CiAgICB2YXIgcm9vdHMgPSBuZXdOb2RlKG51bGwpOwogICAgZnVuY3Rpb24gYWRkQ2hpbGQocm9vdCwgcmVnaW9uKSB7CiAgICAgIC8vIGZpcnN0IGNoZWNrIGlmIHdlJ3JlIGluc2lkZSBhbnkgY2hpbGRyZW4KICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb290LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGNoaWxkID0gcm9vdC5jaGlsZHJlbltpXTsKICAgICAgICBpZiAocmVnaW9uSW5zaWRlUmVnaW9uKHJlZ2lvbiwgY2hpbGQucmVnaW9uKSkgewogICAgICAgICAgLy8gd2UgYXJlLCBzbyBpbnNlcnQgaW5zaWRlIHRoZW0gaW5zdGVhZAogICAgICAgICAgYWRkQ2hpbGQoY2hpbGQsIHJlZ2lvbik7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBub3QgaW5zaWRlIGFueSBjaGlsZHJlbiwgc28gY2hlY2sgdG8gc2VlIGlmIGFueSBjaGlsZHJlbiBhcmUgaW5zaWRlIHVzCiAgICAgIHZhciBub2RlID0gbmV3Tm9kZShyZWdpb24pOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJvb3QuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgY2hpbGQgPSByb290LmNoaWxkcmVuW2ldOwogICAgICAgIGlmIChyZWdpb25JbnNpZGVSZWdpb24oY2hpbGQucmVnaW9uLCByZWdpb24pKSB7CiAgICAgICAgICAvLyBvb3BzLi4uIG1vdmUgdGhlIGNoaWxkIGJlbmVhdGggdXMsIGFuZCByZW1vdmUgdGhlbSBmcm9tIHJvb3QKICAgICAgICAgIG5vZGUuY2hpbGRyZW4ucHVzaChjaGlsZCk7CiAgICAgICAgICByb290LmNoaWxkcmVuLnNwbGljZShpLCAxKTsKICAgICAgICAgIGktLTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIG5vdyB3ZSBjYW4gYWRkIG91cnNlbHZlcwogICAgICByb290LmNoaWxkcmVuLnB1c2gobm9kZSk7CiAgICB9CgogICAgLy8gYWRkIGFsbCByZWdpb25zIHRvIHRoZSByb290CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvbHkucmVnaW9ucy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgcmVnaW9uID0gcG9seS5yZWdpb25zW2ldOwogICAgICBpZiAocmVnaW9uLmxlbmd0aCA8IDMpCiAgICAgICAgLy8gcmVnaW9ucyBtdXN0IGhhdmUgYXQgbGVhc3QgMyBwb2ludHMgKHNhbml0eSBjaGVjaykKICAgICAgICBjb250aW51ZTsKICAgICAgYWRkQ2hpbGQocm9vdHMsIHJlZ2lvbik7CiAgICB9CgogICAgLy8gd2l0aCBvdXIgaGVpcmFyY2h5LCB3ZSBjYW4gZGlzdGluZ3Vpc2ggYmV0d2VlbiBleHRlcmlvciBib3JkZXJzLCBhbmQgaW50ZXJpb3IgaG9sZXMKICAgIC8vIHRoZSByb290IG5vZGVzIGFyZSBleHRlcmlvciwgY2hpbGRyZW4gYXJlIGludGVyaW9yLCBjaGlsZHJlbidzIGNoaWxkcmVuIGFyZSBleHRlcmlvciwKICAgIC8vIGNoaWxkcmVuJ3MgY2hpbGRyZW4ncyBjaGlsZHJlbiBhcmUgaW50ZXJpb3IsIGV0YwoKICAgIC8vIHdoaWxlIHdlJ3JlIGF0IGl0LCBleHRlcmlvcnMgYXJlIGNvdW50ZXItY2xvY2t3aXNlLCBhbmQgaW50ZXJpb3JzIGFyZSBjbG9ja3dpc2UKCiAgICBmdW5jdGlvbiBmb3JjZVdpbmRpbmcocmVnaW9uLCBjbG9ja3dpc2UpIHsKICAgICAgLy8gZmlyc3QsIHNlZSBpZiB3ZSdyZSBjbG9ja3dpc2Ugb3IgY291bnRlci1jbG9ja3dpc2UKICAgICAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU2hvZWxhY2VfZm9ybXVsYQogICAgICB2YXIgd2luZGluZyA9IDA7CiAgICAgIHZhciBsYXN0X3ggPSByZWdpb25bcmVnaW9uLmxlbmd0aCAtIDFdWzBdOwogICAgICB2YXIgbGFzdF95ID0gcmVnaW9uW3JlZ2lvbi5sZW5ndGggLSAxXVsxXTsKICAgICAgdmFyIGNvcHkgPSBbXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWdpb24ubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgY3Vycl94ID0gcmVnaW9uW2ldWzBdOwogICAgICAgIHZhciBjdXJyX3kgPSByZWdpb25baV1bMV07CiAgICAgICAgY29weS5wdXNoKFtjdXJyX3gsIGN1cnJfeV0pOyAvLyBjcmVhdGUgYSBjb3B5IHdoaWxlIHdlJ3JlIGF0IGl0CiAgICAgICAgd2luZGluZyArPSBjdXJyX3kgKiBsYXN0X3ggLSBjdXJyX3ggKiBsYXN0X3k7CiAgICAgICAgbGFzdF94ID0gY3Vycl94OwogICAgICAgIGxhc3RfeSA9IGN1cnJfeTsKICAgICAgfQogICAgICAvLyB0aGlzIGFzc3VtZXMgQ2FydGVzaWFuIGNvb3JkaW5hdGVzIChZIGlzIHBvc2l0aXZlIGdvaW5nIHVwKQogICAgICB2YXIgaXNjbG9ja3dpc2UgPSB3aW5kaW5nIDwgMDsKICAgICAgaWYgKGlzY2xvY2t3aXNlICE9PSBjbG9ja3dpc2UpIGNvcHkucmV2ZXJzZSgpOwogICAgICAvLyB3aGlsZSB3ZSdyZSBoZXJlLCB0aGUgbGFzdCBwb2ludCBtdXN0IGJlIHRoZSBmaXJzdCBwb2ludC4uLgogICAgICBjb3B5LnB1c2goW2NvcHlbMF1bMF0sIGNvcHlbMF1bMV1dKTsKICAgICAgcmV0dXJuIGNvcHk7CiAgICB9CiAgICB2YXIgZ2VvcG9seXMgPSBbXTsKICAgIGZ1bmN0aW9uIGFkZEV4dGVyaW9yKG5vZGUpIHsKICAgICAgdmFyIHBvbHkgPSBbZm9yY2VXaW5kaW5nKG5vZGUucmVnaW9uLCBmYWxzZSldOwogICAgICBnZW9wb2x5cy5wdXNoKHBvbHkpOwogICAgICAvLyBjaGlsZHJlbiBvZiBleHRlcmlvcnMgYXJlIGludGVyaW9yCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykgcG9seS5wdXNoKGdldEludGVyaW9yKG5vZGUuY2hpbGRyZW5baV0pKTsKICAgIH0KICAgIGZ1bmN0aW9uIGdldEludGVyaW9yKG5vZGUpIHsKICAgICAgLy8gY2hpbGRyZW4gb2YgaW50ZXJpb3JzIGFyZSBleHRlcmlvcgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIGFkZEV4dGVyaW9yKG5vZGUuY2hpbGRyZW5baV0pOwogICAgICAvLyByZXR1cm4gdGhlIGNsb2Nrd2lzZSBpbnRlcmlvcgogICAgICByZXR1cm4gZm9yY2VXaW5kaW5nKG5vZGUucmVnaW9uLCB0cnVlKTsKICAgIH0KCiAgICAvLyByb290IG5vZGVzIGFyZSBleHRlcmlvcgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb290cy5jaGlsZHJlbi5sZW5ndGg7IGkrKykgYWRkRXh0ZXJpb3Iocm9vdHMuY2hpbGRyZW5baV0pOwoKICAgIC8vIGxhc3RseSwgY29uc3RydWN0IHRoZSBhcHByb3JwcmlhdGUgR2VvSlNPTiBvYmplY3QKCiAgICBpZiAoZ2VvcG9seXMubGVuZ3RoIDw9IDApCiAgICAgIC8vIGVtcHR5IEdlb0pTT04gUG9seWdvbgogICAgICByZXR1cm4gewogICAgICAgIHR5cGU6ICdQb2x5Z29uJywKICAgICAgICBjb29yZGluYXRlczogW10KICAgICAgfTsKICAgIGlmIChnZW9wb2x5cy5sZW5ndGggPT0gMSkKICAgICAgLy8gdXNlIGEgR2VvSlNPTiBQb2x5Z29uCiAgICAgIHJldHVybiB7CiAgICAgICAgdHlwZTogJ1BvbHlnb24nLAogICAgICAgIGNvb3JkaW5hdGVzOiBnZW9wb2x5c1swXQogICAgICB9OwogICAgcmV0dXJuIHsKICAgICAgLy8gb3RoZXJ3aXNlLCB1c2UgYSBHZW9KU09OIE11bHRpUG9seWdvbgogICAgICB0eXBlOiAnTXVsdGlQb2x5Z29uJywKICAgICAgY29vcmRpbmF0ZXM6IGdlb3BvbHlzCiAgICB9OwogIH0KfTsKdmFyIGdlb2pzb24gPSBHZW9KU09OJDE7CgovKgogKiBAY29weXJpZ2h0IDIwMTYgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwogKiBAbGljZW5zZSBNSVQKICogQHByZXNlcnZlIFByb2plY3QgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL3ZvaWRxay9wb2x5Ym9vbGpzCiAqLwp2YXIgQnVpbGRMb2cgPSBidWlsZExvZyQxOwp2YXIgRXBzaWxvbiA9IGVwc2lsb24kMzsKdmFyIEludGVyc2VjdGVyID0gaW50ZXJzZWN0ZXI7CnZhciBTZWdtZW50Q2hhaW5lciA9IHNlZ21lbnRDaGFpbmVyOwp2YXIgU2VnbWVudFNlbGVjdG9yID0gc2VnbWVudFNlbGVjdG9yOwp2YXIgR2VvSlNPTiA9IGdlb2pzb247CnZhciBidWlsZExvZyA9IGZhbHNlOwp2YXIgZXBzaWxvbiQyID0gRXBzaWxvbigpOwp2YXIgUG9seUJvb2w7ClBvbHlCb29sID0gewogIC8vIGdldHRlci9zZXR0ZXIgZm9yIGJ1aWxkTG9nCiAgYnVpbGRMb2c6IGZ1bmN0aW9uIChibCkgewogICAgaWYgKGJsID09PSB0cnVlKSBidWlsZExvZyA9IEJ1aWxkTG9nKCk7ZWxzZSBpZiAoYmwgPT09IGZhbHNlKSBidWlsZExvZyA9IGZhbHNlOwogICAgcmV0dXJuIGJ1aWxkTG9nID09PSBmYWxzZSA/IGZhbHNlIDogYnVpbGRMb2cubGlzdDsKICB9LAogIC8vIGdldHRlci9zZXR0ZXIgZm9yIGVwc2lsb24KICBlcHNpbG9uOiBmdW5jdGlvbiAodikgewogICAgcmV0dXJuIGVwc2lsb24kMi5lcHNpbG9uKHYpOwogIH0sCiAgLy8gY29yZSBBUEkKICBzZWdtZW50czogZnVuY3Rpb24gKHBvbHkpIHsKICAgIHZhciBpID0gSW50ZXJzZWN0ZXIodHJ1ZSwgZXBzaWxvbiQyLCBidWlsZExvZyk7CiAgICBwb2x5LnJlZ2lvbnMuZm9yRWFjaChpLmFkZFJlZ2lvbik7CiAgICByZXR1cm4gewogICAgICBzZWdtZW50czogaS5jYWxjdWxhdGUocG9seS5pbnZlcnRlZCksCiAgICAgIGludmVydGVkOiBwb2x5LmludmVydGVkCiAgICB9OwogIH0sCiAgY29tYmluZTogZnVuY3Rpb24gKHNlZ21lbnRzMSwgc2VnbWVudHMyKSB7CiAgICB2YXIgaTMgPSBJbnRlcnNlY3RlcihmYWxzZSwgZXBzaWxvbiQyLCBidWlsZExvZyk7CiAgICByZXR1cm4gewogICAgICBjb21iaW5lZDogaTMuY2FsY3VsYXRlKHNlZ21lbnRzMS5zZWdtZW50cywgc2VnbWVudHMxLmludmVydGVkLCBzZWdtZW50czIuc2VnbWVudHMsIHNlZ21lbnRzMi5pbnZlcnRlZCksCiAgICAgIGludmVydGVkMTogc2VnbWVudHMxLmludmVydGVkLAogICAgICBpbnZlcnRlZDI6IHNlZ21lbnRzMi5pbnZlcnRlZAogICAgfTsKICB9LAogIHNlbGVjdFVuaW9uOiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IudW5pb24oY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IGNvbWJpbmVkLmludmVydGVkMSB8fCBjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3RJbnRlcnNlY3Q6IGZ1bmN0aW9uIChjb21iaW5lZCkgewogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IFNlZ21lbnRTZWxlY3Rvci5pbnRlcnNlY3QoY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IGNvbWJpbmVkLmludmVydGVkMSAmJiBjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3REaWZmZXJlbmNlOiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IuZGlmZmVyZW5jZShjb21iaW5lZC5jb21iaW5lZCwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogY29tYmluZWQuaW52ZXJ0ZWQxICYmICFjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3REaWZmZXJlbmNlUmV2OiBmdW5jdGlvbiAoY29tYmluZWQpIHsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBTZWdtZW50U2VsZWN0b3IuZGlmZmVyZW5jZVJldihjb21iaW5lZC5jb21iaW5lZCwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogIWNvbWJpbmVkLmludmVydGVkMSAmJiBjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBzZWxlY3RYb3I6IGZ1bmN0aW9uIChjb21iaW5lZCkgewogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IFNlZ21lbnRTZWxlY3Rvci54b3IoY29tYmluZWQuY29tYmluZWQsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IGNvbWJpbmVkLmludmVydGVkMSAhPT0gY29tYmluZWQuaW52ZXJ0ZWQyCiAgICB9OwogIH0sCiAgcG9seWdvbjogZnVuY3Rpb24gKHNlZ21lbnRzKSB7CiAgICByZXR1cm4gewogICAgICByZWdpb25zOiBTZWdtZW50Q2hhaW5lcihzZWdtZW50cy5zZWdtZW50cywgZXBzaWxvbiQyLCBidWlsZExvZyksCiAgICAgIGludmVydGVkOiBzZWdtZW50cy5pbnZlcnRlZAogICAgfTsKICB9LAogIC8vIEdlb0pTT04gY29udmVydGVycwogIHBvbHlnb25Gcm9tR2VvSlNPTjogZnVuY3Rpb24gKGdlb2pzb24pIHsKICAgIHJldHVybiBHZW9KU09OLnRvUG9seWdvbihQb2x5Qm9vbCwgZ2VvanNvbik7CiAgfSwKICBwb2x5Z29uVG9HZW9KU09OOiBmdW5jdGlvbiAocG9seSkgewogICAgcmV0dXJuIEdlb0pTT04uZnJvbVBvbHlnb24oUG9seUJvb2wsIGVwc2lsb24kMiwgcG9seSk7CiAgfSwKICAvLyBoZWxwZXIgZnVuY3Rpb25zIGZvciBjb21tb24gb3BlcmF0aW9ucwogIHVuaW9uOiBmdW5jdGlvbiAocG9seTEsIHBvbHkyKSB7CiAgICByZXR1cm4gb3BlcmF0ZShwb2x5MSwgcG9seTIsIFBvbHlCb29sLnNlbGVjdFVuaW9uKTsKICB9LAogIGludGVyc2VjdDogZnVuY3Rpb24gKHBvbHkxLCBwb2x5MikgewogICAgcmV0dXJuIG9wZXJhdGUocG9seTEsIHBvbHkyLCBQb2x5Qm9vbC5zZWxlY3RJbnRlcnNlY3QpOwogIH0sCiAgZGlmZmVyZW5jZTogZnVuY3Rpb24gKHBvbHkxLCBwb2x5MikgewogICAgcmV0dXJuIG9wZXJhdGUocG9seTEsIHBvbHkyLCBQb2x5Qm9vbC5zZWxlY3REaWZmZXJlbmNlKTsKICB9LAogIGRpZmZlcmVuY2VSZXY6IGZ1bmN0aW9uIChwb2x5MSwgcG9seTIpIHsKICAgIHJldHVybiBvcGVyYXRlKHBvbHkxLCBwb2x5MiwgUG9seUJvb2wuc2VsZWN0RGlmZmVyZW5jZVJldik7CiAgfSwKICB4b3I6IGZ1bmN0aW9uIChwb2x5MSwgcG9seTIpIHsKICAgIHJldHVybiBvcGVyYXRlKHBvbHkxLCBwb2x5MiwgUG9seUJvb2wuc2VsZWN0WG9yKTsKICB9Cn07CmZ1bmN0aW9uIG9wZXJhdGUocG9seTEsIHBvbHkyLCBzZWxlY3RvcikgewogIHZhciBzZWcxID0gUG9seUJvb2wuc2VnbWVudHMocG9seTEpOwogIHZhciBzZWcyID0gUG9seUJvb2wuc2VnbWVudHMocG9seTIpOwogIHZhciBjb21iID0gUG9seUJvb2wuY29tYmluZShzZWcxLCBzZWcyKTsKICB2YXIgc2VnMyA9IHNlbGVjdG9yKGNvbWIpOwogIHJldHVybiBQb2x5Qm9vbC5wb2x5Z29uKHNlZzMpOwp9CmlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0Jykgd2luZG93LlBvbHlCb29sID0gUG9seUJvb2w7CnZhciBwb2x5Ym9vbGpzID0gUG9seUJvb2w7CgovKioKICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZQogKiBlcXVpdmFsZW50LgogKgogKiAqKk5vdGU6KiogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGFyaW5nIGFycmF5cywgYXJyYXkgYnVmZmVycywgYm9vbGVhbnMsCiAqIGRhdGUgb2JqZWN0cywgZXJyb3Igb2JqZWN0cywgbWFwcywgbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywKICogc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkIGFycmF5cy4gYE9iamVjdGAgb2JqZWN0cyBhcmUgY29tcGFyZWQKICogYnkgdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZ1bmN0aW9ucyBhbmQgRE9NCiAqIG5vZGVzIGFyZSBjb21wYXJlZCBieSBzdHJpY3QgZXF1YWxpdHksIGkuZS4gYD09PWAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9OwogKiB2YXIgb3RoZXIgPSB7ICdhJzogMSB9OwogKgogKiBfLmlzRXF1YWwob2JqZWN0LCBvdGhlcik7CiAqIC8vID0+IHRydWUKICoKICogb2JqZWN0ID09PSBvdGhlcjsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzRXF1YWwodmFsdWUsIG90aGVyKSB7CiAgcmV0dXJuIGJhc2VJc0VxdWFsKHZhbHVlLCBvdGhlcik7Cn0KCi8qKg0KICog5L+u5b6pUG9seWdvbuWFp+WQhFJpbmdTdHJpbmfngrrplonlkIgNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9maXhDbG9zZVBvbHlnb24udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwZ3Mg6Ly45YWlUG9seWdvbuizh+aWmemZo+WIl++8jOeCultbIFtbeDExLHkxMV0sW3gxMix5MTJdLC4uLl0sIFtbeDIxLHkyMV0sW3gyMix5MjJdLC4uLl0gXV3mp4vmiJDkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHJldHVybnMge0FycmF5fSDlm57lgrNQb2x5Z29u6Zmj5YiXDQogKiBAZXhhbXBsZQ0KDQogKi8KZnVuY3Rpb24gZml4Q2xvc2VQb2x5Z29uKHBncywgb3B0ID0ge30pIHsKICAvL2NoZWNrIHBncwogIGlmICghaXNlYXJyKHBncykpIHsKICAgIHRocm93IG5ldyBFcnJvcihgbm8gcGdzYCk7CiAgfQoKICAvL3RvUG9seWdvbgogIHBncyA9IHRvUG9seWdvbihwZ3MpOwoKICAvL+S/ruW+qeaIkOeCuumWieWQiAogIHBncyA9IG1hcChwZ3MsIHJzID0+IHsKICAgIGxldCBpMCA9IDA7CiAgICBsZXQgaTEgPSBzaXplKHJzKSAtIDE7CiAgICBsZXQgcnMwID0gcnNbaTBdOwogICAgbGV0IHJzMSA9IHJzW2kxXTsKICAgIGlmICghaXNFcXVhbChyczAsIHJzMSkpIHsKICAgICAgcnMucHVzaChyczApOwogICAgfQogICAgcmV0dXJuIHJzOwogIH0pOwogIHJldHVybiBwZ3M7Cn0KCi8qKg0KICog6Yed5bCNUG9seWdvbumAsuihjOS6pOmbhihpbnRlcnNlY3Qp6JmV55CGDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvaW50ZXJzZWN0UG9seWdvbi50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBnczEg6Ly45YWl56ysMeWAi1BvbHlnb27os4fmlpnpmaPliJfvvIzngrpbIFtbeDExLHkxMV0sW3gxMix5MTJdLC4uLl0sIFtbeDIxLHkyMV0sW3gyMix5MjJdLC4uLl0gXeani+aIkOS5i+mZo+WIlw0KICogQHBhcmFtIHtBcnJheX0gcGdzMiDovLjlhaXnrKwy5YCLUG9seWdvbuizh+aWmemZo+WIl++8jOeCulsgW1t4MTEseTExXSxbeDEyLHkxMl0sLi4uXSwgW1t4MjEseTIxXSxbeDIyLHkyMl0sLi4uXSBd5qeL5oiQ5LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LmVwc2lsb249MC4wMDAwMDAwMDAwMDFdIOi8uOWFpSBwb2x5Ym9vbGpzIOioiOeul+WuueioseiqpOW3rg0KICogQHJldHVybnMge0FycmF5fSDlm57lgrNQb2x5Z29u6Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwZ3MxDQogKiBsZXQgcGdzMg0KICogbGV0IHINCiAqDQogKiBwZ3MxID0gJ25vdCBhcnJheScNCiAqIHBnczIgPSBbW1syLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFsyLCA0XV1dIC8vcG9seWdvbg0KICogdHJ5IHsNCiAqICAgICByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIH0NCiAqIGNhdGNoIChlcnIpIHsNCiAqICAgICByID0gZXJyLm1lc3NhZ2UNCiAqIH0NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBubyBwZ3MxDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gJ25vdCBhcnJheScNCiAqIHRyeSB7DQogKiAgICAgciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiB9DQogKiBjYXRjaCAoZXJyKSB7DQogKiAgICAgciA9IGVyci5tZXNzYWdlDQogKiB9DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gaW52YWxpZCBwZ3MyDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbMSwgMF0sIFsxLCAxXSwgWzAsIDFdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW10NCiAqIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1swLDBdLFsxLDBdLFsxLDFdLFswLDFdLFswLDBdXV0NCiAqDQogKiBwZ3MxID0gW1tbMCwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMCwgNF1dXSAvL3BvbHlnb24NCiAqIHBnczIgPSBbW1syLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFsyLCA0XV1dIC8vcG9seWdvbg0KICogciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzQsNF0sWzQsMF0sWzIsMF0sWzIsNF0sWzQsNF1dXQ0KICoNCiAqIHBnczEgPSBbW1swLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFswLCA0XV1dIC8vcG9seWdvbg0KICogcGdzMiA9IFtbWzAsIDBdLCBbMiwgMF0sIFsyLCAyXSwgWzAsIDJdXV0gLy9wb2x5Z29uDQogKiByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMiwyXSxbMiwwXSxbMCwwXSxbMCwyXSxbMiwyXV1dDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW1tbMCwgMF0sIFsyLCAyXSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMiwyXSxbMCwwXSxbMCw0XSxbMiwyXV1dDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW1tbLTEsIDBdLCBbMiwgMV0sIFstMSwgNF1dXSAvL3BvbHlnb24NCiAqIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1syLDFdLFswLDAuMzMzMzMzMzMzMzMzMzMzM10sWzAsM10sWzIsMV1dXQ0KICoNCiAqLwpmdW5jdGlvbiBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIG9wdCA9IHt9KSB7CiAgLy90dXJm55qEaW50ZXJzZWN05rqW56K65oCn6IiH6YGp55So5oCn5q+U6LyD5beuLCDlvpfkvb/nlKhwb2x5Ym9vbGpz5q+U6LyD5aW9CgogIC8vY2hlY2sgcGdzMQogIGlmICghaXNlYXJyKHBnczEpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIHBnczFgKTsKICB9CgogIC8vY2hlY2sgcGdzMgogIGlmIChpc2FycihwZ3MyKSAmJiBzaXplKHBnczIpID09PSAwKSB7CiAgICBwZ3MxID0gZml4Q2xvc2VQb2x5Z29uKHBnczEpOwogICAgcmV0dXJuIHBnczE7CiAgfQogIGlmICghaXNhcnIocGdzMikpIHsKICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBwZ3MyYCk7CiAgfQoKICAvL2Vwc2lsb24KICBsZXQgZXBzaWxvbiA9IGdldChvcHQsICdlcHNpbG9uJywgMC4wMDAwMDAwMDAwMDEpOwoKICAvL3RvUG9seWdvbgogIHBnczEgPSB0b1BvbHlnb24ocGdzMSk7CiAgcGdzMiA9IHRvUG9seWdvbihwZ3MyKTsKICAvLyBjb25zb2xlLmxvZygncGdzMScsIHBnczEpCiAgLy8gY29uc29sZS5sb2coJ3BnczInLCBwZ3MyKQoKICAvL2ludGVyc2VjdAogIHBvbHlib29sanMuZXBzaWxvbihlcHNpbG9uKTsKICBsZXQgaW50cyA9IHBvbHlib29sanMuaW50ZXJzZWN0KHsKICAgIHJlZ2lvbnM6IHBnczEKICB9LCB7CiAgICByZWdpb25zOiBwZ3MyCiAgfSk7CiAgLy8gY29uc29sZS5sb2coJ2ludHMnLCBpbnRzKQoKICAvL3BncwogIGxldCBwZ3MgPSBnZXQoaW50cywgJ3JlZ2lvbnMnLCBbXSk7CgogIC8vZml4Q2xvc2VQb2x5Z29uCiAgcGdzID0gZml4Q2xvc2VQb2x5Z29uKHBncyk7CiAgcmV0dXJuIHBnczsKfQoKY29uc3QgZXBzaWxvbiQxID0gMS4xMTAyMjMwMjQ2MjUxNTY1ZS0xNjsKY29uc3Qgc3BsaXR0ZXIgPSAxMzQyMTc3Mjk7CmNvbnN0IHJlc3VsdGVycmJvdW5kID0gKDMgKyA4ICogZXBzaWxvbiQxKSAqIGVwc2lsb24kMTsKCi8vIGZhc3RfZXhwYW5zaW9uX3N1bV96ZXJvZWxpbSByb3V0aW5lIGZyb20gb3JpdGluYWwgY29kZQpmdW5jdGlvbiBzdW0oZWxlbiwgZSwgZmxlbiwgZiwgaCkgewogIGxldCBRLCBRbmV3LCBoaCwgYnZpcnQ7CiAgbGV0IGVub3cgPSBlWzBdOwogIGxldCBmbm93ID0gZlswXTsKICBsZXQgZWluZGV4ID0gMDsKICBsZXQgZmluZGV4ID0gMDsKICBpZiAoZm5vdyA+IGVub3cgPT09IGZub3cgPiAtZW5vdykgewogICAgUSA9IGVub3c7CiAgICBlbm93ID0gZVsrK2VpbmRleF07CiAgfSBlbHNlIHsKICAgIFEgPSBmbm93OwogICAgZm5vdyA9IGZbKytmaW5kZXhdOwogIH0KICBsZXQgaGluZGV4ID0gMDsKICBpZiAoZWluZGV4IDwgZWxlbiAmJiBmaW5kZXggPCBmbGVuKSB7CiAgICBpZiAoZm5vdyA+IGVub3cgPT09IGZub3cgPiAtZW5vdykgewogICAgICBRbmV3ID0gZW5vdyArIFE7CiAgICAgIGhoID0gUSAtIChRbmV3IC0gZW5vdyk7CiAgICAgIGVub3cgPSBlWysrZWluZGV4XTsKICAgIH0gZWxzZSB7CiAgICAgIFFuZXcgPSBmbm93ICsgUTsKICAgICAgaGggPSBRIC0gKFFuZXcgLSBmbm93KTsKICAgICAgZm5vdyA9IGZbKytmaW5kZXhdOwogICAgfQogICAgUSA9IFFuZXc7CiAgICBpZiAoaGggIT09IDApIHsKICAgICAgaFtoaW5kZXgrK10gPSBoaDsKICAgIH0KICAgIHdoaWxlIChlaW5kZXggPCBlbGVuICYmIGZpbmRleCA8IGZsZW4pIHsKICAgICAgaWYgKGZub3cgPiBlbm93ID09PSBmbm93ID4gLWVub3cpIHsKICAgICAgICBRbmV3ID0gUSArIGVub3c7CiAgICAgICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgICAgICBoaCA9IFEgLSAoUW5ldyAtIGJ2aXJ0KSArIChlbm93IC0gYnZpcnQpOwogICAgICAgIGVub3cgPSBlWysrZWluZGV4XTsKICAgICAgfSBlbHNlIHsKICAgICAgICBRbmV3ID0gUSArIGZub3c7CiAgICAgICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgICAgICBoaCA9IFEgLSAoUW5ldyAtIGJ2aXJ0KSArIChmbm93IC0gYnZpcnQpOwogICAgICAgIGZub3cgPSBmWysrZmluZGV4XTsKICAgICAgfQogICAgICBRID0gUW5ldzsKICAgICAgaWYgKGhoICE9PSAwKSB7CiAgICAgICAgaFtoaW5kZXgrK10gPSBoaDsKICAgICAgfQogICAgfQogIH0KICB3aGlsZSAoZWluZGV4IDwgZWxlbikgewogICAgUW5ldyA9IFEgKyBlbm93OwogICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgIGhoID0gUSAtIChRbmV3IC0gYnZpcnQpICsgKGVub3cgLSBidmlydCk7CiAgICBlbm93ID0gZVsrK2VpbmRleF07CiAgICBRID0gUW5ldzsKICAgIGlmIChoaCAhPT0gMCkgewogICAgICBoW2hpbmRleCsrXSA9IGhoOwogICAgfQogIH0KICB3aGlsZSAoZmluZGV4IDwgZmxlbikgewogICAgUW5ldyA9IFEgKyBmbm93OwogICAgYnZpcnQgPSBRbmV3IC0gUTsKICAgIGhoID0gUSAtIChRbmV3IC0gYnZpcnQpICsgKGZub3cgLSBidmlydCk7CiAgICBmbm93ID0gZlsrK2ZpbmRleF07CiAgICBRID0gUW5ldzsKICAgIGlmIChoaCAhPT0gMCkgewogICAgICBoW2hpbmRleCsrXSA9IGhoOwogICAgfQogIH0KICBpZiAoUSAhPT0gMCB8fCBoaW5kZXggPT09IDApIHsKICAgIGhbaGluZGV4KytdID0gUTsKICB9CiAgcmV0dXJuIGhpbmRleDsKfQpmdW5jdGlvbiBlc3RpbWF0ZShlbGVuLCBlKSB7CiAgbGV0IFEgPSBlWzBdOwogIGZvciAobGV0IGkgPSAxOyBpIDwgZWxlbjsgaSsrKSBRICs9IGVbaV07CiAgcmV0dXJuIFE7Cn0KZnVuY3Rpb24gdmVjKG4pIHsKICByZXR1cm4gbmV3IEZsb2F0NjRBcnJheShuKTsKfQoKY29uc3QgY2N3ZXJyYm91bmRBID0gKDMgKyAxNiAqIGVwc2lsb24kMSkgKiBlcHNpbG9uJDE7CmNvbnN0IGNjd2VycmJvdW5kQiA9ICgyICsgMTIgKiBlcHNpbG9uJDEpICogZXBzaWxvbiQxOwpjb25zdCBjY3dlcnJib3VuZEMgPSAoOSArIDY0ICogZXBzaWxvbiQxKSAqIGVwc2lsb24kMSAqIGVwc2lsb24kMTsKY29uc3QgQiA9IHZlYyg0KTsKY29uc3QgQzEgPSB2ZWMoOCk7CmNvbnN0IEMyID0gdmVjKDEyKTsKY29uc3QgRCA9IHZlYygxNik7CmNvbnN0IHUgPSB2ZWMoNCk7CmZ1bmN0aW9uIG9yaWVudDJkYWRhcHQoYXgsIGF5LCBieCwgYnksIGN4LCBjeSwgZGV0c3VtKSB7CiAgbGV0IGFjeHRhaWwsIGFjeXRhaWwsIGJjeHRhaWwsIGJjeXRhaWw7CiAgbGV0IGJ2aXJ0LCBjLCBhaGksIGFsbywgYmhpLCBibG8sIF9pLCBfaiwgXzAsIHMxLCBzMCwgdDEsIHQwLCB1MzsKICBjb25zdCBhY3ggPSBheCAtIGN4OwogIGNvbnN0IGJjeCA9IGJ4IC0gY3g7CiAgY29uc3QgYWN5ID0gYXkgLSBjeTsKICBjb25zdCBiY3kgPSBieSAtIGN5OwogIHMxID0gYWN4ICogYmN5OwogIGMgPSBzcGxpdHRlciAqIGFjeDsKICBhaGkgPSBjIC0gKGMgLSBhY3gpOwogIGFsbyA9IGFjeCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3k7CiAgYmhpID0gYyAtIChjIC0gYmN5KTsKICBibG8gPSBiY3kgLSBiaGk7CiAgczAgPSBhbG8gKiBibG8gLSAoczEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIHQxID0gYWN5ICogYmN4OwogIGMgPSBzcGxpdHRlciAqIGFjeTsKICBhaGkgPSBjIC0gKGMgLSBhY3kpOwogIGFsbyA9IGFjeSAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3g7CiAgYmhpID0gYyAtIChjIC0gYmN4KTsKICBibG8gPSBiY3ggLSBiaGk7CiAgdDAgPSBhbG8gKiBibG8gLSAodDEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIF9pID0gczAgLSB0MDsKICBidmlydCA9IHMwIC0gX2k7CiAgQlswXSA9IHMwIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDApOwogIF9qID0gczEgKyBfaTsKICBidmlydCA9IF9qIC0gczE7CiAgXzAgPSBzMSAtIChfaiAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBfaSA9IF8wIC0gdDE7CiAgYnZpcnQgPSBfMCAtIF9pOwogIEJbMV0gPSBfMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQxKTsKICB1MyA9IF9qICsgX2k7CiAgYnZpcnQgPSB1MyAtIF9qOwogIEJbMl0gPSBfaiAtICh1MyAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBCWzNdID0gdTM7CiAgbGV0IGRldCA9IGVzdGltYXRlKDQsIEIpOwogIGxldCBlcnJib3VuZCA9IGNjd2VycmJvdW5kQiAqIGRldHN1bTsKICBpZiAoZGV0ID49IGVycmJvdW5kIHx8IC1kZXQgPj0gZXJyYm91bmQpIHsKICAgIHJldHVybiBkZXQ7CiAgfQogIGJ2aXJ0ID0gYXggLSBhY3g7CiAgYWN4dGFpbCA9IGF4IC0gKGFjeCArIGJ2aXJ0KSArIChidmlydCAtIGN4KTsKICBidmlydCA9IGJ4IC0gYmN4OwogIGJjeHRhaWwgPSBieCAtIChiY3ggKyBidmlydCkgKyAoYnZpcnQgLSBjeCk7CiAgYnZpcnQgPSBheSAtIGFjeTsKICBhY3l0YWlsID0gYXkgLSAoYWN5ICsgYnZpcnQpICsgKGJ2aXJ0IC0gY3kpOwogIGJ2aXJ0ID0gYnkgLSBiY3k7CiAgYmN5dGFpbCA9IGJ5IC0gKGJjeSArIGJ2aXJ0KSArIChidmlydCAtIGN5KTsKICBpZiAoYWN4dGFpbCA9PT0gMCAmJiBhY3l0YWlsID09PSAwICYmIGJjeHRhaWwgPT09IDAgJiYgYmN5dGFpbCA9PT0gMCkgewogICAgcmV0dXJuIGRldDsKICB9CiAgZXJyYm91bmQgPSBjY3dlcnJib3VuZEMgKiBkZXRzdW0gKyByZXN1bHRlcnJib3VuZCAqIE1hdGguYWJzKGRldCk7CiAgZGV0ICs9IGFjeCAqIGJjeXRhaWwgKyBiY3kgKiBhY3h0YWlsIC0gKGFjeSAqIGJjeHRhaWwgKyBiY3ggKiBhY3l0YWlsKTsKICBpZiAoZGV0ID49IGVycmJvdW5kIHx8IC1kZXQgPj0gZXJyYm91bmQpIHJldHVybiBkZXQ7CiAgczEgPSBhY3h0YWlsICogYmN5OwogIGMgPSBzcGxpdHRlciAqIGFjeHRhaWw7CiAgYWhpID0gYyAtIChjIC0gYWN4dGFpbCk7CiAgYWxvID0gYWN4dGFpbCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3k7CiAgYmhpID0gYyAtIChjIC0gYmN5KTsKICBibG8gPSBiY3kgLSBiaGk7CiAgczAgPSBhbG8gKiBibG8gLSAoczEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIHQxID0gYWN5dGFpbCAqIGJjeDsKICBjID0gc3BsaXR0ZXIgKiBhY3l0YWlsOwogIGFoaSA9IGMgLSAoYyAtIGFjeXRhaWwpOwogIGFsbyA9IGFjeXRhaWwgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN4OwogIGJoaSA9IGMgLSAoYyAtIGJjeCk7CiAgYmxvID0gYmN4IC0gYmhpOwogIHQwID0gYWxvICogYmxvIC0gKHQxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICBfaSA9IHMwIC0gdDA7CiAgYnZpcnQgPSBzMCAtIF9pOwogIHVbMF0gPSBzMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQwKTsKICBfaiA9IHMxICsgX2k7CiAgYnZpcnQgPSBfaiAtIHMxOwogIF8wID0gczEgLSAoX2ogLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgX2kgPSBfMCAtIHQxOwogIGJ2aXJ0ID0gXzAgLSBfaTsKICB1WzFdID0gXzAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MSk7CiAgdTMgPSBfaiArIF9pOwogIGJ2aXJ0ID0gdTMgLSBfajsKICB1WzJdID0gX2ogLSAodTMgLSBidmlydCkgKyAoX2kgLSBidmlydCk7CiAgdVszXSA9IHUzOwogIGNvbnN0IEMxbGVuID0gc3VtKDQsIEIsIDQsIHUsIEMxKTsKICBzMSA9IGFjeCAqIGJjeXRhaWw7CiAgYyA9IHNwbGl0dGVyICogYWN4OwogIGFoaSA9IGMgLSAoYyAtIGFjeCk7CiAgYWxvID0gYWN4IC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeXRhaWw7CiAgYmhpID0gYyAtIChjIC0gYmN5dGFpbCk7CiAgYmxvID0gYmN5dGFpbCAtIGJoaTsKICBzMCA9IGFsbyAqIGJsbyAtIChzMSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgdDEgPSBhY3kgKiBiY3h0YWlsOwogIGMgPSBzcGxpdHRlciAqIGFjeTsKICBhaGkgPSBjIC0gKGMgLSBhY3kpOwogIGFsbyA9IGFjeSAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3h0YWlsOwogIGJoaSA9IGMgLSAoYyAtIGJjeHRhaWwpOwogIGJsbyA9IGJjeHRhaWwgLSBiaGk7CiAgdDAgPSBhbG8gKiBibG8gLSAodDEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIF9pID0gczAgLSB0MDsKICBidmlydCA9IHMwIC0gX2k7CiAgdVswXSA9IHMwIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDApOwogIF9qID0gczEgKyBfaTsKICBidmlydCA9IF9qIC0gczE7CiAgXzAgPSBzMSAtIChfaiAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBfaSA9IF8wIC0gdDE7CiAgYnZpcnQgPSBfMCAtIF9pOwogIHVbMV0gPSBfMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQxKTsKICB1MyA9IF9qICsgX2k7CiAgYnZpcnQgPSB1MyAtIF9qOwogIHVbMl0gPSBfaiAtICh1MyAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICB1WzNdID0gdTM7CiAgY29uc3QgQzJsZW4gPSBzdW0oQzFsZW4sIEMxLCA0LCB1LCBDMik7CiAgczEgPSBhY3h0YWlsICogYmN5dGFpbDsKICBjID0gc3BsaXR0ZXIgKiBhY3h0YWlsOwogIGFoaSA9IGMgLSAoYyAtIGFjeHRhaWwpOwogIGFsbyA9IGFjeHRhaWwgLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN5dGFpbDsKICBiaGkgPSBjIC0gKGMgLSBiY3l0YWlsKTsKICBibG8gPSBiY3l0YWlsIC0gYmhpOwogIHMwID0gYWxvICogYmxvIC0gKHMxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICB0MSA9IGFjeXRhaWwgKiBiY3h0YWlsOwogIGMgPSBzcGxpdHRlciAqIGFjeXRhaWw7CiAgYWhpID0gYyAtIChjIC0gYWN5dGFpbCk7CiAgYWxvID0gYWN5dGFpbCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3h0YWlsOwogIGJoaSA9IGMgLSAoYyAtIGJjeHRhaWwpOwogIGJsbyA9IGJjeHRhaWwgLSBiaGk7CiAgdDAgPSBhbG8gKiBibG8gLSAodDEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIF9pID0gczAgLSB0MDsKICBidmlydCA9IHMwIC0gX2k7CiAgdVswXSA9IHMwIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDApOwogIF9qID0gczEgKyBfaTsKICBidmlydCA9IF9qIC0gczE7CiAgXzAgPSBzMSAtIChfaiAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBfaSA9IF8wIC0gdDE7CiAgYnZpcnQgPSBfMCAtIF9pOwogIHVbMV0gPSBfMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQxKTsKICB1MyA9IF9qICsgX2k7CiAgYnZpcnQgPSB1MyAtIF9qOwogIHVbMl0gPSBfaiAtICh1MyAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICB1WzNdID0gdTM7CiAgY29uc3QgRGxlbiA9IHN1bShDMmxlbiwgQzIsIDQsIHUsIEQpOwogIHJldHVybiBEW0RsZW4gLSAxXTsKfQpmdW5jdGlvbiBvcmllbnQyZChheCwgYXksIGJ4LCBieSwgY3gsIGN5KSB7CiAgY29uc3QgZGV0bGVmdCA9IChheSAtIGN5KSAqIChieCAtIGN4KTsKICBjb25zdCBkZXRyaWdodCA9IChheCAtIGN4KSAqIChieSAtIGN5KTsKICBjb25zdCBkZXQgPSBkZXRsZWZ0IC0gZGV0cmlnaHQ7CiAgaWYgKGRldGxlZnQgPT09IDAgfHwgZGV0cmlnaHQgPT09IDAgfHwgZGV0bGVmdCA+IDAgIT09IGRldHJpZ2h0ID4gMCkgcmV0dXJuIGRldDsKICBjb25zdCBkZXRzdW0gPSBNYXRoLmFicyhkZXRsZWZ0ICsgZGV0cmlnaHQpOwogIGlmIChNYXRoLmFicyhkZXQpID49IGNjd2VycmJvdW5kQSAqIGRldHN1bSkgcmV0dXJuIGRldDsKICByZXR1cm4gLW9yaWVudDJkYWRhcHQoYXgsIGF5LCBieCwgYnksIGN4LCBjeSwgZGV0c3VtKTsKfQoKY29uc3QgRVBTSUxPTiA9IE1hdGgucG93KDIsIC01Mik7CmNvbnN0IEVER0VfU1RBQ0sgPSBuZXcgVWludDMyQXJyYXkoNTEyKTsKY2xhc3MgRGVsYXVuYXRvciB7CiAgc3RhdGljIGZyb20ocG9pbnRzLCBnZXRYID0gZGVmYXVsdEdldFgsIGdldFkgPSBkZWZhdWx0R2V0WSkgewogICAgY29uc3QgbiA9IHBvaW50cy5sZW5ndGg7CiAgICBjb25zdCBjb29yZHMgPSBuZXcgRmxvYXQ2NEFycmF5KG4gKiAyKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGNvbnN0IHAgPSBwb2ludHNbaV07CiAgICAgIGNvb3Jkc1syICogaV0gPSBnZXRYKHApOwogICAgICBjb29yZHNbMiAqIGkgKyAxXSA9IGdldFkocCk7CiAgICB9CiAgICByZXR1cm4gbmV3IERlbGF1bmF0b3IoY29vcmRzKTsKICB9CiAgY29uc3RydWN0b3IoY29vcmRzKSB7CiAgICBjb25zdCBuID0gY29vcmRzLmxlbmd0aCA+PiAxOwogICAgaWYgKG4gPiAwICYmIHR5cGVvZiBjb29yZHNbMF0gIT09ICdudW1iZXInKSB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGNvb3JkcyB0byBjb250YWluIG51bWJlcnMuJyk7CiAgICB0aGlzLmNvb3JkcyA9IGNvb3JkczsKCiAgICAvLyBhcnJheXMgdGhhdCB3aWxsIHN0b3JlIHRoZSB0cmlhbmd1bGF0aW9uIGdyYXBoCiAgICBjb25zdCBtYXhUcmlhbmdsZXMgPSBNYXRoLm1heCgyICogbiAtIDUsIDApOwogICAgdGhpcy5fdHJpYW5nbGVzID0gbmV3IFVpbnQzMkFycmF5KG1heFRyaWFuZ2xlcyAqIDMpOwogICAgdGhpcy5faGFsZmVkZ2VzID0gbmV3IEludDMyQXJyYXkobWF4VHJpYW5nbGVzICogMyk7CgogICAgLy8gdGVtcG9yYXJ5IGFycmF5cyBmb3IgdHJhY2tpbmcgdGhlIGVkZ2VzIG9mIHRoZSBhZHZhbmNpbmcgY29udmV4IGh1bGwKICAgIHRoaXMuX2hhc2hTaXplID0gTWF0aC5jZWlsKE1hdGguc3FydChuKSk7CiAgICB0aGlzLl9odWxsUHJldiA9IG5ldyBVaW50MzJBcnJheShuKTsgLy8gZWRnZSB0byBwcmV2IGVkZ2UKICAgIHRoaXMuX2h1bGxOZXh0ID0gbmV3IFVpbnQzMkFycmF5KG4pOyAvLyBlZGdlIHRvIG5leHQgZWRnZQogICAgdGhpcy5faHVsbFRyaSA9IG5ldyBVaW50MzJBcnJheShuKTsgLy8gZWRnZSB0byBhZGphY2VudCB0cmlhbmdsZQogICAgdGhpcy5faHVsbEhhc2ggPSBuZXcgSW50MzJBcnJheSh0aGlzLl9oYXNoU2l6ZSkuZmlsbCgtMSk7IC8vIGFuZ3VsYXIgZWRnZSBoYXNoCgogICAgLy8gdGVtcG9yYXJ5IGFycmF5cyBmb3Igc29ydGluZyBwb2ludHMKICAgIHRoaXMuX2lkcyA9IG5ldyBVaW50MzJBcnJheShuKTsKICAgIHRoaXMuX2Rpc3RzID0gbmV3IEZsb2F0NjRBcnJheShuKTsKICAgIHRoaXMudXBkYXRlKCk7CiAgfQogIHVwZGF0ZSgpIHsKICAgIGNvbnN0IHsKICAgICAgY29vcmRzLAogICAgICBfaHVsbFByZXY6IGh1bGxQcmV2LAogICAgICBfaHVsbE5leHQ6IGh1bGxOZXh0LAogICAgICBfaHVsbFRyaTogaHVsbFRyaSwKICAgICAgX2h1bGxIYXNoOiBodWxsSGFzaAogICAgfSA9IHRoaXM7CiAgICBjb25zdCBuID0gY29vcmRzLmxlbmd0aCA+PiAxOwoKICAgIC8vIHBvcHVsYXRlIGFuIGFycmF5IG9mIHBvaW50IGluZGljZXM7IGNhbGN1bGF0ZSBpbnB1dCBkYXRhIGJib3gKICAgIGxldCBtaW5YID0gSW5maW5pdHk7CiAgICBsZXQgbWluWSA9IEluZmluaXR5OwogICAgbGV0IG1heFggPSAtSW5maW5pdHk7CiAgICBsZXQgbWF4WSA9IC1JbmZpbml0eTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGNvbnN0IHggPSBjb29yZHNbMiAqIGldOwogICAgICBjb25zdCB5ID0gY29vcmRzWzIgKiBpICsgMV07CiAgICAgIGlmICh4IDwgbWluWCkgbWluWCA9IHg7CiAgICAgIGlmICh5IDwgbWluWSkgbWluWSA9IHk7CiAgICAgIGlmICh4ID4gbWF4WCkgbWF4WCA9IHg7CiAgICAgIGlmICh5ID4gbWF4WSkgbWF4WSA9IHk7CiAgICAgIHRoaXMuX2lkc1tpXSA9IGk7CiAgICB9CiAgICBjb25zdCBjeCA9IChtaW5YICsgbWF4WCkgLyAyOwogICAgY29uc3QgY3kgPSAobWluWSArIG1heFkpIC8gMjsKICAgIGxldCBtaW5EaXN0ID0gSW5maW5pdHk7CiAgICBsZXQgaTAsIGkxLCBpMjsKCiAgICAvLyBwaWNrIGEgc2VlZCBwb2ludCBjbG9zZSB0byB0aGUgY2VudGVyCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBjb25zdCBkID0gZGlzdChjeCwgY3ksIGNvb3Jkc1syICogaV0sIGNvb3Jkc1syICogaSArIDFdKTsKICAgICAgaWYgKGQgPCBtaW5EaXN0KSB7CiAgICAgICAgaTAgPSBpOwogICAgICAgIG1pbkRpc3QgPSBkOwogICAgICB9CiAgICB9CiAgICBjb25zdCBpMHggPSBjb29yZHNbMiAqIGkwXTsKICAgIGNvbnN0IGkweSA9IGNvb3Jkc1syICogaTAgKyAxXTsKICAgIG1pbkRpc3QgPSBJbmZpbml0eTsKCiAgICAvLyBmaW5kIHRoZSBwb2ludCBjbG9zZXN0IHRvIHRoZSBzZWVkCiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICBpZiAoaSA9PT0gaTApIGNvbnRpbnVlOwogICAgICBjb25zdCBkID0gZGlzdChpMHgsIGkweSwgY29vcmRzWzIgKiBpXSwgY29vcmRzWzIgKiBpICsgMV0pOwogICAgICBpZiAoZCA8IG1pbkRpc3QgJiYgZCA+IDApIHsKICAgICAgICBpMSA9IGk7CiAgICAgICAgbWluRGlzdCA9IGQ7CiAgICAgIH0KICAgIH0KICAgIGxldCBpMXggPSBjb29yZHNbMiAqIGkxXTsKICAgIGxldCBpMXkgPSBjb29yZHNbMiAqIGkxICsgMV07CiAgICBsZXQgbWluUmFkaXVzID0gSW5maW5pdHk7CgogICAgLy8gZmluZCB0aGUgdGhpcmQgcG9pbnQgd2hpY2ggZm9ybXMgdGhlIHNtYWxsZXN0IGNpcmN1bWNpcmNsZSB3aXRoIHRoZSBmaXJzdCB0d28KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGlmIChpID09PSBpMCB8fCBpID09PSBpMSkgY29udGludWU7CiAgICAgIGNvbnN0IHIgPSBjaXJjdW1yYWRpdXMoaTB4LCBpMHksIGkxeCwgaTF5LCBjb29yZHNbMiAqIGldLCBjb29yZHNbMiAqIGkgKyAxXSk7CiAgICAgIGlmIChyIDwgbWluUmFkaXVzKSB7CiAgICAgICAgaTIgPSBpOwogICAgICAgIG1pblJhZGl1cyA9IHI7CiAgICAgIH0KICAgIH0KICAgIGxldCBpMnggPSBjb29yZHNbMiAqIGkyXTsKICAgIGxldCBpMnkgPSBjb29yZHNbMiAqIGkyICsgMV07CiAgICBpZiAobWluUmFkaXVzID09PSBJbmZpbml0eSkgewogICAgICAvLyBvcmRlciBjb2xsaW5lYXIgcG9pbnRzIGJ5IGR4IChvciBkeSBpZiBhbGwgeCBhcmUgaWRlbnRpY2FsKQogICAgICAvLyBhbmQgcmV0dXJuIHRoZSBsaXN0IGFzIGEgaHVsbAogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgIHRoaXMuX2Rpc3RzW2ldID0gY29vcmRzWzIgKiBpXSAtIGNvb3Jkc1swXSB8fCBjb29yZHNbMiAqIGkgKyAxXSAtIGNvb3Jkc1sxXTsKICAgICAgfQogICAgICBxdWlja3NvcnQodGhpcy5faWRzLCB0aGlzLl9kaXN0cywgMCwgbiAtIDEpOwogICAgICBjb25zdCBodWxsID0gbmV3IFVpbnQzMkFycmF5KG4pOwogICAgICBsZXQgaiA9IDA7CiAgICAgIGZvciAobGV0IGkgPSAwLCBkMCA9IC1JbmZpbml0eTsgaSA8IG47IGkrKykgewogICAgICAgIGNvbnN0IGlkID0gdGhpcy5faWRzW2ldOwogICAgICAgIGlmICh0aGlzLl9kaXN0c1tpZF0gPiBkMCkgewogICAgICAgICAgaHVsbFtqKytdID0gaWQ7CiAgICAgICAgICBkMCA9IHRoaXMuX2Rpc3RzW2lkXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgdGhpcy5odWxsID0gaHVsbC5zdWJhcnJheSgwLCBqKTsKICAgICAgdGhpcy50cmlhbmdsZXMgPSBuZXcgVWludDMyQXJyYXkoMCk7CiAgICAgIHRoaXMuaGFsZmVkZ2VzID0gbmV3IFVpbnQzMkFycmF5KDApOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gc3dhcCB0aGUgb3JkZXIgb2YgdGhlIHNlZWQgcG9pbnRzIGZvciBjb3VudGVyLWNsb2Nrd2lzZSBvcmllbnRhdGlvbgogICAgaWYgKG9yaWVudDJkKGkweCwgaTB5LCBpMXgsIGkxeSwgaTJ4LCBpMnkpIDwgMCkgewogICAgICBjb25zdCBpID0gaTE7CiAgICAgIGNvbnN0IHggPSBpMXg7CiAgICAgIGNvbnN0IHkgPSBpMXk7CiAgICAgIGkxID0gaTI7CiAgICAgIGkxeCA9IGkyeDsKICAgICAgaTF5ID0gaTJ5OwogICAgICBpMiA9IGk7CiAgICAgIGkyeCA9IHg7CiAgICAgIGkyeSA9IHk7CiAgICB9CiAgICBjb25zdCBjZW50ZXIgPSBjaXJjdW1jZW50ZXIoaTB4LCBpMHksIGkxeCwgaTF5LCBpMngsIGkyeSk7CiAgICB0aGlzLl9jeCA9IGNlbnRlci54OwogICAgdGhpcy5fY3kgPSBjZW50ZXIueTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIHRoaXMuX2Rpc3RzW2ldID0gZGlzdChjb29yZHNbMiAqIGldLCBjb29yZHNbMiAqIGkgKyAxXSwgY2VudGVyLngsIGNlbnRlci55KTsKICAgIH0KCiAgICAvLyBzb3J0IHRoZSBwb2ludHMgYnkgZGlzdGFuY2UgZnJvbSB0aGUgc2VlZCB0cmlhbmdsZSBjaXJjdW1jZW50ZXIKICAgIHF1aWNrc29ydCh0aGlzLl9pZHMsIHRoaXMuX2Rpc3RzLCAwLCBuIC0gMSk7CgogICAgLy8gc2V0IHVwIHRoZSBzZWVkIHRyaWFuZ2xlIGFzIHRoZSBzdGFydGluZyBodWxsCiAgICB0aGlzLl9odWxsU3RhcnQgPSBpMDsKICAgIGxldCBodWxsU2l6ZSA9IDM7CiAgICBodWxsTmV4dFtpMF0gPSBodWxsUHJldltpMl0gPSBpMTsKICAgIGh1bGxOZXh0W2kxXSA9IGh1bGxQcmV2W2kwXSA9IGkyOwogICAgaHVsbE5leHRbaTJdID0gaHVsbFByZXZbaTFdID0gaTA7CiAgICBodWxsVHJpW2kwXSA9IDA7CiAgICBodWxsVHJpW2kxXSA9IDE7CiAgICBodWxsVHJpW2kyXSA9IDI7CiAgICBodWxsSGFzaC5maWxsKC0xKTsKICAgIGh1bGxIYXNoW3RoaXMuX2hhc2hLZXkoaTB4LCBpMHkpXSA9IGkwOwogICAgaHVsbEhhc2hbdGhpcy5faGFzaEtleShpMXgsIGkxeSldID0gaTE7CiAgICBodWxsSGFzaFt0aGlzLl9oYXNoS2V5KGkyeCwgaTJ5KV0gPSBpMjsKICAgIHRoaXMudHJpYW5nbGVzTGVuID0gMDsKICAgIHRoaXMuX2FkZFRyaWFuZ2xlKGkwLCBpMSwgaTIsIC0xLCAtMSwgLTEpOwogICAgZm9yIChsZXQgayA9IDAsIHhwLCB5cDsgayA8IHRoaXMuX2lkcy5sZW5ndGg7IGsrKykgewogICAgICBjb25zdCBpID0gdGhpcy5faWRzW2tdOwogICAgICBjb25zdCB4ID0gY29vcmRzWzIgKiBpXTsKICAgICAgY29uc3QgeSA9IGNvb3Jkc1syICogaSArIDFdOwoKICAgICAgLy8gc2tpcCBuZWFyLWR1cGxpY2F0ZSBwb2ludHMKICAgICAgaWYgKGsgPiAwICYmIE1hdGguYWJzKHggLSB4cCkgPD0gRVBTSUxPTiAmJiBNYXRoLmFicyh5IC0geXApIDw9IEVQU0lMT04pIGNvbnRpbnVlOwogICAgICB4cCA9IHg7CiAgICAgIHlwID0geTsKCiAgICAgIC8vIHNraXAgc2VlZCB0cmlhbmdsZSBwb2ludHMKICAgICAgaWYgKGkgPT09IGkwIHx8IGkgPT09IGkxIHx8IGkgPT09IGkyKSBjb250aW51ZTsKCiAgICAgIC8vIGZpbmQgYSB2aXNpYmxlIGVkZ2Ugb24gdGhlIGNvbnZleCBodWxsIHVzaW5nIGVkZ2UgaGFzaAogICAgICBsZXQgc3RhcnQgPSAwOwogICAgICBmb3IgKGxldCBqID0gMCwga2V5ID0gdGhpcy5faGFzaEtleSh4LCB5KTsgaiA8IHRoaXMuX2hhc2hTaXplOyBqKyspIHsKICAgICAgICBzdGFydCA9IGh1bGxIYXNoWyhrZXkgKyBqKSAlIHRoaXMuX2hhc2hTaXplXTsKICAgICAgICBpZiAoc3RhcnQgIT09IC0xICYmIHN0YXJ0ICE9PSBodWxsTmV4dFtzdGFydF0pIGJyZWFrOwogICAgICB9CiAgICAgIHN0YXJ0ID0gaHVsbFByZXZbc3RhcnRdOwogICAgICBsZXQgZSA9IHN0YXJ0LAogICAgICAgIHE7CiAgICAgIHdoaWxlIChxID0gaHVsbE5leHRbZV0sIG9yaWVudDJkKHgsIHksIGNvb3Jkc1syICogZV0sIGNvb3Jkc1syICogZSArIDFdLCBjb29yZHNbMiAqIHFdLCBjb29yZHNbMiAqIHEgKyAxXSkgPj0gMCkgewogICAgICAgIGUgPSBxOwogICAgICAgIGlmIChlID09PSBzdGFydCkgewogICAgICAgICAgZSA9IC0xOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChlID09PSAtMSkgY29udGludWU7IC8vIGxpa2VseSBhIG5lYXItZHVwbGljYXRlIHBvaW50OyBza2lwIGl0CgogICAgICAvLyBhZGQgdGhlIGZpcnN0IHRyaWFuZ2xlIGZyb20gdGhlIHBvaW50CiAgICAgIGxldCB0ID0gdGhpcy5fYWRkVHJpYW5nbGUoZSwgaSwgaHVsbE5leHRbZV0sIC0xLCAtMSwgaHVsbFRyaVtlXSk7CgogICAgICAvLyByZWN1cnNpdmVseSBmbGlwIHRyaWFuZ2xlcyBmcm9tIHRoZSBwb2ludCB1bnRpbCB0aGV5IHNhdGlzZnkgdGhlIERlbGF1bmF5IGNvbmRpdGlvbgogICAgICBodWxsVHJpW2ldID0gdGhpcy5fbGVnYWxpemUodCArIDIpOwogICAgICBodWxsVHJpW2VdID0gdDsgLy8ga2VlcCB0cmFjayBvZiBib3VuZGFyeSB0cmlhbmdsZXMgb24gdGhlIGh1bGwKICAgICAgaHVsbFNpemUrKzsKCiAgICAgIC8vIHdhbGsgZm9yd2FyZCB0aHJvdWdoIHRoZSBodWxsLCBhZGRpbmcgbW9yZSB0cmlhbmdsZXMgYW5kIGZsaXBwaW5nIHJlY3Vyc2l2ZWx5CiAgICAgIGxldCBuID0gaHVsbE5leHRbZV07CiAgICAgIHdoaWxlIChxID0gaHVsbE5leHRbbl0sIG9yaWVudDJkKHgsIHksIGNvb3Jkc1syICogbl0sIGNvb3Jkc1syICogbiArIDFdLCBjb29yZHNbMiAqIHFdLCBjb29yZHNbMiAqIHEgKyAxXSkgPCAwKSB7CiAgICAgICAgdCA9IHRoaXMuX2FkZFRyaWFuZ2xlKG4sIGksIHEsIGh1bGxUcmlbaV0sIC0xLCBodWxsVHJpW25dKTsKICAgICAgICBodWxsVHJpW2ldID0gdGhpcy5fbGVnYWxpemUodCArIDIpOwogICAgICAgIGh1bGxOZXh0W25dID0gbjsgLy8gbWFyayBhcyByZW1vdmVkCiAgICAgICAgaHVsbFNpemUtLTsKICAgICAgICBuID0gcTsKICAgICAgfQoKICAgICAgLy8gd2FsayBiYWNrd2FyZCBmcm9tIHRoZSBvdGhlciBzaWRlLCBhZGRpbmcgbW9yZSB0cmlhbmdsZXMgYW5kIGZsaXBwaW5nCiAgICAgIGlmIChlID09PSBzdGFydCkgewogICAgICAgIHdoaWxlIChxID0gaHVsbFByZXZbZV0sIG9yaWVudDJkKHgsIHksIGNvb3Jkc1syICogcV0sIGNvb3Jkc1syICogcSArIDFdLCBjb29yZHNbMiAqIGVdLCBjb29yZHNbMiAqIGUgKyAxXSkgPCAwKSB7CiAgICAgICAgICB0ID0gdGhpcy5fYWRkVHJpYW5nbGUocSwgaSwgZSwgLTEsIGh1bGxUcmlbZV0sIGh1bGxUcmlbcV0pOwogICAgICAgICAgdGhpcy5fbGVnYWxpemUodCArIDIpOwogICAgICAgICAgaHVsbFRyaVtxXSA9IHQ7CiAgICAgICAgICBodWxsTmV4dFtlXSA9IGU7IC8vIG1hcmsgYXMgcmVtb3ZlZAogICAgICAgICAgaHVsbFNpemUtLTsKICAgICAgICAgIGUgPSBxOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gdXBkYXRlIHRoZSBodWxsIGluZGljZXMKICAgICAgdGhpcy5faHVsbFN0YXJ0ID0gaHVsbFByZXZbaV0gPSBlOwogICAgICBodWxsTmV4dFtlXSA9IGh1bGxQcmV2W25dID0gaTsKICAgICAgaHVsbE5leHRbaV0gPSBuOwoKICAgICAgLy8gc2F2ZSB0aGUgdHdvIG5ldyBlZGdlcyBpbiB0aGUgaGFzaCB0YWJsZQogICAgICBodWxsSGFzaFt0aGlzLl9oYXNoS2V5KHgsIHkpXSA9IGk7CiAgICAgIGh1bGxIYXNoW3RoaXMuX2hhc2hLZXkoY29vcmRzWzIgKiBlXSwgY29vcmRzWzIgKiBlICsgMV0pXSA9IGU7CiAgICB9CiAgICB0aGlzLmh1bGwgPSBuZXcgVWludDMyQXJyYXkoaHVsbFNpemUpOwogICAgZm9yIChsZXQgaSA9IDAsIGUgPSB0aGlzLl9odWxsU3RhcnQ7IGkgPCBodWxsU2l6ZTsgaSsrKSB7CiAgICAgIHRoaXMuaHVsbFtpXSA9IGU7CiAgICAgIGUgPSBodWxsTmV4dFtlXTsKICAgIH0KCiAgICAvLyB0cmltIHR5cGVkIHRyaWFuZ2xlIG1lc2ggYXJyYXlzCiAgICB0aGlzLnRyaWFuZ2xlcyA9IHRoaXMuX3RyaWFuZ2xlcy5zdWJhcnJheSgwLCB0aGlzLnRyaWFuZ2xlc0xlbik7CiAgICB0aGlzLmhhbGZlZGdlcyA9IHRoaXMuX2hhbGZlZGdlcy5zdWJhcnJheSgwLCB0aGlzLnRyaWFuZ2xlc0xlbik7CiAgfQogIF9oYXNoS2V5KHgsIHkpIHsKICAgIHJldHVybiBNYXRoLmZsb29yKHBzZXVkb0FuZ2xlKHggLSB0aGlzLl9jeCwgeSAtIHRoaXMuX2N5KSAqIHRoaXMuX2hhc2hTaXplKSAlIHRoaXMuX2hhc2hTaXplOwogIH0KICBfbGVnYWxpemUoYSkgewogICAgY29uc3QgewogICAgICBfdHJpYW5nbGVzOiB0cmlhbmdsZXMsCiAgICAgIF9oYWxmZWRnZXM6IGhhbGZlZGdlcywKICAgICAgY29vcmRzCiAgICB9ID0gdGhpczsKICAgIGxldCBpID0gMDsKICAgIGxldCBhciA9IDA7CgogICAgLy8gcmVjdXJzaW9uIGVsaW1pbmF0ZWQgd2l0aCBhIGZpeGVkLXNpemUgc3RhY2sKICAgIHdoaWxlICh0cnVlKSB7CiAgICAgIGNvbnN0IGIgPSBoYWxmZWRnZXNbYV07CgogICAgICAvKiBpZiB0aGUgcGFpciBvZiB0cmlhbmdsZXMgZG9lc24ndCBzYXRpc2Z5IHRoZSBEZWxhdW5heSBjb25kaXRpb24KICAgICAgICogKHAxIGlzIGluc2lkZSB0aGUgY2lyY3VtY2lyY2xlIG9mIFtwMCwgcGwsIHByXSksIGZsaXAgdGhlbSwKICAgICAgICogdGhlbiBkbyB0aGUgc2FtZSBjaGVjay9mbGlwIHJlY3Vyc2l2ZWx5IGZvciB0aGUgbmV3IHBhaXIgb2YgdHJpYW5nbGVzCiAgICAgICAqCiAgICAgICAqICAgICAgICAgICBwbCAgICAgICAgICAgICAgICAgICAgcGwKICAgICAgICogICAgICAgICAgL3x8XCAgICAgICAgICAgICAgICAgIC8gIFwKICAgICAgICogICAgICAgYWwvIHx8IFxibCAgICAgICAgICAgIGFsLyAgICBcYQogICAgICAgKiAgICAgICAgLyAgfHwgIFwgICAgICAgICAgICAgIC8gICAgICBcCiAgICAgICAqICAgICAgIC8gIGF8fGIgIFwgICAgZmxpcCAgICAvX19fYXJfX19cCiAgICAgICAqICAgICBwMFwgICB8fCAgIC9wMSAgID0+ICAgcDBcLS0tYmwtLS0vcDEKICAgICAgICogICAgICAgIFwgIHx8ICAvICAgICAgICAgICAgICBcICAgICAgLwogICAgICAgKiAgICAgICBhclwgfHwgL2JyICAgICAgICAgICAgIGJcICAgIC9icgogICAgICAgKiAgICAgICAgICBcfHwvICAgICAgICAgICAgICAgICAgXCAgLwogICAgICAgKiAgICAgICAgICAgcHIgICAgICAgICAgICAgICAgICAgIHByCiAgICAgICAqLwogICAgICBjb25zdCBhMCA9IGEgLSBhICUgMzsKICAgICAgYXIgPSBhMCArIChhICsgMikgJSAzOwogICAgICBpZiAoYiA9PT0gLTEpIHsKICAgICAgICAvLyBjb252ZXggaHVsbCBlZGdlCiAgICAgICAgaWYgKGkgPT09IDApIGJyZWFrOwogICAgICAgIGEgPSBFREdFX1NUQUNLWy0taV07CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgY29uc3QgYjAgPSBiIC0gYiAlIDM7CiAgICAgIGNvbnN0IGFsID0gYTAgKyAoYSArIDEpICUgMzsKICAgICAgY29uc3QgYmwgPSBiMCArIChiICsgMikgJSAzOwogICAgICBjb25zdCBwMCA9IHRyaWFuZ2xlc1thcl07CiAgICAgIGNvbnN0IHByID0gdHJpYW5nbGVzW2FdOwogICAgICBjb25zdCBwbCA9IHRyaWFuZ2xlc1thbF07CiAgICAgIGNvbnN0IHAxID0gdHJpYW5nbGVzW2JsXTsKICAgICAgY29uc3QgaWxsZWdhbCA9IGluQ2lyY2xlKGNvb3Jkc1syICogcDBdLCBjb29yZHNbMiAqIHAwICsgMV0sIGNvb3Jkc1syICogcHJdLCBjb29yZHNbMiAqIHByICsgMV0sIGNvb3Jkc1syICogcGxdLCBjb29yZHNbMiAqIHBsICsgMV0sIGNvb3Jkc1syICogcDFdLCBjb29yZHNbMiAqIHAxICsgMV0pOwogICAgICBpZiAoaWxsZWdhbCkgewogICAgICAgIHRyaWFuZ2xlc1thXSA9IHAxOwogICAgICAgIHRyaWFuZ2xlc1tiXSA9IHAwOwogICAgICAgIGNvbnN0IGhibCA9IGhhbGZlZGdlc1tibF07CgogICAgICAgIC8vIGVkZ2Ugc3dhcHBlZCBvbiB0aGUgb3RoZXIgc2lkZSBvZiB0aGUgaHVsbCAocmFyZSk7IGZpeCB0aGUgaGFsZmVkZ2UgcmVmZXJlbmNlCiAgICAgICAgaWYgKGhibCA9PT0gLTEpIHsKICAgICAgICAgIGxldCBlID0gdGhpcy5faHVsbFN0YXJ0OwogICAgICAgICAgZG8gewogICAgICAgICAgICBpZiAodGhpcy5faHVsbFRyaVtlXSA9PT0gYmwpIHsKICAgICAgICAgICAgICB0aGlzLl9odWxsVHJpW2VdID0gYTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBlID0gdGhpcy5faHVsbFByZXZbZV07CiAgICAgICAgICB9IHdoaWxlIChlICE9PSB0aGlzLl9odWxsU3RhcnQpOwogICAgICAgIH0KICAgICAgICB0aGlzLl9saW5rKGEsIGhibCk7CiAgICAgICAgdGhpcy5fbGluayhiLCBoYWxmZWRnZXNbYXJdKTsKICAgICAgICB0aGlzLl9saW5rKGFyLCBibCk7CiAgICAgICAgY29uc3QgYnIgPSBiMCArIChiICsgMSkgJSAzOwoKICAgICAgICAvLyBkb24ndCB3b3JyeSBhYm91dCBoaXR0aW5nIHRoZSBjYXA6IGl0IGNhbiBvbmx5IGhhcHBlbiBvbiBleHRyZW1lbHkgZGVnZW5lcmF0ZSBpbnB1dAogICAgICAgIGlmIChpIDwgRURHRV9TVEFDSy5sZW5ndGgpIHsKICAgICAgICAgIEVER0VfU1RBQ0tbaSsrXSA9IGJyOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoaSA9PT0gMCkgYnJlYWs7CiAgICAgICAgYSA9IEVER0VfU1RBQ0tbLS1pXTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGFyOwogIH0KICBfbGluayhhLCBiKSB7CiAgICB0aGlzLl9oYWxmZWRnZXNbYV0gPSBiOwogICAgaWYgKGIgIT09IC0xKSB0aGlzLl9oYWxmZWRnZXNbYl0gPSBhOwogIH0KCiAgLy8gYWRkIGEgbmV3IHRyaWFuZ2xlIGdpdmVuIHZlcnRleCBpbmRpY2VzIGFuZCBhZGphY2VudCBoYWxmLWVkZ2UgaWRzCiAgX2FkZFRyaWFuZ2xlKGkwLCBpMSwgaTIsIGEsIGIsIGMpIHsKICAgIGNvbnN0IHQgPSB0aGlzLnRyaWFuZ2xlc0xlbjsKICAgIHRoaXMuX3RyaWFuZ2xlc1t0XSA9IGkwOwogICAgdGhpcy5fdHJpYW5nbGVzW3QgKyAxXSA9IGkxOwogICAgdGhpcy5fdHJpYW5nbGVzW3QgKyAyXSA9IGkyOwogICAgdGhpcy5fbGluayh0LCBhKTsKICAgIHRoaXMuX2xpbmsodCArIDEsIGIpOwogICAgdGhpcy5fbGluayh0ICsgMiwgYyk7CiAgICB0aGlzLnRyaWFuZ2xlc0xlbiArPSAzOwogICAgcmV0dXJuIHQ7CiAgfQp9CgovLyBtb25vdG9uaWNhbGx5IGluY3JlYXNlcyB3aXRoIHJlYWwgYW5nbGUsIGJ1dCBkb2Vzbid0IG5lZWQgZXhwZW5zaXZlIHRyaWdvbm9tZXRyeQpmdW5jdGlvbiBwc2V1ZG9BbmdsZShkeCwgZHkpIHsKICBjb25zdCBwID0gZHggLyAoTWF0aC5hYnMoZHgpICsgTWF0aC5hYnMoZHkpKTsKICByZXR1cm4gKGR5ID4gMCA/IDMgLSBwIDogMSArIHApIC8gNDsgLy8gWzAuLjFdCn0KCmZ1bmN0aW9uIGRpc3QoYXgsIGF5LCBieCwgYnkpIHsKICBjb25zdCBkeCA9IGF4IC0gYng7CiAgY29uc3QgZHkgPSBheSAtIGJ5OwogIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTsKfQpmdW5jdGlvbiBpbkNpcmNsZShheCwgYXksIGJ4LCBieSwgY3gsIGN5LCBweCwgcHkpIHsKICBjb25zdCBkeCA9IGF4IC0gcHg7CiAgY29uc3QgZHkgPSBheSAtIHB5OwogIGNvbnN0IGV4ID0gYnggLSBweDsKICBjb25zdCBleSA9IGJ5IC0gcHk7CiAgY29uc3QgZnggPSBjeCAtIHB4OwogIGNvbnN0IGZ5ID0gY3kgLSBweTsKICBjb25zdCBhcCA9IGR4ICogZHggKyBkeSAqIGR5OwogIGNvbnN0IGJwID0gZXggKiBleCArIGV5ICogZXk7CiAgY29uc3QgY3AgPSBmeCAqIGZ4ICsgZnkgKiBmeTsKICByZXR1cm4gZHggKiAoZXkgKiBjcCAtIGJwICogZnkpIC0gZHkgKiAoZXggKiBjcCAtIGJwICogZngpICsgYXAgKiAoZXggKiBmeSAtIGV5ICogZngpIDwgMDsKfQpmdW5jdGlvbiBjaXJjdW1yYWRpdXMoYXgsIGF5LCBieCwgYnksIGN4LCBjeSkgewogIGNvbnN0IGR4ID0gYnggLSBheDsKICBjb25zdCBkeSA9IGJ5IC0gYXk7CiAgY29uc3QgZXggPSBjeCAtIGF4OwogIGNvbnN0IGV5ID0gY3kgLSBheTsKICBjb25zdCBibCA9IGR4ICogZHggKyBkeSAqIGR5OwogIGNvbnN0IGNsID0gZXggKiBleCArIGV5ICogZXk7CiAgY29uc3QgZCA9IDAuNSAvIChkeCAqIGV5IC0gZHkgKiBleCk7CiAgY29uc3QgeCA9IChleSAqIGJsIC0gZHkgKiBjbCkgKiBkOwogIGNvbnN0IHkgPSAoZHggKiBjbCAtIGV4ICogYmwpICogZDsKICByZXR1cm4geCAqIHggKyB5ICogeTsKfQpmdW5jdGlvbiBjaXJjdW1jZW50ZXIoYXgsIGF5LCBieCwgYnksIGN4LCBjeSkgewogIGNvbnN0IGR4ID0gYnggLSBheDsKICBjb25zdCBkeSA9IGJ5IC0gYXk7CiAgY29uc3QgZXggPSBjeCAtIGF4OwogIGNvbnN0IGV5ID0gY3kgLSBheTsKICBjb25zdCBibCA9IGR4ICogZHggKyBkeSAqIGR5OwogIGNvbnN0IGNsID0gZXggKiBleCArIGV5ICogZXk7CiAgY29uc3QgZCA9IDAuNSAvIChkeCAqIGV5IC0gZHkgKiBleCk7CiAgY29uc3QgeCA9IGF4ICsgKGV5ICogYmwgLSBkeSAqIGNsKSAqIGQ7CiAgY29uc3QgeSA9IGF5ICsgKGR4ICogY2wgLSBleCAqIGJsKSAqIGQ7CiAgcmV0dXJuIHsKICAgIHgsCiAgICB5CiAgfTsKfQpmdW5jdGlvbiBxdWlja3NvcnQoaWRzLCBkaXN0cywgbGVmdCwgcmlnaHQpIHsKICBpZiAocmlnaHQgLSBsZWZ0IDw9IDIwKSB7CiAgICBmb3IgKGxldCBpID0gbGVmdCArIDE7IGkgPD0gcmlnaHQ7IGkrKykgewogICAgICBjb25zdCB0ZW1wID0gaWRzW2ldOwogICAgICBjb25zdCB0ZW1wRGlzdCA9IGRpc3RzW3RlbXBdOwogICAgICBsZXQgaiA9IGkgLSAxOwogICAgICB3aGlsZSAoaiA+PSBsZWZ0ICYmIGRpc3RzW2lkc1tqXV0gPiB0ZW1wRGlzdCkgaWRzW2ogKyAxXSA9IGlkc1tqLS1dOwogICAgICBpZHNbaiArIDFdID0gdGVtcDsKICAgIH0KICB9IGVsc2UgewogICAgY29uc3QgbWVkaWFuID0gbGVmdCArIHJpZ2h0ID4+IDE7CiAgICBsZXQgaSA9IGxlZnQgKyAxOwogICAgbGV0IGogPSByaWdodDsKICAgIHN3YXAoaWRzLCBtZWRpYW4sIGkpOwogICAgaWYgKGRpc3RzW2lkc1tsZWZ0XV0gPiBkaXN0c1tpZHNbcmlnaHRdXSkgc3dhcChpZHMsIGxlZnQsIHJpZ2h0KTsKICAgIGlmIChkaXN0c1tpZHNbaV1dID4gZGlzdHNbaWRzW3JpZ2h0XV0pIHN3YXAoaWRzLCBpLCByaWdodCk7CiAgICBpZiAoZGlzdHNbaWRzW2xlZnRdXSA+IGRpc3RzW2lkc1tpXV0pIHN3YXAoaWRzLCBsZWZ0LCBpKTsKICAgIGNvbnN0IHRlbXAgPSBpZHNbaV07CiAgICBjb25zdCB0ZW1wRGlzdCA9IGRpc3RzW3RlbXBdOwogICAgd2hpbGUgKHRydWUpIHsKICAgICAgZG8gaSsrOyB3aGlsZSAoZGlzdHNbaWRzW2ldXSA8IHRlbXBEaXN0KTsKICAgICAgZG8gai0tOyB3aGlsZSAoZGlzdHNbaWRzW2pdXSA+IHRlbXBEaXN0KTsKICAgICAgaWYgKGogPCBpKSBicmVhazsKICAgICAgc3dhcChpZHMsIGksIGopOwogICAgfQogICAgaWRzW2xlZnQgKyAxXSA9IGlkc1tqXTsKICAgIGlkc1tqXSA9IHRlbXA7CiAgICBpZiAocmlnaHQgLSBpICsgMSA+PSBqIC0gbGVmdCkgewogICAgICBxdWlja3NvcnQoaWRzLCBkaXN0cywgaSwgcmlnaHQpOwogICAgICBxdWlja3NvcnQoaWRzLCBkaXN0cywgbGVmdCwgaiAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgcXVpY2tzb3J0KGlkcywgZGlzdHMsIGxlZnQsIGogLSAxKTsKICAgICAgcXVpY2tzb3J0KGlkcywgZGlzdHMsIGksIHJpZ2h0KTsKICAgIH0KICB9Cn0KZnVuY3Rpb24gc3dhcChhcnIsIGksIGopIHsKICBjb25zdCB0bXAgPSBhcnJbaV07CiAgYXJyW2ldID0gYXJyW2pdOwogIGFycltqXSA9IHRtcDsKfQpmdW5jdGlvbiBkZWZhdWx0R2V0WChwKSB7CiAgcmV0dXJuIHBbMF07Cn0KZnVuY3Rpb24gZGVmYXVsdEdldFkocCkgewogIHJldHVybiBwWzFdOwp9Cgpjb25zdCBlcHNpbG9uID0gMWUtNjsKY2xhc3MgUGF0aCB7CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLl94MCA9IHRoaXMuX3kwID0KICAgIC8vIHN0YXJ0IG9mIGN1cnJlbnQgc3VicGF0aAogICAgdGhpcy5feDEgPSB0aGlzLl95MSA9IG51bGw7IC8vIGVuZCBvZiBjdXJyZW50IHN1YnBhdGgKICAgIHRoaXMuXyA9ICIiOwogIH0KICBtb3ZlVG8oeCwgeSkgewogICAgdGhpcy5fICs9IGBNJHt0aGlzLl94MCA9IHRoaXMuX3gxID0gK3h9LCR7dGhpcy5feTAgPSB0aGlzLl95MSA9ICt5fWA7CiAgfQogIGNsb3NlUGF0aCgpIHsKICAgIGlmICh0aGlzLl94MSAhPT0gbnVsbCkgewogICAgICB0aGlzLl94MSA9IHRoaXMuX3gwLCB0aGlzLl95MSA9IHRoaXMuX3kwOwogICAgICB0aGlzLl8gKz0gIloiOwogICAgfQogIH0KICBsaW5lVG8oeCwgeSkgewogICAgdGhpcy5fICs9IGBMJHt0aGlzLl94MSA9ICt4fSwke3RoaXMuX3kxID0gK3l9YDsKICB9CiAgYXJjKHgsIHksIHIpIHsKICAgIHggPSAreCwgeSA9ICt5LCByID0gK3I7CiAgICBjb25zdCB4MCA9IHggKyByOwogICAgY29uc3QgeTAgPSB5OwogICAgaWYgKHIgPCAwKSB0aHJvdyBuZXcgRXJyb3IoIm5lZ2F0aXZlIHJhZGl1cyIpOwogICAgaWYgKHRoaXMuX3gxID09PSBudWxsKSB0aGlzLl8gKz0gYE0ke3gwfSwke3kwfWA7ZWxzZSBpZiAoTWF0aC5hYnModGhpcy5feDEgLSB4MCkgPiBlcHNpbG9uIHx8IE1hdGguYWJzKHRoaXMuX3kxIC0geTApID4gZXBzaWxvbikgdGhpcy5fICs9ICJMIiArIHgwICsgIiwiICsgeTA7CiAgICBpZiAoIXIpIHJldHVybjsKICAgIHRoaXMuXyArPSBgQSR7cn0sJHtyfSwwLDEsMSwke3ggLSByfSwke3l9QSR7cn0sJHtyfSwwLDEsMSwke3RoaXMuX3gxID0geDB9LCR7dGhpcy5feTEgPSB5MH1gOwogIH0KICByZWN0KHgsIHksIHcsIGgpIHsKICAgIHRoaXMuXyArPSBgTSR7dGhpcy5feDAgPSB0aGlzLl94MSA9ICt4fSwke3RoaXMuX3kwID0gdGhpcy5feTEgPSAreX1oJHsrd312JHsraH1oJHstd31aYDsKICB9CiAgdmFsdWUoKSB7CiAgICByZXR1cm4gdGhpcy5fIHx8IG51bGw7CiAgfQp9CgpjbGFzcyBQb2x5Z29uIHsKICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMuXyA9IFtdOwogIH0KICBtb3ZlVG8oeCwgeSkgewogICAgdGhpcy5fLnB1c2goW3gsIHldKTsKICB9CiAgY2xvc2VQYXRoKCkgewogICAgdGhpcy5fLnB1c2godGhpcy5fWzBdLnNsaWNlKCkpOwogIH0KICBsaW5lVG8oeCwgeSkgewogICAgdGhpcy5fLnB1c2goW3gsIHldKTsKICB9CiAgdmFsdWUoKSB7CiAgICByZXR1cm4gdGhpcy5fLmxlbmd0aCA/IHRoaXMuXyA6IG51bGw7CiAgfQp9CgpjbGFzcyBWb3Jvbm9pIHsKICBjb25zdHJ1Y3RvcihkZWxhdW5heSwgW3htaW4sIHltaW4sIHhtYXgsIHltYXhdID0gWzAsIDAsIDk2MCwgNTAwXSkgewogICAgaWYgKCEoKHhtYXggPSAreG1heCkgPj0gKHhtaW4gPSAreG1pbikpIHx8ICEoKHltYXggPSAreW1heCkgPj0gKHltaW4gPSAreW1pbikpKSB0aHJvdyBuZXcgRXJyb3IoImludmFsaWQgYm91bmRzIik7CiAgICB0aGlzLmRlbGF1bmF5ID0gZGVsYXVuYXk7CiAgICB0aGlzLl9jaXJjdW1jZW50ZXJzID0gbmV3IEZsb2F0NjRBcnJheShkZWxhdW5heS5wb2ludHMubGVuZ3RoICogMik7CiAgICB0aGlzLnZlY3RvcnMgPSBuZXcgRmxvYXQ2NEFycmF5KGRlbGF1bmF5LnBvaW50cy5sZW5ndGggKiAyKTsKICAgIHRoaXMueG1heCA9IHhtYXgsIHRoaXMueG1pbiA9IHhtaW47CiAgICB0aGlzLnltYXggPSB5bWF4LCB0aGlzLnltaW4gPSB5bWluOwogICAgdGhpcy5faW5pdCgpOwogIH0KICB1cGRhdGUoKSB7CiAgICB0aGlzLmRlbGF1bmF5LnVwZGF0ZSgpOwogICAgdGhpcy5faW5pdCgpOwogICAgcmV0dXJuIHRoaXM7CiAgfQogIF9pbml0KCkgewogICAgY29uc3QgewogICAgICBkZWxhdW5heTogewogICAgICAgIHBvaW50cywKICAgICAgICBodWxsLAogICAgICAgIHRyaWFuZ2xlcwogICAgICB9LAogICAgICB2ZWN0b3JzCiAgICB9ID0gdGhpczsKICAgIGxldCBieCwgYnk7IC8vIGxhemlseSBjb21wdXRlZCBiYXJ5Y2VudGVyIG9mIHRoZSBodWxsCgogICAgLy8gQ29tcHV0ZSBjaXJjdW1jZW50ZXJzLgogICAgY29uc3QgY2lyY3VtY2VudGVycyA9IHRoaXMuY2lyY3VtY2VudGVycyA9IHRoaXMuX2NpcmN1bWNlbnRlcnMuc3ViYXJyYXkoMCwgdHJpYW5nbGVzLmxlbmd0aCAvIDMgKiAyKTsKICAgIGZvciAobGV0IGkgPSAwLCBqID0gMCwgbiA9IHRyaWFuZ2xlcy5sZW5ndGgsIHgsIHk7IGkgPCBuOyBpICs9IDMsIGogKz0gMikgewogICAgICBjb25zdCB0MSA9IHRyaWFuZ2xlc1tpXSAqIDI7CiAgICAgIGNvbnN0IHQyID0gdHJpYW5nbGVzW2kgKyAxXSAqIDI7CiAgICAgIGNvbnN0IHQzID0gdHJpYW5nbGVzW2kgKyAyXSAqIDI7CiAgICAgIGNvbnN0IHgxID0gcG9pbnRzW3QxXTsKICAgICAgY29uc3QgeTEgPSBwb2ludHNbdDEgKyAxXTsKICAgICAgY29uc3QgeDIgPSBwb2ludHNbdDJdOwogICAgICBjb25zdCB5MiA9IHBvaW50c1t0MiArIDFdOwogICAgICBjb25zdCB4MyA9IHBvaW50c1t0M107CiAgICAgIGNvbnN0IHkzID0gcG9pbnRzW3QzICsgMV07CiAgICAgIGNvbnN0IGR4ID0geDIgLSB4MTsKICAgICAgY29uc3QgZHkgPSB5MiAtIHkxOwogICAgICBjb25zdCBleCA9IHgzIC0geDE7CiAgICAgIGNvbnN0IGV5ID0geTMgLSB5MTsKICAgICAgY29uc3QgYWIgPSAoZHggKiBleSAtIGR5ICogZXgpICogMjsKICAgICAgaWYgKE1hdGguYWJzKGFiKSA8IDFlLTkpIHsKICAgICAgICAvLyBGb3IgYSBkZWdlbmVyYXRlIHRyaWFuZ2xlLCB0aGUgY2lyY3VtY2VudGVyIGlzIGF0IHRoZSBpbmZpbml0eSwgaW4gYQogICAgICAgIC8vIGRpcmVjdGlvbiBvcnRob2dvbmFsIHRvIHRoZSBoYWxmZWRnZSBhbmQgYXdheSBmcm9tIHRoZSDigJxjZW50ZXLigJ0gb2YKICAgICAgICAvLyB0aGUgZGlhZ3JhbSA8YngsIGJ5PiwgZGVmaW5lZCBhcyB0aGUgaHVsbOKAmXMgYmFyeWNlbnRlci4KICAgICAgICBpZiAoYnggPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgYnggPSBieSA9IDA7CiAgICAgICAgICBmb3IgKGNvbnN0IGkgb2YgaHVsbCkgYnggKz0gcG9pbnRzW2kgKiAyXSwgYnkgKz0gcG9pbnRzW2kgKiAyICsgMV07CiAgICAgICAgICBieCAvPSBodWxsLmxlbmd0aCwgYnkgLz0gaHVsbC5sZW5ndGg7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGEgPSAxZTkgKiBNYXRoLnNpZ24oKGJ4IC0geDEpICogZXkgLSAoYnkgLSB5MSkgKiBleCk7CiAgICAgICAgeCA9ICh4MSArIHgzKSAvIDIgLSBhICogZXk7CiAgICAgICAgeSA9ICh5MSArIHkzKSAvIDIgKyBhICogZXg7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29uc3QgZCA9IDEgLyBhYjsKICAgICAgICBjb25zdCBibCA9IGR4ICogZHggKyBkeSAqIGR5OwogICAgICAgIGNvbnN0IGNsID0gZXggKiBleCArIGV5ICogZXk7CiAgICAgICAgeCA9IHgxICsgKGV5ICogYmwgLSBkeSAqIGNsKSAqIGQ7CiAgICAgICAgeSA9IHkxICsgKGR4ICogY2wgLSBleCAqIGJsKSAqIGQ7CiAgICAgIH0KICAgICAgY2lyY3VtY2VudGVyc1tqXSA9IHg7CiAgICAgIGNpcmN1bWNlbnRlcnNbaiArIDFdID0geTsKICAgIH0KCiAgICAvLyBDb21wdXRlIGV4dGVyaW9yIGNlbGwgcmF5cy4KICAgIGxldCBoID0gaHVsbFtodWxsLmxlbmd0aCAtIDFdOwogICAgbGV0IHAwLAogICAgICBwMSA9IGggKiA0OwogICAgbGV0IHgwLAogICAgICB4MSA9IHBvaW50c1syICogaF07CiAgICBsZXQgeTAsCiAgICAgIHkxID0gcG9pbnRzWzIgKiBoICsgMV07CiAgICB2ZWN0b3JzLmZpbGwoMCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bGwubGVuZ3RoOyArK2kpIHsKICAgICAgaCA9IGh1bGxbaV07CiAgICAgIHAwID0gcDEsIHgwID0geDEsIHkwID0geTE7CiAgICAgIHAxID0gaCAqIDQsIHgxID0gcG9pbnRzWzIgKiBoXSwgeTEgPSBwb2ludHNbMiAqIGggKyAxXTsKICAgICAgdmVjdG9yc1twMCArIDJdID0gdmVjdG9yc1twMV0gPSB5MCAtIHkxOwogICAgICB2ZWN0b3JzW3AwICsgM10gPSB2ZWN0b3JzW3AxICsgMV0gPSB4MSAtIHgwOwogICAgfQogIH0KICByZW5kZXIoY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIGRlbGF1bmF5OiB7CiAgICAgICAgaGFsZmVkZ2VzLAogICAgICAgIGluZWRnZXMsCiAgICAgICAgaHVsbAogICAgICB9LAogICAgICBjaXJjdW1jZW50ZXJzLAogICAgICB2ZWN0b3JzCiAgICB9ID0gdGhpczsKICAgIGlmIChodWxsLmxlbmd0aCA8PSAxKSByZXR1cm4gbnVsbDsKICAgIGZvciAobGV0IGkgPSAwLCBuID0gaGFsZmVkZ2VzLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgICBjb25zdCBqID0gaGFsZmVkZ2VzW2ldOwogICAgICBpZiAoaiA8IGkpIGNvbnRpbnVlOwogICAgICBjb25zdCB0aSA9IE1hdGguZmxvb3IoaSAvIDMpICogMjsKICAgICAgY29uc3QgdGogPSBNYXRoLmZsb29yKGogLyAzKSAqIDI7CiAgICAgIGNvbnN0IHhpID0gY2lyY3VtY2VudGVyc1t0aV07CiAgICAgIGNvbnN0IHlpID0gY2lyY3VtY2VudGVyc1t0aSArIDFdOwogICAgICBjb25zdCB4aiA9IGNpcmN1bWNlbnRlcnNbdGpdOwogICAgICBjb25zdCB5aiA9IGNpcmN1bWNlbnRlcnNbdGogKyAxXTsKICAgICAgdGhpcy5fcmVuZGVyU2VnbWVudCh4aSwgeWksIHhqLCB5aiwgY29udGV4dCk7CiAgICB9CiAgICBsZXQgaDAsCiAgICAgIGgxID0gaHVsbFtodWxsLmxlbmd0aCAtIDFdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBodWxsLmxlbmd0aDsgKytpKSB7CiAgICAgIGgwID0gaDEsIGgxID0gaHVsbFtpXTsKICAgICAgY29uc3QgdCA9IE1hdGguZmxvb3IoaW5lZGdlc1toMV0gLyAzKSAqIDI7CiAgICAgIGNvbnN0IHggPSBjaXJjdW1jZW50ZXJzW3RdOwogICAgICBjb25zdCB5ID0gY2lyY3VtY2VudGVyc1t0ICsgMV07CiAgICAgIGNvbnN0IHYgPSBoMCAqIDQ7CiAgICAgIGNvbnN0IHAgPSB0aGlzLl9wcm9qZWN0KHgsIHksIHZlY3RvcnNbdiArIDJdLCB2ZWN0b3JzW3YgKyAzXSk7CiAgICAgIGlmIChwKSB0aGlzLl9yZW5kZXJTZWdtZW50KHgsIHksIHBbMF0sIHBbMV0sIGNvbnRleHQpOwogICAgfQogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgcmVuZGVyQm91bmRzKGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29udGV4dC5yZWN0KHRoaXMueG1pbiwgdGhpcy55bWluLCB0aGlzLnhtYXggLSB0aGlzLnhtaW4sIHRoaXMueW1heCAtIHRoaXMueW1pbik7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICByZW5kZXJDZWxsKGksIGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgcG9pbnRzID0gdGhpcy5fY2xpcChpKTsKICAgIGlmIChwb2ludHMgPT09IG51bGwgfHwgIXBvaW50cy5sZW5ndGgpIHJldHVybjsKICAgIGNvbnRleHQubW92ZVRvKHBvaW50c1swXSwgcG9pbnRzWzFdKTsKICAgIGxldCBuID0gcG9pbnRzLmxlbmd0aDsKICAgIHdoaWxlIChwb2ludHNbMF0gPT09IHBvaW50c1tuIC0gMl0gJiYgcG9pbnRzWzFdID09PSBwb2ludHNbbiAtIDFdICYmIG4gPiAxKSBuIC09IDI7CiAgICBmb3IgKGxldCBpID0gMjsgaSA8IG47IGkgKz0gMikgewogICAgICBpZiAocG9pbnRzW2ldICE9PSBwb2ludHNbaSAtIDJdIHx8IHBvaW50c1tpICsgMV0gIT09IHBvaW50c1tpIC0gMV0pIGNvbnRleHQubGluZVRvKHBvaW50c1tpXSwgcG9pbnRzW2kgKyAxXSk7CiAgICB9CiAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgKmNlbGxQb2x5Z29ucygpIHsKICAgIGNvbnN0IHsKICAgICAgZGVsYXVuYXk6IHsKICAgICAgICBwb2ludHMKICAgICAgfQogICAgfSA9IHRoaXM7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvaW50cy5sZW5ndGggLyAyOyBpIDwgbjsgKytpKSB7CiAgICAgIGNvbnN0IGNlbGwgPSB0aGlzLmNlbGxQb2x5Z29uKGkpOwogICAgICBpZiAoY2VsbCkgY2VsbC5pbmRleCA9IGksIHlpZWxkIGNlbGw7CiAgICB9CiAgfQogIGNlbGxQb2x5Z29uKGkpIHsKICAgIGNvbnN0IHBvbHlnb24gPSBuZXcgUG9seWdvbigpOwogICAgdGhpcy5yZW5kZXJDZWxsKGksIHBvbHlnb24pOwogICAgcmV0dXJuIHBvbHlnb24udmFsdWUoKTsKICB9CiAgX3JlbmRlclNlZ21lbnQoeDAsIHkwLCB4MSwgeTEsIGNvbnRleHQpIHsKICAgIGxldCBTOwogICAgY29uc3QgYzAgPSB0aGlzLl9yZWdpb25jb2RlKHgwLCB5MCk7CiAgICBjb25zdCBjMSA9IHRoaXMuX3JlZ2lvbmNvZGUoeDEsIHkxKTsKICAgIGlmIChjMCA9PT0gMCAmJiBjMSA9PT0gMCkgewogICAgICBjb250ZXh0Lm1vdmVUbyh4MCwgeTApOwogICAgICBjb250ZXh0LmxpbmVUbyh4MSwgeTEpOwogICAgfSBlbHNlIGlmIChTID0gdGhpcy5fY2xpcFNlZ21lbnQoeDAsIHkwLCB4MSwgeTEsIGMwLCBjMSkpIHsKICAgICAgY29udGV4dC5tb3ZlVG8oU1swXSwgU1sxXSk7CiAgICAgIGNvbnRleHQubGluZVRvKFNbMl0sIFNbM10pOwogICAgfQogIH0KICBjb250YWlucyhpLCB4LCB5KSB7CiAgICBpZiAoKHggPSAreCwgeCAhPT0geCkgfHwgKHkgPSAreSwgeSAhPT0geSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0aGlzLmRlbGF1bmF5Ll9zdGVwKGksIHgsIHkpID09PSBpOwogIH0KICAqbmVpZ2hib3JzKGkpIHsKICAgIGNvbnN0IGNpID0gdGhpcy5fY2xpcChpKTsKICAgIGlmIChjaSkgZm9yIChjb25zdCBqIG9mIHRoaXMuZGVsYXVuYXkubmVpZ2hib3JzKGkpKSB7CiAgICAgIGNvbnN0IGNqID0gdGhpcy5fY2xpcChqKTsKICAgICAgLy8gZmluZCB0aGUgY29tbW9uIGVkZ2UKICAgICAgaWYgKGNqKSBsb29wOiBmb3IgKGxldCBhaSA9IDAsIGxpID0gY2kubGVuZ3RoOyBhaSA8IGxpOyBhaSArPSAyKSB7CiAgICAgICAgZm9yIChsZXQgYWogPSAwLCBsaiA9IGNqLmxlbmd0aDsgYWogPCBsajsgYWogKz0gMikgewogICAgICAgICAgaWYgKGNpW2FpXSA9PT0gY2pbYWpdICYmIGNpW2FpICsgMV0gPT09IGNqW2FqICsgMV0gJiYgY2lbKGFpICsgMikgJSBsaV0gPT09IGNqWyhhaiArIGxqIC0gMikgJSBsal0gJiYgY2lbKGFpICsgMykgJSBsaV0gPT09IGNqWyhhaiArIGxqIC0gMSkgJSBsal0pIHsKICAgICAgICAgICAgeWllbGQgajsKICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CiAgX2NlbGwoaSkgewogICAgY29uc3QgewogICAgICBjaXJjdW1jZW50ZXJzLAogICAgICBkZWxhdW5heTogewogICAgICAgIGluZWRnZXMsCiAgICAgICAgaGFsZmVkZ2VzLAogICAgICAgIHRyaWFuZ2xlcwogICAgICB9CiAgICB9ID0gdGhpczsKICAgIGNvbnN0IGUwID0gaW5lZGdlc1tpXTsKICAgIGlmIChlMCA9PT0gLTEpIHJldHVybiBudWxsOyAvLyBjb2luY2lkZW50IHBvaW50CiAgICBjb25zdCBwb2ludHMgPSBbXTsKICAgIGxldCBlID0gZTA7CiAgICBkbyB7CiAgICAgIGNvbnN0IHQgPSBNYXRoLmZsb29yKGUgLyAzKTsKICAgICAgcG9pbnRzLnB1c2goY2lyY3VtY2VudGVyc1t0ICogMl0sIGNpcmN1bWNlbnRlcnNbdCAqIDIgKyAxXSk7CiAgICAgIGUgPSBlICUgMyA9PT0gMiA/IGUgLSAyIDogZSArIDE7CiAgICAgIGlmICh0cmlhbmdsZXNbZV0gIT09IGkpIGJyZWFrOyAvLyBiYWQgdHJpYW5ndWxhdGlvbgogICAgICBlID0gaGFsZmVkZ2VzW2VdOwogICAgfSB3aGlsZSAoZSAhPT0gZTAgJiYgZSAhPT0gLTEpOwogICAgcmV0dXJuIHBvaW50czsKICB9CiAgX2NsaXAoaSkgewogICAgLy8gZGVnZW5lcmF0ZSBjYXNlICgxIHZhbGlkIHBvaW50OiByZXR1cm4gdGhlIGJveCkKICAgIGlmIChpID09PSAwICYmIHRoaXMuZGVsYXVuYXkuaHVsbC5sZW5ndGggPT09IDEpIHsKICAgICAgcmV0dXJuIFt0aGlzLnhtYXgsIHRoaXMueW1pbiwgdGhpcy54bWF4LCB0aGlzLnltYXgsIHRoaXMueG1pbiwgdGhpcy55bWF4LCB0aGlzLnhtaW4sIHRoaXMueW1pbl07CiAgICB9CiAgICBjb25zdCBwb2ludHMgPSB0aGlzLl9jZWxsKGkpOwogICAgaWYgKHBvaW50cyA9PT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICBjb25zdCB7CiAgICAgIHZlY3RvcnM6IFYKICAgIH0gPSB0aGlzOwogICAgY29uc3QgdiA9IGkgKiA0OwogICAgcmV0dXJuIHRoaXMuX3NpbXBsaWZ5KFZbdl0gfHwgVlt2ICsgMV0gPyB0aGlzLl9jbGlwSW5maW5pdGUoaSwgcG9pbnRzLCBWW3ZdLCBWW3YgKyAxXSwgVlt2ICsgMl0sIFZbdiArIDNdKSA6IHRoaXMuX2NsaXBGaW5pdGUoaSwgcG9pbnRzKSk7CiAgfQogIF9jbGlwRmluaXRlKGksIHBvaW50cykgewogICAgY29uc3QgbiA9IHBvaW50cy5sZW5ndGg7CiAgICBsZXQgUCA9IG51bGw7CiAgICBsZXQgeDAsCiAgICAgIHkwLAogICAgICB4MSA9IHBvaW50c1tuIC0gMl0sCiAgICAgIHkxID0gcG9pbnRzW24gLSAxXTsKICAgIGxldCBjMCwKICAgICAgYzEgPSB0aGlzLl9yZWdpb25jb2RlKHgxLCB5MSk7CiAgICBsZXQgZTAsCiAgICAgIGUxID0gMDsKICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaiArPSAyKSB7CiAgICAgIHgwID0geDEsIHkwID0geTEsIHgxID0gcG9pbnRzW2pdLCB5MSA9IHBvaW50c1tqICsgMV07CiAgICAgIGMwID0gYzEsIGMxID0gdGhpcy5fcmVnaW9uY29kZSh4MSwgeTEpOwogICAgICBpZiAoYzAgPT09IDAgJiYgYzEgPT09IDApIHsKICAgICAgICBlMCA9IGUxLCBlMSA9IDA7CiAgICAgICAgaWYgKFApIFAucHVzaCh4MSwgeTEpO2Vsc2UgUCA9IFt4MSwgeTFdOwogICAgICB9IGVsc2UgewogICAgICAgIGxldCBTLCBzeDAsIHN5MCwgc3gxLCBzeTE7CiAgICAgICAgaWYgKGMwID09PSAwKSB7CiAgICAgICAgICBpZiAoKFMgPSB0aGlzLl9jbGlwU2VnbWVudCh4MCwgeTAsIHgxLCB5MSwgYzAsIGMxKSkgPT09IG51bGwpIGNvbnRpbnVlOwogICAgICAgICAgW3N4MCwgc3kwLCBzeDEsIHN5MV0gPSBTOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoKFMgPSB0aGlzLl9jbGlwU2VnbWVudCh4MSwgeTEsIHgwLCB5MCwgYzEsIGMwKSkgPT09IG51bGwpIGNvbnRpbnVlOwogICAgICAgICAgW3N4MSwgc3kxLCBzeDAsIHN5MF0gPSBTOwogICAgICAgICAgZTAgPSBlMSwgZTEgPSB0aGlzLl9lZGdlY29kZShzeDAsIHN5MCk7CiAgICAgICAgICBpZiAoZTAgJiYgZTEpIHRoaXMuX2VkZ2UoaSwgZTAsIGUxLCBQLCBQLmxlbmd0aCk7CiAgICAgICAgICBpZiAoUCkgUC5wdXNoKHN4MCwgc3kwKTtlbHNlIFAgPSBbc3gwLCBzeTBdOwogICAgICAgIH0KICAgICAgICBlMCA9IGUxLCBlMSA9IHRoaXMuX2VkZ2Vjb2RlKHN4MSwgc3kxKTsKICAgICAgICBpZiAoZTAgJiYgZTEpIHRoaXMuX2VkZ2UoaSwgZTAsIGUxLCBQLCBQLmxlbmd0aCk7CiAgICAgICAgaWYgKFApIFAucHVzaChzeDEsIHN5MSk7ZWxzZSBQID0gW3N4MSwgc3kxXTsKICAgICAgfQogICAgfQogICAgaWYgKFApIHsKICAgICAgZTAgPSBlMSwgZTEgPSB0aGlzLl9lZGdlY29kZShQWzBdLCBQWzFdKTsKICAgICAgaWYgKGUwICYmIGUxKSB0aGlzLl9lZGdlKGksIGUwLCBlMSwgUCwgUC5sZW5ndGgpOwogICAgfSBlbHNlIGlmICh0aGlzLmNvbnRhaW5zKGksICh0aGlzLnhtaW4gKyB0aGlzLnhtYXgpIC8gMiwgKHRoaXMueW1pbiArIHRoaXMueW1heCkgLyAyKSkgewogICAgICByZXR1cm4gW3RoaXMueG1heCwgdGhpcy55bWluLCB0aGlzLnhtYXgsIHRoaXMueW1heCwgdGhpcy54bWluLCB0aGlzLnltYXgsIHRoaXMueG1pbiwgdGhpcy55bWluXTsKICAgIH0KICAgIHJldHVybiBQOwogIH0KICBfY2xpcFNlZ21lbnQoeDAsIHkwLCB4MSwgeTEsIGMwLCBjMSkgewogICAgLy8gZm9yIG1vcmUgcm9idXN0bmVzcywgYWx3YXlzIGNvbnNpZGVyIHRoZSBzZWdtZW50IGluIHRoZSBzYW1lIG9yZGVyCiAgICBjb25zdCBmbGlwID0gYzAgPCBjMTsKICAgIGlmIChmbGlwKSBbeDAsIHkwLCB4MSwgeTEsIGMwLCBjMV0gPSBbeDEsIHkxLCB4MCwgeTAsIGMxLCBjMF07CiAgICB3aGlsZSAodHJ1ZSkgewogICAgICBpZiAoYzAgPT09IDAgJiYgYzEgPT09IDApIHJldHVybiBmbGlwID8gW3gxLCB5MSwgeDAsIHkwXSA6IFt4MCwgeTAsIHgxLCB5MV07CiAgICAgIGlmIChjMCAmIGMxKSByZXR1cm4gbnVsbDsKICAgICAgbGV0IHgsCiAgICAgICAgeSwKICAgICAgICBjID0gYzAgfHwgYzE7CiAgICAgIGlmIChjICYgMGIxMDAwKSB4ID0geDAgKyAoeDEgLSB4MCkgKiAodGhpcy55bWF4IC0geTApIC8gKHkxIC0geTApLCB5ID0gdGhpcy55bWF4O2Vsc2UgaWYgKGMgJiAwYjAxMDApIHggPSB4MCArICh4MSAtIHgwKSAqICh0aGlzLnltaW4gLSB5MCkgLyAoeTEgLSB5MCksIHkgPSB0aGlzLnltaW47ZWxzZSBpZiAoYyAmIDBiMDAxMCkgeSA9IHkwICsgKHkxIC0geTApICogKHRoaXMueG1heCAtIHgwKSAvICh4MSAtIHgwKSwgeCA9IHRoaXMueG1heDtlbHNlIHkgPSB5MCArICh5MSAtIHkwKSAqICh0aGlzLnhtaW4gLSB4MCkgLyAoeDEgLSB4MCksIHggPSB0aGlzLnhtaW47CiAgICAgIGlmIChjMCkgeDAgPSB4LCB5MCA9IHksIGMwID0gdGhpcy5fcmVnaW9uY29kZSh4MCwgeTApO2Vsc2UgeDEgPSB4LCB5MSA9IHksIGMxID0gdGhpcy5fcmVnaW9uY29kZSh4MSwgeTEpOwogICAgfQogIH0KICBfY2xpcEluZmluaXRlKGksIHBvaW50cywgdngwLCB2eTAsIHZ4biwgdnluKSB7CiAgICBsZXQgUCA9IEFycmF5LmZyb20ocG9pbnRzKSwKICAgICAgcDsKICAgIGlmIChwID0gdGhpcy5fcHJvamVjdChQWzBdLCBQWzFdLCB2eDAsIHZ5MCkpIFAudW5zaGlmdChwWzBdLCBwWzFdKTsKICAgIGlmIChwID0gdGhpcy5fcHJvamVjdChQW1AubGVuZ3RoIC0gMl0sIFBbUC5sZW5ndGggLSAxXSwgdnhuLCB2eW4pKSBQLnB1c2gocFswXSwgcFsxXSk7CiAgICBpZiAoUCA9IHRoaXMuX2NsaXBGaW5pdGUoaSwgUCkpIHsKICAgICAgZm9yIChsZXQgaiA9IDAsIG4gPSBQLmxlbmd0aCwgYzAsIGMxID0gdGhpcy5fZWRnZWNvZGUoUFtuIC0gMl0sIFBbbiAtIDFdKTsgaiA8IG47IGogKz0gMikgewogICAgICAgIGMwID0gYzEsIGMxID0gdGhpcy5fZWRnZWNvZGUoUFtqXSwgUFtqICsgMV0pOwogICAgICAgIGlmIChjMCAmJiBjMSkgaiA9IHRoaXMuX2VkZ2UoaSwgYzAsIGMxLCBQLCBqKSwgbiA9IFAubGVuZ3RoOwogICAgICB9CiAgICB9IGVsc2UgaWYgKHRoaXMuY29udGFpbnMoaSwgKHRoaXMueG1pbiArIHRoaXMueG1heCkgLyAyLCAodGhpcy55bWluICsgdGhpcy55bWF4KSAvIDIpKSB7CiAgICAgIFAgPSBbdGhpcy54bWluLCB0aGlzLnltaW4sIHRoaXMueG1heCwgdGhpcy55bWluLCB0aGlzLnhtYXgsIHRoaXMueW1heCwgdGhpcy54bWluLCB0aGlzLnltYXhdOwogICAgfQogICAgcmV0dXJuIFA7CiAgfQogIF9lZGdlKGksIGUwLCBlMSwgUCwgaikgewogICAgd2hpbGUgKGUwICE9PSBlMSkgewogICAgICBsZXQgeCwgeTsKICAgICAgc3dpdGNoIChlMCkgewogICAgICAgIGNhc2UgMGIwMTAxOgogICAgICAgICAgZTAgPSAwYjAxMDA7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICAvLyB0b3AtbGVmdAogICAgICAgIGNhc2UgMGIwMTAwOgogICAgICAgICAgZTAgPSAwYjAxMTAsIHggPSB0aGlzLnhtYXgsIHkgPSB0aGlzLnltaW47CiAgICAgICAgICBicmVhazsKICAgICAgICAvLyB0b3AKICAgICAgICBjYXNlIDBiMDExMDoKICAgICAgICAgIGUwID0gMGIwMDEwOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgLy8gdG9wLXJpZ2h0CiAgICAgICAgY2FzZSAwYjAwMTA6CiAgICAgICAgICBlMCA9IDBiMTAxMCwgeCA9IHRoaXMueG1heCwgeSA9IHRoaXMueW1heDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIHJpZ2h0CiAgICAgICAgY2FzZSAwYjEwMTA6CiAgICAgICAgICBlMCA9IDBiMTAwMDsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIC8vIGJvdHRvbS1yaWdodAogICAgICAgIGNhc2UgMGIxMDAwOgogICAgICAgICAgZTAgPSAwYjEwMDEsIHggPSB0aGlzLnhtaW4sIHkgPSB0aGlzLnltYXg7CiAgICAgICAgICBicmVhazsKICAgICAgICAvLyBib3R0b20KICAgICAgICBjYXNlIDBiMTAwMToKICAgICAgICAgIGUwID0gMGIwMDAxOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgLy8gYm90dG9tLWxlZnQKICAgICAgICBjYXNlIDBiMDAwMToKICAgICAgICAgIGUwID0gMGIwMTAxLCB4ID0gdGhpcy54bWluLCB5ID0gdGhpcy55bWluOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gbGVmdAogICAgICB9CiAgICAgIC8vIE5vdGU6IHRoaXMgaW1wbGljaXRseSBjaGVja3MgZm9yIG91dCBvZiBib3VuZHM6IGlmIFBbal0gb3IgUFtqKzFdIGFyZQogICAgICAvLyB1bmRlZmluZWQsIHRoZSBjb25kaXRpb25hbCBzdGF0ZW1lbnQgd2lsbCBiZSBleGVjdXRlZC4KICAgICAgaWYgKChQW2pdICE9PSB4IHx8IFBbaiArIDFdICE9PSB5KSAmJiB0aGlzLmNvbnRhaW5zKGksIHgsIHkpKSB7CiAgICAgICAgUC5zcGxpY2UoaiwgMCwgeCwgeSksIGogKz0gMjsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGo7CiAgfQogIF9wcm9qZWN0KHgwLCB5MCwgdngsIHZ5KSB7CiAgICBsZXQgdCA9IEluZmluaXR5LAogICAgICBjLAogICAgICB4LAogICAgICB5OwogICAgaWYgKHZ5IDwgMCkgewogICAgICAvLyB0b3AKICAgICAgaWYgKHkwIDw9IHRoaXMueW1pbikgcmV0dXJuIG51bGw7CiAgICAgIGlmICgoYyA9ICh0aGlzLnltaW4gLSB5MCkgLyB2eSkgPCB0KSB5ID0gdGhpcy55bWluLCB4ID0geDAgKyAodCA9IGMpICogdng7CiAgICB9IGVsc2UgaWYgKHZ5ID4gMCkgewogICAgICAvLyBib3R0b20KICAgICAgaWYgKHkwID49IHRoaXMueW1heCkgcmV0dXJuIG51bGw7CiAgICAgIGlmICgoYyA9ICh0aGlzLnltYXggLSB5MCkgLyB2eSkgPCB0KSB5ID0gdGhpcy55bWF4LCB4ID0geDAgKyAodCA9IGMpICogdng7CiAgICB9CiAgICBpZiAodnggPiAwKSB7CiAgICAgIC8vIHJpZ2h0CiAgICAgIGlmICh4MCA+PSB0aGlzLnhtYXgpIHJldHVybiBudWxsOwogICAgICBpZiAoKGMgPSAodGhpcy54bWF4IC0geDApIC8gdngpIDwgdCkgeCA9IHRoaXMueG1heCwgeSA9IHkwICsgKHQgPSBjKSAqIHZ5OwogICAgfSBlbHNlIGlmICh2eCA8IDApIHsKICAgICAgLy8gbGVmdAogICAgICBpZiAoeDAgPD0gdGhpcy54bWluKSByZXR1cm4gbnVsbDsKICAgICAgaWYgKChjID0gKHRoaXMueG1pbiAtIHgwKSAvIHZ4KSA8IHQpIHggPSB0aGlzLnhtaW4sIHkgPSB5MCArICh0ID0gYykgKiB2eTsKICAgIH0KICAgIHJldHVybiBbeCwgeV07CiAgfQogIF9lZGdlY29kZSh4LCB5KSB7CiAgICByZXR1cm4gKHggPT09IHRoaXMueG1pbiA/IDBiMDAwMSA6IHggPT09IHRoaXMueG1heCA/IDBiMDAxMCA6IDBiMDAwMCkgfCAoeSA9PT0gdGhpcy55bWluID8gMGIwMTAwIDogeSA9PT0gdGhpcy55bWF4ID8gMGIxMDAwIDogMGIwMDAwKTsKICB9CiAgX3JlZ2lvbmNvZGUoeCwgeSkgewogICAgcmV0dXJuICh4IDwgdGhpcy54bWluID8gMGIwMDAxIDogeCA+IHRoaXMueG1heCA/IDBiMDAxMCA6IDBiMDAwMCkgfCAoeSA8IHRoaXMueW1pbiA/IDBiMDEwMCA6IHkgPiB0aGlzLnltYXggPyAwYjEwMDAgOiAwYjAwMDApOwogIH0KICBfc2ltcGxpZnkoUCkgewogICAgaWYgKFAgJiYgUC5sZW5ndGggPiA0KSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUC5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGogPSAoaSArIDIpICUgUC5sZW5ndGgsCiAgICAgICAgICBrID0gKGkgKyA0KSAlIFAubGVuZ3RoOwogICAgICAgIGlmIChQW2ldID09PSBQW2pdICYmIFBbal0gPT09IFBba10gfHwgUFtpICsgMV0gPT09IFBbaiArIDFdICYmIFBbaiArIDFdID09PSBQW2sgKyAxXSkgewogICAgICAgICAgUC5zcGxpY2UoaiwgMiksIGkgLT0gMjsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKCFQLmxlbmd0aCkgUCA9IG51bGw7CiAgICB9CiAgICByZXR1cm4gUDsKICB9Cn0KCmNvbnN0IHRhdSA9IDIgKiBNYXRoLlBJLAogIHBvdyA9IE1hdGgucG93OwpmdW5jdGlvbiBwb2ludFgocCkgewogIHJldHVybiBwWzBdOwp9CmZ1bmN0aW9uIHBvaW50WShwKSB7CiAgcmV0dXJuIHBbMV07Cn0KCi8vIEEgdHJpYW5ndWxhdGlvbiBpcyBjb2xsaW5lYXIgaWYgYWxsIGl0cyB0cmlhbmdsZXMgaGF2ZSBhIG5vbi1udWxsIGFyZWEKZnVuY3Rpb24gY29sbGluZWFyKGQpIHsKICBjb25zdCB7CiAgICB0cmlhbmdsZXMsCiAgICBjb29yZHMKICB9ID0gZDsKICBmb3IgKGxldCBpID0gMDsgaSA8IHRyaWFuZ2xlcy5sZW5ndGg7IGkgKz0gMykgewogICAgY29uc3QgYSA9IDIgKiB0cmlhbmdsZXNbaV0sCiAgICAgIGIgPSAyICogdHJpYW5nbGVzW2kgKyAxXSwKICAgICAgYyA9IDIgKiB0cmlhbmdsZXNbaSArIDJdLAogICAgICBjcm9zcyA9IChjb29yZHNbY10gLSBjb29yZHNbYV0pICogKGNvb3Jkc1tiICsgMV0gLSBjb29yZHNbYSArIDFdKSAtIChjb29yZHNbYl0gLSBjb29yZHNbYV0pICogKGNvb3Jkc1tjICsgMV0gLSBjb29yZHNbYSArIDFdKTsKICAgIGlmIChjcm9zcyA+IDFlLTEwKSByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiB0cnVlOwp9CmZ1bmN0aW9uIGppdHRlcih4LCB5LCByKSB7CiAgcmV0dXJuIFt4ICsgTWF0aC5zaW4oeCArIHkpICogciwgeSArIE1hdGguY29zKHggLSB5KSAqIHJdOwp9CmNsYXNzIERlbGF1bmF5IHsKICBzdGF0aWMgZnJvbShwb2ludHMsIGZ4ID0gcG9pbnRYLCBmeSA9IHBvaW50WSwgdGhhdCkgewogICAgcmV0dXJuIG5ldyBEZWxhdW5heSgibGVuZ3RoIiBpbiBwb2ludHMgPyBmbGF0QXJyYXkocG9pbnRzLCBmeCwgZnksIHRoYXQpIDogRmxvYXQ2NEFycmF5LmZyb20oZmxhdEl0ZXJhYmxlKHBvaW50cywgZngsIGZ5LCB0aGF0KSkpOwogIH0KICBjb25zdHJ1Y3Rvcihwb2ludHMpIHsKICAgIHRoaXMuX2RlbGF1bmF0b3IgPSBuZXcgRGVsYXVuYXRvcihwb2ludHMpOwogICAgdGhpcy5pbmVkZ2VzID0gbmV3IEludDMyQXJyYXkocG9pbnRzLmxlbmd0aCAvIDIpOwogICAgdGhpcy5faHVsbEluZGV4ID0gbmV3IEludDMyQXJyYXkocG9pbnRzLmxlbmd0aCAvIDIpOwogICAgdGhpcy5wb2ludHMgPSB0aGlzLl9kZWxhdW5hdG9yLmNvb3JkczsKICAgIHRoaXMuX2luaXQoKTsKICB9CiAgdXBkYXRlKCkgewogICAgdGhpcy5fZGVsYXVuYXRvci51cGRhdGUoKTsKICAgIHRoaXMuX2luaXQoKTsKICAgIHJldHVybiB0aGlzOwogIH0KICBfaW5pdCgpIHsKICAgIGNvbnN0IGQgPSB0aGlzLl9kZWxhdW5hdG9yLAogICAgICBwb2ludHMgPSB0aGlzLnBvaW50czsKCiAgICAvLyBjaGVjayBmb3IgY29sbGluZWFyCiAgICBpZiAoZC5odWxsICYmIGQuaHVsbC5sZW5ndGggPiAyICYmIGNvbGxpbmVhcihkKSkgewogICAgICB0aGlzLmNvbGxpbmVhciA9IEludDMyQXJyYXkuZnJvbSh7CiAgICAgICAgbGVuZ3RoOiBwb2ludHMubGVuZ3RoIC8gMgogICAgICB9LCAoXywgaSkgPT4gaSkuc29ydCgoaSwgaikgPT4gcG9pbnRzWzIgKiBpXSAtIHBvaW50c1syICogal0gfHwgcG9pbnRzWzIgKiBpICsgMV0gLSBwb2ludHNbMiAqIGogKyAxXSk7IC8vIGZvciBleGFjdCBuZWlnaGJvcnMKICAgICAgY29uc3QgZSA9IHRoaXMuY29sbGluZWFyWzBdLAogICAgICAgIGYgPSB0aGlzLmNvbGxpbmVhclt0aGlzLmNvbGxpbmVhci5sZW5ndGggLSAxXSwKICAgICAgICBib3VuZHMgPSBbcG9pbnRzWzIgKiBlXSwgcG9pbnRzWzIgKiBlICsgMV0sIHBvaW50c1syICogZl0sIHBvaW50c1syICogZiArIDFdXSwKICAgICAgICByID0gMWUtOCAqIE1hdGguaHlwb3QoYm91bmRzWzNdIC0gYm91bmRzWzFdLCBib3VuZHNbMl0gLSBib3VuZHNbMF0pOwogICAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvaW50cy5sZW5ndGggLyAyOyBpIDwgbjsgKytpKSB7CiAgICAgICAgY29uc3QgcCA9IGppdHRlcihwb2ludHNbMiAqIGldLCBwb2ludHNbMiAqIGkgKyAxXSwgcik7CiAgICAgICAgcG9pbnRzWzIgKiBpXSA9IHBbMF07CiAgICAgICAgcG9pbnRzWzIgKiBpICsgMV0gPSBwWzFdOwogICAgICB9CiAgICAgIHRoaXMuX2RlbGF1bmF0b3IgPSBuZXcgRGVsYXVuYXRvcihwb2ludHMpOwogICAgfSBlbHNlIHsKICAgICAgZGVsZXRlIHRoaXMuY29sbGluZWFyOwogICAgfQogICAgY29uc3QgaGFsZmVkZ2VzID0gdGhpcy5oYWxmZWRnZXMgPSB0aGlzLl9kZWxhdW5hdG9yLmhhbGZlZGdlczsKICAgIGNvbnN0IGh1bGwgPSB0aGlzLmh1bGwgPSB0aGlzLl9kZWxhdW5hdG9yLmh1bGw7CiAgICBjb25zdCB0cmlhbmdsZXMgPSB0aGlzLnRyaWFuZ2xlcyA9IHRoaXMuX2RlbGF1bmF0b3IudHJpYW5nbGVzOwogICAgY29uc3QgaW5lZGdlcyA9IHRoaXMuaW5lZGdlcy5maWxsKC0xKTsKICAgIGNvbnN0IGh1bGxJbmRleCA9IHRoaXMuX2h1bGxJbmRleC5maWxsKC0xKTsKCiAgICAvLyBDb21wdXRlIGFuIGluZGV4IGZyb20gZWFjaCBwb2ludCB0byBhbiAoYXJiaXRyYXJ5KSBpbmNvbWluZyBoYWxmZWRnZQogICAgLy8gVXNlZCB0byBnaXZlIHRoZSBmaXJzdCBuZWlnaGJvciBvZiBlYWNoIHBvaW50OyBmb3IgdGhpcyByZWFzb24sCiAgICAvLyBvbiB0aGUgaHVsbCB3ZSBnaXZlIHByaW9yaXR5IHRvIGV4dGVyaW9yIGhhbGZlZGdlcwogICAgZm9yIChsZXQgZSA9IDAsIG4gPSBoYWxmZWRnZXMubGVuZ3RoOyBlIDwgbjsgKytlKSB7CiAgICAgIGNvbnN0IHAgPSB0cmlhbmdsZXNbZSAlIDMgPT09IDIgPyBlIC0gMiA6IGUgKyAxXTsKICAgICAgaWYgKGhhbGZlZGdlc1tlXSA9PT0gLTEgfHwgaW5lZGdlc1twXSA9PT0gLTEpIGluZWRnZXNbcF0gPSBlOwogICAgfQogICAgZm9yIChsZXQgaSA9IDAsIG4gPSBodWxsLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgICBodWxsSW5kZXhbaHVsbFtpXV0gPSBpOwogICAgfQoKICAgIC8vIGRlZ2VuZXJhdGUgY2FzZTogMSBvciAyIChkaXN0aW5jdCkgcG9pbnRzCiAgICBpZiAoaHVsbC5sZW5ndGggPD0gMiAmJiBodWxsLmxlbmd0aCA+IDApIHsKICAgICAgdGhpcy50cmlhbmdsZXMgPSBuZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKTsKICAgICAgdGhpcy5oYWxmZWRnZXMgPSBuZXcgSW50MzJBcnJheSgzKS5maWxsKC0xKTsKICAgICAgdGhpcy50cmlhbmdsZXNbMF0gPSBodWxsWzBdOwogICAgICBpbmVkZ2VzW2h1bGxbMF1dID0gMTsKICAgICAgaWYgKGh1bGwubGVuZ3RoID09PSAyKSB7CiAgICAgICAgaW5lZGdlc1todWxsWzFdXSA9IDA7CiAgICAgICAgdGhpcy50cmlhbmdsZXNbMV0gPSBodWxsWzFdOwogICAgICAgIHRoaXMudHJpYW5nbGVzWzJdID0gaHVsbFsxXTsKICAgICAgfQogICAgfQogIH0KICB2b3Jvbm9pKGJvdW5kcykgewogICAgcmV0dXJuIG5ldyBWb3Jvbm9pKHRoaXMsIGJvdW5kcyk7CiAgfQogICpuZWlnaGJvcnMoaSkgewogICAgY29uc3QgewogICAgICBpbmVkZ2VzLAogICAgICBodWxsLAogICAgICBfaHVsbEluZGV4LAogICAgICBoYWxmZWRnZXMsCiAgICAgIHRyaWFuZ2xlcywKICAgICAgY29sbGluZWFyCiAgICB9ID0gdGhpczsKCiAgICAvLyBkZWdlbmVyYXRlIGNhc2Ugd2l0aCBzZXZlcmFsIGNvbGxpbmVhciBwb2ludHMKICAgIGlmIChjb2xsaW5lYXIpIHsKICAgICAgY29uc3QgbCA9IGNvbGxpbmVhci5pbmRleE9mKGkpOwogICAgICBpZiAobCA+IDApIHlpZWxkIGNvbGxpbmVhcltsIC0gMV07CiAgICAgIGlmIChsIDwgY29sbGluZWFyLmxlbmd0aCAtIDEpIHlpZWxkIGNvbGxpbmVhcltsICsgMV07CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGUwID0gaW5lZGdlc1tpXTsKICAgIGlmIChlMCA9PT0gLTEpIHJldHVybjsgLy8gY29pbmNpZGVudCBwb2ludAogICAgbGV0IGUgPSBlMCwKICAgICAgcDAgPSAtMTsKICAgIGRvIHsKICAgICAgeWllbGQgcDAgPSB0cmlhbmdsZXNbZV07CiAgICAgIGUgPSBlICUgMyA9PT0gMiA/IGUgLSAyIDogZSArIDE7CiAgICAgIGlmICh0cmlhbmdsZXNbZV0gIT09IGkpIHJldHVybjsgLy8gYmFkIHRyaWFuZ3VsYXRpb24KICAgICAgZSA9IGhhbGZlZGdlc1tlXTsKICAgICAgaWYgKGUgPT09IC0xKSB7CiAgICAgICAgY29uc3QgcCA9IGh1bGxbKF9odWxsSW5kZXhbaV0gKyAxKSAlIGh1bGwubGVuZ3RoXTsKICAgICAgICBpZiAocCAhPT0gcDApIHlpZWxkIHA7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICB9IHdoaWxlIChlICE9PSBlMCk7CiAgfQogIGZpbmQoeCwgeSwgaSA9IDApIHsKICAgIGlmICgoeCA9ICt4LCB4ICE9PSB4KSB8fCAoeSA9ICt5LCB5ICE9PSB5KSkgcmV0dXJuIC0xOwogICAgY29uc3QgaTAgPSBpOwogICAgbGV0IGM7CiAgICB3aGlsZSAoKGMgPSB0aGlzLl9zdGVwKGksIHgsIHkpKSA+PSAwICYmIGMgIT09IGkgJiYgYyAhPT0gaTApIGkgPSBjOwogICAgcmV0dXJuIGM7CiAgfQogIF9zdGVwKGksIHgsIHkpIHsKICAgIGNvbnN0IHsKICAgICAgaW5lZGdlcywKICAgICAgaHVsbCwKICAgICAgX2h1bGxJbmRleCwKICAgICAgaGFsZmVkZ2VzLAogICAgICB0cmlhbmdsZXMsCiAgICAgIHBvaW50cwogICAgfSA9IHRoaXM7CiAgICBpZiAoaW5lZGdlc1tpXSA9PT0gLTEgfHwgIXBvaW50cy5sZW5ndGgpIHJldHVybiAoaSArIDEpICUgKHBvaW50cy5sZW5ndGggPj4gMSk7CiAgICBsZXQgYyA9IGk7CiAgICBsZXQgZGMgPSBwb3coeCAtIHBvaW50c1tpICogMl0sIDIpICsgcG93KHkgLSBwb2ludHNbaSAqIDIgKyAxXSwgMik7CiAgICBjb25zdCBlMCA9IGluZWRnZXNbaV07CiAgICBsZXQgZSA9IGUwOwogICAgZG8gewogICAgICBsZXQgdCA9IHRyaWFuZ2xlc1tlXTsKICAgICAgY29uc3QgZHQgPSBwb3coeCAtIHBvaW50c1t0ICogMl0sIDIpICsgcG93KHkgLSBwb2ludHNbdCAqIDIgKyAxXSwgMik7CiAgICAgIGlmIChkdCA8IGRjKSBkYyA9IGR0LCBjID0gdDsKICAgICAgZSA9IGUgJSAzID09PSAyID8gZSAtIDIgOiBlICsgMTsKICAgICAgaWYgKHRyaWFuZ2xlc1tlXSAhPT0gaSkgYnJlYWs7IC8vIGJhZCB0cmlhbmd1bGF0aW9uCiAgICAgIGUgPSBoYWxmZWRnZXNbZV07CiAgICAgIGlmIChlID09PSAtMSkgewogICAgICAgIGUgPSBodWxsWyhfaHVsbEluZGV4W2ldICsgMSkgJSBodWxsLmxlbmd0aF07CiAgICAgICAgaWYgKGUgIT09IHQpIHsKICAgICAgICAgIGlmIChwb3coeCAtIHBvaW50c1tlICogMl0sIDIpICsgcG93KHkgLSBwb2ludHNbZSAqIDIgKyAxXSwgMikgPCBkYykgcmV0dXJuIGU7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9IHdoaWxlIChlICE9PSBlMCk7CiAgICByZXR1cm4gYzsKICB9CiAgcmVuZGVyKGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgewogICAgICBwb2ludHMsCiAgICAgIGhhbGZlZGdlcywKICAgICAgdHJpYW5nbGVzCiAgICB9ID0gdGhpczsKICAgIGZvciAobGV0IGkgPSAwLCBuID0gaGFsZmVkZ2VzLmxlbmd0aDsgaSA8IG47ICsraSkgewogICAgICBjb25zdCBqID0gaGFsZmVkZ2VzW2ldOwogICAgICBpZiAoaiA8IGkpIGNvbnRpbnVlOwogICAgICBjb25zdCB0aSA9IHRyaWFuZ2xlc1tpXSAqIDI7CiAgICAgIGNvbnN0IHRqID0gdHJpYW5nbGVzW2pdICogMjsKICAgICAgY29udGV4dC5tb3ZlVG8ocG9pbnRzW3RpXSwgcG9pbnRzW3RpICsgMV0pOwogICAgICBjb250ZXh0LmxpbmVUbyhwb2ludHNbdGpdLCBwb2ludHNbdGogKyAxXSk7CiAgICB9CiAgICB0aGlzLnJlbmRlckh1bGwoY29udGV4dCk7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICByZW5kZXJQb2ludHMoY29udGV4dCwgcikgewogICAgaWYgKHIgPT09IHVuZGVmaW5lZCAmJiAoIWNvbnRleHQgfHwgdHlwZW9mIGNvbnRleHQubW92ZVRvICE9PSAiZnVuY3Rpb24iKSkgciA9IGNvbnRleHQsIGNvbnRleHQgPSBudWxsOwogICAgciA9IHIgPT0gdW5kZWZpbmVkID8gMiA6ICtyOwogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIHBvaW50cwogICAgfSA9IHRoaXM7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBuOyBpICs9IDIpIHsKICAgICAgY29uc3QgeCA9IHBvaW50c1tpXSwKICAgICAgICB5ID0gcG9pbnRzW2kgKyAxXTsKICAgICAgY29udGV4dC5tb3ZlVG8oeCArIHIsIHkpOwogICAgICBjb250ZXh0LmFyYyh4LCB5LCByLCAwLCB0YXUpOwogICAgfQogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgcmVuZGVySHVsbChjb250ZXh0KSB7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IHsKICAgICAgaHVsbCwKICAgICAgcG9pbnRzCiAgICB9ID0gdGhpczsKICAgIGNvbnN0IGggPSBodWxsWzBdICogMiwKICAgICAgbiA9IGh1bGwubGVuZ3RoOwogICAgY29udGV4dC5tb3ZlVG8ocG9pbnRzW2hdLCBwb2ludHNbaCArIDFdKTsKICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbjsgKytpKSB7CiAgICAgIGNvbnN0IGggPSAyICogaHVsbFtpXTsKICAgICAgY29udGV4dC5saW5lVG8ocG9pbnRzW2hdLCBwb2ludHNbaCArIDFdKTsKICAgIH0KICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICBodWxsUG9seWdvbigpIHsKICAgIGNvbnN0IHBvbHlnb24gPSBuZXcgUG9seWdvbigpOwogICAgdGhpcy5yZW5kZXJIdWxsKHBvbHlnb24pOwogICAgcmV0dXJuIHBvbHlnb24udmFsdWUoKTsKICB9CiAgcmVuZGVyVHJpYW5nbGUoaSwgY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIHBvaW50cywKICAgICAgdHJpYW5nbGVzCiAgICB9ID0gdGhpczsKICAgIGNvbnN0IHQwID0gdHJpYW5nbGVzW2kgKj0gM10gKiAyOwogICAgY29uc3QgdDEgPSB0cmlhbmdsZXNbaSArIDFdICogMjsKICAgIGNvbnN0IHQyID0gdHJpYW5nbGVzW2kgKyAyXSAqIDI7CiAgICBjb250ZXh0Lm1vdmVUbyhwb2ludHNbdDBdLCBwb2ludHNbdDAgKyAxXSk7CiAgICBjb250ZXh0LmxpbmVUbyhwb2ludHNbdDFdLCBwb2ludHNbdDEgKyAxXSk7CiAgICBjb250ZXh0LmxpbmVUbyhwb2ludHNbdDJdLCBwb2ludHNbdDIgKyAxXSk7CiAgICBjb250ZXh0LmNsb3NlUGF0aCgpOwogICAgcmV0dXJuIGJ1ZmZlciAmJiBidWZmZXIudmFsdWUoKTsKICB9CiAgKnRyaWFuZ2xlUG9seWdvbnMoKSB7CiAgICBjb25zdCB7CiAgICAgIHRyaWFuZ2xlcwogICAgfSA9IHRoaXM7CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHRyaWFuZ2xlcy5sZW5ndGggLyAzOyBpIDwgbjsgKytpKSB7CiAgICAgIHlpZWxkIHRoaXMudHJpYW5nbGVQb2x5Z29uKGkpOwogICAgfQogIH0KICB0cmlhbmdsZVBvbHlnb24oaSkgewogICAgY29uc3QgcG9seWdvbiA9IG5ldyBQb2x5Z29uKCk7CiAgICB0aGlzLnJlbmRlclRyaWFuZ2xlKGksIHBvbHlnb24pOwogICAgcmV0dXJuIHBvbHlnb24udmFsdWUoKTsKICB9Cn0KZnVuY3Rpb24gZmxhdEFycmF5KHBvaW50cywgZngsIGZ5LCB0aGF0KSB7CiAgY29uc3QgbiA9IHBvaW50cy5sZW5ndGg7CiAgY29uc3QgYXJyYXkgPSBuZXcgRmxvYXQ2NEFycmF5KG4gKiAyKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47ICsraSkgewogICAgY29uc3QgcCA9IHBvaW50c1tpXTsKICAgIGFycmF5W2kgKiAyXSA9IGZ4LmNhbGwodGhhdCwgcCwgaSwgcG9pbnRzKTsKICAgIGFycmF5W2kgKiAyICsgMV0gPSBmeS5jYWxsKHRoYXQsIHAsIGksIHBvaW50cyk7CiAgfQogIHJldHVybiBhcnJheTsKfQpmdW5jdGlvbiogZmxhdEl0ZXJhYmxlKHBvaW50cywgZngsIGZ5LCB0aGF0KSB7CiAgbGV0IGkgPSAwOwogIGZvciAoY29uc3QgcCBvZiBwb2ludHMpIHsKICAgIHlpZWxkIGZ4LmNhbGwodGhhdCwgcCwgaSwgcG9pbnRzKTsKICAgIHlpZWxkIGZ5LmNhbGwodGhhdCwgcCwgaSwgcG9pbnRzKTsKICAgICsraTsKICB9Cn0KCi8qKg0KICog6Ieq54S26YSw6bue5YWn5o+S5rOVKE5hdHVyYWwgTmVpZ2hib3IgSW50ZXJwb2xhdGlvbinlhafmj5Lpu57mlbjlgLwNCiAqDQogKiBBIEZhc3QgYW5kIEFjY3VyYXRlIEFsZ29yaXRobSBmb3IgTmF0dXJhbCBOZWlnaGJvciBJbnRlcnBvbGF0aW9uDQogKiBodHRwczovL2d3bHVjYXN0cmlnLmdpdGh1Yi5pby9UaW5mb3VyRG9jcy9OYXR1cmFsTmVpZ2hib3JUaW5mb3VyQWxnb3JpdGhtL2luZGV4Lmh0bWwNCiAqDQogKiBBbiBJbnRyb2R1Y3Rpb24gdG8gTmF0dXJhbCBOZWlnaGJvciBJbnRlcnBvbGF0aW9uDQogKiBodHRwczovL2d3bHVjYXN0cmlnLmdpdGh1Yi5pby9UaW5mb3VyRG9jcy9OYXR1cmFsTmVpZ2hib3JJbnRyby9pbmRleC5odG1sDQogKg0KICogW3dpa2ldTmF0dXJhbCBuZWlnaGJvciBpbnRlcnBvbGF0aW9uDQogKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9OYXR1cmFsX25laWdoYm9yX2ludGVycG9sYXRpb24NCiAqDQogKiBOYXR1cmFsIG5laWdoYm9yIGludGVycG9sYXRpb24NCiAqIGh0dHBzOi8vb2JzZXJ2YWJsZWhxLmNvbS9Aa2FybGVyc3MvbmF0dXJhbC1uZWlnaGJvci1pbnRlcnBvbGF0aW9uDQogKg0KICogZDMtZGVsYXVuYXkNCiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1kZWxhdW5heQ0KICoNCiAqIG9ubGluZSB0ZXN0DQogKiBodHRwczovL2NhcnRvZ3JhcGh5LXBsYXlncm91bmQuZ2l0bGFiLmlvL3BsYXlncm91bmRzL3RyaWFuZ3VsYXRpb24tZGVsYXVuYXktdm9yb25vaS1kaWFncmFtLw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ludGVycDJOYXR1cmFsTmVpZ2hib3IudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwc1NyYyDovLjlhaXkuozntq3luqfmqJnliqDop4DmuKzmlbjmk5rpu57pmaPliJfvvIzngrpbe3g6eDEseTp5MSx6OnoxfSx7eDp4Mix5OnkyLHo6ejJ9LC4uLl3pu57nianku7bkuYvpmaPliJcNCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBwc1RhciDovLjlhaXkuozntq3luqfmqJnpu57pmaPliJfmiJbpu57nianku7bvvIzngrpbe3g6eDEseTp5MX0se3g6eDIseTp5Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIl++8jOaIlnt4OngxLHk6eTF96bue54mp5Lu2DQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7bkuYt45qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu25LmLeeashOS9jeWtl+S4su+8jOeCuuW6p+aome+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5Wj0neiddIOi8uOWFpem7nueJqeS7tuS5i3rmrITkvY3lrZfkuLLvvIzngrrop4DmuKzlgLzvvIzpoJDoqK0neicNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LnNjYWxlPTFdIOi8uOWFpeato+imj+WMluevhOWcjeaVuOWAvO+8jOWboOiZleeQhuWkmumCiuW9ouaZguacieaVuOWAvOWuueioseiqpOW3ru+8jOaVhemgiOmAmumBjue4ruaUvuWAvOWfn+S+hua4m+WwkeWVj+mhjO+8jOmgkOiorTHmmK/mraPopo/ljJYw6IezMeS5i+mWk++8jOS9v+eUqHNjYWxlWFnliYfmmK/mraPopo/ljJbngrow6Iezc2NhbGVYWeS5i+mWk++8jOmgkOiorTENCiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IOWbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpeeZvOeUn+mMr+iqpOWJh+WbnuWCs+mMr+iqpOioiuaBr+eJqeS7tg0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCBwDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTI0MywNCiAqICAgICB5OiAxMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAxMjQzLCB5OiAxMjA3LCB6OiBudWxsIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IG51bGwsIHk6IDIwMSwgejogMTIyIH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiBsZXQgZnVuSW50ZXJwRnJhZ21lbnQgPSAobXNnKSA9PiB7DQogKiAgICAgLy8gY29uc29sZS5sb2coJ2Z1bkludGVycEZyYWdtZW50JywgbXNnKQ0KICogICAgIHJldHVybiBtc2cudiAvL+mgkOioreWbnuWCs21zZy52LCDkuInop5LlvaLkuInop5Lpu57lkITpu55254K6ckEqeiwg5pWF5LiJ6bue5LmLckHlkIjngroxLCDmjIflrprlhafmj5LlgLx654K65LiJ6KeS6bueduS5i+e4veWSjCh2MSx2Mix2MykNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwLCB7IGZ1bkludGVycEZyYWdtZW50IH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogbnVsbCwgeTogMjAxLCB6OiAxMjIgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTI0MywNCiAqICAgICB5OiAxMjA3LA0KICogfQ0KICogbGV0IGZ1bkludGVycEZyYWdtZW50Tm9Vc2UgPSAobXNnKSA9PiB7DQogKiAgICAgLy8gY29uc29sZS5sb2coJ2Z1bkludGVycEZyYWdtZW50Tm9Vc2UnLCBtc2cpDQogKiAgICAgcmV0dXJuIG1zZy52IC8v6aCQ6Kit5Zue5YKzbXNnLnYsIOatpOiZleWboOWFp+aPkum7nuaWvOWOn+Wni+m7nuaJgOW9ouaIkOacgOWwj+WHuOWkmumCiuW9ouS5i+Wkliwg5pWF54Sh5rOV5YWn5o+SLCDkuqbkuI3mnIPlkbzlj6tmdW5JbnRlcnBGcmFnbWVudA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsgZnVuSW50ZXJwRnJhZ21lbnQ6IGZ1bkludGVycEZyYWdtZW50Tm9Vc2UgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDEyNDMsIHk6IDEyMDcsIHo6IG51bGwgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogbnVsbCwgeTogMjAxLCB6OiAxMjIgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIGxldCBmdW5JbnRlcnBGcmFnbWVudHMgPSAobXNnKSA9PiB7DQogKiAgICAgLy8gY29uc29sZS5sb2coJ2Z1bkludGVycEZyYWdtZW50cycsIG1zZykNCiAqICAgICAvLyBsZXQgdiA9IHBzWzBdLnYgKyBwc1sxXS52ICsgcHNbMl0udg0KICogICAgIHJldHVybiBtc2cudiAvL+mgkOioreWbnuWCs21zZy52LCDkuInop5LlvaLkuInop5Lpu57ngrptc2cucHMsIOWQhOm7nnbngrpyQSp6LCDmlYXkuInpu57kuYtyQeWQiOeCujEsIOaMh+WumuWFp+aPkuWAvHrngrrkuInop5Lpu5525LmL57i95ZKMKHYxLHYyLHYzKQ0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsgZnVuSW50ZXJwRnJhZ21lbnRzIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI4MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI4MywgeTogMjA3LCB6OiAxMTQuNDMwNDA0MjE5NTE5MDggfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDExNjAsDQogKiAgICAgeTogMzgwLA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAxMTYwLCB5OiAzODAsIHo6IG51bGwgfQ0KICoNCiAqIHBzID0gW3sgYTogMjQzLCBiOiAyMDYsIGM6IDk1IH0sIHsgYTogMjMzLCBiOiAyMjUsIGM6IDE0NiB9LCB7IGE6IDIxLCBiOiAzMjUsIGM6IDIyIH0sIHsgYTogOTUzLCBiOiAyOCwgYzogMjIzIH0sIHsgYTogMTA5MiwgYjogMjkwLCBjOiAzOSB9LCB7IGE6IDc0NCwgYjogMjAwLCBjOiAxOTEgfSwgeyBhOiAxNzQsIGI6IDMsIGM6IDIyIH0sIHsgYTogNTM3LCBiOiAzNjgsIGM6IDI0OSB9LCB7IGE6IDExNTEsIGI6IDM3MSwgYzogODYgfSwgeyBhOiA4MTQsIGI6IDI1MiwgYzogMTI1IH1dDQogKiBwID0gew0KICogICAgIGE6IDI0MywNCiAqICAgICBiOiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCwgeyBrZXlYOiAnYScsIGtleVk6ICdiJywga2V5WjogJ2MnIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyBhOiAyNDMsIGI6IDIwNywgYzogOTcuMjk0NDc2ODI0ODY4MTMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gWw0KICogICAgIHsNCiAqICAgICAgICAgeDogMjQzLA0KICogICAgICAgICB5OiAyMDcsDQogKiAgICAgfSwNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI4MywNCiAqICAgICAgICAgeTogMjA3LA0KICogICAgIH0sDQogKiBdDQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0sDQogKiAvLyAgIHsgeDogMjgzLCB5OiAyMDcsIHo6IDExNC40MzA0MDQyMTk1MTkwOCB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyB4OiAwLjAwMDI0MywgeTogMC4wMDAyMDYsIHo6IDk1IH0sIHsgeDogMC4wMDAyMzMsIHk6IDAuMDAwMjI1LCB6OiAxNDYgfSwgeyB4OiAwLjAwMDAyMSwgeTogMC4wMDAzMjUsIHo6IDIyIH0sIHsgeDogMC4wMDA5NTMsIHk6IDAuMDAwMDI4LCB6OiAyMjMgfSwgeyB4OiAwLjAwMTA5MiwgeTogMC4wMDAyOSwgejogMzkgfSwgeyB4OiAwLjAwMDc0NCwgeTogMC4wMDAyMDAsIHo6IDE5MSB9LCB7IHg6IDAuMDAwMTc0LCB5OiAwLjAwMDAwMywgejogMjIgfSwgeyB4OiAwLjAwMDUzNywgeTogMC4wMDAzNjgsIHo6IDI0OSB9LCB7IHg6IDAuMDAxMTUxLCB5OiAwLjAwMDM3MSwgejogODYgfSwgeyB4OiAwLjAwMDgxNCwgeTogMC4wMDAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAwLjAwMDI0MywNCiAqICAgICB5OiAwLjAwMDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMC4wMDAyNDMsIHk6IDAuMDAwMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4Njc4IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsgc2NhbGU6IDEwMDAgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4Njg1NSB9DQogKg0KICovCmZ1bmN0aW9uIGludGVycDJOYXR1cmFsTmVpZ2hib3IocHNTcmMsIHBzVGFyLCBvcHQgPSB7fSkgewogIC8vY2hlY2sgcHNTcmMKICBpZiAoIWlzZWFycihwc1NyYykpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzU3JjIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXknCiAgICB9OwogIH0KCiAgLy9jaGVjayBwc1RhcgogIGlmICghaXNlb2JqKHBzVGFyKSAmJiAhaXNlYXJyKHBzVGFyKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNUYXIgaXMgbm90IGFuIGVmZmVjdGl2ZSBvYmplY3Qgb3IgYXJyYXknCiAgICB9OwogIH0KCiAgLy9pc09uZQogIGxldCBpc09uZSA9IGlzZW9iaihwc1Rhcik7CiAgaWYgKGlzT25lKSB7CiAgICBwc1RhciA9IFtwc1Rhcl07CiAgfQoKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleVoKICBsZXQga2V5WiA9IGdldChvcHQsICdrZXlaJyk7CiAgaWYgKCFpc2VzdHIoa2V5WikpIHsKICAgIGtleVogPSAneic7CiAgfQoKICAvL3NjYWxlCiAgbGV0IHNjYWxlID0gZ2V0KG9wdCwgJ3NjYWxlJyk7CiAgaWYgKCFpc251bShzY2FsZSkpIHsKICAgIHNjYWxlID0gMTsKICB9CiAgc2NhbGUgPSBjZGJsKHNjYWxlKTsKCiAgLy9mdW5JbnRlcnBGcmFnbWVudAogIGxldCBmdW5JbnRlcnBGcmFnbWVudCA9IGdldChvcHQsICdmdW5JbnRlcnBGcmFnbWVudCcpOwogIGxldCB1c2VGdW5JbnRlcnBGcmFnbWVudCA9IGlzZnVuKGZ1bkludGVycEZyYWdtZW50KTsKCiAgLy9mdW5JbnRlcnBGcmFnbWVudHMKICBsZXQgZnVuSW50ZXJwRnJhZ21lbnRzID0gZ2V0KG9wdCwgJ2Z1bkludGVycEZyYWdtZW50cycpOwogIGxldCB1c2VGdW5JbnRlcnBGcmFnbWVudHMgPSBpc2Z1bihmdW5JbnRlcnBGcmFnbWVudHMpOwoKICAvL2tleUluZAogIGxldCBrZXlJbmQgPSAnaW5kJzsKCiAgLy9wdHNYWVp0b0FycgogIHBzU3JjID0gcHRzWFladG9BcnIocHNTcmMsIHsKICAgIGtleVgsCiAgICBrZXlZLAogICAga2V5WiwKICAgIGtleUluZAogIH0pOwoKICAvL2NoZWNrIHBzU3JjCiAgaWYgKHNpemUocHNTcmMpID09PSAwKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1NyYyBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KICAvLyBjb25zb2xlLmxvZygncHRzWFladG9BcnIgcHNTcmMnLCBwc1NyYykKCiAgLy9wdHNYWXRvQXJyCiAgcHNUYXIgPSBwdHNYWXRvQXJyKHBzVGFyLCB7CiAgICBrZXlYLAogICAga2V5WSwKICAgIGtleUluZAogIH0pOwoKICAvL2NoZWNrIHBzVGFyCiAgaWYgKHNpemUocHNUYXIpID09PSAwKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1RhciBoYXMgbm8gZWZmZWN0aXZlIGRhdGEnCiAgICB9OwogIH0KICAvLyBjb25zb2xlLmxvZygncHRzWFl0b0FyciBwc1RhcicsIHBzVGFyKQoKICAvL2ludGVycDJOb3JtYWxpemUKICBsZXQgaXRubSA9IGludGVycDJOb3JtYWxpemUocHNTcmMsIHsKICAgIGtleUluZCwKICAgIHNjYWxlCiAgfSk7CiAgLy8gY29uc29sZS5sb2coJ2l0bm0uc3QnLCBpdG5tLnN0KQogIC8vIGNvbnNvbGUubG9nKCdpdG5tLnBzTWluTWF4JywgaXRubS5wc01pbk1heCkKICBwc1NyYyA9IGl0bm0ucHM7IC8v6KSH5a+r5q2j6KaP5YyW5pW45pOaCiAgbGV0IG52ID0gaXRubS5udjsKICBsZXQgaW52ID0gaXRubS5pbnY7CiAgLy8gY29uc29sZS5sb2coJ2ludGVycDJOb3JtYWxpemUgcHNTcmMnLCBwc1NyYykKCiAgLy9wc1NyY0l0cgogIGxldCBwc1NyY0l0ciA9IFsuLi5wc1NyY107CgogIC8vcHNTcmNPcmkKICBsZXQgcHNTcmNPcmkgPSBbLi4ucHNTcmNdOwoKICAvL2twS25vd24KICBsZXQga3BLbm93biA9IHt9OwogIGZvckVhY2gocHNTcmMsIHYgPT4gewogICAgbGV0IGsgPSBgJHt2Lnh9LSR7di55fWA7IC8veCx55bey57aT6KKr5q2j6KaP5YyWCiAgICBrcEtub3duW2tdID0gdi56OyAvL3gseSx65bey57aT6KKr5q2j6KaP5YyWCiAgfSk7CgogIC8vaW50RG55CiAgbGV0IGludERueSA9IERlbGF1bmF5LmZyb20ocHNTcmNPcmksIGQgPT4gZC54LCBkID0+IGQueSk7IC8veCx55bey57aT6KKr5q2j6KaP5YyWCgogIC8vIC8vaHBnLCDljp/lp4vmlbjmk5rlvaLmiJDmnIDlpJbmoYbpgornlYwKICAvLyBsZXQgaHBnID0gaW50RG55Lmh1bGxQb2x5Z29uKCkKICAvLyAvLyBjb25zb2xlLmxvZygnaW50RG55Lmh1bGxQb2x5Z29uJywgaHBnKQoKICAvL3Zib3gKICBsZXQgdmJveCA9IFswLCAwLCBzY2FsZSwgc2NhbGVdOwoKICAvL2luaVZvcgogIGxldCBpbmlWb3IgPSBpbnREbnkudm9yb25vaSh2Ym94KTsKICAvLyBjb25zb2xlLmxvZygnaW5pVm9yJywgaW5pVm9yKQoKICAvL2FkZFBvaW50Q29yZQogIGxldCBhZGRQb2ludENvcmUgPSAoZGF0YSwgeCwgeSwgaW5kVGFyKSA9PiB7CiAgICAvL3BzU3JjVGVtcAogICAgbGV0IHBzU3JjVGVtcCA9IFsuLi5wc1NyY107CgogICAgLy9uZXdJdGVtCiAgICBsZXQgbmV3SXRlbSA9IHsKICAgICAgeCwKICAgICAgeSwKICAgICAgejogMAogICAgfTsgLy94LHkseuW3sue2k+iiq+ato+imj+WMlgoKICAgIC8vcHVzaAogICAgcHNTcmNUZW1wLnB1c2gobmV3SXRlbSk7CiAgICBkYXRhLnB1c2gobmV3SXRlbSk7CgogICAgLy9wb3N0Vm9yCiAgICBsZXQgcG9zdFZvciA9IERlbGF1bmF5LmZyb20ocHNTcmNUZW1wLCBkID0+IGQueCwgZCA9PiBkLnkpLnZvcm9ub2kodmJveCk7IC8veCx55bey57aT6KKr5q2j6KaP5YyWCiAgICAvLyBjb25zb2xlLmxvZygncG9zdFZvcicsIHBvc3RWb3IpCgogICAgLy9uZXdJZHgKICAgIGxldCBuZXdJZHggPSBwc1NyY1RlbXAubGVuZ3RoIC0gMTsKICAgIC8vIGNvbnNvbGUubG9nKCduZXdJZHgnLCBuZXdJZHgpCgogICAgLy9wZ3NRdWVyeQogICAgbGV0IHBnc1F1ZXJ5ID0gcG9zdFZvci5jZWxsUG9seWdvbihuZXdJZHgpOwogICAgLy8gY29uc29sZS5sb2coJ3Bnc1F1ZXJ5JywgcGdzUXVlcnkpCgogICAgLy9hcmVhUXVlcnkKICAgIGxldCBhcmVhUXVlcnkgPSBnZXRBcmVhUG9seWdvbihwZ3NRdWVyeSk7CiAgICAvLyBjb25zb2xlLmxvZygnYXJlYVF1ZXJ5JywgYXJlYVF1ZXJ5KQoKICAgIC8vbmV3UG9pbnRWYWwKICAgIGxldCBuZXdQb2ludFZhbCA9IG51bGw7CiAgICB7CiAgICAgIC8vbmVpZ2hib3JJbmRpY2VzCiAgICAgIGxldCBuZWlnaGJvckluZGljZXMgPSBbXTsKICAgICAgLy8gZm9yIChsZXQgaSBvZiBwb3N0Vm9yLmRlbGF1bmF5Lm5laWdoYm9ycyhuZXdJZHgpKSB7IC8v5Zug54K6cG9zdFZvci5kZWxhdW5heS5uZWlnaGJvcnPmmK9nZW5lcmF0b3IsIOiAg+aFruimgeaUr+aPtGllMTHlvpfkvb/nlKh3aGlsZeiIh25leHToroDlj5YKICAgICAgLy8gICAgIG5laWdoYm9ySW5kaWNlcy5wdXNoKGkpCiAgICAgIC8vIH0KICAgICAgbGV0IHNxID0gcG9zdFZvci5kZWxhdW5heS5uZWlnaGJvcnMobmV3SWR4KTsKICAgICAgLy8gY29uc29sZS5sb2coYHNxYCwgc3EpCiAgICAgIGxldCBuZXh0ID0gc3EubmV4dCgpOwogICAgICB3aGlsZSAoIW5leHQuZG9uZSkgewogICAgICAgIGxldCB2ID0gbmV4dC52YWx1ZTsKICAgICAgICBuZWlnaGJvckluZGljZXMucHVzaCh2KTsKICAgICAgICBuZXh0ID0gc3EubmV4dCgpOwogICAgICB9CiAgICAgIC8vIGNvbnNvbGUubG9nKCduZWlnaGJvckluZGljZXMnLCBuZWlnaGJvckluZGljZXMpCgogICAgICAvL3N1YlZhbHVlcwogICAgICBsZXQgc3ViVmFsdWVzID0gbWFwKG5laWdoYm9ySW5kaWNlcywgaWR4ID0+IHsKICAgICAgICAvLyBjb25zb2xlLmxvZygnaWR4JywgaWR4KQoKICAgICAgICAvL3BnczEsIHBnczIKICAgICAgICBsZXQgcGdzMSA9IFtwZ3NRdWVyeV07CiAgICAgICAgbGV0IHBnczIgPSBbaW5pVm9yLmNlbGxQb2x5Z29uKGlkeCldOwogICAgICAgIC8vIGNvbnNvbGUubG9nKCdwZ3MxJywgcGdzMSwgJ3BnczInLCBwZ3MyKQoKICAgICAgICAvL2ludGVyc2VjdAogICAgICAgIGxldCBwZ3NJbnRzID0gW107CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHBnc0ludHMgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIpOwogICAgICAgICAgLy8gY29uc29sZS5sb2coJ3Bnc0ludHMnLCBwZ3NJbnRzKQogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgLy9jb25zb2xlLmxvZygncGdzMScsIHBnczEpCiAgICAgICAgICAvL2NvbnNvbGUubG9nKCdwZ3MyJywgcGdzMikKICAgICAgICAgIC8vY29uc29sZS5sb2coZXJyKQogICAgICAgIH0KCiAgICAgICAgLy9hcmVhSW50cwogICAgICAgIGxldCBhcmVhSW50cyA9IDA7CiAgICAgICAgaWYgKHNpemUocGdzSW50cykgPT09IDEpIHsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGFyZWFJbnRzID0gZ2V0QXJlYVBvbHlnb24ocGdzSW50c1swXSk7CiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ2dldEFyZWFQb2x5Z29uJyxkMy5nZXRBcmVhUG9seWdvbihpcy5yZWdpb25zWzBdKSxnZXRBcmVhUG9seWdvbihpcy5yZWdpb25zWzBdKSkKICAgICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICBjb25zb2xlLmxvZygncGdzSW50cycsIHBnc0ludHMpOwogICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gewogICAgICAgICAgaWE6IGFyZWFJbnRzLAogICAgICAgICAgaWR4CiAgICAgICAgfTsKICAgICAgfSk7CiAgICAgIC8vIGNvbnNvbGUubG9nKCdzdWJWYWx1ZXMnLCBzdWJWYWx1ZXMpCgogICAgICAvL2NoZWNrCiAgICAgIHsKICAgICAgICAvL24KICAgICAgICBsZXQgbiA9IHNpemUoc3ViVmFsdWVzKTsKCiAgICAgICAgLy9pYXMKICAgICAgICBsZXQgaWFzID0gbWFwKHN1YlZhbHVlcywgJ2lhJyk7CgogICAgICAgIC8vcgogICAgICAgIGxldCByID0gc3VtJDEoaWFzKTsKCiAgICAgICAgLy9jaGVjawogICAgICAgIGlmIChyICE9PSBhcmVhUXVlcnkpIHsKICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBpYee4veWSjOacieaZguacg+S4jeetieaWvGFyZWFRdWVyeWApCiAgICAgICAgICAvL2lh57i95ZKM5pyJ5pmC5pyD5LiN562J5pa8YXJlYVF1ZXJ5CgogICAgICAgICAgaWYgKGFyZWFRdWVyeSA+IDAgJiYgciA+IDApIHsKICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYOiLpWlh57i95ZKM6IiHYXJlYVF1ZXJ56YO9PjAsIOWJh+iqv+aVtOWQhGlh5L2/5YW257i95ZKM57iu5pS+6IezYXJlYVF1ZXJ5YCkKICAgICAgICAgICAgLy/oi6VpYee4veWSjOiIh2FyZWFRdWVyeemDvT4wLCDliYfoqr/mlbTlkIRpYeS9v+WFtue4veWSjOe4ruaUvuiHs2FyZWFRdWVyeQogICAgICAgICAgICBsZXQgcyA9IGFyZWFRdWVyeSAvIHI7CiAgICAgICAgICAgIHN1YlZhbHVlcyA9IG1hcChzdWJWYWx1ZXMsIHN2ID0+IHsKICAgICAgICAgICAgICBzdi5pYSAqPSBzOwogICAgICAgICAgICAgIHJldHVybiBzdjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9IGVsc2UgaWYgKGFyZWFRdWVyeSA9PT0gMCAmJiByID4gMCkgewogICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhg6IulYXJlYVF1ZXJ554K6MOS4lGlh57i95ZKMPjAsIOWJh+S9v+eUqGlh57i95ZKM54K6YXJlYVF1ZXJ5YCkKICAgICAgICAgICAgLy/oi6VhcmVhUXVlcnnngrow5LiUaWHnuL3lkow+MCwg5YmH5L2/55SoaWHnuL3lkozngrphcmVhUXVlcnkKICAgICAgICAgICAgYXJlYVF1ZXJ5ID0gcjsKICAgICAgICAgIH0gZWxzZSBpZiAoYXJlYVF1ZXJ5ID4gMCAmJiByID09PSAwKSB7CiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGDoi6VhcmVhUXVlcnk+MOS4lGlh57i95ZKMPTAsIOWJh+WBh+ioreWQhGlh54K65bmz5YiGYXJlYVF1ZXJ5YCkKICAgICAgICAgICAgLy/oi6VhcmVhUXVlcnk+MOS4lGlh57i95ZKMPTAsIOWJh+WBh+ioreWQhGlh54K65bmz5YiGYXJlYVF1ZXJ5CiAgICAgICAgICAgIGxldCBzID0gYXJlYVF1ZXJ5IC8gbjsKICAgICAgICAgICAgc3ViVmFsdWVzID0gbWFwKHN1YlZhbHVlcywgc3YgPT4gewogICAgICAgICAgICAgIHN2LmlhID0gczsKICAgICAgICAgICAgICByZXR1cm4gc3Y7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29uc29sZS5sb2coJ2FyZWFRdWVyeScsIGFyZWFRdWVyeSk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzdW0oaWFzKScsIHIpOwogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FyZWFRdWVyeSE9PXN1bShpYXMpICYmIChhcmVhUXVlcnk8MCBvciBzdW0oaWFzKTwwKScpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoYXJlYVF1ZXJ5ID09PSAwKSB7CiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhg6IulYXJlYVF1ZXJ5PTDkuJRpYee4veWSjD0wLCDliYflgYfoqK1hcmVhUXVlcnnngroxLCDogIzlkIRpYeeCuuW5s+WIhjFgKQogICAgICAgICAgLy/oi6VhcmVhUXVlcnk9aWHnuL3lkow9MCwg5YmH5YGH6KitYXJlYVF1ZXJ554K6MSwg6ICM5ZCEaWHngrrlubPliIYxCiAgICAgICAgICBhcmVhUXVlcnkgPSAxOwogICAgICAgICAgbGV0IHMgPSAxIC8gbjsKICAgICAgICAgIHN1YlZhbHVlcyA9IG1hcChzdWJWYWx1ZXMsIHN2ID0+IHsKICAgICAgICAgICAgc3YuaWEgPSBzOwogICAgICAgICAgICByZXR1cm4gc3Y7CiAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKGFyZWFRdWVyeSA8IDApIHsKICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGDoi6VhcmVhUXVlcnk9aWHnuL3lkow8MCwg5YmH5aCx6YyvYCkKICAgICAgICAgIC8v6IulYXJlYVF1ZXJ5PWlh57i95ZKMPDAsIOWJh+WgsemMrwogICAgICAgICAgY29uc29sZS5sb2coJ2FyZWFRdWVyeScsIGFyZWFRdWVyeSk7CiAgICAgICAgICBjb25zb2xlLmxvZygnc3VtKGlhcyknLCByKTsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXJlYVF1ZXJ5PDAgJiYgc3VtKGlhcyk8MCcpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy9uZXdQb2ludFZhbHMKICAgICAgbGV0IG5ld1BvaW50VmFscyA9IFtdOwogICAgICBmb3JFYWNoKHN1YlZhbHVlcywgbyA9PiB7CiAgICAgICAgLy9yQSwgeiwgdgogICAgICAgIGxldCByQSA9IG8uaWEgLyBhcmVhUXVlcnk7CiAgICAgICAgbGV0IHogPSBkYXRhW28uaWR4XS56OyAvL3gseSx65bey57aT6KKr5q2j6KaP5YyWCiAgICAgICAgbGV0IHYgPSByQSAqIHo7CiAgICAgICAgLy8gY29uc29sZS5sb2coJ3N1YlZhbHVlJywgJ3JBJywgckEsICdvLmlkeCcsIG8uaWR4LCAneicsIHosICd2JywgdikKCiAgICAgICAgLy91c2VGdW5JbnRlcnBGcmFnbWVudAogICAgICAgIGlmICh1c2VGdW5JbnRlcnBGcmFnbWVudCkgewogICAgICAgICAgdiA9IGZ1bkludGVycEZyYWdtZW50KHsKICAgICAgICAgICAgdiwKICAgICAgICAgICAgYXJlYTogby5pYSwKICAgICAgICAgICAgYXJlYVRvdGFsOiBhcmVhUXVlcnksCiAgICAgICAgICAgIGFyZWFSYXRpbzogckEsCiAgICAgICAgICAgIHosCiAgICAgICAgICAgIGluZFNyYzogby5pZHgsCiAgICAgICAgICAgIGluZFRhcgogICAgICAgICAgICAvLyBkYXRhLAogICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvL3AKICAgICAgICBsZXQgcCA9IHsKICAgICAgICAgIHYsCiAgICAgICAgICBhcmVhOiBvLmlhLAogICAgICAgICAgYXJlYVRvdGFsOiBhcmVhUXVlcnksCiAgICAgICAgICBhcmVhUmF0aW86IHJBLAogICAgICAgICAgeiwKICAgICAgICAgIGluZFNyYzogby5pZHgsCiAgICAgICAgICBpbmRUYXIKICAgICAgICB9OwoKICAgICAgICAvL3B1c2gKICAgICAgICBuZXdQb2ludFZhbHMucHVzaChwKTsKICAgICAgfSk7CgogICAgICAvL25ld1BvaW50VmFsCiAgICAgIGxldCB2dCA9IHN1bSQxKG1hcChuZXdQb2ludFZhbHMsICd2JykpOwogICAgICBpZiAodXNlRnVuSW50ZXJwRnJhZ21lbnRzKSB7CiAgICAgICAgdnQgPSBmdW5JbnRlcnBGcmFnbWVudHMoewogICAgICAgICAgcHM6IG5ld1BvaW50VmFscywKICAgICAgICAgIHY6IHZ0LAogICAgICAgICAgaW5kVGFyLAogICAgICAgICAgZnVuSW52OiB2diA9PiB7CiAgICAgICAgICAgIHJldHVybiBpbnYodnYsIDIpOwogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICAgIG5ld1BvaW50VmFsID0gdnQ7CgogICAgICAvLyBpZiAoaXNOYU4obmV3UG9pbnRWYWwpKSB7CiAgICAgIC8vICAgICBjb25zb2xlLmxvZygnaXNOYU4obmV3UG9pbnRWYWwpJywgc3ViVmFsdWVzLCAnYXJlYVF1ZXJ5JywgYXJlYVF1ZXJ5KQogICAgICAvLyB9CiAgICAgIC8vIGNvbnNvbGUubG9nKGBhcmVhUXVlcnlbJHthcmVhUXVlcnl9XSA+IDBgLCAnbmV3UG9pbnRWYWwnLCBuZXdQb2ludFZhbCkKICAgIH0KCiAgICAvL3VwZGF0ZSBuZXdQb2ludFZhbAogICAgZGF0YVtkYXRhLmxlbmd0aCAtIDFdLnogPSBuZXdQb2ludFZhbDsgLy94LHkseuW3sue2k+iiq+ato+imj+WMlgoKICAgIHJldHVybiBuZXdQb2ludFZhbDsKICB9OwoKICAvL2FkZFBvaW50CiAgbGV0IGFkZFBvaW50ID0gKGRhdGEsIHgsIHksIGluZFRhcikgPT4gewogICAgLy9yCiAgICBsZXQgcjsKICAgIHRyeSB7CiAgICAgIHIgPSBhZGRQb2ludENvcmUoZGF0YSwgeCwgeSwgaW5kVGFyKTsKICAgIH0gY2F0Y2ggKGVycikgewogICAgICBjb25zb2xlLmxvZyhlcnIpOwogICAgICByID0gbnVsbDsKICAgICAgZGF0YS5wb3AoKTsKICAgIH0KICAgIHJldHVybiByOwogIH07CgogIC8vZ2V0TnoKICBsZXQgZ2V0TnogPSAobngsIG55LCBpbmRUYXIpID0+IHsKICAgIC8vY2hlY2sKICAgIGxldCBrID0gYCR7bnh9LSR7bnl9YDsgLy94LHnlt7LntpPooqvmraPopo/ljJYKICAgIGlmIChoYXNrZXkoa3BLbm93biwgaykpIHsKICAgICAgcmV0dXJuIGtwS25vd25ba107CiAgICB9CgogICAgLy9jaGVjawogICAgaWYgKG54IDwgdmJveFswXSB8fCBueCA+IHZib3hbMl0gfHwgbnkgPCB2Ym94WzFdIHx8IG55ID4gdmJveFszXSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvL3ByZWRpY3QKICAgIGxldCBueiA9IGFkZFBvaW50KHBzU3JjSXRyLCBueCwgbnksIGluZFRhcik7CgogICAgLy9zYXZlCiAgICBrcEtub3duW2tdID0gbno7CiAgICByZXR1cm4gbno7CiAgfTsKCiAgLy9pdHYKICBsZXQgaXR2ID0gKHAsIGluZFRhcikgPT4gewogICAgLy94LCBueAogICAgbGV0IHggPSBwLng7CiAgICBsZXQgbnggPSBudih4LCAneCcpOwogICAgaWYgKCFpc051bWJlcihueCkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG54WyR7bnh9XWApOyAvL3gseemgkOacn+mDveaYr+acieWAvAogICAgfQoKICAgIC8veSwgbnkKICAgIGxldCB5ID0gcC55OwogICAgbGV0IG55ID0gbnYoeSwgJ3knKTsKICAgIGlmICghaXNOdW1iZXIobnkpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBueVske255fV1gKTsgLy94LHnpoJDmnJ/pg73mmK/mnInlgLwKICAgIH0KCiAgICAvL256LCB6CiAgICBsZXQgbnogPSBnZXROeihueCwgbnksIGluZFRhcik7CiAgICBsZXQgeiA9IGludihueiwgJ3onKTsKICAgIGlmICghaXNOdW1iZXIoeikpIHsKICAgICAgeiA9IG51bGw7IC8veumgiOaUr+aPtOWPr+iDveeEoeazleWFp+aPkgogICAgfQoKICAgIC8vIGNvbnNvbGUubG9nKCd4JywgeCwgJ3knLCB5LCAneicsIHopCiAgICAvLyBjb25zb2xlLmxvZygnbngnLCBueCwgJ255JywgbnksICdueicsIG56KQoKICAgIC8vcgogICAgbGV0IHIgPSB7CiAgICAgIFtrZXlYXTogeCwKICAgICAgW2tleVldOiB5LAogICAgICBba2V5Wl06IHoKICAgIH07CiAgICByZXR1cm4gcjsKICB9OwoKICAvL3IKICBsZXQgcjsKICBpZiAoaXNPbmUpIHsKICAgIGxldCBwID0gcHNUYXJbMF07CiAgICByID0gaXR2KHAsIDApOwogIH0gZWxzZSB7CiAgICByID0gW107CiAgICBmb3JFYWNoKHBzVGFyLCAocCwgaW5kVGFyKSA9PiB7CiAgICAgIHIucHVzaChpdHYocCwgaW5kVGFyKSk7CiAgICB9KTsKICB9CiAgcmV0dXJuIHI7Cn0KCi8vZm9yayBmcm9tOiBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vb2VvNGIva3JpZ2luZy5qcy9tYXN0ZXIva3JpZ2luZy5qcwoKLy/nqbrplpPntbHoqIjliIbmnpDkuYvorornlbDmlbjnmoTnkIboq5bmqKHlnos6IGh0dHBzOi8vd3d3LnN1cGVyZ2VvdGVrLmNvbS90dy9tYW51YWxzL1NTQS90b3BpYzMyLmh0bQovL+WcqOepuumWk+WIhuaekOeahOWBh+ioreS5i+S4i++8jOebuOmEsOaEiOi/keeahOWFqem7nu+8jOWcqOebuOS8vOaIluaYr+ebuOmXnOeoi+W6puS4iuaHieaciei8g+W8t+eahOmXnOS/guOAguWPjeS5i++8jOiLpeWFqem7nueahOi3nembouaLieWkp++8jOWJh+WFtumWk+eahOebuOmXnOeoi+W6puaHieS5n+acg+WwseatpOmZjeS9juOAggovL+iAjOWNiuiuiueVsOWclu+8iFNlbWl2YXJpb2dyYW1z77yJ6IiH5YWx6K6K5pW477yIQ292YXJpYW5jZe+8ieeQhuirlueahOeZvOWxle+8jOWdh+aYr+eUqOmHj+a4rOi3nemboueahOS6kuebuOmXnOeoi+W6pu+8jOWNs+aYr+Wwh+atpOingOW/temAj+mBjuaWueeoi+W8j+eahOi9ieaPm+Wwh+WFtumHj+WMluOAggoKLy8gLy8gRXh0ZW5kIHRoZSBBcnJheSBjbGFzcwovLyBBcnJheS5wcm90b3R5cGUubWF4ID0gZnVuY3Rpb24oKSB7Ci8vICAgICByZXR1cm4gTWF0aC5tYXguYXBwbHkobnVsbCwgdGhpcykKLy8gfQovLyBBcnJheS5wcm90b3R5cGUubWluID0gZnVuY3Rpb24oKSB7Ci8vICAgICByZXR1cm4gTWF0aC5taW4uYXBwbHkobnVsbCwgdGhpcykKLy8gfQovLyBBcnJheS5wcm90b3R5cGUubWVhbiA9IGZ1bmN0aW9uKCkgewovLyAgICAgbGV0IGksIHN1bQovLyAgICAgZm9yIChpID0gMCwgc3VtID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHsKLy8gICAgICAgICBzdW0gKz0gdGhpc1tpXQovLyAgICAgfQovLyAgICAgcmV0dXJuIHN1bSAvIHRoaXMubGVuZ3RoCi8vIH0KLy8gQXJyYXkucHJvdG90eXBlLnBpcCA9IGZ1bmN0aW9uKHgsIHkpIHsKLy8gICAgIGxldCBpOyBsZXQgajsgbGV0IGMgPSBmYWxzZQovLyAgICAgZm9yIChpID0gMCwgaiA9IHRoaXMubGVuZ3RoIC0gMTsgaSA8IHRoaXMubGVuZ3RoOyBqID0gaSsrKSB7Ci8vICAgICAgICAgaWYgKCgodGhpc1tpXVsxXSA+IHkpICE9PSAodGhpc1tqXVsxXSA+IHkpKSAmJgovLyAgICAgICh4IDwgKHRoaXNbal1bMF0gLSB0aGlzW2ldWzBdKSAqICh5IC0gdGhpc1tpXVsxXSkgLyAodGhpc1tqXVsxXSAtIHRoaXNbaV1bMV0pICsgdGhpc1tpXVswXSkpIHsKLy8gICAgICBjID0gIWMKLy8gICAgICAgICB9Ci8vICAgICB9Ci8vICAgICByZXR1cm4gYwovLyB9CgpsZXQga3JpZ2luZyA9IHt9OwoKLy8gbGV0IHBpcCA9IGZ1bmN0aW9uKGFyciwgeCwgeSkgewovLyAgICAgbGV0IGkKLy8gICAgIGxldCBqCi8vICAgICBsZXQgYyA9IGZhbHNlCi8vICAgICBmb3IgKGkgPSAwLCBqID0gYXJyLmxlbmd0aCAtIDE7IGkgPCBhcnIubGVuZ3RoOyBqID0gaSsrKSB7Ci8vICAgICAgICAgaWYgKCgoYXJyW2ldWzFdID4geSkgIT09IChhcnJbal1bMV0gPiB5KSkgJiYKLy8gICAgICAgICAgKHggPCAoYXJyW2pdWzBdIC0gYXJyW2ldWzBdKSAqICh5IC0gYXJyW2ldWzFdKSAvIChhcnJbal1bMV0gLSBhcnJbaV1bMV0pICsgYXJyW2ldWzBdKSkgewovLyAgICAgICAgICAgICBjID0gIWMKLy8gICAgICAgICB9Ci8vICAgICB9Ci8vICAgICByZXR1cm4gYwovLyB9CgpsZXQgY3JlYXRlQXJyYXlXaXRoVmFsdWVzID0gZnVuY3Rpb24gKHZhbHVlLCBuKSB7CiAgbGV0IGFycmF5ID0gW107CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGFycmF5LnB1c2godmFsdWUpOwogIH0KICByZXR1cm4gYXJyYXk7Cn07CgovLyBNYXRyaXggYWxnZWJyYQpsZXQga3JpZ2luZ19tYXRyaXhfZGlhZyA9IGZ1bmN0aW9uIChjLCBuKSB7CiAgbGV0IFogPSBjcmVhdGVBcnJheVdpdGhWYWx1ZXMoMCwgbiAqIG4pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBaW2kgKiBuICsgaV0gPSBjOwogIHJldHVybiBaOwp9OwpsZXQga3JpZ2luZ19tYXRyaXhfdHJhbnNwb3NlID0gZnVuY3Rpb24gKFgsIG4sIG0pIHsKICBsZXQgaTsKICBsZXQgajsKICBsZXQgWiA9IEFycmF5KG0gKiBuKTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgbTsgaisrKSB7CiAgICAgIFpbaiAqIG4gKyBpXSA9IFhbaSAqIG0gKyBqXTsKICAgIH0KICB9CiAgcmV0dXJuIFo7Cn07CgovLyBsZXQga3JpZ2luZ19tYXRyaXhfc2NhbGUgPSBmdW5jdGlvbihYLCBjLCBuLCBtKSB7Ci8vICAgICBsZXQgaSwgagovLyAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewovLyAgICAgICAgIGZvciAoaiA9IDA7IGogPCBtOyBqKyspIHsKLy8gICAgICAgICAgICAgWFtpICogbSArIGpdICo9IGMKLy8gICAgICAgICB9Ci8vICAgICB9Ci8vIH0KCmxldCBrcmlnaW5nX21hdHJpeF9hZGQgPSBmdW5jdGlvbiAoWCwgWSwgbiwgbSkgewogIGxldCBpOwogIGxldCBqOwogIGxldCBaID0gQXJyYXkobiAqIG0pOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBtOyBqKyspIHsKICAgICAgWltpICogbSArIGpdID0gWFtpICogbSArIGpdICsgWVtpICogbSArIGpdOwogICAgfQogIH0KICByZXR1cm4gWjsKfTsKCi8vIE5haXZlIG1hdHJpeCBtdWx0aXBsaWNhdGlvbgpsZXQga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkgPSBmdW5jdGlvbiAoWCwgWSwgbiwgbSwgcCkgewogIGxldCBpOwogIGxldCBqOwogIGxldCBrOwogIGxldCBaID0gQXJyYXkobiAqIHApOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBwOyBqKyspIHsKICAgICAgWltpICogcCArIGpdID0gMDsKICAgICAgZm9yIChrID0gMDsgayA8IG07IGsrKykgewogICAgICAgIFpbaSAqIHAgKyBqXSArPSBYW2kgKiBtICsga10gKiBZW2sgKiBwICsgal07CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFo7Cn07CgovLyBDaG9sZXNreSBkZWNvbXBvc2l0aW9uCmxldCBrcmlnaW5nX21hdHJpeF9jaG9sID0gZnVuY3Rpb24gKFgsIG4pIHsKICBsZXQgaTsKICBsZXQgajsKICBsZXQgazsKICBsZXQgcCA9IEFycmF5KG4pOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHBbaV0gPSBYW2kgKiBuICsgaV07CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IGk7IGorKykgewogICAgICBwW2ldIC09IFhbaSAqIG4gKyBqXSAqIFhbaSAqIG4gKyBqXTsKICAgIH0KICAgIGlmIChwW2ldIDw9IDApIHJldHVybiBmYWxzZTsKICAgIHBbaV0gPSBNYXRoLnNxcnQocFtpXSk7CiAgICBmb3IgKGogPSBpICsgMTsgaiA8IG47IGorKykgewogICAgICBmb3IgKGsgPSAwOyBrIDwgaTsgaysrKSB7CiAgICAgICAgWFtqICogbiArIGldIC09IFhbaiAqIG4gKyBrXSAqIFhbaSAqIG4gKyBrXTsKICAgICAgfQogICAgICBYW2ogKiBuICsgaV0gLz0gcFtpXTsKICAgIH0KICB9CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgWFtpICogbiArIGldID0gcFtpXTsKICByZXR1cm4gdHJ1ZTsKfTsKCi8vIEludmVyc2lvbiBvZiBjaG9sZXNreSBkZWNvbXBvc2l0aW9uCmxldCBrcmlnaW5nX21hdHJpeF9jaG9sMmludiA9IGZ1bmN0aW9uIChYLCBuKSB7CiAgbGV0IGk7CiAgbGV0IGo7CiAgbGV0IGs7CiAgbGV0IHN1bTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBYW2kgKiBuICsgaV0gPSAxIC8gWFtpICogbiArIGldOwogICAgZm9yIChqID0gaSArIDE7IGogPCBuOyBqKyspIHsKICAgICAgc3VtID0gMDsKICAgICAgZm9yIChrID0gaTsgayA8IGo7IGsrKykgewogICAgICAgIHN1bSAtPSBYW2ogKiBuICsga10gKiBYW2sgKiBuICsgaV07CiAgICAgIH0KICAgICAgWFtqICogbiArIGldID0gc3VtIC8gWFtqICogbiArIGpdOwogICAgfQogIH0KICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSBpICsgMTsgaiA8IG47IGorKykgewogICAgICBYW2kgKiBuICsgal0gPSAwOwogICAgfQogIH0KICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBYW2kgKiBuICsgaV0gKj0gWFtpICogbiArIGldOwogICAgZm9yIChrID0gaSArIDE7IGsgPCBuOyBrKyspIHsKICAgICAgWFtpICogbiArIGldICs9IFhbayAqIG4gKyBpXSAqIFhbayAqIG4gKyBpXTsKICAgIH0KICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7CiAgICAgIGZvciAoayA9IGo7IGsgPCBuOyBrKyspIHsKICAgICAgICBYW2kgKiBuICsgal0gKz0gWFtrICogbiArIGldICogWFtrICogbiArIGpdOwogICAgICB9CiAgICB9CiAgfQogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBpOyBqKyspIHsKICAgICAgWFtpICogbiArIGpdID0gWFtqICogbiArIGldOwogICAgfQogIH0KfTsKCi8vIEludmVyc2lvbiB2aWEgZ2F1c3Mtam9yZGFuIGVsaW1pbmF0aW9uCmxldCBrcmlnaW5nX21hdHJpeF9zb2x2ZSA9IGZ1bmN0aW9uIChYLCBuKSB7CiAgbGV0IG0gPSBuOwogIGxldCBiID0gQXJyYXkobiAqIG4pOwogIGxldCBpbmR4YyA9IEFycmF5KG4pOwogIGxldCBpbmR4ciA9IEFycmF5KG4pOwogIGxldCBpcGl2ID0gQXJyYXkobik7CiAgbGV0IGk7CiAgbGV0IGljb2w7CiAgbGV0IGlyb3c7CiAgbGV0IGo7CiAgbGV0IGs7CiAgbGV0IGw7CiAgbGV0IGxsOwogIGxldCBiaWcsIGR1bSwgcGl2aW52LCB0ZW1wOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgaWYgKGkgPT09IGopIGJbaSAqIG4gKyBqXSA9IDE7ZWxzZSBiW2kgKiBuICsgal0gPSAwOwogICAgfQogIH0KICBmb3IgKGogPSAwOyBqIDwgbjsgaisrKSBpcGl2W2pdID0gMDsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBiaWcgPSAwOwogICAgZm9yIChqID0gMDsgaiA8IG47IGorKykgewogICAgICBpZiAoaXBpdltqXSAhPT0gMSkgewogICAgICAgIGZvciAoayA9IDA7IGsgPCBuOyBrKyspIHsKICAgICAgICAgIGlmIChpcGl2W2tdID09PSAwKSB7CiAgICAgICAgICAgIGlmIChNYXRoLmFicyhYW2ogKiBuICsga10pID49IGJpZykgewogICAgICAgICAgICAgIGJpZyA9IE1hdGguYWJzKFhbaiAqIG4gKyBrXSk7CiAgICAgICAgICAgICAgaXJvdyA9IGo7CiAgICAgICAgICAgICAgaWNvbCA9IGs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgICsraXBpdltpY29sXTsKICAgIGlmIChpcm93ICE9PSBpY29sKSB7CiAgICAgIGZvciAobCA9IDA7IGwgPCBuOyBsKyspIHsKICAgICAgICB0ZW1wID0gWFtpcm93ICogbiArIGxdOwogICAgICAgIFhbaXJvdyAqIG4gKyBsXSA9IFhbaWNvbCAqIG4gKyBsXTsKICAgICAgICBYW2ljb2wgKiBuICsgbF0gPSB0ZW1wOwogICAgICB9CiAgICAgIGZvciAobCA9IDA7IGwgPCBtOyBsKyspIHsKICAgICAgICB0ZW1wID0gYltpcm93ICogbiArIGxdOwogICAgICAgIGJbaXJvdyAqIG4gKyBsXSA9IGJbaWNvbCAqIG4gKyBsXTsKICAgICAgICBiW2ljb2wgKiBuICsgbF0gPSB0ZW1wOwogICAgICB9CiAgICB9CiAgICBpbmR4cltpXSA9IGlyb3c7CiAgICBpbmR4Y1tpXSA9IGljb2w7CiAgICBpZiAoWFtpY29sICogbiArIGljb2xdID09PSAwKSByZXR1cm4gZmFsc2U7IC8vIFNpbmd1bGFyCgogICAgcGl2aW52ID0gMSAvIFhbaWNvbCAqIG4gKyBpY29sXTsKICAgIFhbaWNvbCAqIG4gKyBpY29sXSA9IDE7CiAgICBmb3IgKGwgPSAwOyBsIDwgbjsgbCsrKSBYW2ljb2wgKiBuICsgbF0gKj0gcGl2aW52OwogICAgZm9yIChsID0gMDsgbCA8IG07IGwrKykgYltpY29sICogbiArIGxdICo9IHBpdmludjsKICAgIGZvciAobGwgPSAwOyBsbCA8IG47IGxsKyspIHsKICAgICAgaWYgKGxsICE9PSBpY29sKSB7CiAgICAgICAgZHVtID0gWFtsbCAqIG4gKyBpY29sXTsKICAgICAgICBYW2xsICogbiArIGljb2xdID0gMDsKICAgICAgICBmb3IgKGwgPSAwOyBsIDwgbjsgbCsrKSBYW2xsICogbiArIGxdIC09IFhbaWNvbCAqIG4gKyBsXSAqIGR1bTsKICAgICAgICBmb3IgKGwgPSAwOyBsIDwgbTsgbCsrKSBiW2xsICogbiArIGxdIC09IGJbaWNvbCAqIG4gKyBsXSAqIGR1bTsKICAgICAgfQogICAgfQogIH0KICBmb3IgKGwgPSBuIC0gMTsgbCA+PSAwOyBsLS0pIHsKICAgIGlmIChpbmR4cltsXSAhPT0gaW5keGNbbF0pIHsKICAgICAgZm9yIChrID0gMDsgayA8IG47IGsrKykgewogICAgICAgIHRlbXAgPSBYW2sgKiBuICsgaW5keHJbbF1dOwogICAgICAgIFhbayAqIG4gKyBpbmR4cltsXV0gPSBYW2sgKiBuICsgaW5keGNbbF1dOwogICAgICAgIFhbayAqIG4gKyBpbmR4Y1tsXV0gPSB0ZW1wOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiB0cnVlOwp9OwoKLy8gVmFyaW9ncmFtIG1vZGVscwpsZXQga3JpZ2luZ192YXJpb2dyYW1fZ2F1c3NpYW4gPSBmdW5jdGlvbiAoaCwgbnVnZ2V0LCByYW5nZSwgc2lsbCwgQSkgewogIHJldHVybiBudWdnZXQgKyAoc2lsbCAtIG51Z2dldCkgLyByYW5nZSAqICgxLjAgLSBNYXRoLmV4cCgtKDEuMCAvIEEpICogTWF0aC5wb3coaCAvIHJhbmdlLCAyKSkpOwp9OwpsZXQga3JpZ2luZ192YXJpb2dyYW1fZXhwb25lbnRpYWwgPSBmdW5jdGlvbiAoaCwgbnVnZ2V0LCByYW5nZSwgc2lsbCwgQSkgewogIHJldHVybiBudWdnZXQgKyAoc2lsbCAtIG51Z2dldCkgLyByYW5nZSAqICgxLjAgLSBNYXRoLmV4cCgtKDEuMCAvIEEpICogKGggLyByYW5nZSkpKTsKfTsKbGV0IGtyaWdpbmdfdmFyaW9ncmFtX3NwaGVyaWNhbCA9IGZ1bmN0aW9uIChoLCBudWdnZXQsIHJhbmdlLCBzaWxsLCBBKSB7CiAgaWYgKGggPiByYW5nZSkgcmV0dXJuIG51Z2dldCArIChzaWxsIC0gbnVnZ2V0KSAvIHJhbmdlOwogIHJldHVybiBudWdnZXQgKyAoc2lsbCAtIG51Z2dldCkgLyByYW5nZSAqICgxLjUgKiAoaCAvIHJhbmdlKSAtIDAuNSAqIE1hdGgucG93KGggLyByYW5nZSwgMykpOwp9OwoKLy8gVHJhaW4gdXNpbmcgZ2F1c3NpYW4gcHJvY2Vzc2VzIHdpdGggYmF5ZXNpYW4gcHJpb3JzCmtyaWdpbmcudHJhaW4gPSBmdW5jdGlvbiAodCwgeCwgeSwgbW9kZWwsIHNpZ21hMiwgYWxwaGEpIHsKICBsZXQgdmFyaW9ncmFtID0gewogICAgdCwKICAgIHgsCiAgICB5LAogICAgbnVnZ2V0OiAwLjAsCiAgICByYW5nZTogMC4wLAogICAgc2lsbDogMC4wLAogICAgQTogMSAvIDMsCiAgICBuOiAwCiAgfTsKICBzd2l0Y2ggKG1vZGVsKSB7CiAgICBjYXNlICdnYXVzc2lhbic6CiAgICAgIHZhcmlvZ3JhbS5tb2RlbCA9IGtyaWdpbmdfdmFyaW9ncmFtX2dhdXNzaWFuOwogICAgICBicmVhazsKICAgIGNhc2UgJ2V4cG9uZW50aWFsJzoKICAgICAgdmFyaW9ncmFtLm1vZGVsID0ga3JpZ2luZ192YXJpb2dyYW1fZXhwb25lbnRpYWw7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnc3BoZXJpY2FsJzoKICAgICAgdmFyaW9ncmFtLm1vZGVsID0ga3JpZ2luZ192YXJpb2dyYW1fc3BoZXJpY2FsOwogICAgICBicmVhazsKICB9CgogIC8vIExhZyBkaXN0YW5jZS9zZW1pdmFyaWFuY2UKICBsZXQgaTsKICBsZXQgajsKICBsZXQgazsKICBsZXQgbDsKICBsZXQgbiA9IHQubGVuZ3RoOwogIGxldCBkaXN0YW5jZSA9IEFycmF5KChuICogbiAtIG4pIC8gMik7CiAgZm9yIChpID0gMCwgayA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBpOyBqKyssIGsrKykgewogICAgICBkaXN0YW5jZVtrXSA9IEFycmF5KDIpOwogICAgICBkaXN0YW5jZVtrXVswXSA9IE1hdGgucG93KE1hdGgucG93KHhbaV0gLSB4W2pdLCAyKSArIE1hdGgucG93KHlbaV0gLSB5W2pdLCAyKSwgMC41KTsKICAgICAgZGlzdGFuY2Vba11bMV0gPSBNYXRoLmFicyh0W2ldIC0gdFtqXSk7CiAgICB9CiAgfQogIGRpc3RhbmNlLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsKICAgIHJldHVybiBhWzBdIC0gYlswXTsKICB9KTsKICB2YXJpb2dyYW0ucmFuZ2UgPSBkaXN0YW5jZVsobiAqIG4gLSBuKSAvIDIgLSAxXVswXTsKCiAgLy8gQmluIGxhZyBkaXN0YW5jZQogIGxldCBsYWdzID0gKG4gKiBuIC0gbikgLyAyID4gMzAgPyAzMCA6IChuICogbiAtIG4pIC8gMjsKICAvLyBjb25zb2xlLmxvZygnbGFncycsIGxhZ3MpCiAgbGV0IHRvbGVyYW5jZSA9IHZhcmlvZ3JhbS5yYW5nZSAvIGxhZ3M7CiAgbGV0IGxhZyA9IGNyZWF0ZUFycmF5V2l0aFZhbHVlcygwLCBsYWdzKTsKICBsZXQgc2VtaSA9IGNyZWF0ZUFycmF5V2l0aFZhbHVlcygwLCBsYWdzKTsKICBpZiAobGFncyA8IDMwKSB7CiAgICBmb3IgKGwgPSAwOyBsIDwgbGFnczsgbCsrKSB7CiAgICAgIGxhZ1tsXSA9IGRpc3RhbmNlW2xdWzBdOwogICAgICBzZW1pW2xdID0gZGlzdGFuY2VbbF1bMV07CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvciAoaSA9IDAsIGogPSAwLCBrID0gMCwgbCA9IDA7IGkgPCBsYWdzICYmIGogPCAobiAqIG4gLSBuKSAvIDI7IGkrKywgayA9IDApIHsKICAgICAgd2hpbGUgKGRpc3RhbmNlW2pdWzBdIDw9IChpICsgMSkgKiB0b2xlcmFuY2UpIHsKICAgICAgICBsYWdbbF0gKz0gZGlzdGFuY2Vbal1bMF07CiAgICAgICAgc2VtaVtsXSArPSBkaXN0YW5jZVtqXVsxXTsKICAgICAgICBqKys7CiAgICAgICAgaysrOwogICAgICAgIGlmIChqID49IChuICogbiAtIG4pIC8gMikgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKGsgPiAwKSB7CiAgICAgICAgbGFnW2xdIC89IGs7CiAgICAgICAgc2VtaVtsXSAvPSBrOwogICAgICAgIGwrKzsKICAgICAgICAvLyBjb25zb2xlLmxvZygnbCsrJywgbCkKICAgICAgfQogICAgfQoKICAgIGlmIChsIDwgMikgcmV0dXJuIHZhcmlvZ3JhbTsgLy8gRXJyb3I6IE5vdCBlbm91Z2ggcG9pbnRzCiAgfQoKICAvL3NhdmUKICBsZXQgYmFycyA9IFtdOwogIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHsKICAgIGxldCBzMCA9IGxhZ1tpXTsKICAgIGxldCBzMSA9IHNlbWlbaV07CiAgICBiYXJzLnB1c2goW3MwLCBzMV0pOwogIH0KICBsZXQgc3ZwZCA9IHsKICAgIGRhdGE6IGRpc3RhbmNlLAogICAgYmFycwogIH07CiAgdmFyaW9ncmFtLnN2cGQgPSBzdnBkOwoKICAvLyBGZWF0dXJlIHRyYW5zZm9ybWF0aW9uCiAgbiA9IGw7CiAgdmFyaW9ncmFtLnJhbmdlID0gbGFnW24gLSAxXSAtIGxhZ1swXTsKICBsZXQgWCA9IGNyZWF0ZUFycmF5V2l0aFZhbHVlcygxLCAyICogbik7CiAgbGV0IFkgPSBBcnJheShuKTsKICBsZXQgQSA9IHZhcmlvZ3JhbS5BOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIHN3aXRjaCAobW9kZWwpIHsKICAgICAgY2FzZSAnZ2F1c3NpYW4nOgogICAgICAgIFhbaSAqIDIgKyAxXSA9IDEuMCAtIE1hdGguZXhwKC0oMS4wIC8gQSkgKiBNYXRoLnBvdyhsYWdbaV0gLyB2YXJpb2dyYW0ucmFuZ2UsIDIpKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnZXhwb25lbnRpYWwnOgogICAgICAgIFhbaSAqIDIgKyAxXSA9IDEuMCAtIE1hdGguZXhwKC0oMS4wIC8gQSkgKiBsYWdbaV0gLyB2YXJpb2dyYW0ucmFuZ2UpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzcGhlcmljYWwnOgogICAgICAgIFhbaSAqIDIgKyAxXSA9IDEuNSAqIChsYWdbaV0gLyB2YXJpb2dyYW0ucmFuZ2UpIC0gMC41ICogTWF0aC5wb3cobGFnW2ldIC8gdmFyaW9ncmFtLnJhbmdlLCAzKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIFlbaV0gPSBzZW1pW2ldOwogIH0KCiAgLy8gTGVhc3Qgc3F1YXJlcwogIGxldCBYdCA9IGtyaWdpbmdfbWF0cml4X3RyYW5zcG9zZShYLCBuLCAyKTsKICBsZXQgWiA9IGtyaWdpbmdfbWF0cml4X211bHRpcGx5KFh0LCBYLCAyLCBuLCAyKTsKICBaID0ga3JpZ2luZ19tYXRyaXhfYWRkKFosIGtyaWdpbmdfbWF0cml4X2RpYWcoMSAvIGFscGhhLCAyKSwgMiwgMik7CiAgbGV0IGNsb25lWiA9IFouc2xpY2UoMCk7CiAgaWYgKGtyaWdpbmdfbWF0cml4X2Nob2woWiwgMikpIHsKICAgIGtyaWdpbmdfbWF0cml4X2Nob2wyaW52KFosIDIpOwogIH0gZWxzZSB7CiAgICBrcmlnaW5nX21hdHJpeF9zb2x2ZShjbG9uZVosIDIpOwogICAgWiA9IGNsb25lWjsKICB9CiAgbGV0IFcgPSBrcmlnaW5nX21hdHJpeF9tdWx0aXBseShrcmlnaW5nX21hdHJpeF9tdWx0aXBseShaLCBYdCwgMiwgMiwgbiksIFksIDIsIG4sIDEpOwoKICAvLyBWYXJpb2dyYW0gcGFyYW1ldGVycwogIHZhcmlvZ3JhbS5udWdnZXQgPSBXWzBdOwogIHZhcmlvZ3JhbS5zaWxsID0gV1sxXSAqIHZhcmlvZ3JhbS5yYW5nZSArIHZhcmlvZ3JhbS5udWdnZXQ7CiAgdmFyaW9ncmFtLm4gPSB4Lmxlbmd0aDsKCiAgLy8gR3JhbSBtYXRyaXggd2l0aCBwcmlvcgogIG4gPSB4Lmxlbmd0aDsKICBsZXQgSyA9IEFycmF5KG4gKiBuKTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgaTsgaisrKSB7CiAgICAgIEtbaSAqIG4gKyBqXSA9IHZhcmlvZ3JhbS5tb2RlbChNYXRoLnBvdyhNYXRoLnBvdyh4W2ldIC0geFtqXSwgMikgKyBNYXRoLnBvdyh5W2ldIC0geVtqXSwgMiksIDAuNSksIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKTsKICAgICAgS1tqICogbiArIGldID0gS1tpICogbiArIGpdOwogICAgfQogICAgS1tpICogbiArIGldID0gdmFyaW9ncmFtLm1vZGVsKDAsIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKTsKICB9CgogIC8vIEludmVyc2UgcGVuYWxpemVkIEdyYW0gbWF0cml4IHByb2plY3RlZCB0byB0YXJnZXQgdmVjdG9yCiAgbGV0IEMgPSBrcmlnaW5nX21hdHJpeF9hZGQoSywga3JpZ2luZ19tYXRyaXhfZGlhZyhzaWdtYTIsIG4pLCBuLCBuKTsKICBsZXQgY2xvbmVDID0gQy5zbGljZSgwKTsKICBpZiAoa3JpZ2luZ19tYXRyaXhfY2hvbChDLCBuKSkgewogICAga3JpZ2luZ19tYXRyaXhfY2hvbDJpbnYoQywgbik7CiAgfSBlbHNlIHsKICAgIGtyaWdpbmdfbWF0cml4X3NvbHZlKGNsb25lQywgbik7CiAgICBDID0gY2xvbmVDOwogIH0KCiAgLy8gQ29weSB1bnByb2plY3RlZCBpbnZlcnRlZCBtYXRyaXggYXMgSwogIGxldCBfSyA9IEMuc2xpY2UoMCk7CiAgbGV0IF9NID0ga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoQywgdCwgbiwgbiwgMSk7CiAgdmFyaW9ncmFtLksgPSBfSzsKICB2YXJpb2dyYW0uTSA9IF9NOwogIHJldHVybiB2YXJpb2dyYW07Cn07CgovLyBNb2RlbCBwcmVkaWN0aW9uCmtyaWdpbmcucHJlZGljdCA9IGZ1bmN0aW9uICh4LCB5LCB2YXJpb2dyYW0pIHsKICBsZXQgaTsKICBsZXQgayA9IEFycmF5KHZhcmlvZ3JhbS5uKTsKICBmb3IgKGkgPSAwOyBpIDwgdmFyaW9ncmFtLm47IGkrKykgewogICAga1tpXSA9IHZhcmlvZ3JhbS5tb2RlbChNYXRoLnBvdyhNYXRoLnBvdyh4IC0gdmFyaW9ncmFtLnhbaV0sIDIpICsgTWF0aC5wb3coeSAtIHZhcmlvZ3JhbS55W2ldLCAyKSwgMC41KSwgdmFyaW9ncmFtLm51Z2dldCwgdmFyaW9ncmFtLnJhbmdlLCB2YXJpb2dyYW0uc2lsbCwgdmFyaW9ncmFtLkEpOwogIH0KICByZXR1cm4ga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoaywgdmFyaW9ncmFtLk0sIDEsIHZhcmlvZ3JhbS5uLCAxKVswXTsKfTsKa3JpZ2luZy52YXJpYW5jZSA9IGZ1bmN0aW9uICh4LCB5LCB2YXJpb2dyYW0pIHsKICBsZXQgaTsKICBsZXQgayA9IEFycmF5KHZhcmlvZ3JhbS5uKTsKICBmb3IgKGkgPSAwOyBpIDwgdmFyaW9ncmFtLm47IGkrKykgewogICAga1tpXSA9IHZhcmlvZ3JhbS5tb2RlbChNYXRoLnBvdyhNYXRoLnBvdyh4IC0gdmFyaW9ncmFtLnhbaV0sIDIpICsgTWF0aC5wb3coeSAtIHZhcmlvZ3JhbS55W2ldLCAyKSwgMC41KSwgdmFyaW9ncmFtLm51Z2dldCwgdmFyaW9ncmFtLnJhbmdlLCB2YXJpb2dyYW0uc2lsbCwgdmFyaW9ncmFtLkEpOwogIH0KICByZXR1cm4gdmFyaW9ncmFtLm1vZGVsKDAsIHZhcmlvZ3JhbS5udWdnZXQsIHZhcmlvZ3JhbS5yYW5nZSwgdmFyaW9ncmFtLnNpbGwsIHZhcmlvZ3JhbS5BKSArIGtyaWdpbmdfbWF0cml4X211bHRpcGx5KGtyaWdpbmdfbWF0cml4X211bHRpcGx5KGssIHZhcmlvZ3JhbS5LLCAxLCB2YXJpb2dyYW0ubiwgdmFyaW9ncmFtLm4pLCBrLCAxLCB2YXJpb2dyYW0ubiwgMSlbMF07Cn07CgovLyEgTGluZWFyIGFsZ2VicmEgcHJpbWl0aXZlcyAocHVyZSBKUywgemVybyBkZXBlbmRlbmNpZXMpCi8vIQovLyEgUG9ydCBvZiBgZnJpZWRyaWNoIDAuNi4wYDoKLy8hICAgLSBgc3JjL2FsZ2VicmEvbW9kLnJzYCAgICAgICAgICAgICAgKGNvdmFyaWFuY2UtbWF0cml4IGhlbHBlcnMpCi8vISAgIC0gYHNyYy9hbGdlYnJhL2V4dGVuZGFibGVfbWF0cml4LnJzYCAoRU1hdHJpeCAvIEVWZWN0b3Ig4oaSIEV4dGVuZGFibGVNYXRyaXggLyBFeHRlbmRhYmxlVmVjdG9yKQovLyEgICAtIHRoZSBzbGljZSBvZiBgbmFsZ2VicmFgIHRoYXQgZnJpZWRyaWNoIGFjdHVhbGx5IHVzZXMKLy8hICAgICAobWF0cml4IC8gdmVjdG9yIG9wcywgQ2hvbGVza3kgZGVjb21wb3NpdGlvbiwgdHJpYW5ndWxhciBzb2x2ZXMsCi8vISAgICAgIENob2xlc2t5IHNvbHZlIC8gaW52ZXJzZSwgbGVhc3Qtc3F1YXJlcykuCi8vIQovLyEgRGF0YSByZXByZXNlbnRhdGlvbiAoc2VlIFBPUlRfU1BFQyDCpzIpOgovLyEgICAtIHZlY3RvciA9IG51bWJlcltdCi8vISAgIC0gbWF0cml4ID0gbnVtYmVyW11bXSAocm93LW1ham9yOyBtYXRyaXhbcl1bY10gPSByb3cgciwgY29sIGMpCi8vIQovLyEgQWxsIG1hdHJpeCBtYXRoIGhlcmUgaXMgcm93LW1ham9yOyB3ZSBkbyBOT1QgZW11bGF0ZSBuYWxnZWJyYSdzCi8vISBjb2x1bW4tbWFqb3IgbWVtb3J5IGxheW91dCwgb25seSBpdHMgbWF0aGVtYXRpY2FsIHNlbWFudGljcy4KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gQkFTSUMgVkVDVE9SIE9QRVJBVElPTlMgKGlucHV0OiBudW1iZXJbXSkKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIERvdCBwcm9kdWN0IM6jIGHhtaLCt2LhtaIuCiAqIEBwYXJhbSB7bnVtYmVyW119IGEKICogQHBhcmFtIHtudW1iZXJbXX0gYgogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gZG90KGEsIGIpIHsKICBsZXQgcyA9IDA7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSBzICs9IGFbaV0gKiBiW2ldOwogIHJldHVybiBzOwp9CgovKioKICogRWxlbWVudC13aXNlIHN1YnRyYWN0aW9uIGEg4oiSIGIuCiAqIEBwYXJhbSB7bnVtYmVyW119IGEKICogQHBhcmFtIHtudW1iZXJbXX0gYgogKiBAcmV0dXJucyB7bnVtYmVyW119CiAqLwpmdW5jdGlvbiBzdWJWZWMoYSwgYikgewogIGNvbnN0IG91dCA9IG5ldyBBcnJheShhLmxlbmd0aCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSBvdXRbaV0gPSBhW2ldIC0gYltpXTsKICByZXR1cm4gb3V0Owp9CgovKioKICogRXVjbGlkZWFuIG5vcm0gc3FydCjOoyBh4bWiwrIpLgogKiBAcGFyYW0ge251bWJlcltdfSBhCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBub3JtKGEpIHsKICByZXR1cm4gTWF0aC5zcXJ0KG5vcm1TcXVhcmVkKGEpKTsKfQoKLyoqCiAqIFNxdWFyZWQgRXVjbGlkZWFuIG5vcm0gzqMgYeG1osKyLgogKiBAcGFyYW0ge251bWJlcltdfSBhCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBub3JtU3F1YXJlZChhKSB7CiAgbGV0IHMgPSAwOwogIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgcyArPSBhW2ldICogYVtpXTsKICByZXR1cm4gczsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNQVRSSVggLyBNQVRSSVgtVkVDVE9SIE9QRVJBVElPTlMgKG1hdHJpeCA9IG51bWJlcltdW10sIG9uZSByb3cgcGVyIHJvdykKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIE1hdHJpeCBwcm9kdWN0IEEobcOXaykgwrcgQihrw5duKSDihpIgKG3Dl24pLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHBhcmFtIHtudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gbWF0TXVsKEEsIEIpIHsKICBjb25zdCBtID0gQS5sZW5ndGg7CiAgY29uc3QgayA9IEFbMF0ubGVuZ3RoOwogIGNvbnN0IG4gPSBCWzBdLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobSk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIHsKICAgIGNvbnN0IEFpID0gQVtpXTsKICAgIGNvbnN0IHJvdyA9IG5ldyBBcnJheShuKS5maWxsKDApOwogICAgZm9yIChsZXQgcCA9IDA7IHAgPCBrOyBwKyspIHsKICAgICAgY29uc3QgYSA9IEFpW3BdOwogICAgICBjb25zdCBCcCA9IEJbcF07CiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSByb3dbal0gKz0gYSAqIEJwW2pdOwogICAgfQogICAgb3V0W2ldID0gcm93OwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogTWF0cml4LXZlY3RvciBwcm9kdWN0IEEobcOXbikgwrcgeChuKSDihpIgbnVtYmVyW10obSkuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcGFyYW0ge251bWJlcltdfSB4CiAqIEByZXR1cm5zIHtudW1iZXJbXX0KICovCmZ1bmN0aW9uIG1hdFZlYyhBLCB4KSB7CiAgY29uc3QgbSA9IEEubGVuZ3RoOwogIGNvbnN0IG91dCA9IG5ldyBBcnJheShtKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG07IGkrKykgewogICAgY29uc3QgQWkgPSBBW2ldOwogICAgbGV0IHMgPSAwOwogICAgZm9yIChsZXQgaiA9IDA7IGogPCBBaS5sZW5ndGg7IGorKykgcyArPSBBaVtqXSAqIHhbal07CiAgICBvdXRbaV0gPSBzOwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogVHJhbnNwb3NlIG9mIEEuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHRyYW5zcG9zZShBKSB7CiAgY29uc3QgbSA9IEEubGVuZ3RoOwogIGNvbnN0IG4gPSBBWzBdLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgIGNvbnN0IGNvbCA9IG5ldyBBcnJheShtKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSBjb2xbaV0gPSBBW2ldW2pdOwogICAgb3V0W2pdID0gY29sOwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogRWxlbWVudC13aXNlIG1hdHJpeCBzdWJ0cmFjdGlvbiBBIOKIkiBCLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHBhcmFtIHtudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gbWF0U3ViKEEsIEIpIHsKICBjb25zdCBtID0gQS5sZW5ndGg7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG0pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICBjb25zdCBuID0gQVtpXS5sZW5ndGg7CiAgICBjb25zdCByb3cgPSBuZXcgQXJyYXkobik7CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykgcm93W2pdID0gQVtpXVtqXSAtIEJbaV1bal07CiAgICBvdXRbaV0gPSByb3c7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBuw5duIGlkZW50aXR5IG1hdHJpeC4KICogQHBhcmFtIHtudW1iZXJ9IG4KICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiBpZGVudGl0eShuKSB7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBjb25zdCByb3cgPSBuZXcgQXJyYXkobikuZmlsbCgwKTsKICAgIHJvd1tpXSA9IDE7CiAgICBvdXRbaV0gPSByb3c7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBtw5duIHplcm8gbWF0cml4LgogKiBAcGFyYW0ge251bWJlcn0gbQogKiBAcGFyYW0ge251bWJlcn0gbgogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHplcm9zKG0sIG4pIHsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobSk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIG91dFtpXSA9IG5ldyBBcnJheShuKS5maWxsKDApOwogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBUcmFjZSDOoyBB4bWi4bWiIChhbHNvIHVzZWQgYXMgZ2VuZXJpYyBkaWFnb25hbCBzdW0sIGUuZy4gdHJhY2UoQeKBu8K5KSkuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gdHJhY2UoQSkgewogIGNvbnN0IG4gPSBNYXRoLm1pbihBLmxlbmd0aCwgQVswXS5sZW5ndGgpOwogIGxldCBzID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgcyArPSBBW2ldW2ldOwogIHJldHVybiBzOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIENIT0xFU0tZIERFQ09NUE9TSVRJT04gJiBUUklBTkdVTEFSIFNPTFZFUwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQ2hvbGVza3kgZGVjb21wb3NpdGlvbiBvZiBhIHN5bW1ldHJpYyBwb3NpdGl2ZS1kZWZpbml0ZSBtYXRyaXggQShuw5duKSwKICogcmV0dXJuaW5nIHRoZSBsb3dlci10cmlhbmd1bGFyIGZhY3RvciBMIHN1Y2ggdGhhdCBBID0gTMK3TOG1gC4KICoKICogRmFpbHVyZSAobm9uLXBvc2l0aXZlLWRlZmluaXRlKSBiZWhhdmlvdXI6CiAqICAgLSBgZXBzaWxvbiA9PT0gbnVsbGAg4oaSIHRocm93IEVycm9yIChtYXRjaGVzIFJ1c3QgYC5leHBlY3QoKWAgcGFuaWMpLgogKiAgIC0gYGVwc2lsb25gIGEgZmluaXRlIHBvc2l0aXZlIG51bWJlciDihpIgbWltaWMgbmFsZ2VicmEKICogICAgIGBDaG9sZXNreTo6bmV3X3dpdGhfc3Vic3RpdHV0ZWA6IHdoZW5ldmVyIGEgZGlhZ29uYWwgcGl2b3QgZOKxvCDiiaQgMCwKICogICAgIHN1YnN0aXR1dGUgYGVwc2lsb25gIGZvciB0aGF0IHBpdm90IGFuZCBrZWVwIGdvaW5nLiBJZiBldmVuIHRoZQogKiAgICAgc3Vic3RpdHV0ZSBmYWlscyB0byBrZWVwIHRoaW5ncyByZWFsIChjYW5ub3QgaGFwcGVuIGZvciBlcHNpbG9uID4gMCksCiAqICAgICB0aHJvdy4KICoKICogUmVhZHMgb25seSB0aGUgbG93ZXIgdHJpYW5nbGUgb2YgQSAodGhlIHVwcGVyIHRyaWFuZ2xlIGlzIGlnbm9yZWQpLCBtYXRjaGluZwogKiBuYWxnZWJyYSdzIGJlaGF2aW91ciBvZiB1c2luZyBvbmx5IHRoZSBsb3dlci10cmlhbmd1bGFyIHBhcnQuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcGFyYW0ge251bWJlcnxudWxsfSBbZXBzaWxvbj1udWxsXQogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0gbG93ZXItdHJpYW5ndWxhciBMCiAqLwpmdW5jdGlvbiBjaG9sZXNreShBLCBlcHNpbG9uID0gbnVsbCkgewogIGNvbnN0IG4gPSBBLmxlbmd0aDsKICAvLyBMIHN0YXJ0cyBhcyBhIHplcm8gbWF0cml4OyB3ZSBmaWxsIHRoZSBsb3dlciB0cmlhbmdsZSBjb2x1bW4gYnkgY29sdW1uLAogIC8vIG1pcnJvcmluZyBuYWxnZWJyYSdzIGluLXBsYWNlIGFsZ29yaXRobSAobG93ZXItdHJpYW5ndWxhciwgY29sdW1uLW1ham9yKS4KICBjb25zdCBMID0gemVyb3Mobiwgbik7CiAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgIC8vIERpYWdvbmFsIHBpdm90OiBBW2pdW2pdIOKIkiDOo197azxqfSBMW2pdW2tdwrIKICAgIGxldCBkaWFnID0gQVtqXVtqXTsKICAgIGZvciAobGV0IGsgPSAwOyBrIDwgajsgaysrKSBkaWFnIC09IExbal1ba10gKiBMW2pdW2tdOwogICAgaWYgKGVwc2lsb24gPT09IG51bGwpIHsKICAgICAgaWYgKCEoZGlhZyA+IDApKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJDaG9sZXNreSBkZWNvbXBvc2l0aW9uIGZhaWxlZCwgY29uc2lkZXIgc2V0dGluZyBgY2hvbGVza3lfZXBzaWxvbmAgdmlhIGBHYXVzc2lhblByb2Nlc3NCdWlsZGVyYCIpOwogICAgICB9CiAgICB9IGVsc2UgaWYgKCEoZGlhZyA+IDApKSB7CiAgICAgIC8vIG5ld193aXRoX3N1YnN0aXR1dGU6IHJlcGxhY2UgdGhlIG5vbi1wb3NpdGl2ZSBwaXZvdCB3aXRoIGVwc2lsb24uCiAgICAgIGRpYWcgPSBlcHNpbG9uOwogICAgfQogICAgY29uc3QgbGpqID0gTWF0aC5zcXJ0KGRpYWcpOwogICAgTFtqXVtqXSA9IGxqajsKCiAgICAvLyBCZWxvdy1kaWFnb25hbCBlbnRyaWVzIG9mIGNvbHVtbiBqOgogICAgLy8gICBMW2ldW2pdID0gKEFbaV1bal0g4oiSIM6jX3trPGp9IExbaV1ba13Ct0xbal1ba10pIC8gTFtqXVtqXQogICAgZm9yIChsZXQgaSA9IGogKyAxOyBpIDwgbjsgaSsrKSB7CiAgICAgIGxldCBzID0gQVtpXVtqXTsKICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBqOyBrKyspIHMgLT0gTFtpXVtrXSAqIExbal1ba107CiAgICAgIExbaV1bal0gPSBzIC8gbGpqOwogICAgfQogIH0KICByZXR1cm4gTDsKfQoKLyoqCiAqIFNvbHZlIEzCt1ggPSBCIHdoZXJlIEwgaXMgbG93ZXItdHJpYW5ndWxhciAoZm9yd2FyZCBzdWJzdGl0dXRpb24pLgogKiBCIG1heSBiZSBhIHZlY3RvciAobnVtYmVyW10pIOKGkiBzb2x2ZXMgb25lIFJIUywgb3IgYSBtYXRyaXggKG51bWJlcltdW10pCiAqIOKGkiBzb2x2ZXMgY29sdW1uIGJ5IGNvbHVtbiAoZWFjaCBjb2x1bW4gaXMgb25lIFJIUyksIHJldHVybmluZyB0aGUgc2FtZSBzaGFwZS4KICogTWF0Y2hlcyBuYWxnZWJyYSBgc29sdmVfbG93ZXJfdHJpYW5ndWxhcmAuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTCBsb3dlci10cmlhbmd1bGFyCiAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gQgogKiBAcmV0dXJucyB7bnVtYmVyW118bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHNvbHZlTG93ZXJUcmkoTCwgQikgewogIGlmIChBcnJheS5pc0FycmF5KEJbMF0pKSB7CiAgICAvLyBCIGlzIGEgbWF0cml4OiBzb2x2ZSBlYWNoIGNvbHVtbi4KICAgIGNvbnN0IG4gPSBMLmxlbmd0aDsKICAgIGNvbnN0IG5jb2xzID0gQlswXS5sZW5ndGg7CiAgICBjb25zdCBYID0gemVyb3MobiwgbmNvbHMpOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuY29sczsgYysrKSB7CiAgICAgIGNvbnN0IGNvbCA9IG5ldyBBcnJheShuKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIGNvbFtpXSA9IEJbaV1bY107CiAgICAgIGNvbnN0IHNvbCA9IHNvbHZlTG93ZXJUcmlWZWMoTCwgY29sKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIFhbaV1bY10gPSBzb2xbaV07CiAgICB9CiAgICByZXR1cm4gWDsKICB9CiAgcmV0dXJuIHNvbHZlTG93ZXJUcmlWZWMoTCwgQik7Cn0KCi8qKgogKiBGb3J3YXJkIHN1YnN0aXR1dGlvbiBmb3IgYSBzaW5nbGUgUkhTIHZlY3Rvcjogc29sdmUgTMK3eCA9IGIuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTCBsb3dlci10cmlhbmd1bGFyCiAqIEBwYXJhbSB7bnVtYmVyW119IGIKICogQHJldHVybnMge251bWJlcltdfQogKi8KZnVuY3Rpb24gc29sdmVMb3dlclRyaVZlYyhMLCBiKSB7CiAgY29uc3QgbiA9IEwubGVuZ3RoOwogIGNvbnN0IHggPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGxldCBzID0gYltpXTsKICAgIGNvbnN0IExpID0gTFtpXTsKICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaTsgaysrKSBzIC09IExpW2tdICogeFtrXTsKICAgIHhbaV0gPSBzIC8gTGlbaV07CiAgfQogIHJldHVybiB4Owp9CgovKioKICogU29sdmUgVcK3WCA9IEIgd2hlcmUgVSBpcyB1cHBlci10cmlhbmd1bGFyIChiYWNrIHN1YnN0aXR1dGlvbikuCiAqIEluIGZyaWVkcmljaCB0aGUgdXBwZXItdHJpYW5ndWxhciBzeXN0ZW0gaXMgVSA9IEzhtYAuCiAqIEIgbWF5IGJlIG51bWJlcltdIG9yIG51bWJlcltdW10gKGNvbHVtbi13aXNlKSwgcmV0dXJuaW5nIHRoZSBzYW1lIHNoYXBlLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IFUgdXBwZXItdHJpYW5ndWxhcgogKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IEIKICogQHJldHVybnMge251bWJlcltdfG51bWJlcltdW119CiAqLwpmdW5jdGlvbiBzb2x2ZVVwcGVyVHJpKFUsIEIpIHsKICBpZiAoQXJyYXkuaXNBcnJheShCWzBdKSkgewogICAgY29uc3QgbiA9IFUubGVuZ3RoOwogICAgY29uc3QgbmNvbHMgPSBCWzBdLmxlbmd0aDsKICAgIGNvbnN0IFggPSB6ZXJvcyhuLCBuY29scyk7CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG5jb2xzOyBjKyspIHsKICAgICAgY29uc3QgY29sID0gbmV3IEFycmF5KG4pOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgY29sW2ldID0gQltpXVtjXTsKICAgICAgY29uc3Qgc29sID0gc29sdmVVcHBlclRyaVZlYyhVLCBjb2wpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgWFtpXVtjXSA9IHNvbFtpXTsKICAgIH0KICAgIHJldHVybiBYOwogIH0KICByZXR1cm4gc29sdmVVcHBlclRyaVZlYyhVLCBCKTsKfQoKLyoqCiAqIEJhY2sgc3Vic3RpdHV0aW9uIGZvciBhIHNpbmdsZSBSSFMgdmVjdG9yOiBzb2x2ZSBVwrd4ID0gYi4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBVIHVwcGVyLXRyaWFuZ3VsYXIKICogQHBhcmFtIHtudW1iZXJbXX0gYgogKiBAcmV0dXJucyB7bnVtYmVyW119CiAqLwpmdW5jdGlvbiBzb2x2ZVVwcGVyVHJpVmVjKFUsIGIpIHsKICBjb25zdCBuID0gVS5sZW5ndGg7CiAgY29uc3QgeCA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCBpID0gbiAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICBsZXQgcyA9IGJbaV07CiAgICBjb25zdCBVaSA9IFVbaV07CiAgICBmb3IgKGxldCBrID0gaSArIDE7IGsgPCBuOyBrKyspIHMgLT0gVWlba10gKiB4W2tdOwogICAgeFtpXSA9IHMgLyBVaVtpXTsKICB9CiAgcmV0dXJuIHg7Cn0KCi8qKgogKiBTb2x2ZSBBwrdYID0gQiBnaXZlbiB0aGUgbG93ZXItdHJpYW5ndWxhciBDaG9sZXNreSBmYWN0b3IgTCAoQSA9IEzCt0zhtYApOgogKiBmaXJzdCBzb2x2ZSBMwrdZID0gQiAoZm9yd2FyZCksIHRoZW4gTOG1gMK3WCA9IFkgKGJhY2spLgogKiBNYXRjaGVzIG5hbGdlYnJhIGBDaG9sZXNreTo6c29sdmVgLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IEwgbG93ZXItdHJpYW5ndWxhciBmYWN0b3IKICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXXxudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gY2hvbGVza3lTb2x2ZShMLCBCKSB7CiAgY29uc3QgeSA9IHNvbHZlTG93ZXJUcmkoTCwgQik7CiAgY29uc3QgTHQgPSB0cmFuc3Bvc2UoTCk7CiAgcmV0dXJuIHNvbHZlVXBwZXJUcmkoTHQsIHkpOwp9CgovKioKICogQ29tcHV0ZSBB4oG7wrkgPSAoTMK3TOG1gCnigbvCuSBmcm9tIHRoZSBsb3dlci10cmlhbmd1bGFyIENob2xlc2t5IGZhY3RvciBMLAogKiBieSBzb2x2aW5nIEHCt1ggPSBJLiBNYXRjaGVzIG5hbGdlYnJhIGBDaG9sZXNreTo6aW52ZXJzZWAuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTCBsb3dlci10cmlhbmd1bGFyIGZhY3RvcgogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0gQeKBu8K5CiAqLwpmdW5jdGlvbiBjaG9sZXNreUludmVyc2UoTCkgewogIGNvbnN0IG4gPSBMLmxlbmd0aDsKICByZXR1cm4gY2hvbGVza3lTb2x2ZShMLCBpZGVudGl0eShuKSk7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gRVhURU5EQUJMRSBNQVRSSVggLyBWRUNUT1IgIChFTWF0cml4IC8gRVZlY3RvcikKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIEEgbWF0cml4IHRoYXQgY2FuIGdyb3cgYnkgYXBwZW5kaW5nIHJvd3MuCiAqCiAqIEpTIHBvcnQgbm90ZTogd2Ugc2ltcGx5IGBwdXNoYCByb3dzLiBUaGUgUnVzdCB2ZXJzaW9uIHByZS1hbGxvY2F0ZXMgd2l0aCBhCiAqIDEuNcOXIGNhcGFjaXR5LWRvdWJsaW5nIHN0cmF0ZWd5IHB1cmVseSBmb3IgbWVtb3J5IGVmZmljaWVuY3k7IHRoYXQgaGFzIG5vCiAqIGVmZmVjdCBvbiB0aGUgbnVtZXJpY2FsIHJlc3VsdCwgc28gd2Ugb21pdCBpdCAoUE9SVF9TUEVDIMKnMi4zKS4KICovCmNsYXNzIEV4dGVuZGFibGVNYXRyaXggewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gZGF0YQogICAqLwogIGNvbnN0cnVjdG9yKGRhdGEpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW11bXX0gKi8KICAgIHRoaXMuZGF0YSA9IGRhdGE7CiAgfQoKICAvKiogTnVtYmVyIG9mIHJvd3MuIEByZXR1cm5zIHtudW1iZXJ9ICovCiAgZ2V0IG5yb3dzKCkgewogICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGg7CiAgfQoKICAvKiogTnVtYmVyIG9mIGNvbHVtbnMuIEByZXR1cm5zIHtudW1iZXJ9ICovCiAgZ2V0IG5jb2xzKCkgewogICAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggPT09IDAgPyAwIDogdGhpcy5kYXRhWzBdLmxlbmd0aDsKICB9CgogIC8qKgogICAqIEN1cnJlbnQgZGF0YSBhcyBudW1iZXJbXVtdIChpbnRlcm5hbCByZWZlcmVuY2U7IGNhbGxlciBtdXN0IHRyZWF0IGFzIHJlYWQtb25seSkuCiAgICogQHJldHVybnMge251bWJlcltdW119CiAgICovCiAgYXNNYXRyaXgoKSB7CiAgICByZXR1cm4gdGhpcy5kYXRhOwogIH0KCiAgLyoqCiAgICogQXBwZW5kIHJvd3MgYXQgdGhlIGJvdHRvbSAoaW4gcGxhY2UpLgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gcm93cwogICAqLwogIGFkZFJvd3Mocm93cykgewogICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB0aGlzLmRhdGEucHVzaChyb3dzW2ldKTsKICB9Cn0KCi8qKgogKiBBIHZlY3RvciB0aGF0IGNhbiBncm93IGJ5IGFwcGVuZGluZyBlbnRyaWVzLgogKi8KY2xhc3MgRXh0ZW5kYWJsZVZlY3RvciB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXX0gZGF0YQogICAqLwogIGNvbnN0cnVjdG9yKGRhdGEpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW119ICovCiAgICB0aGlzLmRhdGEgPSBkYXRhOwogIH0KCiAgLyoqIE51bWJlciBvZiByb3dzIChlbnRyaWVzKS4gQHJldHVybnMge251bWJlcn0gKi8KICBnZXQgbnJvd3MoKSB7CiAgICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aDsKICB9CgogIC8qKgogICAqIEN1cnJlbnQgZGF0YSBhcyBudW1iZXJbXSAoaW50ZXJuYWwgcmVmZXJlbmNlOyBjYWxsZXIgbXVzdCB0cmVhdCBhcyByZWFkLW9ubHkpLgogICAqIEByZXR1cm5zIHtudW1iZXJbXX0KICAgKi8KICBhc1ZlY3RvcigpIHsKICAgIHJldHVybiB0aGlzLmRhdGE7CiAgfQoKICAvKioKICAgKiBBcHBlbmQgZW50cmllcyAoaW4gcGxhY2UpLgogICAqIEBwYXJhbSB7bnVtYmVyW119IHJvd3MKICAgKi8KICBhZGRSb3dzKHJvd3MpIHsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykgdGhpcy5kYXRhLnB1c2gocm93c1tpXSk7CiAgfQoKICAvKioKICAgKiBPdmVyd3JpdGUgdGhlIHdob2xlIGNvbnRlbnQ7IGxlbmd0aCBtdXN0IGVxdWFsIHRoZSBjdXJyZW50IGxlbmd0aAogICAqIChtYXRjaGVzIFJ1c3QgYGFzc2VydF9lcSFgKS4KICAgKiBAcGFyYW0ge251bWJlcltdfSByb3dzCiAgICovCiAgYXNzaWduKHJvd3MpIHsKICAgIGlmIChyb3dzLmxlbmd0aCAhPT0gdGhpcy5kYXRhLmxlbmd0aCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4dGVuZGFibGVWZWN0b3IuYXNzaWduOiBsZW5ndGggbWlzbWF0Y2ggKGdvdCAke3Jvd3MubGVuZ3RofSwgZXhwZWN0ZWQgJHt0aGlzLmRhdGEubGVuZ3RofSlgKTsKICAgIH0KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykgdGhpcy5kYXRhW2ldID0gcm93c1tpXTsKICB9Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gQ0hPTEVTS1kgREVDT01QT1NJVElPTiBDTEFTUyAoaW5jcmVtZW50YWwgTyhuwrIpIHVwZGF0ZSkKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIEEgc3RvcmVkIENob2xlc2t5IGRlY29tcG9zaXRpb24gb2YgYSBzeW1tZXRyaWMgcG9zaXRpdmUtZGVmaW5pdGUgbWF0cml4LAogKiBzdXBwb3J0aW5nIGluY3JlbWVudGFsIE8obsKyKSBncm93dGggdmlhIGBpbnNlcnRDb2x1bW5gICh1c2VkIGJ5CiAqIEdhdXNzaWFuUHJvY2Vzcy5hZGRTYW1wbGVzKS4gTWlycm9ycyBuYWxnZWJyYSdzIGBDaG9sZXNreWAgb2JqZWN0IHRoYXQKICogZnJpZWRyaWNoIGtlZXBzIGluc2lkZSB0aGUgR1AuCiAqLwpjbGFzcyBDaG9sZXNreURlY29tcG9zaXRpb24gewogIC8qKgogICAqIEJ1aWxkIGZyb20gYSBzeW1tZXRyaWMgcG9zaXRpdmUtZGVmaW5pdGUgbWF0cml4LgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogICAqIEBwYXJhbSB7bnVtYmVyfG51bGx9IFtlcHNpbG9uPW51bGxdIG51bGwg4oaSIHRocm93IG9uIGZhaWx1cmU7IHBvc2l0aXZlIOKGkiBzdWJzdGl0dXRlIG1vZGUuCiAgICovCiAgY29uc3RydWN0b3IoQSwgZXBzaWxvbiA9IG51bGwpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW11bXX0gbG93ZXItdHJpYW5ndWxhciBmYWN0b3IgTCAoQSA9IEzCt0zhtYApICovCiAgICB0aGlzLl9MID0gY2hvbGVza3koQSwgZXBzaWxvbik7CiAgICAvKiogQHR5cGUge251bWJlcnxudWxsfSAqLwogICAgdGhpcy5fZXBzaWxvbiA9IGVwc2lsb247CiAgfQoKICAvKioKICAgKiBMb3dlci10cmlhbmd1bGFyIGZhY3RvciBMLgogICAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogICAqLwogIGwoKSB7CiAgICByZXR1cm4gdGhpcy5fTDsKICB9CgogIC8qKgogICAqIFNvbHZlIEHCt1ggPSBCIChCOiBudW1iZXJbXSB8IG51bWJlcltdW10pLCBzYW1lIHNoYXBlIG91dC4KICAgKiBFcXVpdmFsZW50IHRvIGNob2xlc2t5U29sdmUodGhpcy5sKCksIEIpLgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gQgogICAqIEByZXR1cm5zIHtudW1iZXJbXXxudW1iZXJbXVtdfQogICAqLwogIHNvbHZlKEIpIHsKICAgIHJldHVybiBjaG9sZXNreVNvbHZlKHRoaXMuX0wsIEIpOwogIH0KCiAgLyoqCiAgICogU29sdmUgTMK3WCA9IEIgKGZvcndhcmQgc3Vic3RpdHV0aW9uIG9ubHkpLgogICAqIEVxdWl2YWxlbnQgdG8gc29sdmVMb3dlclRyaSh0aGlzLmwoKSwgQikuCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBCCiAgICogQHJldHVybnMge251bWJlcltdfG51bWJlcltdW119CiAgICovCiAgc29sdmVMb3dlcihCKSB7CiAgICByZXR1cm4gc29sdmVMb3dlclRyaSh0aGlzLl9MLCBCKTsKICB9CgogIC8qKgogICAqIEludmVyc2UgQeKBu8K5LgogICAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogICAqLwogIGludmVyc2UoKSB7CiAgICByZXR1cm4gY2hvbGVza3lJbnZlcnNlKHRoaXMuX0wpOwogIH0KCiAgLyoqCiAgICogSW5zZXJ0IGEgcm93L2NvbHVtbiBhdCBwb3NpdGlvbiBgY29sSW5kZXhgLCB5aWVsZGluZyB0aGUKICAgKiAobisxKcOXKG4rMSkgZGVjb21wb3NpdGlvbi4gSW4gZnJpZWRyaWNoIGBjb2xJbmRleGAgaXMgYWx3YXlzIHRoZSBvbGQKICAgKiBkaW1lbnNpb24gKGkuZS4gYXBwZW5kZWQgYXQgdGhlIGVuZCksIHNvIHRoaXMgaW1wbGVtZW50cyB0aGUgc3RhbmRhcmQKICAgKiAiYm9yZGVyaW5nIiB1cGRhdGU6CiAgICoKICAgKiAgIEwnID0gWyBMICAgICAgMCAgIF0gICAgICB3aXRoICAgTCDCtyBsMjEgPSB2WzAuLm5dICAgKGxvd2VyLXRyaSBzb2x2ZSkKICAgKiAgICAgICAgWyBsMjHhtYAgICBsMjIgXSAgICAgICAgICAgICBsMjIgPSBzcXJ0KHZbbl0g4oiSIGwyMcK3bDIxKQogICAqCiAgICogd2hlcmUgYHZgID0gYG5ld0NvbHVtbmAgKGxlbmd0aCBuKzEpOiB2WzAuLm5dIGFyZSBjb3ZhcmlhbmNlcyB3aXRoIHRoZQogICAqIGV4aXN0aW5nIHJvd3MgYW5kIHZbbl0gaXMgdGhlIG5ldyBwb2ludCdzIHNlbGYtY292YXJpYW5jZSAoYWxyZWFkeQogICAqIGluY2x1ZGluZyBub2lzZcKyKS4KICAgKgogICAqIElmIGwyMsKyIOKJpCAwIGFuZCBhbiBlcHNpbG9uIHdhcyBjb25maWd1cmVkLCBzdWJzdGl0dXRlIGVwc2lsb24gZm9yIHRoZQogICAqIHBpdm90IChtYXRjaGVzIHRoZSBzdWJzdGl0dXRlIGJlaGF2aW91ciBvZiB0aGUgYmF0Y2ggQ2hvbGVza3kpLgogICAqCiAgICogVXBkYXRlcyB0aGlzIG9iamVjdCBpbiBwbGFjZSBhbmQgcmV0dXJucyBgdGhpc2AuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcn0gY29sSW5kZXggIG11c3QgZXF1YWwgdGhlIGN1cnJlbnQgZGltZW5zaW9uIChlbmQgaW5zZXJ0aW9uKQogICAqIEBwYXJhbSB7bnVtYmVyW119IG5ld0NvbHVtbiBsZW5ndGggY29sSW5kZXgrMQogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIGluc2VydENvbHVtbihjb2xJbmRleCwgbmV3Q29sdW1uKSB7CiAgICBjb25zdCBuID0gdGhpcy5fTC5sZW5ndGg7IC8vIG9sZCBkaW1lbnNpb24KICAgIC8vIGZyaWVkcmljaCBvbmx5IGV2ZXIgaW5zZXJ0cyBhdCB0aGUgZW5kLgogICAgaWYgKGNvbEluZGV4ICE9PSBuKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hvbGVza3lEZWNvbXBvc2l0aW9uLmluc2VydENvbHVtbjogb25seSBlbmQgaW5zZXJ0aW9uIHN1cHBvcnRlZCAoY29sSW5kZXg9JHtjb2xJbmRleH0sIGRpbT0ke259KWApOwogICAgfQogICAgY29uc3QgTCA9IHRoaXMuX0w7CgogICAgLy8gU29sdmUgTCDCtyBsMjEgPSB2WzAuLm5dICAoZm9yd2FyZCBzdWJzdGl0dXRpb24pLgogICAgY29uc3QgdiA9IG5ld0NvbHVtbjsKICAgIGNvbnN0IGwyMSA9IG5ldyBBcnJheShuKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGxldCBzID0gdltpXTsKICAgICAgY29uc3QgTGkgPSBMW2ldOwogICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykgcyAtPSBMaVtrXSAqIGwyMVtrXTsKICAgICAgbDIxW2ldID0gcyAvIExpW2ldOwogICAgfQoKICAgIC8vIGwyMiA9IHNxcnQodltuXSDiiJIgbDIxwrdsMjEpCiAgICBsZXQgcGl2b3QgPSB2W25dOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHBpdm90IC09IGwyMVtpXSAqIGwyMVtpXTsKICAgIGlmICh0aGlzLl9lcHNpbG9uID09PSBudWxsKSB7CiAgICAgIGlmICghKHBpdm90ID4gMCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkNob2xlc2t5IGRlY29tcG9zaXRpb24gZmFpbGVkLCBjb25zaWRlciBzZXR0aW5nIGBjaG9sZXNreV9lcHNpbG9uYCB2aWEgYEdhdXNzaWFuUHJvY2Vzc0J1aWxkZXJgIik7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoIShwaXZvdCA+IDApKSB7CiAgICAgIHBpdm90ID0gdGhpcy5fZXBzaWxvbjsKICAgIH0KICAgIGNvbnN0IGwyMiA9IE1hdGguc3FydChwaXZvdCk7CgogICAgLy8gQnVpbGQgdGhlIChuKzEpw5cobisxKSBsb3dlci10cmlhbmd1bGFyIGZhY3Rvci4KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBMW2ldLnB1c2goMCk7IC8vIHBhZCBleGlzdGluZyByb3dzIHdpdGggYSAwIGluIHRoZSBuZXcgY29sdW1uCiAgICBjb25zdCBsYXN0Um93ID0gbmV3IEFycmF5KG4gKyAxKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBsYXN0Um93W2ldID0gbDIxW2ldOwogICAgbGFzdFJvd1tuXSA9IGwyMjsKICAgIEwucHVzaChsYXN0Um93KTsKICAgIHJldHVybiB0aGlzOwogIH0KfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDT1ZBUklBTkNFLU1BVFJJWCBIRUxQRVJTICAoYWxnZWJyYS9tb2QucnMgZnJlZSBmdW5jdGlvbnMpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBDb3ZhcmlhbmNlIG1hdHJpeCBiZXR3ZWVuIHJvd3Mgb2YgbTEgYW5kIHJvd3Mgb2YgbTIgdXNpbmcgYGtlcm5lbGAuCiAqIG91dFtyXVtjXSA9IGtlcm5lbC5rZXJuZWwobTFbcl0sIG0yW2NdKS4gU2hhcGUgKG0xLmxlbmd0aCDDlyBtMi5sZW5ndGgpLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IG0xCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gbTIKICogQHBhcmFtIHt7a2VybmVsOiAoeDE6bnVtYmVyW10sIHgyOm51bWJlcltdKSA9PiBudW1iZXJ9fSBrZXJuZWwKICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiBtYWtlQ292YXJpYW5jZU1hdHJpeChtMSwgbTIsIGtlcm5lbCkgewogIGNvbnN0IHIgPSBtMS5sZW5ndGg7CiAgY29uc3QgYyA9IG0yLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkocik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByOyBpKyspIHsKICAgIGNvbnN0IHJvdyA9IG5ldyBBcnJheShjKTsKICAgIGNvbnN0IHhpID0gbTFbaV07CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGM7IGorKykgcm93W2pdID0ga2VybmVsLmtlcm5lbCh4aSwgbTJbal0pOwogICAgb3V0W2ldID0gcm93OwogIH0KICByZXR1cm4gb3V0Owp9CgovKioKICogQ292YXJpYW5jZSBtYXRyaXggb2YgYGlucHV0c2Agd2l0aCBkaWFnb25hbCBub2lzZcKyLCByZXR1cm5lZCBhcyBpdHMKICogQ2hvbGVza3lEZWNvbXBvc2l0aW9uLgogKgogKiAgIGNvdltpXVtqXSA9IGtlcm5lbC5rZXJuZWwoaW5wdXRzW2ldLCBpbnB1dHNbal0pCiAqICAgY292W2ldW2ldICs9IGRpYWdvbmFsTm9pc2XCsiAgIChub3RlOiB0aGUgU1FVQVJFIG9mIHRoZSBub2lzZSkKICoKICogYGVwc2lsb25gIGlzIGZvcndhcmRlZCB0byB0aGUgQ2hvbGVza3kgKG51bGwg4oaSIHRocm93IG9uIGZhaWx1cmU7CiAqIHBvc2l0aXZlIOKGkiBzdWJzdGl0dXRlIG1vZGUpLgogKgogKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogKiBAcGFyYW0ge3trZXJuZWw6ICh4MTpudW1iZXJbXSwgeDI6bnVtYmVyW10pID0+IG51bWJlcn19IGtlcm5lbAogKiBAcGFyYW0ge251bWJlcn0gZGlhZ29uYWxOb2lzZSB0aGUgbm9pc2UgU1RBTkRBUkQgREVWSUFUSU9OCiAqIEBwYXJhbSB7bnVtYmVyfG51bGx9IFtlcHNpbG9uPW51bGxdCiAqIEByZXR1cm5zIHtDaG9sZXNreURlY29tcG9zaXRpb259CiAqLwpmdW5jdGlvbiBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoaW5wdXRzLCBrZXJuZWwsIGRpYWdvbmFsTm9pc2UsIGVwc2lsb24gPSBudWxsKSB7CiAgY29uc3QgbiA9IGlucHV0cy5sZW5ndGg7CiAgY29uc3Qgbm9pc2VTcSA9IGRpYWdvbmFsTm9pc2UgKiBkaWFnb25hbE5vaXNlOwogIGNvbnN0IGNvdiA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgY29uc3Qgcm93ID0gbmV3IEFycmF5KG4pOwogICAgY29uc3QgeGkgPSBpbnB1dHNbaV07CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykgcm93W2pdID0ga2VybmVsLmtlcm5lbCh4aSwgaW5wdXRzW2pdKTsKICAgIHJvd1tpXSArPSBub2lzZVNxOwogICAgY292W2ldID0gcm93OwogIH0KICByZXR1cm4gbmV3IENob2xlc2t5RGVjb21wb3NpdGlvbihjb3YsIGVwc2lsb24pOwp9CgovKioKICogSW5jcmVtZW50YWxseSBhZGQgdGhlIGxhc3QgYG5iTmV3SW5wdXRzYCByb3dzIG9mIGBhbGxJbnB1dHNgIHRvIGFuIGV4aXN0aW5nCiAqIENob2xlc2t5IGRlY29tcG9zaXRpb24gKGluIHBsYWNlKSwgb25lIHJvdyBhdCBhIHRpbWUuIEZvciBlYWNoIG5ldyByb3c6CiAqICAgLSBjb21wdXRlIHRoZSBuZXcgY29sdW1uIChjb3ZhcmlhbmNlcyB3aXRoIGFsbCByb3dzIHVwIHRvIGFuZCBpbmNsdWRpbmcKICogICAgIGl0c2VsZiwgbGVuZ3RoIGNvbF9pbmRleCsxKSwKICogICAtIGFkZCBub2lzZcKyIHRvIHRoZSBmaW5hbCAoc2VsZikgZW50cnksCiAqICAgLSBjYWxsIGBjaG9sZXNreS5pbnNlcnRDb2x1bW4oY29sX2luZGV4LCBjb2x1bW4pYC4KICoKICogQHBhcmFtIHtDaG9sZXNreURlY29tcG9zaXRpb259IGNob2xlc2t5IHVwZGF0ZWQgaW4gcGxhY2UKICogQHBhcmFtIHtudW1iZXJbXVtdfSBhbGxJbnB1dHMgZnVsbCBpbnB1dCBtYXRyaXggKG9sZCByb3dzIHRoZW4gbmV3IHJvd3MpCiAqIEBwYXJhbSB7bnVtYmVyfSBuYk5ld0lucHV0cyBudW1iZXIgb2YgdHJhaWxpbmcgcm93cyB0byBhZGQKICogQHBhcmFtIHt7a2VybmVsOiAoeDE6bnVtYmVyW10sIHgyOm51bWJlcltdKSA9PiBudW1iZXJ9fSBrZXJuZWwKICogQHBhcmFtIHtudW1iZXJ9IGRpYWdvbmFsTm9pc2UgdGhlIG5vaXNlIFNUQU5EQVJEIERFVklBVElPTgogKi8KZnVuY3Rpb24gYWRkUm93c0Nob2xlc2t5Q292TWF0cml4KGNob2xlc2t5LCBhbGxJbnB1dHMsIG5iTmV3SW5wdXRzLCBrZXJuZWwsIGRpYWdvbmFsTm9pc2UpIHsKICBjb25zdCB0b3RhbCA9IGFsbElucHV0cy5sZW5ndGg7CiAgY29uc3QgbmJPbGQgPSB0b3RhbCAtIG5iTmV3SW5wdXRzOwogIGNvbnN0IG5vaXNlU3EgPSBkaWFnb25hbE5vaXNlICogZGlhZ29uYWxOb2lzZTsKICBmb3IgKGxldCByb3dJbmRleCA9IDA7IHJvd0luZGV4IDwgbmJOZXdJbnB1dHM7IHJvd0luZGV4KyspIHsKICAgIGNvbnN0IGNvbEluZGV4ID0gbmJPbGQgKyByb3dJbmRleDsKICAgIGNvbnN0IHJvdyA9IGFsbElucHV0c1tjb2xJbmRleF07CiAgICBjb25zdCBjb2x1bW5TaXplID0gY29sSW5kZXggKyAxOwogICAgY29uc3QgbmV3Q29sdW1uID0gbmV3IEFycmF5KGNvbHVtblNpemUpOwogICAgZm9yIChsZXQgdHJhaW5pbmdSb3dJbmRleCA9IDA7IHRyYWluaW5nUm93SW5kZXggPCBjb2x1bW5TaXplOyB0cmFpbmluZ1Jvd0luZGV4KyspIHsKICAgICAgbmV3Q29sdW1uW3RyYWluaW5nUm93SW5kZXhdID0ga2VybmVsLmtlcm5lbChhbGxJbnB1dHNbdHJhaW5pbmdSb3dJbmRleF0sIHJvdyk7CiAgICB9CiAgICBuZXdDb2x1bW5bY29sSW5kZXhdICs9IG5vaXNlU3E7CiAgICBjaG9sZXNreS5pbnNlcnRDb2x1bW4oY29sSW5kZXgsIG5ld0NvbHVtbik7CiAgfQp9CgovKioKICogRm9yIGVhY2gga2VybmVsIGh5cGVyLXBhcmFtZXRlciwgYnVpbGQgdGhlIChzeW1tZXRyaWMpIGdyYWRpZW50IG1hdHJpeAogKiDiiIJLL+KIgnBhcmFtLiBSZXR1cm5zIG51bWJlcltdW11bXSBvZiBsZW5ndGgga2VybmVsLm5iUGFyYW1ldGVycygpLgogKgogKiAgIG1hdHNbcF1bcl1bY10gPSBtYXRzW3BdW2NdW3JdID0ga2VybmVsLmdyYWRpZW50KGlucHV0c1tyXSwgaW5wdXRzW2NdKVtwXQogKgogKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogKiBAcGFyYW0ge3tuYlBhcmFtZXRlcnM6ICgpID0+IG51bWJlciwgZ3JhZGllbnQ6ICh4MTpudW1iZXJbXSwgeDI6bnVtYmVyW10pID0+IG51bWJlcltdfX0ga2VybmVsCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdW119CiAqLwpmdW5jdGlvbiBtYWtlR3JhZGllbnRDb3ZhcmlhbmNlTWF0cmljZXMoaW5wdXRzLCBrZXJuZWwpIHsKICBjb25zdCBuID0gaW5wdXRzLmxlbmd0aDsKICBjb25zdCBuYlBhcmFtcyA9IGtlcm5lbC5uYlBhcmFtZXRlcnMoKTsKICBjb25zdCBtYXRzID0gbmV3IEFycmF5KG5iUGFyYW1zKTsKICBmb3IgKGxldCBwID0gMDsgcCA8IG5iUGFyYW1zOyBwKyspIG1hdHNbcF0gPSB6ZXJvcyhuLCBuKTsKICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgewogICAgY29uc3QgeHIgPSBpbnB1dHNbcl07CiAgICAvLyBTeW1tZXRyaWM6IGZpbGwgKHIsYykgYW5kIChjLHIpIHRvZ2V0aGVyIGZvciBjIOKJpSByLgogICAgZm9yIChsZXQgYyA9IHI7IGMgPCBuOyBjKyspIHsKICAgICAgY29uc3QgZ3JhZCA9IGtlcm5lbC5ncmFkaWVudCh4ciwgaW5wdXRzW2NdKTsKICAgICAgZm9yIChsZXQgcCA9IDA7IHAgPCBuYlBhcmFtczsgcCsrKSB7CiAgICAgICAgbWF0c1twXVtyXVtjXSA9IGdyYWRbcF07CiAgICAgICAgbWF0c1twXVtjXVtyXSA9IGdyYWRbcF07CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIG1hdHM7Cn0KCi8vISAjIEtlcm5lbHMKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gRklUIEhFVVJJU1RJQ1MgKGZyZWUgZnVuY3Rpb25zLCBleHBvcnRlZCBmb3Iga2VybmVscyAmIHRlc3RzKQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogUm91Z2ggYmFuZHdpZHRoIGVzdGltYXRlOiBtZWFuIEV1Y2xpZGVhbiBkaXN0YW5jZSBiZXR3ZWVuIGRpc3RpbmN0IHNhbXBsZXMuCiAqICAgzqNfe2k8an0g4oCWeOG1oiDiiJIgeOKxvOKAliAvIChuKG7iiJIxKS8yKQogKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gZml0QmFuZHdpZHRoTWVhbihpbnB1dHMpIHsKICBsZXQgc3VtRGlzdGFuY2VzID0gMDsKICBjb25zdCBuYlNhbXBsZXMgPSBpbnB1dHMubGVuZ3RoOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbmJTYW1wbGVzOyBpKyspIHsKICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IG5iU2FtcGxlczsgaisrKSB7CiAgICAgIHN1bURpc3RhbmNlcyArPSBub3JtKHN1YlZlYyhpbnB1dHNbaV0sIGlucHV0c1tqXSkpOwogICAgfQogIH0KICAvLyBJbnRlZ2VyIGFyaXRobWV0aWMgbWF0Y2hlcyBSdXN0IGAobipuIC0gbikgLyAyYC4KICBjb25zdCBuYkRpc3RhbmNlcyA9IChuYlNhbXBsZXMgKiBuYlNhbXBsZXMgLSBuYlNhbXBsZXMpIC8gMjsKICByZXR1cm4gc3VtRGlzdGFuY2VzIC8gbmJEaXN0YW5jZXM7Cn0KCi8qKgogKiBCZXN0LWd1ZXNzIGFtcGxpdHVkZSA9IHZhcmlhbmNlIG9mIHRoZSBvdXRwdXRzLgogKgogKiBNYXRjaGVzIG5hbGdlYnJhIGB2YXJpYW5jZSgpYDogzqMoeeG1oiDiiJIgbWVhbinCsiAvIE4gKGRpdmlkZXMgYnkgTiwgdGhlIHNhbXBsZQogKiBjb3VudCDigJQgTk9UIE7iiJIxKS4gQ29uZmlybWVkIGZyb20gbmFsZ2VicmEgMC4zNC4yIHN0YXRpc3RpY3MucnMgKFBPUlRfU1BFQyDCpzQuMSkuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW119IG91dHB1dHMKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIGZpdEFtcGxpdHVkZVZhcihvdXRwdXRzKSB7CiAgY29uc3QgbiA9IG91dHB1dHMubGVuZ3RoOwogIGxldCBtZWFuID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgbWVhbiArPSBvdXRwdXRzW2ldOwogIG1lYW4gLz0gbjsKICBsZXQgYWNjID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgY29uc3QgZCA9IG91dHB1dHNbaV0gLSBtZWFuOwogICAgYWNjICs9IGQgKiBkOwogIH0KICByZXR1cm4gYWNjIC8gbjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIFNxdWFyZWQgZXhwb25lbnRpYWwgKGEuay5hLiBHYXVzc2lhbikga2VybmVsOgogKiAgIGsoeCx5KSA9IEHCt2V4cCjiiJLigJZ44oiSeeKAlsKyIC8gKDLCt2xzwrIpKSwgIEEgPSB8YW1wbHwuCiAqIFBhcmFtZXRlcnM6IFtscywgYW1wbF0gKGRlZmF1bHRzIGxzID0gMSwgYW1wbCA9IDEpLiBuYlBhcmFtZXRlcnMgPSAyLiBTY2FsYWJsZS4KICovCmNsYXNzIFNxdWFyZWRFeHAgewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyfSBbbHM9MV0KICAgKiBAcGFyYW0ge251bWJlcn0gW2FtcGw9MV0KICAgKi8KICBjb25zdHJ1Y3RvcihscyA9IDEsIGFtcGwgPSAxKSB7CiAgICAvKiogQHR5cGUge251bWJlcn0gbGVuZ3RoIHNjYWxlICovCiAgICB0aGlzLmxzID0gbHM7CiAgICAvKiogQHR5cGUge251bWJlcn0gYW1wbGl0dWRlICovCiAgICB0aGlzLmFtcGwgPSBhbXBsOwogIH0KICBuYlBhcmFtZXRlcnMoKSB7CiAgICByZXR1cm4gMjsKICB9CiAgaXNTY2FsYWJsZSgpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDEKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MgogICAqIEByZXR1cm5zIHtudW1iZXJ9CiAgICovCiAga2VybmVsKHgxLCB4MikgewogICAgLy8gU2FuaXRpemUgcGFyYW1ldGVycy4KICAgIGNvbnN0IGFtcGwgPSBNYXRoLmFicyh0aGlzLmFtcGwpOwogICAgY29uc3QgZGlzdGFuY2VTcXVhcmVkID0gbm9ybVNxdWFyZWQoc3ViVmVjKHgxLCB4MikpOwogICAgY29uc3QgeCA9IC1kaXN0YW5jZVNxdWFyZWQgLyAoMiAqIHRoaXMubHMgKiB0aGlzLmxzKTsKICAgIHJldHVybiBhbXBsICogTWF0aC5leHAoeCk7CiAgfQoKICAvKioKICAgKiBncmFkaWVudCA9IFtncmFkX2xzLCBncmFkX2FtcGxdIHdpdGggZMKyID0g4oCWeOKIknnigJbCsiwgQSA9IHxhbXBsfCwKICAgKiAgIGUgPSBleHAo4oiSZMKyLygywrdsc8KyKSk6CiAgICogICBncmFkX2xzICAgPSAoZMKyIMK3IEEgwrcgZSkgLyBsc8KzCiAgICogICBncmFkX2FtcGwgPSBzaWduKGFtcGwpIMK3IGUKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MQogICAqIEBwYXJhbSB7bnVtYmVyW119IHgyCiAgICogQHJldHVybnMge251bWJlcltdfQogICAqLwogIGdyYWRpZW50KHgxLCB4MikgewogICAgY29uc3QgYW1wbCA9IE1hdGguYWJzKHRoaXMuYW1wbCk7CiAgICBjb25zdCBkaXN0YW5jZVNxdWFyZWQgPSBub3JtU3F1YXJlZChzdWJWZWMoeDEsIHgyKSk7CiAgICBjb25zdCBleHBvbmVudGlhbCA9IE1hdGguZXhwKC1kaXN0YW5jZVNxdWFyZWQgLyAoMiAqIHRoaXMubHMgKiB0aGlzLmxzKSk7CiAgICBjb25zdCBncmFkTHMgPSBkaXN0YW5jZVNxdWFyZWQgKiBhbXBsICogZXhwb25lbnRpYWwgLyBNYXRoLnBvdyh0aGlzLmxzLCAzKTsKICAgIGNvbnN0IGdyYWRBbXBsID0gTWF0aC5zaWduKHRoaXMuYW1wbCkgKiBleHBvbmVudGlhbDsKICAgIHJldHVybiBbZ3JhZExzLCBncmFkQW1wbF07CiAgfQoKICAvKiogQHBhcmFtIHtudW1iZXJ9IHNjYWxlICovCiAgcmVzY2FsZShzY2FsZSkgewogICAgdGhpcy5hbXBsICo9IHNjYWxlOwogIH0KICBnZXRQYXJhbWV0ZXJzKCkgewogICAgcmV0dXJuIFt0aGlzLmxzLCB0aGlzLmFtcGxdOwogIH0KCiAgLyoqIEBwYXJhbSB7bnVtYmVyW119IHBhcmFtZXRlcnMgKi8KICBzZXRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpIHsKICAgIHRoaXMubHMgPSBwYXJhbWV0ZXJzWzBdOwogICAgdGhpcy5hbXBsID0gcGFyYW1ldGVyc1sxXTsKICB9CgogIC8qKgogICAqIGhldXJpc3RpYzogbHMgPSBtZWFuIGludGVyLXNhbXBsZSBkaXN0YW5jZSwgYW1wbCA9IG91dHB1dCB2YXJpYW5jZS4KICAgKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyW119IG91dHB1dHMKICAgKi8KICBoZXVyaXN0aWNGaXQoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICB0aGlzLmxzID0gZml0QmFuZHdpZHRoTWVhbihpbnB1dHMpOwogICAgdGhpcy5hbXBsID0gZml0QW1wbGl0dWRlVmFyKG91dHB1dHMpOwogIH0KfQoKLyoqIEdhdXNzaWFuIGtlcm5lbCDigJQgYWxpYXMgb2YgU3F1YXJlZEV4cCAoUnVzdCBgcHViIHR5cGUgR2F1c3NpYW4gPSBTcXVhcmVkRXhwYCkuICovCmNvbnN0IEdhdXNzaWFuID0gU3F1YXJlZEV4cDsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBFeHBvbmVudGlhbCBrZXJuZWw6CiAqICAgayh4LHkpID0gQcK3ZXhwKOKIkuKAlnjiiJJ54oCWIC8gKDLCt2xzwrIpKSwgIEEgPSB8YW1wbHwuCiAqIE5PVEUgdGhlIGRlbm9taW5hdG9yIGlzIDLCt2xzwrIgKE5PVCBscyksIGZhaXRoZnVsIHRvIFJ1c3QuCiAqIFBhcmFtZXRlcnM6IFtscywgYW1wbF0gKGRlZmF1bHRzIGxzID0gMSwgYW1wbCA9IDEpLiBuYlBhcmFtZXRlcnMgPSAyLiBTY2FsYWJsZS4KICovCmNsYXNzIEV4cG9uZW50aWFsIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcn0gW2xzPTFdCiAgICogQHBhcmFtIHtudW1iZXJ9IFthbXBsPTFdCiAgICovCiAgY29uc3RydWN0b3IobHMgPSAxLCBhbXBsID0gMSkgewogICAgLyoqIEB0eXBlIHtudW1iZXJ9IGxlbmd0aCBzY2FsZSAqLwogICAgdGhpcy5scyA9IGxzOwogICAgLyoqIEB0eXBlIHtudW1iZXJ9IGFtcGxpdHVkZSAqLwogICAgdGhpcy5hbXBsID0gYW1wbDsKICB9CiAgbmJQYXJhbWV0ZXJzKCkgewogICAgcmV0dXJuIDI7CiAgfQogIGlzU2NhbGFibGUoKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW119IHgxCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDIKICAgKiBAcmV0dXJucyB7bnVtYmVyfQogICAqLwogIGtlcm5lbCh4MSwgeDIpIHsKICAgIGNvbnN0IGFtcGwgPSBNYXRoLmFicyh0aGlzLmFtcGwpOwogICAgY29uc3QgZGlzdGFuY2UgPSBub3JtKHN1YlZlYyh4MSwgeDIpKTsKICAgIGNvbnN0IHggPSAtZGlzdGFuY2UgLyAoMiAqIHRoaXMubHMgKiB0aGlzLmxzKTsKICAgIHJldHVybiBhbXBsICogTWF0aC5leHAoeCk7CiAgfQoKICAvKioKICAgKiBncmFkaWVudCA9IFtncmFkX2xzLCBncmFkX2FtcGxdIHdpdGggZCA9IOKAlnjiiJJ54oCWLCBBID0gfGFtcGx8LAogICAqICAgZSA9IGV4cCjiiJJkLygywrdsc8KyKSk6CiAgICogICBncmFkX2xzICAgPSAoZCDCtyBBIMK3IGUpIC8gbHPCswogICAqICAgZ3JhZF9hbXBsID0gc2lnbihhbXBsKSDCtyBlCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDEKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MgogICAqIEByZXR1cm5zIHtudW1iZXJbXX0KICAgKi8KICBncmFkaWVudCh4MSwgeDIpIHsKICAgIGNvbnN0IGFtcGwgPSBNYXRoLmFicyh0aGlzLmFtcGwpOwogICAgY29uc3QgZGlzdGFuY2UgPSBub3JtKHN1YlZlYyh4MSwgeDIpKTsKICAgIGNvbnN0IGV4cG9uZW50aWFsID0gTWF0aC5leHAoLWRpc3RhbmNlIC8gKDIgKiB0aGlzLmxzICogdGhpcy5scykpOwogICAgY29uc3QgZ3JhZExzID0gZGlzdGFuY2UgKiBhbXBsICogZXhwb25lbnRpYWwgLyBNYXRoLnBvdyh0aGlzLmxzLCAzKTsKICAgIGNvbnN0IGdyYWRBbXBsID0gTWF0aC5zaWduKHRoaXMuYW1wbCkgKiBleHBvbmVudGlhbDsKICAgIHJldHVybiBbZ3JhZExzLCBncmFkQW1wbF07CiAgfQoKICAvKiogQHBhcmFtIHtudW1iZXJ9IHNjYWxlICovCiAgcmVzY2FsZShzY2FsZSkgewogICAgdGhpcy5hbXBsICo9IHNjYWxlOwogIH0KICBnZXRQYXJhbWV0ZXJzKCkgewogICAgcmV0dXJuIFt0aGlzLmxzLCB0aGlzLmFtcGxdOwogIH0KCiAgLyoqIEBwYXJhbSB7bnVtYmVyW119IHBhcmFtZXRlcnMgKi8KICBzZXRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpIHsKICAgIHRoaXMubHMgPSBwYXJhbWV0ZXJzWzBdOwogICAgdGhpcy5hbXBsID0gcGFyYW1ldGVyc1sxXTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJbXX0gb3V0cHV0cwogICAqLwogIGhldXJpc3RpY0ZpdChpbnB1dHMsIG91dHB1dHMpIHsKICAgIHRoaXMubHMgPSBmaXRCYW5kd2lkdGhNZWFuKGlucHV0cyk7CiAgICB0aGlzLmFtcGwgPSBmaXRBbXBsaXR1ZGVWYXIob3V0cHV0cyk7CiAgfQp9CgovKioKICogUHJpb3IgbW9kZWxzIGZvciBHYXVzc2lhbiBQcm9jZXNzIFJlZ3Jlc3Npb24uCiAqCiAqIFBvcnQgb2YgYGZyaWVkcmljaCAwLjYuMCBzcmMvcGFyYW1ldGVycy9wcmlvci5yc2AuCiAqCiAqIFdoZW4gYXNrZWQgdG8gcHJlZGljdCBhIHZhbHVlIGZvciBhbiBpbnB1dCB0aGF0IGlzIHRvbyBkaXNzaW1pbGFyIHRvIGtub3duCiAqIGlucHV0cywgdGhlIG1vZGVsIHJldHVybnMgdGhlIHByaW9yLiBUaGUgR1AgaXMgZml0dGVkIG9uIHRoZSAqcmVzaWR1YWwqIG9mCiAqIHRoZSBwcmlvciwgc28gYSBnb29kIHByaW9yIGNhbiBzaWduaWZpY2FudGx5IGltcHJvdmUgcHJlY2lzaW9uLgogKgogKiBEYXRhIHJlcHJlc2VudGF0aW9uIChzZWUgUE9SVF9TUEVDIMKnMik6CiAqICAgLSBpbnB1dHMgIDogbnVtYmVyW11bXSAocm93LW1ham9yOyBvbmUgc2FtcGxlIHBlciByb3cpCiAqICAgLSBvdXRwdXRzIDogbnVtYmVyW10KICoKICogRGVwZW5kZW5jaWVzOiBhbGdlYnJhLm1qcyAoZG90LCBsc3RzcVNvbHZlKQogKi8KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBDb25zdGFudFByaW9yCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIFRoZSBDb25zdGFudCBwcmlvci4KICoKICogUmV0dXJucyBhIHNpbmdsZSBjb25zdGFudCB2YWx1ZSBmb3IgZXZlcnkgaW5wdXQgcG9pbnQ6IGYoeCkgPSBjLgogKiBDYW4gYmUgZml0dGVkIHRvIHRoZSBtZWFuIG9mIHRoZSB0cmFpbmluZyBvdXRwdXRzLgogKi8KY2xhc3MgQ29uc3RhbnRQcmlvciB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJ9IGMgdGhlIGNvbnN0YW50IHByaW9yIHZhbHVlCiAgICovCiAgY29uc3RydWN0b3IoYykgewogICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovCiAgICB0aGlzLmMgPSBjOwogIH0KCiAgLyoqCiAgICogQ3JlYXRlcyB0aGUgZGVmYXVsdCBDb25zdGFudFByaW9yIHdpdGggYyA9IDAuCiAgICogTWF0Y2hlcyBSdXN0IGBDb25zdGFudFByaW9yOjpkZWZhdWx0KF9pbnB1dF9kaW1lbnNpb24pIOKGkiBTZWxmOjpuZXcoMGY2NClgLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJ9IF9pbnB1dERpbWVuc2lvbiBpZ25vcmVkCiAgICogQHJldHVybnMge0NvbnN0YW50UHJpb3J9CiAgICovCiAgc3RhdGljIGRlZmF1bHQoX2lucHV0RGltZW5zaW9uKSB7CiAgICByZXR1cm4gbmV3IENvbnN0YW50UHJpb3IoMCk7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIGEgY29uc3RhbnQgdmVjdG9yIG9mIGxlbmd0aCBgaW5wdXRzLmxlbmd0aGAsIGVhY2ggZW50cnkgPSB0aGlzLmMuCiAgICogTWF0Y2hlcyBSdXN0IGBwcmlvcihpbnB1dCkg4oaSIERWZWN0b3I6OmZyb21fZWxlbWVudChpbnB1dC5ucm93cygpLCBzZWxmLmMpYC4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzIG9uZSBzYW1wbGUgcGVyIHJvdwogICAqIEByZXR1cm5zIHtudW1iZXJbXX0gY29uc3RhbnQgYXJyYXksIGxlbmd0aCA9IGlucHV0cy5sZW5ndGgKICAgKi8KICBwcmlvcihpbnB1dHMpIHsKICAgIHJldHVybiBuZXcgQXJyYXkoaW5wdXRzLmxlbmd0aCkuZmlsbCh0aGlzLmMpOwogIH0KCiAgLyoqCiAgICogRml0cyB0aGUgcHJpb3IgdG8gdGhlIGFyaXRobWV0aWMgbWVhbiBvZiBgb3V0cHV0c2AuCiAgICogTWF0Y2hlcyBSdXN0IGBmaXQoXywgdHJhaW5pbmdfb3V0cHV0cykgeyBzZWxmLmMgPSB0cmFpbmluZ19vdXRwdXRzLm1lYW4oKSB9YC4KICAgKiBuYWxnZWJyYSdzIGBtZWFuKClgIGRpdmlkZXMgYnkgTiAoZWxlbWVudCBjb3VudCksIG1hdGNoaW5nIEpTIGFyaXRobWV0aWMgbWVhbi4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gX2lucHV0cyBpZ25vcmVkCiAgICogQHBhcmFtIHtudW1iZXJbXX0gb3V0cHV0cyB0cmFpbmluZyBvdXRwdXQgdmFsdWVzCiAgICovCiAgZml0KF9pbnB1dHMsIG91dHB1dHMpIHsKICAgIGNvbnN0IG4gPSBvdXRwdXRzLmxlbmd0aDsKICAgIGxldCBzdW0gPSAwOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHN1bSArPSBvdXRwdXRzW2ldOwogICAgdGhpcy5jID0gc3VtIC8gbjsKICB9Cn0KCi8qKgogKiBjb252ZXJzaW9uLm1qcyDigJQgSW5wdXQgZmxleGliaWxpdHkgZm9yIHRoZSBKUyBwb3J0IG9mIGZyaWVkcmljaCAwLjYuMC4KICoKICogUG9ydCBvZiBgc3JjL2NvbnZlcnNpb24vbW9kLnJzYC4KICoKICogUnVzdCdzIGBJbnB1dGAgdHJhaXQgdXNlcyB0aGUgdHlwZSBzeXN0ZW0gdG8gZGlzdGluZ3Vpc2g6CiAqICAgLSBgVmVjPGY2ND5gICAgICAgIChzaW5nbGUgbXVsdGlkaW1lbnNpb25hbCBwb2ludCkg4oaSIG91dHB1dCBgZjY0YAogKiAgIC0gYFZlYzxWZWM8ZjY0Pj5gIChtdWx0aXBsZSBwb2ludHMpICAgICAgICAgICAgICAg4oaSIG91dHB1dCBgVmVjPGY2ND5gCiAqICAgLSBgRE1hdHJpeDxmNjQ+YCAgKG5hbGdlYnJhIG1hdHJpeCkgICAgICAgICAgICAgICDihpIgb3V0cHV0IGBEVmVjdG9yPGY2ND5gCiAqCiAqIEpTIGhhcyBubyBwYXJhbWV0cmljIHR5cGVzLCBzbyB3ZSB1c2UgKipydW50aW1lIGRldGVjdGlvbioqIG9uIHRoZSBmaXJzdAogKiBlbGVtZW50IG9mIHRoZSBpbnB1dCBhcnJheToKICogICAtIGBudW1iZXJbXWAgICB3aGVyZSBgdHlwZW9mIGlucHV0WzBdID09PSAnbnVtYmVyJ2Ag4oaSIHNpbmdsZSBwb2ludAogKiAgIC0gYG51bWJlcltdW11gIHdoZXJlIGBBcnJheS5pc0FycmF5KGlucHV0WzBdKWAgICAgICDihpIgbXVsdGlwbGUgcG9pbnRzCiAqCiAqIFRoZSAiaXNTaW5nbGUiIGZsYWcgaXMgcHJvcGFnYXRlZCBpbnRvIEdQIHJlc3VsdHMgc28gdGhhdDoKICogICAtIHNpbmdsZS1wb2ludCBpbnB1dHMgIOKGkiBzY2FsYXIgb3V0cHV0cyAgKGBudW1iZXJgKQogKiAgIC0gbXVsdGktcG9pbnQgaW5wdXRzICAg4oaSIHZlY3RvciBvdXRwdXRzICAoYG51bWJlcltdYCkKICoKICogVGhpcyBtYXRjaGVzIHRoZSBgT3V0VmVjdG9yID0gZjY0YCB2cyBgT3V0VmVjdG9yID0gVmVjPGY2ND5gIGRpc3RpbmN0aW9uCiAqIG9mIHRoZSBSdXN0IHRyYWl0IGltcGxzLgogKgogKiBQT1JUX1NQRUMgwqc5IChjb252ZXJzaW9uLm1qcyksIMKnMTIgaXRlbSAxMCAoY29sdW1uLW1ham9yIHZzIHJvdy1tYWpvcikuCiAqCiAqIE5vIGludGVybmFsIGRlcGVuZGVuY2llcyAoY29udmVyc2lvbi5tanMgaGFzIG5vIGltcG9ydHMgcGVyIFBPUlRfU1BFQyDCpzEKICogZGVwZW5kZW5jeSBncmFwaCkuCiAqLwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIGlzU2luZ2xlCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIERldGVjdCB3aGV0aGVyIGBpbnB1dGAgcmVwcmVzZW50cyBhICoqc2luZ2xlKiogbXVsdGlkaW1lbnNpb25hbCBwb2ludC4KICoKICogUnVsZXMgKG1pcnJvcnMgUnVzdCB0cmFpdCBkaXNwYXRjaCk6CiAqICAgLSBgbnVtYmVyW11gICAgKGFsbCBlbGVtZW50cyBhcmUgbnVtYmVycykgIOKGkiB0cnVlICAgKHNpbmdsZSBwb2ludCwgbGlrZSBgVmVjPGY2ND5gKQogKiAgIC0gYG51bWJlcltdW11gIChmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5KSAg4oaSIGZhbHNlICAobXVsdGlwbGUgcG9pbnRzLCBsaWtlIGBWZWM8VmVjPGY2ND4+YCkKICoKICogQW4gZW1wdHkgYXJyYXkgaXMgdHJlYXRlZCBhcyBtdWx0aS1wb2ludCAoZmFsc3kgc2luZ2xlLCBtYXRjaGVzCiAqIHRoZSBgYXNzZXJ0X25lIShuYl9yb3dzLCAwKWAgZ3VhcmQgaW4gdGhlIFJ1c3QgYFZlYzxWZWM8ZjY0Pj5gIGltcGwg4oCUCiAqIGVtcHR5IGlucHV0cyBhcmUgcmVqZWN0ZWQgdXBzdHJlYW0gYW55d2F5KS4KICoKICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dAogKiBAcmV0dXJucyB7Ym9vbGVhbn0KICovCmZ1bmN0aW9uIGlzU2luZ2xlKGlucHV0KSB7CiAgaWYgKCFBcnJheS5pc0FycmF5KGlucHV0KSB8fCBpbnB1dC5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTsKICByZXR1cm4gdHlwZW9mIGlucHV0WzBdID09PSAnbnVtYmVyJzsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIHRvTWF0cml4Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIE5vcm1hbGlzZSBhbnkgcmVjb2duaXNlZCBpbnB1dCBmb3JtIHRvIGBudW1iZXJbXVtdYCAob25lIHJvdyBwZXIgc2FtcGxlKS4KICoKICogfCBKUyBpbnB1dCAgICAgICAgICAgICAgfCBSdXN0IGFuYWxvZ3VlICAgICAgICAgfCBSZXN1bHQgICAgICAgICAgICAgICB8CiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAogKiB8IGBbYSwgYiwgY11gICAgICAgICAgICB8IGBWZWM8ZjY0PmAgICAgICAgICAgICB8IGBbW2EsIGIsIGNdXWAgKDHDl2QpICB8CiAqIHwgYFtbYSxiXSxbYyxkXSzigKZdYCAgICAgfCBgVmVjPFZlYzxmNjQ+PmAgICAgICAgfCB1bmNoYW5nZWQgICAgICAgICAgICB8CiAqCiAqIE1hdGNoZXMgYElucHV0Ojp0b19kbWF0cml4YCAoYm90aCBpbXBscyk6CiAqICAgLSBgVmVjPGY2ND5gIOKGkiBgRE1hdHJpeDo6ZnJvbV9yb3dfc2xpY2UoMSwgbS5sZW4oKSwgbSlgIOKAlCB3cmFwcyBpbiAxIHJvdy4KICogICAtIGBWZWM8VmVjPGY2ND4+YCDihpIgYERNYXRyaXg6OmZyb21fZm4obmJfcm93cywgbmJfY29scywgfHIsY3wgbVtyXVtjXSlgIOKAlCBkaXJlY3QuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXQKICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiB0b01hdHJpeChpbnB1dCkgewogIGlmIChpc1NpbmdsZShpbnB1dCkpIHsKICAgIC8vIFNpbmdsZSBwb2ludDogd3JhcCBpbnRvIGEgMS1yb3cgbWF0cml4LgogICAgcmV0dXJuIFtpbnB1dC5zbGljZSgpXTsKICB9CiAgLy8gTXVsdGlwbGUgcG9pbnRzOiByZXR1cm4gYSBzaGFsbG93IGNvcHkgb2YgdGhlIG91dGVyIGFycmF5IHNvIGNhbGxlcnMKICAvLyBjYW5ub3QgYWNjaWRlbnRhbGx5IG11dGF0ZSB0aGUgb3JpZ2luYWwsIHdoaWxlIGtlZXBpbmcgaW5uZXIgcm93IHJlZnMuCiAgcmV0dXJuIGlucHV0LnNsaWNlKCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyB0b1ZlY3RvcgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgogKiBOb3JtYWxpc2UgYSB0cmFpbmluZy1vdXRwdXQgdmFsdWUgdG8gYG51bWJlcltdYC4KICoKICogfCBKUyBvdXRwdXQgICB8IFJ1c3QgYW5hbG9ndWUgIHwgUmVzdWx0ICAgfAogKiB8LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS18CiAqIHwgYG51bWJlcmAgICAgfCBgZjY0YCAgICAgICAgICB8IGBbdl1gICAgIHwKICogfCBgbnVtYmVyW11gICB8IGBWZWM8ZjY0PmAgICAgIHwgdW5jaGFuZ2VkfAogKgogKiBNYXRjaGVzIGBJbnB1dDo6dG9fZHZlY3RvcmA6CiAqICAgLSBgVmVjPGY2ND5gIGltcGw6IGBEVmVjdG9yOjpmcm9tX2VsZW1lbnQoMSwgKnYpYCDigJQgd3JhcHMgc2NhbGFyIGluIDEtZWxlbWVudCB2ZWN0b3IuCiAqICAgLSBgVmVjPFZlYzxmNjQ+PmAgaW1wbDogYERWZWN0b3I6OmZyb21fY29sdW1uX3NsaWNlKHYpYCDigJQgZGlyZWN0IHNsaWNlLgogKgogKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gb3V0cHV0CiAqIEByZXR1cm5zIHtudW1iZXJbXX0KICovCmZ1bmN0aW9uIHRvVmVjdG9yKG91dHB1dCkgewogIGlmICh0eXBlb2Ygb3V0cHV0ID09PSAnbnVtYmVyJykgewogICAgcmV0dXJuIFtvdXRwdXRdOwogIH0KICByZXR1cm4gb3V0cHV0LnNsaWNlKCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBmcm9tVmVjdG9yCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIENvbnZlcnQgYW4gaW50ZXJuYWwgcmVzdWx0IHZlY3RvciBiYWNrIHRvIHRoZSB1c2VyLWZhY2luZyBvdXRwdXQgdHlwZS4KICoKICogfCBgc2luZ2xlYCB8IFJlc3VsdCAgICAgICAgICB8IFJ1c3QgYW5hbG9ndWUgKGBmcm9tX2R2ZWN0b3JgKSAgICAgICAgIHwKICogfC0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKICogfCBgdHJ1ZWAgICB8IGB2WzBdYCAobnVtYmVyKSB8IGBWZWM8ZjY0PmAgaW1wbDogYGFzc2VydF9lcSEobnJvd3MsMSk7IHZbMF1gIHwKICogfCBgZmFsc2VgICB8IGB2LnNsaWNlKClgICAgICB8IGBWZWM8VmVjPGY2ND4+YCBpbXBsOiBgdi5pdGVyKCkuY2xvbmVkKCkuY29sbGVjdCgpYCB8CiAqCiAqIE5vdGU6IGBwcmVkaWN0Q292YXJpYW5jZWAgKiphbHdheXMqKiByZXR1cm5zIGBudW1iZXJbXVtdYCBhbmQgbXVzdCBOT1QgY2FsbAogKiB0aGlzIGZ1bmN0aW9uIChQT1JUX1NQRUMgwqc5LCDCpzYuNykuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW119IHYgICAgICBpbnRlcm5hbCByZXN1bHQgdmVjdG9yCiAqIEBwYXJhbSB7Ym9vbGVhbn0gIHNpbmdsZSB0cnVlIGlmIHRoZSBvcmlnaW5hbCBpbnB1dCB3YXMgYSBzaW5nbGUgcG9pbnQKICogQHJldHVybnMge251bWJlcnxudW1iZXJbXX0KICovCmZ1bmN0aW9uIGZyb21WZWN0b3Iodiwgc2luZ2xlKSB7CiAgaWYgKHNpbmdsZSkgewogICAgLy8gTWlycm9yczogYXNzZXJ0X2VxISh2Lm5yb3dzKCksIDEpOyB2WzBdCiAgICByZXR1cm4gdlswXTsKICB9CiAgcmV0dXJuIHYuc2xpY2UoKTsKfQoKLyoqCiAqIE11bHRpdmFyaWF0ZSBOb3JtYWwgRGlzdHJpYnV0aW9uIHNhbXBsZXIuCiAqCiAqIFBvcnQgb2YgYGZyaWVkcmljaCAwLjYuMGAgYHNyYy9nYXVzc2lhbl9wcm9jZXNzL211bHRpdmFyaWF0ZV9ub3JtYWwucnNgLgogKgogKiBFeHBvcnRzOgogKiAgIC0gYG11bGJlcnJ5MzIoc2VlZClgICAgICDigJMgc2VlZGFibGUgUFJORyAoUE9SVF9TUEVDIMKnMykKICogICAtIGBzdGFuZGFyZE5vcm1hbChybmcpYCAg4oCTIEJveC1NdWxsZXIgTigwLDEpIHNhbXBsZXIgKFBPUlRfU1BFQyDCpzMpCiAqICAgLSBgTXVsdGl2YXJpYXRlTm9ybWFsYCAgIOKAkyBjbGFzcyBwcm9kdWNlZCBieSBgR2F1c3NpYW5Qcm9jZXNzLnNhbXBsZUF0YAogKgogKiBaZXJvIGV4dGVybmFsIG5wbSBkZXBlbmRlbmNpZXMuIFBSTkcgY2hvaWNlIChtdWxiZXJyeTMyICsgQm94LU11bGxlcikgaXMKICogTk9UIGJpdC1mb3ItYml0IGlkZW50aWNhbCB0byBSdXN0J3MgcmFuZCAvIHJhbmRfZGlzdHIsIGJ1dCBpcyBzdGF0aXN0aWNhbGx5CiAqIGNvcnJlY3QgYW5kIHJlcHJvZHVjaWJsZSBnaXZlbiBhIHNlZWQgKFBPUlRfU1BFQyDCpzEyLjYpLgogKgogKiBEYXRhIHJlcHJlc2VudGF0aW9uIChQT1JUX1NQRUMgwqcyKToKICogICB2ZWN0b3IgPSBudW1iZXJbXQogKiAgIG1hdHJpeCA9IG51bWJlcltdW10gKHJvdy1tYWpvcikKICovCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE5PUk1BTCBTQU1QTEVSIOKAkyBCb3gtTXVsbGVyIChQT1JUX1NQRUMgwqczLCBleGFjdCBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpZWQpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBEcmF3IG9uZSBzdGFuZGFyZC1ub3JtYWwgc2FtcGxlIE4oMCwxKSB1c2luZyB0aGUgQm94LU11bGxlciB0cmFuc2Zvcm0uCiAqCiAqIENvbnN1bWVzIHR3byB1bmlmb3JtIGRyYXdzIGZyb20gYHJuZ2A7IHJldHJpZXMgaWYgdGhlIGZpcnN0IGRyYXcgaXMgZXhhY3RseQogKiAwICh0byBhdm9pZCBsb2coMCkg4oaSIC1JbmZpbml0eSkuCiAqCiAqIE5vdGU6IHRoaXMgdXNlcyBvbmx5IHRoZSBjb3NpbmUgYnJhbmNoIG9mIEJveC1NdWxsZXIgKHRoZSBzaW5lIGJyYW5jaCBpcwogKiBkaXNjYXJkZWQpLCBtYXRjaGluZyB0aGUgUE9SVF9TUEVDIMKnMyBjYW5vbmljYWwgaW1wbGVtZW50YXRpb24uIFN0YXRpc3RpY2FsCiAqIGNvcnJlY3RuZXNzIGlzIG1haW50YWluZWQ7IHRoZSBzaW5lIGJyYW5jaCB3b3VsZCBnaXZlIGVxdWFsbHkgdmFsaWQgc2FtcGxlcwogKiBidXQgaXMgbm90IHJlcXVpcmVkLgogKgogKiBAcGFyYW0geygpID0+IG51bWJlcn0gcm5nICB1bmlmb3JtIFswLCAxKSBnZW5lcmF0b3IgKGUuZy4gZnJvbSBtdWxiZXJyeTMyKQogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gc3RhbmRhcmROb3JtYWwocm5nKSB7CiAgbGV0IHUxID0gMCwKICAgIHUyID0gMDsKICB3aGlsZSAodTEgPT09IDApIHUxID0gcm5nKCk7IC8vIGF2b2lkIGxvZygwKQogIHUyID0gcm5nKCk7CiAgcmV0dXJuIE1hdGguc3FydCgtMiAqIE1hdGgubG9nKHUxKSkgKiBNYXRoLmNvcygyICogTWF0aC5QSSAqIHUyKTsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNdWx0aXZhcmlhdGVOb3JtYWwgQ0xBU1MKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIE11bHRpdmFyaWF0ZSBOb3JtYWwgRGlzdHJpYnV0aW9uIE4obWVhbiwgzqMpLgogKgogKiBQcm9kdWNlZCBieSBgR2F1c3NpYW5Qcm9jZXNzLnNhbXBsZUF0KGlucHV0cylgLiBTdG9yZXMgdGhlIENob2xlc2t5IGZhY3RvcgogKiBMIG9mIHRoZSBwb3N0ZXJpb3IgY292YXJpYW5jZSDOoyAod2hlcmUgzqMgPSBMwrdM4bWAKS4gU2FtcGxpbmcgdXNlczoKICoKICogICB6IH4gTigwLCBJKSAgKGRyYXcgZWFjaCBjb21wb25lbnQgdmlhIEJveC1NdWxsZXIpCiAqICAgeCA9IG1lYW4gKyBMwrd6ICDihpIgIHggfiBOKG1lYW4sIM6jKQogKgogKiBUaGUgYGlzU2luZ2xlYCBmbGFnIG1pcnJvcnMgdGhlIFJ1c3QgYFBoYW50b21EYXRhPFQ+YCBtZWNoYW5pc206IHdoZW4gdGhlCiAqIEdQIHdhcyBxdWVyaWVkIGF0IGEgc2luZ2xlIHBvaW50IChgVCA9IFZlYzxmNjQ+YCkgdGhlIG91dHB1dCBvZiBgbWVhbigpYCBhbmQKICogYHNhbXBsZSgpYCBpcyBhIGBudW1iZXJgOyB3aGVuIHF1ZXJpZWQgYXQgbXVsdGlwbGUgcG9pbnRzIGl0IGlzIGEgYG51bWJlcltdYC4KICoKICogUG9ydCBub3RlczoKICogICAtIFJ1c3Qgc3RvcmVzIGBjaG9sZXNreV9jb3ZhcmlhbmNlYCAoYWxyZWFkeSB0aGUgbG93ZXItdHJpYW5ndWxhciBmYWN0b3IgTAogKiAgICAgZnJvbSBgbmFsZ2VicmE6OkNob2xlc2t5Ojp1bnBhY2soKWApLiBKUyBsaWtld2lzZSBzdG9yZXMgb25seSBMIGFmdGVyCiAqICAgICBkZWNvbXBvc2luZyB0aGUgY292YXJpYW5jZSBpbiB0aGUgY29uc3RydWN0b3IuCiAqICAgLSBDaG9sZXNreSBmYWlsdXJlIOKGkiB0aHJvdyAobWF0Y2hlcyBSdXN0IGAuZXhwZWN0KCIuLi4iKWApLgogKi8KY2xhc3MgTXVsdGl2YXJpYXRlTm9ybWFsIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdfSAgIG1lYW4gICAgICAgIHBvc3RlcmlvciBtZWFuIHZlY3RvciAobGVuZ3RoIG4pCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBjb3ZhcmlhbmNlICBwb3N0ZXJpb3IgY292YXJpYW5jZSBtYXRyaXggKG7Dl24pLCBzeW1tZXRyaWMgcG9zaXRpdmUtZGVmaW5pdGUKICAgKiBAcGFyYW0ge2Jvb2xlYW59ICAgIGlzU2luZ2xlICAgIHRydWUgd2hlbiB0aGUgR1AgaW5wdXQgd2FzIGEgc2luZ2xlIHBvaW50IChudW1iZXJbXSk7CiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSB3aGVuIG11bHRpcGxlIHBvaW50cyAobnVtYmVyW11bXSkKICAgKi8KICBjb25zdHJ1Y3RvcihtZWFuLCBjb3ZhcmlhbmNlLCBpc1NpbmdsZSkgewogICAgLyoqIEB0eXBlIHtudW1iZXJbXX0gKi8KICAgIHRoaXMuX21lYW4gPSBtZWFuOwogICAgLyoqCiAgICAgKiBMb3dlci10cmlhbmd1bGFyIENob2xlc2t5IGZhY3RvciBMIG9mIHRoZSBjb3ZhcmlhbmNlICjOoyA9IEzCt0zhtYApLgogICAgICogQHR5cGUge251bWJlcltdW119CiAgICAgKi8KICAgIHRoaXMuX0wgPSBjaG9sZXNreShjb3ZhcmlhbmNlLCBudWxsKTsgLy8gbnVsbCDihpIgdGhyb3cgb24gZmFpbHVyZSAobWF0Y2hlcyBSdXN0IC5leHBlY3QpCiAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovCiAgICB0aGlzLl9pc1NpbmdsZSA9IGlzU2luZ2xlOwogIH0KCiAgLyoqCiAgICogUG9zdGVyaW9yIG1lYW4uCiAgICoKICAgKiBSZXR1cm5zIGEgYG51bWJlcmAgd2hlbiBgaXNTaW5nbGVgIGlzIHRydWUgKHNpbmdsZS1wb2ludCBxdWVyeSksCiAgICogb3IgYSBgbnVtYmVyW11gIHdoZW4gZmFsc2UgKG11bHRpLXBvaW50IHF1ZXJ5KS4KICAgKgogICAqIEByZXR1cm5zIHtudW1iZXIgfCBudW1iZXJbXX0KICAgKi8KICBtZWFuKCkgewogICAgcmV0dXJuIGZyb21WZWN0b3IodGhpcy5fbWVhbiwgdGhpcy5faXNTaW5nbGUpOwogIH0KCiAgLyoqCiAgICogRHJhdyBvbmUgc2FtcGxlIGZyb20gTihtZWFuLCDOoykuCiAgICoKICAgKiBBbGdvcml0aG0gKFBPUlRfU1BFQyDCpzgpOgogICAqICAgMS4geiA9IFtzdGFuZGFyZE5vcm1hbChybmcpLCDigKZdICAob25lIE4oMCwxKSBwZXIgZGltZW5zaW9uKQogICAqICAgMi4gc2FtcGxlVmVjID0gbWVhbiArIEzCt3oKICAgKiAgIDMuIHJldHVybiBmcm9tVmVjdG9yKHNhbXBsZVZlYywgaXNTaW5nbGUpCiAgICoKICAgKiBgcm5nYCBtdXN0IGJlIGEgYCgpID0+IG51bWJlciDiiIggWzAsIDEpYCBmdW5jdGlvbiwgZS5nLiB0aGUgY2xvc3VyZQogICAqIHJldHVybmVkIGJ5IGBtdWxiZXJyeTMyKHNlZWQpYC4gVGhlIG91dHB1dCB0eXBlIG1pcnJvcnMgYG1lYW4oKWAuCiAgICoKICAgKiBOdW1lcmljIG5vdGU6IHRoZSBQUk5HIGFuZCBCb3gtTXVsbGVyIGltcGxlbWVudGF0aW9uIGRpZmZlciBmcm9tIFJ1c3QncwogICAqIGByYW5kYC9gcmFuZF9kaXN0cmAsIHNvIHNhbXBsZSB2YWx1ZXMgd2lsbCBub3QgbWF0Y2ggUnVzdCBiaXQtZm9yLWJpdC4KICAgKiBTdGF0aXN0aWNhbCBjb3JyZWN0bmVzcyBhbmQgcmVwcm9kdWNpYmlsaXR5IGdpdmVuIGEgc2VlZCBhcmUgZ3VhcmFudGVlZC4KICAgKgogICAqIEBwYXJhbSB7KCkgPT4gbnVtYmVyfSBybmcKICAgKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVtYmVyW119CiAgICovCiAgc2FtcGxlKHJuZykgewogICAgY29uc3QgbiA9IHRoaXMuX21lYW4ubGVuZ3RoOwogICAgLy8gU3RlcCAxOiBkcmF3IHogfiBOKDAsIEkpCiAgICBjb25zdCB6ID0gbmV3IEFycmF5KG4pOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHpbaV0gPSBzdGFuZGFyZE5vcm1hbChybmcpOwogICAgLy8gU3RlcCAyOiBzYW1wbGVWZWMgPSBtZWFuICsgTMK3egogICAgY29uc3QgTHogPSBtYXRWZWModGhpcy5fTCwgeik7CiAgICBjb25zdCBzYW1wbGVWZWMgPSBuZXcgQXJyYXkobik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgc2FtcGxlVmVjW2ldID0gdGhpcy5fbWVhbltpXSArIEx6W2ldOwogICAgLy8gU3RlcCAzOiBjb252ZXJ0IHRvIHNjYWxhciBvciB2ZWN0b3IgZGVwZW5kaW5nIG9uIHF1ZXJ5IHR5cGUKICAgIHJldHVybiBmcm9tVmVjdG9yKHNhbXBsZVZlYywgdGhpcy5faXNTaW5nbGUpOwogIH0KfQoKLy8hIFBhcmFtZXRlciBvcHRpbWl6YXRpb24gKEFEQU0gZ3JhZGllbnQgYXNjZW50IG9uIHRoZSBtYXJnaW5hbCBsb2ctbGlrZWxpaG9vZCkuCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE5PTi1TQ0FMQUJMRSBLRVJORUwKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIENvbXB1dGVzIHRoZSBncmFkaWVudCBvZiB0aGUgbWFyZ2luYWwgbGlrZWxpaG9vZCBmb3IgdGhlIGN1cnJlbnQgdmFsdWUgb2YKICogZWFjaCBwYXJhbWV0ZXIuIFRoZSBwcm9kdWNlZCB2ZWN0b3IgY29udGFpbnMgdGhlIGdyYWRpZW50IHBlciBrZXJuZWwKICogcGFyYW1ldGVyIGZvbGxvd2VkIGJ5IHRoZSBncmFkaWVudCBmb3IgdGhlIG5vaXNlIHBhcmFtZXRlci4KICoKICogUGVyLXBhcmFtZXRlciBmb3JtdWxhIChgb3B0aW1pemVyLnJzOjI0YCk6CiAqICAgwr0gKCBhbHBoYeG1gCDCtyBkcCDCtyBhbHBoYSDiiJIgdHJhY2UoS+KBu8K5IMK3IGRwKSApCiAqIHdoZXJlCiAqICAgSyAgICAgPSBjb3YodHJhaW4sIHRyYWluKQogKiAgIGFscGhhID0gS+KBu8K5IMK3IG91dHB1dAogKiAgIGRwICAgID0g4oiCSy/iiIJwYXJhbWV0ZXIKICoKICogTm9pc2UgZ3JhZGllbnQgKGBncmFkaWVudChLLCBub2lzZSkgPSAywrdub2lzZcK3SWRgKToKICogICBub2lzZSDCtyAoIGFscGhhwrdhbHBoYSDiiJIgdHJhY2UoS+KBu8K5KSApCiAqCiAqIEBwYXJhbSB7b2JqZWN0fSBncCBHYXVzc2lhblByb2Nlc3MgKHNlZSBtb2R1bGUgbm90ZSkKICogQHJldHVybnMge251bWJlcltdfSBsZW5ndGggPSBrZXJuZWwubmJQYXJhbWV0ZXJzKCkgKyAxIChsYXN0IGVudHJ5ID0gbm9pc2UpCiAqLwpmdW5jdGlvbiBncmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZChncCkgewogIC8vIE5lZWRlZCBmb3IgdGhlIHBlci1wYXJhbWV0ZXIgZ3JhZGllbnQgY29tcHV0YXRpb24uCiAgY29uc3QgY292SW52ID0gZ3AuY292bWF0Q2hvbGVza3kuaW52ZXJzZSgpOyAvLyBL4oG7wrkKICBjb25zdCBvdXRwdXQgPSBncC50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsKCiAgLy8gYWxwaGEgPSBL4oG7wrkgwrcgb3V0cHV0ICAobWF0VmVjOyBjb3ZJbnYgaXMgc3ltbWV0cmljKS4KICBjb25zdCBuID0gb3V0cHV0Lmxlbmd0aDsKICBjb25zdCBhbHBoYSA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgewogICAgbGV0IHMgPSAwOwogICAgY29uc3Qgcm93ID0gY292SW52W3JdOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuOyBjKyspIHMgKz0gcm93W2NdICogb3V0cHV0W2NdOwogICAgYWxwaGFbcl0gPSBzOwogIH0KICBjb25zdCBpbnB1dHMgPSBncC50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwogIGNvbnN0IHJlc3VsdHMgPSBbXTsKCiAgLy8gTG9vcCBvdmVyIHRoZSBncmFkaWVudCBtYXRyaXggZm9yIGVhY2ggcGFyYW1ldGVyLgogIGZvciAoY29uc3QgY292R3JhZGllbnQgb2YgbWFrZUdyYWRpZW50Q292YXJpYW5jZU1hdHJpY2VzKGlucHV0cywgZ3Aua2VybmVsKSkgewogICAgLy8gZGF0YV9maXQgPSDOo19jIGFscGhhW2NdIMK3IChhbHBoYSDCtyBjb2xfYykgID0gIGFscGhh4bWAIMK3IGNvdkdyYWRpZW50IMK3IGFscGhhCiAgICAvLyBjb3ZHcmFkaWVudCBpcyBzeW1tZXRyaWMsIHNvIGl0cyBjb2x1bW4gYyBlcXVhbHMgaXRzIHJvdyBjLgogICAgbGV0IGRhdGFGaXQgPSAwOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuOyBjKyspIHsKICAgICAgLy8gYWxwaGEgwrcgKGNvbHVtbiBjIG9mIGNvdkdyYWRpZW50KQogICAgICBsZXQgYWNvbCA9IDA7CiAgICAgIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSBhY29sICs9IGFscGhhW3JdICogY292R3JhZGllbnRbcl1bY107CiAgICAgIGRhdGFGaXQgKz0gYWNvbCAqIGFscGhhW2NdOwogICAgfQoKICAgIC8vIGNvbXBsZXhpdHlfcGVuYWx0eSA9IM6jX3IgKHJvdyByIG9mIGNvdkludikgwrcgKGNvbHVtbiByIG9mIGNvdkdyYWRpZW50KQogICAgLy8gICAgICAgICAgICAgICAgICAgID0gdHJhY2UoY292SW52IMK3IGNvdkdyYWRpZW50KQogICAgbGV0IGNvbXBsZXhpdHlQZW5hbHR5ID0gMDsKICAgIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSB7CiAgICAgIGNvbnN0IGNSb3cgPSBjb3ZJbnZbcl07CiAgICAgIGxldCB0ciA9IDA7CiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgbjsgaysrKSB0ciArPSBjUm93W2tdICogY292R3JhZGllbnRba11bcl07CiAgICAgIGNvbXBsZXhpdHlQZW5hbHR5ICs9IHRyOwogICAgfQogICAgcmVzdWx0cy5wdXNoKChkYXRhRml0IC0gY29tcGxleGl0eVBlbmFsdHkpIC8gMik7CiAgfQoKICAvLyBOb2lzZSBwYXJhbWV0ZXI6IGdyYWRpZW50KEssIG5vaXNlKSA9IDLCt25vaXNlwrdJZC4KICBjb25zdCBkYXRhRml0ID0gZG90KGFscGhhLCBhbHBoYSk7CiAgY29uc3QgY29tcGxleGl0eVBlbmFsdHkgPSB0cmFjZShjb3ZJbnYpOyAvLyB0cmFjZShL4oG7wrkpCiAgY29uc3Qgbm9pc2VHcmFkaWVudCA9IGdwLm5vaXNlICogKGRhdGFGaXQgLSBjb21wbGV4aXR5UGVuYWx0eSk7CiAgcmVzdWx0cy5wdXNoKG5vaXNlR3JhZGllbnQpOwogIHJldHVybiByZXN1bHRzOwp9CgovKioKICogRml0IHBhcmFtZXRlcnMgdXNpbmcgdGhlIEFEQU0gZ3JhZGllbnQtYXNjZW50IGFsZ29yaXRobS4KICoKICogUnVucyBmb3IgYXQgbW9zdCBgbWF4SXRlcmAgaXRlcmF0aW9ucy4gU3RvcHMgZWFybHkgaWYgZXZlcnkgY29tcG9uZW50IG9mIHRoZQogKiB1cGRhdGUgc3RlcCBgZGVsdGFgIGlzIOKJpCBgY29udmVyZ2VuY2VGcmFjdGlvbmAgaW4gbWFnbml0dWRlIChubyBzaWduaWZpY2FudAogKiBwcm9ncmVzcyksIG9yIGlmIHRoZSBydW50aW1lIGV4Y2VlZHMgYG1heFRpbWVgIChtaWxsaXNlY29uZHMpLgogKgogKiBUaGUgYG5vaXNlYCBwYXJhbWV0ZXIgaXMgZml0dGVkIGluIGxvZy1zY2FsZSwgc2luY2UgaXRzIG1hZ25pdHVkZSBtYXR0ZXJzCiAqIG1vcmUgdGhhbiBpdHMgcHJlY2lzZSB2YWx1ZS4KICoKICogQURBTSBjb25zdGFudHMgKGBvcHRpbWl6ZXIucnM6NzlgKTogYmV0YTE9MC45LCBiZXRhMj0wLjk5OSwgZXBzaWxvbj0xZS04LAogKiBsZWFybmluZ1JhdGU9MC4xLgogKgogKiBAcGFyYW0ge29iamVjdH0gZ3AKICogQHBhcmFtIHtudW1iZXJ9IG1heEl0ZXIKICogQHBhcmFtIHtudW1iZXJ9IGNvbnZlcmdlbmNlRnJhY3Rpb24KICogQHBhcmFtIHtudW1iZXJ9IG1heFRpbWUgbWlsbGlzZWNvbmRzCiAqLwpmdW5jdGlvbiBvcHRpbWl6ZVBhcmFtZXRlcnMoZ3AsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpIHsKICBjb25zdCBiZXRhMSA9IDAuOTsKICBjb25zdCBiZXRhMiA9IDAuOTk5OwogIGNvbnN0IGVwc2lsb24gPSAxZS04OwogIGNvbnN0IGxlYXJuaW5nUmF0ZSA9IDAuMTsKCiAgLy8gSW5pdGlhbCBwYXJhbWV0ZXJzOiBrZXJuZWwgcGFyYW1zIHdpdGggYW55IDAgcmVwbGFjZWQgYnkgZXBzaWxvbiAoYSAwCiAgLy8gcGFyYW1ldGVyIHdvdWxkIGJsb2NrIHRoZSBtdWx0aXBsaWNhdGl2ZSBBREFNIHVwZGF0ZSksIHRoZW4gbm9pc2UgaW4KICAvLyBsb2ctc3BhY2UuCiAgY29uc3QgcGFyYW1ldGVycyA9IGdwLmtlcm5lbC5nZXRQYXJhbWV0ZXJzKCkubWFwKHAgPT4gcCA9PT0gMCA/IGVwc2lsb24gOiBwKTsKICBwYXJhbWV0ZXJzLnB1c2goTWF0aC5sb2coZ3Aubm9pc2UpKTsgLy8gbm9pc2UgaW4gbG9nLXNwYWNlCgogIGNvbnN0IG1lYW5HcmFkID0gbmV3IEFycmF5KHBhcmFtZXRlcnMubGVuZ3RoKS5maWxsKDApOwogIGNvbnN0IHZhckdyYWQgPSBuZXcgQXJyYXkocGFyYW1ldGVycy5sZW5ndGgpLmZpbGwoMCk7CiAgY29uc3QgdGltZVN0YXJ0ID0gRGF0ZS5ub3coKTsKICBmb3IgKGxldCBpID0gMTsgaSA8PSBtYXhJdGVyOyBpKyspIHsKICAgIGNvbnN0IGdyYWRpZW50cyA9IGdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKGdwKTsKICAgIC8vIENvcnJlY3QgdGhlIG5vaXNlIGdyYWRpZW50IGZvciBsb2ctc3BhY2UuCiAgICBncmFkaWVudHNbZ3JhZGllbnRzLmxlbmd0aCAtIDFdICo9IGdwLm5vaXNlOwogICAgbGV0IGhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgPSBmYWxzZTsKICAgIGZvciAobGV0IHAgPSAwOyBwIDwgcGFyYW1ldGVycy5sZW5ndGg7IHArKykgewogICAgICBtZWFuR3JhZFtwXSA9IGJldGExICogbWVhbkdyYWRbcF0gKyAoMSAtIGJldGExKSAqIGdyYWRpZW50c1twXTsKICAgICAgdmFyR3JhZFtwXSA9IGJldGEyICogdmFyR3JhZFtwXSArICgxIC0gYmV0YTIpICogZ3JhZGllbnRzW3BdICogZ3JhZGllbnRzW3BdOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkTWVhbiA9IG1lYW5HcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMSwgaSkpOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkVmFyaWFuY2UgPSB2YXJHcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMiwgaSkpOwogICAgICBjb25zdCBkZWx0YSA9IGxlYXJuaW5nUmF0ZSAqIGJpYXNDb3JyZWN0ZWRNZWFuIC8gKE1hdGguc3FydChiaWFzQ29ycmVjdGVkVmFyaWFuY2UpICsgZXBzaWxvbik7CiAgICAgIGlmIChNYXRoLmFicyhkZWx0YSkgPiBjb252ZXJnZW5jZUZyYWN0aW9uKSBoYWRTaWduaWZpY2FudFByb2dyZXNzID0gdHJ1ZTsKICAgICAgcGFyYW1ldGVyc1twXSAqPSAxICsgZGVsdGE7CiAgICB9CgogICAgLy8gU2V0IGtlcm5lbCBwYXJhbWV0ZXJzICh0aGUga2VybmVsIHJlYWRzIG9ubHkgaXRzIG93biBsZWFkaW5nIHByZWZpeAogICAgLy8gb2YgYHBhcmFtZXRlcnNgOyB0aGUgdHJhaWxpbmcgbm9pc2UgbG9nLXZhbHVlIGlzIGlnbm9yZWQgYnkgaXQpLgogICAgZ3Aua2VybmVsLnNldFBhcmFtZXRlcnMocGFyYW1ldGVycyk7CiAgICAvLyBHZXQgdGhlIG5vaXNlIG91dCBvZiBsb2ctc3BhY2UgYmVmb3JlIHNldHRpbmcgaXQuCiAgICBncC5ub2lzZSA9IE1hdGguZXhwKHBhcmFtZXRlcnNbcGFyYW1ldGVycy5sZW5ndGggLSAxXSk7CgogICAgLy8gUmVmaXQgdGhlIG1vZGVsIChyZWJ1aWxkIHRoZSBDaG9sZXNreSBmYWN0b3Igb2YgdGhlIGNvdmFyaWFuY2UgbWF0cml4KS4KICAgIGdwLmNvdm1hdENob2xlc2t5ID0gbWFrZUNob2xlc2t5Q292TWF0cml4KGdwLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCksIGdwLmtlcm5lbCwgZ3Aubm9pc2UsIGdwLmNob2xlc2t5RXBzaWxvbik7CiAgICBpZiAoIWhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgfHwgRGF0ZS5ub3coKSAtIHRpbWVTdGFydCA+IG1heFRpbWUpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFNDQUxBQkxFIEtFUk5FTAovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogUmV0dXJucyBgW3NjYWxlLCBncmFkaWVudHNdYDogdGhlIG9wdGltYWwgc2NhbGUgZm9yIHRoZSBrZXJuZWwrbm9pc2UgKHVzZWQgdG8KICogb3B0aW1pemUgdGhlIG5vaXNlKSBwbHVzIHRoZSBncmFkaWVudCBwZXIga2VybmVsIHBhcmFtZXRlciAoTk9UIGluY2x1ZGluZyB0aGUKICogbm9pc2UgZ3JhZGllbnQpLgogKgogKiBQZXItcGFyYW1ldGVyIGZvcm11bGEgKGBvcHRpbWl6ZXIucnM6MTUwYCk6CiAqICAgwr0gKCBhbHBoYeG1gCDCtyBkcCDCtyBhbHBoYSAvIHNjYWxlIOKIkiB0cmFjZShL4oG7wrkgwrcgZHApICkKICogICBzY2FsZSA9IG91dHB1dOG1gCDCtyBL4oG7wrkgwrcgb3V0cHV0IC8gbgogKiBOT1RFOiB0aGUgZGF0YS1maXQgdGVybSBpcyBkaXZpZGVkIGJ5IGBzY2FsZWAsIHVubGlrZSB0aGUgdW5zY2FsZWQgZ3JhZGllbnQuCiAqCiAqIEBwYXJhbSB7b2JqZWN0fSBncAogKiBAcmV0dXJucyB7W251bWJlciwgbnVtYmVyW11dfSBbc2NhbGUsIHJlc3VsdHNdIChyZXN1bHRzIGxlbmd0aCA9IG5iUGFyYW1ldGVycykKICovCmZ1bmN0aW9uIHNjYWxlZEdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKGdwKSB7CiAgY29uc3QgY292SW52ID0gZ3AuY292bWF0Q2hvbGVza3kuaW52ZXJzZSgpOyAvLyBL4oG7wrkKICBjb25zdCBvdXRwdXQgPSBncC50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsKICBjb25zdCBuID0gb3V0cHV0Lmxlbmd0aDsKCiAgLy8gYWxwaGEgPSBL4oG7wrkgwrcgb3V0cHV0CiAgY29uc3QgYWxwaGEgPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIHsKICAgIGxldCBzID0gMDsKICAgIGNvbnN0IHJvdyA9IGNvdkludltyXTsKICAgIGZvciAobGV0IGMgPSAwOyBjIDwgbjsgYysrKSBzICs9IHJvd1tjXSAqIG91dHB1dFtjXTsKICAgIGFscGhhW3JdID0gczsKICB9CgogIC8vIFNjYWxpbmcgZm9yIHRoZSBrZXJuZWw6IG91dHB1dOG1gCDCtyBL4oG7wrkgwrcgb3V0cHV0IC8gbiA9IG91dHB1dMK3YWxwaGEgLyBuLgogIGNvbnN0IHNjYWxlID0gZG90KG91dHB1dCwgYWxwaGEpIC8gbjsKICBjb25zdCBpbnB1dHMgPSBncC50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBmb3IgKGNvbnN0IGNvdkdyYWRpZW50IG9mIG1ha2VHcmFkaWVudENvdmFyaWFuY2VNYXRyaWNlcyhpbnB1dHMsIGdwLmtlcm5lbCkpIHsKICAgIC8vIGRhdGFfZml0ID0gKGFscGhh4bWAIMK3IGNvdkdyYWRpZW50IMK3IGFscGhhKSAvIHNjYWxlCiAgICBsZXQgZGF0YUZpdCA9IDA7CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG47IGMrKykgewogICAgICBsZXQgYWNvbCA9IDA7CiAgICAgIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSBhY29sICs9IGFscGhhW3JdICogY292R3JhZGllbnRbcl1bY107CiAgICAgIGRhdGFGaXQgKz0gYWNvbCAqIGFscGhhW2NdOwogICAgfQogICAgZGF0YUZpdCAvPSBzY2FsZTsKCiAgICAvLyBjb21wbGV4aXR5X3BlbmFsdHkgPSB0cmFjZShjb3ZJbnYgwrcgY292R3JhZGllbnQpCiAgICBsZXQgY29tcGxleGl0eVBlbmFsdHkgPSAwOwogICAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIHsKICAgICAgY29uc3QgY1JvdyA9IGNvdkludltyXTsKICAgICAgbGV0IHRyID0gMDsKICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBuOyBrKyspIHRyICs9IGNSb3dba10gKiBjb3ZHcmFkaWVudFtrXVtyXTsKICAgICAgY29tcGxleGl0eVBlbmFsdHkgKz0gdHI7CiAgICB9CiAgICByZXN1bHRzLnB1c2goKGRhdGFGaXQgLSBjb21wbGV4aXR5UGVuYWx0eSkgLyAyKTsKICB9CgogIC8vIE5PVEU6IGZhaXRoZnVsIHRvIFJ1c3Qgc291cmNlIOKAlCB0aGUgbm9pc2UgZ3JhZGllbnQgaXMgaW50ZW50aW9uYWxseSBOT1QKICAvLyBwdXNoZWQgaGVyZSAoaXQgaXMgY29tbWVudGVkIG91dCBpbiBvcHRpbWl6ZXIucnM6MTg4LTE5MSk7IHRoZSBub2lzZSBpcwogIC8vIGluc3RlYWQgZml0dGVkIHZpYSBga2VybmVsLnJlc2NhbGUoc2NhbGUpYCArIGBncC5ub2lzZSAqPSBzY2FsZWAuCgogIHJldHVybiBbc2NhbGUsIHJlc3VsdHNdOwp9CgovKioKICogRml0IHBhcmFtZXRlcnMgdXNpbmcgQURBTSBncmFkaWVudCBhc2NlbnQ7IGFkZGl0aW9uYWxseSwgYXQgZWFjaCBzdGVwIHRoZQogKiBrZXJuZWwgYW5kIG5vaXNlIGFyZSByZXNjYWxlZCBieSB0aGUgb3B0aW1hbCBtYWduaXR1ZGUgYHNjYWxlYC4KICoKICogUnVucyBmb3IgYXQgbW9zdCBgbWF4SXRlcmAgaXRlcmF0aW9ucy4gU3RvcHMgZWFybHkgb24gbm8gc2lnbmlmaWNhbnQgcHJvZ3Jlc3MKICogKGFsbCBgZGVsdGFgIOKJpCBgY29udmVyZ2VuY2VGcmFjdGlvbmApIG9yIGlmIHRoZSBydW50aW1lIGV4Y2VlZHMgYG1heFRpbWVgCiAqIChtaWxsaXNlY29uZHMpLgogKgogKiBBREFNIGNvbnN0YW50cyBpZGVudGljYWwgdG8ge0BsaW5rIG9wdGltaXplUGFyYW1ldGVyc30uCiAqCiAqIEBwYXJhbSB7b2JqZWN0fSBncAogKiBAcGFyYW0ge251bWJlcn0gbWF4SXRlcgogKiBAcGFyYW0ge251bWJlcn0gY29udmVyZ2VuY2VGcmFjdGlvbgogKiBAcGFyYW0ge251bWJlcn0gbWF4VGltZSBtaWxsaXNlY29uZHMKICovCmZ1bmN0aW9uIHNjYWxlZE9wdGltaXplUGFyYW1ldGVycyhncCwgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSkgewogIGNvbnN0IGJldGExID0gMC45OwogIGNvbnN0IGJldGEyID0gMC45OTk7CiAgY29uc3QgZXBzaWxvbiA9IDFlLTg7CiAgY29uc3QgbGVhcm5pbmdSYXRlID0gMC4xOwoKICAvLyBJbml0aWFsIHBhcmFtZXRlcnM6IGtlcm5lbCBwYXJhbXMgd2l0aCAwIHJlcGxhY2VkIGJ5IGVwc2lsb24uCiAgLy8gKE5vIG5vaXNlIHB1c2hlZDogdGhlIG5vaXNlIGlzIGZpdHRlZCBieSByZXNjYWxpbmcsIG5vdCBieSBncmFkaWVudC4pCiAgbGV0IHBhcmFtZXRlcnMgPSBncC5rZXJuZWwuZ2V0UGFyYW1ldGVycygpLm1hcChwID0+IHAgPT09IDAgPyBlcHNpbG9uIDogcCk7CiAgY29uc3QgbWVhbkdyYWQgPSBuZXcgQXJyYXkocGFyYW1ldGVycy5sZW5ndGgpLmZpbGwoMCk7CiAgY29uc3QgdmFyR3JhZCA9IG5ldyBBcnJheShwYXJhbWV0ZXJzLmxlbmd0aCkuZmlsbCgwKTsKICBjb25zdCB0aW1lU3RhcnQgPSBEYXRlLm5vdygpOwogIGZvciAobGV0IGkgPSAxOyBpIDw9IG1heEl0ZXI7IGkrKykgewogICAgY29uc3QgW3NjYWxlLCBncmFkaWVudHNdID0gc2NhbGVkR3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QoZ3ApOwogICAgbGV0IGhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgPSBmYWxzZTsKICAgIGZvciAobGV0IHAgPSAwOyBwIDwgcGFyYW1ldGVycy5sZW5ndGg7IHArKykgewogICAgICBtZWFuR3JhZFtwXSA9IGJldGExICogbWVhbkdyYWRbcF0gKyAoMSAtIGJldGExKSAqIGdyYWRpZW50c1twXTsKICAgICAgdmFyR3JhZFtwXSA9IGJldGEyICogdmFyR3JhZFtwXSArICgxIC0gYmV0YTIpICogZ3JhZGllbnRzW3BdICogZ3JhZGllbnRzW3BdOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkTWVhbiA9IG1lYW5HcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMSwgaSkpOwogICAgICBjb25zdCBiaWFzQ29ycmVjdGVkVmFyaWFuY2UgPSB2YXJHcmFkW3BdIC8gKDEgLSBNYXRoLnBvdyhiZXRhMiwgaSkpOwogICAgICBjb25zdCBkZWx0YSA9IGxlYXJuaW5nUmF0ZSAqIGJpYXNDb3JyZWN0ZWRNZWFuIC8gKE1hdGguc3FydChiaWFzQ29ycmVjdGVkVmFyaWFuY2UpICsgZXBzaWxvbik7CiAgICAgIGlmIChNYXRoLmFicyhkZWx0YSkgPiBjb252ZXJnZW5jZUZyYWN0aW9uKSBoYWRTaWduaWZpY2FudFByb2dyZXNzID0gdHJ1ZTsKICAgICAgcGFyYW1ldGVyc1twXSAqPSAxICsgZGVsdGE7CiAgICB9CgogICAgLy8gU2V0IHBhcmFtZXRlcnMsIHRoZW4gcmVzY2FsZSB0aGUga2VybmVsIGFuZCBub2lzZSBieSB0aGUgb3B0aW1hbCBzY2FsZS4KICAgIGdwLmtlcm5lbC5zZXRQYXJhbWV0ZXJzKHBhcmFtZXRlcnMpOwogICAgZ3Aua2VybmVsLnJlc2NhbGUoc2NhbGUpOwogICAgZ3Aubm9pc2UgKj0gc2NhbGU7CiAgICAvLyBHZXQgcGFyYW1ldGVycyBiYWNrIGFzIHRoZXkgaGF2ZSBiZWVuIHJlc2NhbGVkIChyZXNjYWxlIGNoYW5nZXMgdGhlCiAgICAvLyBhbXBsaXR1ZGUsIHNvIHRoZSBsb2NhbCBgcGFyYW1ldGVyc2AgbXVzdCBiZSByZWZyZXNoZWQgZnJvbSB0aGUga2VybmVsKS4KICAgIHBhcmFtZXRlcnMgPSBncC5rZXJuZWwuZ2V0UGFyYW1ldGVycygpOwoKICAgIC8vIFJlZml0IHRoZSBtb2RlbC4KICAgIGdwLmNvdm1hdENob2xlc2t5ID0gbWFrZUNob2xlc2t5Q292TWF0cml4KGdwLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCksIGdwLmtlcm5lbCwgZ3Aubm9pc2UsIGdwLmNob2xlc2t5RXBzaWxvbik7CiAgICBpZiAoIWhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgfHwgRGF0ZS5ub3coKSAtIHRpbWVTdGFydCA+IG1heFRpbWUpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgovLyEgR2F1c3NpYW4gcHJvY2Vzcy4KCi8qKiBEZWZhdWx0IG1heGltdW0gZml0dGluZyB0aW1lOiBvbmUgaG91ciwgZXhwcmVzc2VkIGluIG1pbGxpc2Vjb25kcyAoUnVzdCB1c2VzIGNocm9ubzo6RHVyYXRpb246OnNlY29uZHMoMzYwMCkpLiAqLwpjb25zdCBERUZBVUxUX01BWF9USU1FX01TID0gMzYwMCAqIDEwMDA7CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEdhdXNzaWFuUHJvY2VzcwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQSBHYXVzc2lhbiBwcm9jZXNzIHRoYXQgY2FuIGJlIHVzZWQgdG8gbWFrZSBwcmVkaWN0aW9ucyBiYXNlZCBvbiBpdHMgdHJhaW5pbmcKICogZGF0YS4KICoKICogSW50ZXJuYWwgc3RhdGUgKG1pcnJvcnMgdGhlIFJ1c3QgYEdhdXNzaWFuUHJvY2Vzc2Agc3RydWN0LCBgbW9kLnJzOjU5YCk6CiAqICAgLSBgcHJpb3JgICAgICAgICAgICBQcmlvciBpbnN0YW5jZS4KICogICAtIGBrZXJuZWxgICAgICAgICAgIEtlcm5lbCBpbnN0YW5jZS4KICogICAtIGBub2lzZWAgICAgICAgICAgIG51bWJlciDigJQgbm9pc2UgU1RBTkRBUkQgREVWSUFUSU9OIChub3QgdmFyaWFuY2UpLgogKiAgIC0gYGNob2xlc2t5RXBzaWxvbmAgbnVtYmVyIHwgbnVsbCDigJQgc3Vic3RpdHV0ZSBwaXZvdCBmb3IgQ2hvbGVza3kgKG9yIG51bGwpLgogKiAgIC0gYHRyYWluaW5nSW5wdXRzYCAgRXh0ZW5kYWJsZU1hdHJpeC4KICogICAtIGB0cmFpbmluZ091dHB1dHNgIEV4dGVuZGFibGVWZWN0b3Ig4oCUIHN0b3JlcyBgb3V0cHV0cyDiiJIgcHJpb3IoaW5wdXRzKWAgKHRoZSByZXNpZHVhbCEpLgogKiAgIC0gYGNvdm1hdENob2xlc2t5YCAgQ2hvbGVza3lEZWNvbXBvc2l0aW9uIG9mIEsgPSBrZXJuZWwoWCxYKSArIG5vaXNlwrLCt0kuCiAqLwpjbGFzcyBHYXVzc2lhblByb2Nlc3MgewogIC8qKgogICAqIFJhdyBjb25zdHJ1Y3RvciAoYG1vZC5yczoxNDJgKS4gUHJlZmVyIHtAbGluayBHYXVzc2lhblByb2Nlc3MuZGVmYXVsdH0gb3IKICAgKiB7QGxpbmsgR2F1c3NpYW5Qcm9jZXNzLmJ1aWxkZXJ9LgogICAqCiAgICogQHBhcmFtIHtvYmplY3R9ICAgICAgIHByaW9yICAgICAgICAgICAgUHJpb3IgaW5zdGFuY2UuCiAgICogQHBhcmFtIHtvYmplY3R9ICAgICAgIGtlcm5lbCAgICAgICAgICAgS2VybmVsIGluc3RhbmNlLgogICAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICBub2lzZSAgICAgICAgICAgIG5vaXNlIHN0YW5kYXJkIGRldmlhdGlvbiAo4omlIDApLgogICAqIEBwYXJhbSB7bnVtYmVyfG51bGx9ICBjaG9sZXNreUVwc2lsb24gIHN1YnN0aXR1dGUgcGl2b3QgKG9yIG51bGwgdG8gdGhyb3cgb24gZmFpbHVyZSkuCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSB0cmFpbmluZ0lucHV0cyAgcmF3IGlucHV0cy4KICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIHRyYWluaW5nT3V0cHV0cyByYXcgb3V0cHV0cyAoTk9UIHlldCByZXNpZHVhbGlzZWQpLgogICAqLwogIGNvbnN0cnVjdG9yKHByaW9yLCBrZXJuZWwsIG5vaXNlLCBjaG9sZXNreUVwc2lsb24sIHRyYWluaW5nSW5wdXRzLCB0cmFpbmluZ091dHB1dHMpIHsKICAgIGlmICghKG5vaXNlID49IDApKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIG5vaXNlIHBhcmFtZXRlciBzaG91bGQgYmUgbm9uLW5lZ2F0aXZlIGJ1dCB3ZSB0cmllZCB0byBzZXQgaXQgdG8gJHtub2lzZX1gKTsKICAgIH0KCiAgICAvLyBOb3JtYWxpc2UgaW5wdXRzL291dHB1dHMgaW50byBtYXRyaXggLyB2ZWN0b3IgZm9ybSAobWF0Y2hlcyBUOjppbnRvX2RtYXRyaXggLyBpbnRvX2R2ZWN0b3IpLgogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgodHJhaW5pbmdJbnB1dHMpOwogICAgY29uc3Qgb3V0cHV0c1ZlY3RvciA9IHRvVmVjdG9yKHRyYWluaW5nT3V0cHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4Lmxlbmd0aCAhPT0gb3V0cHV0c1ZlY3Rvci5sZW5ndGgpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGB0cmFpbmluZ19pbnB1dHMubnJvd3MoKSAoJHtpbnB1dHNNYXRyaXgubGVuZ3RofSkgIT09IHRyYWluaW5nX291dHB1dHMubnJvd3MoKSAoJHtvdXRwdXRzVmVjdG9yLmxlbmd0aH0pYCk7CiAgICB9CgogICAgLyoqIEB0eXBlIHtvYmplY3R9ICovCiAgICB0aGlzLnByaW9yID0gcHJpb3I7CiAgICAvKiogQHR5cGUge29iamVjdH0gKi8KICAgIHRoaXMua2VybmVsID0ga2VybmVsOwogICAgLyoqIEB0eXBlIHtudW1iZXJ9IG5vaXNlIHN0YW5kYXJkIGRldmlhdGlvbiAqLwogICAgdGhpcy5ub2lzZSA9IG5vaXNlOwogICAgLyoqIEB0eXBlIHtudW1iZXJ8bnVsbH0gKi8KICAgIHRoaXMuY2hvbGVza3lFcHNpbG9uID0gY2hvbGVza3lFcHNpbG9uOwoKICAgIC8vIEV4dGVuZGFibGUgdHJhaW5pbmcgZGF0YS4gdHJhaW5pbmdPdXRwdXRzIGhvbGRzIHRoZSBQUklPUiBSRVNJRFVBTC4KICAgIC8qKiBAdHlwZSB7RXh0ZW5kYWJsZU1hdHJpeH0gKi8KICAgIHRoaXMudHJhaW5pbmdJbnB1dHMgPSBuZXcgRXh0ZW5kYWJsZU1hdHJpeChpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgcHJpb3JWYWx1ZXMgPSBwcmlvci5wcmlvcihpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgcmVzaWR1YWwgPSBuZXcgQXJyYXkob3V0cHV0c1ZlY3Rvci5sZW5ndGgpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRzVmVjdG9yLmxlbmd0aDsgaSsrKSB7CiAgICAgIHJlc2lkdWFsW2ldID0gb3V0cHV0c1ZlY3RvcltpXSAtIHByaW9yVmFsdWVzW2ldOwogICAgfQogICAgLyoqIEB0eXBlIHtFeHRlbmRhYmxlVmVjdG9yfSAqLwogICAgdGhpcy50cmFpbmluZ091dHB1dHMgPSBuZXcgRXh0ZW5kYWJsZVZlY3RvcihyZXNpZHVhbCk7CgogICAgLy8gQ2hvbGVza3kgb2YgdGhlIGNvdmFyaWFuY2UgbWF0cml4IEsgPSBrZXJuZWwoWCxYKSArIG5vaXNlwrLCt0kuCiAgICAvKiogQHR5cGUge2ltcG9ydCgnLi9hbGdlYnJhLm1qcycpLkNob2xlc2t5RGVjb21wb3NpdGlvbn0gKi8KICAgIHRoaXMuY292bWF0Q2hvbGVza3kgPSBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoaW5wdXRzTWF0cml4LCBrZXJuZWwsIG5vaXNlLCBjaG9sZXNreUVwc2lsb24pOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFNUQVRJQyBDT05TVFJVQ1RPUlMKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFJldHVybnMgYSBHYXVzc2lhbiBwcm9jZXNzIHdpdGggYSBHYXVzc2lhbiBrZXJuZWwgYW5kIGEgY29uc3RhbnQgcHJpb3IsCiAgICogYm90aCBmaXR0ZWQgdG8gdGhlIGRhdGEgKGBtb2QucnM6OTZgKS4KICAgKgogICAqIEVxdWl2YWxlbnQgdG8gYGJ1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKS5maXRfa2VybmVsKCkuZml0X3ByaW9yKCkudHJhaW4oKWAuCiAgICoKICAgKiBOb3RlOiBgZGVmYXVsdGAgaXMgYSB2YWxpZCBzdGF0aWMtbWV0aG9kIG5hbWUgaW4gSlMgY2xhc3Nlczsgc2VlCiAgICoge0BsaW5rIEdhdXNzaWFuUHJvY2Vzcy5mcm9tRGF0YX0gZm9yIGEgc2FmZSBhbGlhcy4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICBvdXRwdXRzCiAgICogQHJldHVybnMge0dhdXNzaWFuUHJvY2Vzc30KICAgKi8KICBzdGF0aWMgZGVmYXVsdChpbnB1dHMsIG91dHB1dHMpIHsKICAgIHJldHVybiBHYXVzc2lhblByb2Nlc3MuYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpLmZpdEtlcm5lbCgpLmZpdFByaW9yKCkudHJhaW4oKTsKICB9CgogIC8qKgogICAqIFNhZmUgYWxpYXMgb2Yge0BsaW5rIEdhdXNzaWFuUHJvY2Vzcy5kZWZhdWx0fSAoaW4gY2FzZSBhIHRvb2xjaGFpbiBkaXNsaWtlcwogICAqIHRoZSBgZGVmYXVsdGAgbWV0aG9kIG5hbWUpLiBJZGVudGljYWwgYmVoYXZpb3VyLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIG91dHB1dHMKICAgKiBAcmV0dXJucyB7R2F1c3NpYW5Qcm9jZXNzfQogICAqLwogIHN0YXRpYyBmcm9tRGF0YShpbnB1dHMsIG91dHB1dHMpIHsKICAgIHJldHVybiBHYXVzc2lhblByb2Nlc3MuZGVmYXVsdChpbnB1dHMsIG91dHB1dHMpOwogIH0KCiAgLyoqCiAgICogUmV0dXJucyBhIGJ1aWxkZXIgdG8gZGVmaW5lIHNwZWNpZmljIHBhcmFtZXRlcnMgb2YgdGhlIEdhdXNzaWFuIHByb2Nlc3MKICAgKiAoYG1vZC5yczoxMjlgKS4gRGVmYXVsdHMgdG8gYSBHYXVzc2lhbiBrZXJuZWwgKyBjb25zdGFudCBwcmlvci4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICBvdXRwdXRzCiAgICogQHJldHVybnMge0dhdXNzaWFuUHJvY2Vzc0J1aWxkZXJ9CiAgICovCiAgc3RhdGljIGJ1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICByZXR1cm4gbmV3IEdhdXNzaWFuUHJvY2Vzc0J1aWxkZXIoaW5wdXRzLCBvdXRwdXRzKTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBBREQgU0FNUExFUwogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogQWRkcyBuZXcgc2FtcGxlcyB0byB0aGUgbW9kZWwgKGBtb2QucnM6MTczYCkuCiAgICoKICAgKiBVcGRhdGVzIHRoZSBtb2RlbCBpbiBPKG7CsikgKGZhc3RlciB0aGFuIHJldHJhaW5pbmcgZnJvbSBzY3JhdGNoKSBidXQgZG9lcwogICAqIE5PVCByZWZpdCB0aGUgcGFyYW1ldGVycy4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICBvdXRwdXRzCiAgICovCiAgYWRkX3NhbXBsZXMoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgY29uc3Qgb3V0cHV0c1ZlY3RvciA9IHRvVmVjdG9yKG91dHB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeC5sZW5ndGggIT09IG91dHB1dHNWZWN0b3IubGVuZ3RoKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5yb3dzKCkgKCR7aW5wdXRzTWF0cml4Lmxlbmd0aH0pICE9PSBvdXRwdXRzLm5yb3dzKCkgKCR7b3V0cHV0c1ZlY3Rvci5sZW5ndGh9KWApOwogICAgfQogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQoKICAgIC8vIFJlc2lkdWFsaXNlIHRoZSBuZXcgb3V0cHV0cyBhZ2FpbnN0IHRoZSBjdXJyZW50IHByaW9yLgogICAgY29uc3QgcHJpb3JWYWx1ZXMgPSB0aGlzLnByaW9yLnByaW9yKGlucHV0c01hdHJpeCk7CiAgICBjb25zdCByZXNpZHVhbCA9IG5ldyBBcnJheShvdXRwdXRzVmVjdG9yLmxlbmd0aCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dHNWZWN0b3IubGVuZ3RoOyBpKyspIHsKICAgICAgcmVzaWR1YWxbaV0gPSBvdXRwdXRzVmVjdG9yW2ldIC0gcHJpb3JWYWx1ZXNbaV07CiAgICB9CgogICAgLy8gR3JvdyB0aGUgdHJhaW5pbmcgZGF0YS4KICAgIHRoaXMudHJhaW5pbmdJbnB1dHMuYWRkUm93cyhpbnB1dHNNYXRyaXgpOwogICAgdGhpcy50cmFpbmluZ091dHB1dHMuYWRkUm93cyhyZXNpZHVhbCk7CgogICAgLy8gSW5jcmVtZW50YWxseSBleHRlbmQgdGhlIENob2xlc2t5IGRlY29tcG9zaXRpb24gd2l0aCB0aGUgbmV3IHJvd3MuCiAgICBjb25zdCBuYk5ld0lucHV0cyA9IGlucHV0c01hdHJpeC5sZW5ndGg7CiAgICBhZGRSb3dzQ2hvbGVza3lDb3ZNYXRyaXgodGhpcy5jb3ZtYXRDaG9sZXNreSwgdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpLCBuYk5ld0lucHV0cywgdGhpcy5rZXJuZWwsIHRoaXMubm9pc2UpOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIExJS0VMSUhPT0QKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIExvZyBsaWtlbGlob29kIG9mIHRoZSBjdXJyZW50IG1vZGVsIGdpdmVuIHRoZSB0cmFpbmluZyBkYXRhIChgbW9kLnJzOjE5NmApLgogICAqCiAgICogRm9ybXVsYToKICAgKiAgIOKIksK9ICggb3V0cHV04bWAwrdL4oG7wrnCt291dHB1dCArIM6jX3IgbG58a2VybmVsKHjhtaMseOG1oykgKyBub2lzZcKyfCArIG7Ct2xuKDLPgCkgKQogICAqCiAgICogd2hlcmUgYG91dHB1dGAgaXMgdGhlIHByaW9yIHJlc2lkdWFsLgogICAqCiAgICogQHJldHVybnMge251bWJlcn0KICAgKi8KICBsaWtlbGlob29kKCkgewogICAgY29uc3Qgb3V0cHV0ID0gdGhpcy50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsgLy8gcmVzaWR1YWwKICAgIGNvbnN0IEwgPSB0aGlzLmNvdm1hdENob2xlc2t5LmwoKTsKCiAgICAvLyB0cmFuc3Bvc2Uob2wpwrdvbCA9IG91dHB1dOG1gMK3S+KBu8K5wrdvdXRwdXQsIHdoZXJlIEzCt29sID0gb3V0cHV0LgogICAgY29uc3Qgb2wgPSBzb2x2ZUxvd2VyVHJpKEwsIG91dHB1dCk7CiAgICBjb25zdCBkYXRhRml0ID0gbm9ybVNxdWFyZWQob2wpOwoKICAgIC8vIENvbXBsZXhpdHkgcGVuYWx0eTogzqMgbG58IHNlbGYtY292YXJpYW5jZSArIG5vaXNlwrIgfC4KICAgIGNvbnN0IGlucHV0cyA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKICAgIGNvbnN0IG5vaXNlU3EgPSB0aGlzLm5vaXNlICogdGhpcy5ub2lzZTsKICAgIGxldCBjb21wbGV4aXR5UGVuYWx0eSA9IDA7CiAgICBmb3IgKGxldCByID0gMDsgciA8IGlucHV0cy5sZW5ndGg7IHIrKykgewogICAgICBjb25zdCBzZWxmQ292ID0gdGhpcy5rZXJuZWwua2VybmVsKGlucHV0c1tyXSwgaW5wdXRzW3JdKSArIG5vaXNlU3E7CiAgICAgIGNvbXBsZXhpdHlQZW5hbHR5ICs9IE1hdGgubG9nKE1hdGguYWJzKHNlbGZDb3YpKTsKICAgIH0KICAgIGNvbnN0IG4gPSBpbnB1dHMubGVuZ3RoOwogICAgY29uc3Qgbm9ybWFsaXphdGlvbkNvbnN0YW50ID0gbiAqIE1hdGgubG9nKDIgKiBNYXRoLlBJKTsKICAgIHJldHVybiAtKGRhdGFGaXQgKyBjb21wbGV4aXR5UGVuYWx0eSArIG5vcm1hbGl6YXRpb25Db25zdGFudCkgLyAyOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFBSRURJQ1QKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFByZWRpY3RzIHRoZSBtZWFuIG9mIHRoZSBHYXVzc2lhbiBwcm9jZXNzIGZvciBlYWNoIHJvdyBvZiBgaW5wdXRzYAogICAqIChgbW9kLnJzOjIyNmApLgogICAqCiAgICogRm9ybXVsYTogYHByaW9yICsgY292KGlucHV0LHRyYWluKcK3S+KBu8K5wrdvdXRwdXRgLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcmV0dXJucyB7bnVtYmVyfG51bWJlcltdfSBudW1iZXIgZm9yIGEgc2luZ2xlLXBvaW50IGlucHV0LCBudW1iZXJbXSBvdGhlcndpc2UuCiAgICovCiAgcHJlZGljdChpbnB1dHMpIHsKICAgIGNvbnN0IHNpbmdsZSA9IGlzU2luZ2xlKGlucHV0cyk7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQogICAgY29uc3QgdHJhaW5NYXRyaXggPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CgogICAgLy8gd2VpZ2h0cyAoblRyYWluIMOXIG5JbnB1dCkgPSBL4oG7wrkgwrcgY292KHRyYWluLCBpbnB1dHMpLgogICAgbGV0IHdlaWdodHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICB3ZWlnaHRzID0gdGhpcy5jb3ZtYXRDaG9sZXNreS5zb2x2ZSh3ZWlnaHRzKTsKICAgIGNvbnN0IG1lYW4gPSB0aGlzLl9tZWFuRnJvbVdlaWdodHMod2VpZ2h0cywgaW5wdXRzTWF0cml4KTsKICAgIHJldHVybiBmcm9tVmVjdG9yKG1lYW4sIHNpbmdsZSk7CiAgfQoKICAvKioKICAgKiBQcmVkaWN0cyB0aGUgdmFyaWFuY2Ugb2YgdGhlIEdhdXNzaWFuIHByb2Nlc3MgZm9yIGVhY2ggcm93IG9mIGBpbnB1dHNgCiAgICogKGBtb2QucnM6MjQ4YCkuCiAgICoKICAgKiBGb3JtdWxhIChkaWFnb25hbCBvZik6CiAgICogICBjb3YoaW5wdXQsaW5wdXQpIOKIkiBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt2Nvdih0cmFpbixpbnB1dCkKICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge251bWJlcnxudW1iZXJbXX0KICAgKi8KICBwcmVkaWN0X3ZhcmlhbmNlKGlucHV0cykgewogICAgY29uc3Qgc2luZ2xlID0gaXNTaW5nbGUoaW5wdXRzKTsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KGlucHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4WzBdLmxlbmd0aCAhPT0gdGhpcy50cmFpbmluZ0lucHV0cy5uY29scykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5uY29scygpICgke2lucHV0c01hdHJpeFswXS5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfaW5wdXRzLm5jb2xzKCkgKCR7dGhpcy50cmFpbmluZ0lucHV0cy5uY29sc30pYCk7CiAgICB9CiAgICBjb25zdCB0cmFpbk1hdHJpeCA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKCiAgICAvLyBjb3ZfdHJhaW5faW5wdXRzIChuVHJhaW4gw5cgbklucHV0KS4KICAgIGNvbnN0IGNvdlRyYWluSW5wdXRzID0gbWFrZUNvdmFyaWFuY2VNYXRyaXgodHJhaW5NYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwoKICAgIC8vIGtsID0gTOKBu8K5IMK3IGNvdl90cmFpbl9pbnB1dHMgIChzb2x2ZSBMwrdrbCA9IGNvdl90cmFpbl9pbnB1dHMpLgogICAgY29uc3Qga2wgPSBzb2x2ZUxvd2VyVHJpKHRoaXMuY292bWF0Q2hvbGVza3kubCgpLCBjb3ZUcmFpbklucHV0cyk7CgogICAgLy8gdmFyaWFuY2VbaV0gPSBrZXJuZWwoaW5wdXThtaIsaW5wdXThtaIpIOKIkiDigJZjb2x1bW4gaSBvZiBrbOKAlsKyLgogICAgY29uc3QgbklucHV0ID0gaW5wdXRzTWF0cml4Lmxlbmd0aDsKICAgIGNvbnN0IHZhcmlhbmNlcyA9IG5ldyBBcnJheShuSW5wdXQpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSW5wdXQ7IGkrKykgewogICAgICBjb25zdCBiYXNlQ292ID0gdGhpcy5rZXJuZWwua2VybmVsKGlucHV0c01hdHJpeFtpXSwgaW5wdXRzTWF0cml4W2ldKTsKICAgICAgY29uc3QgcHJlZGljdGVkQ292ID0gY29sdW1uTm9ybVNxdWFyZWQoa2wsIGkpOwogICAgICB2YXJpYW5jZXNbaV0gPSBiYXNlQ292IC0gcHJlZGljdGVkQ292OwogICAgfQogICAgcmV0dXJuIGZyb21WZWN0b3IodmFyaWFuY2VzLCBzaW5nbGUpOwogIH0KCiAgLyoqCiAgICogUHJlZGljdHMgYm90aCB0aGUgbWVhbiBhbmQgdGhlIHZhcmlhbmNlIGZvciBlYWNoIHJvdyBvZiBgaW5wdXRzYAogICAqIChgbW9kLnJzOjI5MGApLiBGYXN0ZXIgdGhhbiBjYWxsaW5nIGBwcmVkaWN0YCBhbmQgYHByZWRpY3RfdmFyaWFuY2VgCiAgICogc2VwYXJhdGVseS4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge1tudW1iZXJ8bnVtYmVyW10sIG51bWJlcnxudW1iZXJbXV19IGBbbWVhbiwgdmFyaWFuY2VdYC4KICAgKi8KICBwcmVkaWN0X21lYW5fdmFyaWFuY2UoaW5wdXRzKSB7CiAgICBjb25zdCBzaW5nbGUgPSBpc1NpbmdsZShpbnB1dHMpOwogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgIC8vIGNvdl90cmFpbl9pbnB1dHMgKG5UcmFpbiDDlyBuSW5wdXQpOyAgd2VpZ2h0cyA9IEvigbvCuSDCtyBjb3ZfdHJhaW5faW5wdXRzLgogICAgY29uc3QgY292VHJhaW5JbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICBjb25zdCB3ZWlnaHRzID0gdGhpcy5jb3ZtYXRDaG9sZXNreS5zb2x2ZShjb3ZUcmFpbklucHV0cyk7CgogICAgLy8gLS0tLS0gbWVhbiAtLS0tLQogICAgY29uc3QgbWVhblZlYyA9IHRoaXMuX21lYW5Gcm9tV2VpZ2h0cyh3ZWlnaHRzLCBpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgbWVhbiA9IGZyb21WZWN0b3IobWVhblZlYywgc2luZ2xlKTsKCiAgICAvLyAtLS0tLSB2YXJpYW5jZSAtLS0tLQogICAgLy8gdmFyaWFuY2VbaV0gPSBrZXJuZWwoaW5wdXThtaIsaW5wdXThtaIpIOKIkiAoY29sdW1uIGkgb2YgY292X3RyYWluX2lucHV0cynCtyhjb2x1bW4gaSBvZiB3ZWlnaHRzKS4KICAgIGNvbnN0IG5JbnB1dCA9IGlucHV0c01hdHJpeC5sZW5ndGg7CiAgICBjb25zdCB2YXJpYW5jZXMgPSBuZXcgQXJyYXkobklucHV0KTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbklucHV0OyBpKyspIHsKICAgICAgY29uc3QgYmFzZUNvdiA9IHRoaXMua2VybmVsLmtlcm5lbChpbnB1dHNNYXRyaXhbaV0sIGlucHV0c01hdHJpeFtpXSk7CiAgICAgIGNvbnN0IHByZWRpY3RlZENvdiA9IGNvbHVtbkRvdChjb3ZUcmFpbklucHV0cywgd2VpZ2h0cywgaSk7CiAgICAgIHZhcmlhbmNlc1tpXSA9IGJhc2VDb3YgLSBwcmVkaWN0ZWRDb3Y7CiAgICB9CiAgICBjb25zdCB2YXJpYW5jZSA9IGZyb21WZWN0b3IodmFyaWFuY2VzLCBzaW5nbGUpOwogICAgcmV0dXJuIFttZWFuLCB2YXJpYW5jZV07CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBmdWxsIGNvdmFyaWFuY2UgbWF0cml4IGZvciB0aGUgcm93cyBvZiBgaW5wdXRzYCAoYG1vZC5yczozMjlgKS4KICAgKgogICAqIEZvcm11bGE6CiAgICogICBjb3YoaW5wdXQsaW5wdXQpIOKIkiBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt2Nvdih0cmFpbixpbnB1dCkKICAgKgogICAqIEFMV0FZUyByZXR1cm5zIGEgYG51bWJlcltdW11gIG1hdHJpeCAobmV2ZXIgc2NhbGFyaXNlZCDigJQgbWF0Y2hlcyBSdXN0IHdoaWNoCiAgICogYWx3YXlzIHJldHVybnMgYSBgRE1hdHJpeGApLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcmV0dXJucyB7bnVtYmVyW11bXX0gKG5JbnB1dCDDlyBuSW5wdXQpCiAgICovCiAgcHJlZGljdF9jb3ZhcmlhbmNlKGlucHV0cykgewogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwogICAgY29uc3QgY292VHJhaW5JbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICBjb25zdCBjb3ZJbnB1dHNJbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeChpbnB1dHNNYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwoKICAgIC8vIGtsID0gTOKBu8K5IMK3IGNvdl90cmFpbl9pbnB1dHMuCiAgICBjb25zdCBrbCA9IHNvbHZlTG93ZXJUcmkodGhpcy5jb3ZtYXRDaG9sZXNreS5sKCksIGNvdlRyYWluSW5wdXRzKTsKCiAgICAvLyByZXN1bHQgPSBjb3ZfaW5wdXRzX2lucHV0cyDiiJIga2zhtYDCt2tsICAgKG1hdGNoZXMgZ2VtbV90cigtMSwga2wsIGtsLCAxKSkuCiAgICBjb25zdCBrbHRfa2wgPSBtYXRNdWwodHJhbnNwb3NlKGtsKSwga2wpOwogICAgcmV0dXJuIG1hdFN1Yihjb3ZJbnB1dHNJbnB1dHMsIGtsdF9rbCk7CiAgfQoKICAvKioKICAgKiBQcm9kdWNlcyBhIG11bHRpdmFyaWF0ZSBHYXVzc2lhbiB0aGF0IGNhbiBiZSBzYW1wbGVkIGF0IHRoZSBpbnB1dCBwb2ludHMKICAgKiAoYG1vZC5yczozNzFgKS4KICAgKgogICAqIENvdmFyaWFuY2U6CiAgICogICBjb3YoaW5wdXQsaW5wdXQpIOKIkiBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt2Nvdih0cmFpbixpbnB1dCkKICAgKiBNZWFuOgogICAqICAgcHJpb3IgKyBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt291dHB1dAogICAqCiAgICogVGhlIHJldHVybmVkIHtAbGluayBNdWx0aXZhcmlhdGVOb3JtYWx9IGhhcyBhIGAuc2FtcGxlKHJuZylgIG1ldGhvZCB3aGVyZQogICAqIGBybmdgIGlzIGEgYCgpID0+IG51bWJlciDiiIggWzAsMSlgIChlLmcuIGZyb20gYG11bGJlcnJ5MzJgKS4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHJldHVybnMge011bHRpdmFyaWF0ZU5vcm1hbH0KICAgKi8KICBzYW1wbGVfYXQoaW5wdXRzKSB7CiAgICBjb25zdCBzaW5nbGUgPSBpc1NpbmdsZShpbnB1dHMpOwogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgIC8vIHdlaWdodHMgPSBL4oG7wrkgwrcgY292KHRyYWluLCBpbnB1dHMpLgogICAgY29uc3QgY292VHJhaW5JbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICBjb25zdCB3ZWlnaHRzID0gdGhpcy5jb3ZtYXRDaG9sZXNreS5zb2x2ZShjb3ZUcmFpbklucHV0cyk7CgogICAgLy8gY292ID0gY292KGlucHV0LGlucHV0KSDiiJIgY292X3RyYWluX2lucHV0c+G1gMK3d2VpZ2h0cyAgKGdlbW1fdHIoLTEsIGNvdlRyYWluSW5wdXRzLCB3ZWlnaHRzLCAxKSkuCiAgICBjb25zdCBjb3ZJbnB1dHNJbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeChpbnB1dHNNYXRyaXgsIGlucHV0c01hdHJpeCwgdGhpcy5rZXJuZWwpOwogICAgY29uc3QgY3RfdyA9IG1hdE11bCh0cmFuc3Bvc2UoY292VHJhaW5JbnB1dHMpLCB3ZWlnaHRzKTsKICAgIGNvbnN0IGNvdiA9IG1hdFN1Yihjb3ZJbnB1dHNJbnB1dHMsIGN0X3cpOwoKICAgIC8vIG1lYW4gPSBwcmlvciArIHdlaWdodHPhtYDCt3RyYWluaW5nT3V0cHV0cy4KICAgIGNvbnN0IG1lYW4gPSB0aGlzLl9tZWFuRnJvbVdlaWdodHMod2VpZ2h0cywgaW5wdXRzTWF0cml4KTsKICAgIHJldHVybiBuZXcgTXVsdGl2YXJpYXRlTm9ybWFsKG1lYW4sIGNvdiwgc2luZ2xlKTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBGSVQKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIEZpdHMgdGhlIHJlcXVlc3RlZCBwYXJhbWV0ZXJzIGFuZCByZXRyYWlucyB0aGUgbW9kZWwgKGBtb2QucnM6NDA2YCkuCiAgICoKICAgKiBOb2lzZSBhbmQga2VybmVsIHBhcmFtZXRlcnMgYXJlIGZpdHRlZCBieSBncmFkaWVudCBhc2NlbnQgKEFEQU0pIG9uIHRoZQogICAqIG1hcmdpbmFsIGxvZy1saWtlbGlob29kLiBSdW5zIGZvciBhdCBtb3N0IGBtYXhJdGVyYCBpdGVyYXRpb25zLCBzdG9wcGluZwogICAqIGVhcmx5IHdoZW4gYWxsIGdyYWRpZW50cyBhcmUgYmVsb3cgYGNvbnZlcmdlbmNlRnJhY3Rpb25gwrdwYXJhbSBvciBhZnRlcgogICAqIGBtYXhUaW1lYC4KICAgKgogICAqIEBwYXJhbSB7Ym9vbGVhbn0gZml0UHJpb3IgICAgICAgICAgICAgIGZpdCB0aGUgcHJpb3IgdG8gdGhlIGRhdGEuCiAgICogQHBhcmFtIHtib29sZWFufSBmaXRLZXJuZWwgICAgICAgICAgICAgZml0IHRoZSBrZXJuZWwgKGFuZCBub2lzZSkgcGFyYW1ldGVycy4KICAgKiBAcGFyYW0ge251bWJlcn0gIG1heEl0ZXIgICAgICAgICAgICAgICBtYXggZ3JhZGllbnQtYXNjZW50IGl0ZXJhdGlvbnMuCiAgICogQHBhcmFtIHtudW1iZXJ9ICBjb252ZXJnZW5jZUZyYWN0aW9uICAgcmVsYXRpdmUgY29udmVyZ2VuY2UgdGhyZXNob2xkLgogICAqIEBwYXJhbSB7bnVtYmVyfSBbbWF4VGltZT0zNjAwMDAwXSAgICAgIG1heCBmaXR0aW5nIHRpbWUgaW4gTUlMTElTRUNPTkRTCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFJ1c3QgdXNlcyBjaHJvbm86OkR1cmF0aW9uIHNlY29uZHMpLgogICAqLwogIGZpdF9wYXJhbWV0ZXJzKGZpdFByaW9yLCBmaXRLZXJuZWwsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUgPSBERUZBVUxUX01BWF9USU1FX01TKSB7CiAgICBpZiAoZml0UHJpb3IpIHsKICAgICAgY29uc3QgaW5wdXRzID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgICAgLy8gUmVjb3ZlciB0aGUgb3JpZ2luYWwgKHJhdykgb3V0cHV0czogcmVzaWR1YWwgKyBwcmlvcl9vbGQoaW5wdXRzKS4KICAgICAgY29uc3QgcmVzaWR1YWxPbGQgPSB0aGlzLnRyYWluaW5nT3V0cHV0cy5hc1ZlY3RvcigpOwogICAgICBjb25zdCBwcmlvck9sZCA9IHRoaXMucHJpb3IucHJpb3IoaW5wdXRzKTsKICAgICAgY29uc3Qgb3JpZ2luYWxPdXRwdXRzID0gbmV3IEFycmF5KHJlc2lkdWFsT2xkLmxlbmd0aCk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzaWR1YWxPbGQubGVuZ3RoOyBpKyspIHsKICAgICAgICBvcmlnaW5hbE91dHB1dHNbaV0gPSByZXNpZHVhbE9sZFtpXSArIHByaW9yT2xkW2ldOwogICAgICB9CgogICAgICAvLyBSZWZpdCB0aGUgcHJpb3Igb24gdGhlIHJhdyBvdXRwdXRzLgogICAgICB0aGlzLnByaW9yLmZpdChpbnB1dHMsIG9yaWdpbmFsT3V0cHV0cyk7CgogICAgICAvLyBSZS1yZXNpZHVhbGlzZSBhZ2FpbnN0IHRoZSBuZXcgcHJpb3IgYW5kIHN0b3JlIGJhY2suCiAgICAgIGNvbnN0IHByaW9yTmV3ID0gdGhpcy5wcmlvci5wcmlvcihpbnB1dHMpOwogICAgICBjb25zdCByZXNpZHVhbE5ldyA9IG5ldyBBcnJheShvcmlnaW5hbE91dHB1dHMubGVuZ3RoKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmlnaW5hbE91dHB1dHMubGVuZ3RoOyBpKyspIHsKICAgICAgICByZXNpZHVhbE5ld1tpXSA9IG9yaWdpbmFsT3V0cHV0c1tpXSAtIHByaW9yTmV3W2ldOwogICAgICB9CiAgICAgIHRoaXMudHJhaW5pbmdPdXRwdXRzLmFzc2lnbihyZXNpZHVhbE5ldyk7CgogICAgICAvLyBJZiB0aGUga2VybmVsIGlzIE5PVCBiZWluZyBmaXR0ZWQsIHJldHJhaW4gdGhlIGNvdmFyaWFuY2UgQ2hvbGVza3kKICAgICAgLy8gZnJvbSBzY3JhdGNoICh0aGUgcmVzaWR1YWxzIGNoYW5nZWQpLiBXaGVuIGZpdEtlcm5lbCBpcyB0cnVlIHRoZQogICAgICAvLyBvcHRpbWl6ZXIgcmVidWlsZHMgaXQgYW55d2F5LgogICAgICBpZiAoIWZpdEtlcm5lbCkgewogICAgICAgIHRoaXMuY292bWF0Q2hvbGVza3kgPSBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoaW5wdXRzLCB0aGlzLmtlcm5lbCwgdGhpcy5ub2lzZSwgdGhpcy5jaG9sZXNreUVwc2lsb24pOwogICAgICB9CiAgICB9CiAgICBpZiAoZml0S2VybmVsKSB7CiAgICAgIGlmICh0aGlzLmtlcm5lbC5pc1NjYWxhYmxlKCkpIHsKICAgICAgICBzY2FsZWRPcHRpbWl6ZVBhcmFtZXRlcnModGhpcywgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb3B0aW1pemVQYXJhbWV0ZXJzKHRoaXMsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpOwogICAgICB9CiAgICB9CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gSU5URVJOQUwgSEVMUEVSUwogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogQ29tcHV0ZXMgdGhlIHBvc3RlcmlvciBtZWFuIGBwcmlvciArIHdlaWdodHPhtYDCt3RyYWluaW5nT3V0cHV0c2AsIGkuZS4KICAgKiBgbWVhbltpXSA9IHByaW9yKGlucHV0cylbaV0gKyDOo190IHdlaWdodHNbdF1baV3Ct3RyYWluaW5nT3V0cHV0c1t0XWAuCiAgICoKICAgKiBUaGlzIHJlcHJvZHVjZXMgbmFsZ2VicmEgYHByaW9yLmdlbW1fdHIoMSwgd2VpZ2h0cywgdHJhaW5pbmdPdXRwdXRzLCAxKWAsCiAgICogd2hlcmUgYHdlaWdodHNgIGlzIChuVHJhaW4gw5cgbklucHV0KSwgYHRyYWluaW5nT3V0cHV0c2AgaXMgdGhlIHJlc2lkdWFsCiAgICogdmVjdG9yIChsZW5ndGggblRyYWluKSwgYW5kIHRoZSByZXN1bHQgaGFzIGxlbmd0aCBuSW5wdXQuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdW119IHdlaWdodHMgICAgICAoblRyYWluIMOXIG5JbnB1dCkKICAgKiBAcGFyYW0ge251bWJlcltdW119IGlucHV0c01hdHJpeCAobklucHV0IMOXIGQpCiAgICogQHJldHVybnMge251bWJlcltdfSBwb3N0ZXJpb3IgbWVhbiAobGVuZ3RoIG5JbnB1dCksIHByaW9yIGFscmVhZHkgYWRkZWQuCiAgICogQHByaXZhdGUKICAgKi8KICBfbWVhbkZyb21XZWlnaHRzKHdlaWdodHMsIGlucHV0c01hdHJpeCkgewogICAgY29uc3QgbklucHV0ID0gaW5wdXRzTWF0cml4Lmxlbmd0aDsKICAgIGNvbnN0IG5UcmFpbiA9IHdlaWdodHMubGVuZ3RoOwogICAgY29uc3Qgb3V0cHV0cyA9IHRoaXMudHJhaW5pbmdPdXRwdXRzLmFzVmVjdG9yKCk7IC8vIHJlc2lkdWFsCiAgICBjb25zdCBwcmlvclZlYyA9IHRoaXMucHJpb3IucHJpb3IoaW5wdXRzTWF0cml4KTsKICAgIGNvbnN0IG1lYW4gPSBuZXcgQXJyYXkobklucHV0KTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbklucHV0OyBpKyspIHsKICAgICAgbGV0IHMgPSBwcmlvclZlY1tpXTsKICAgICAgZm9yIChsZXQgdCA9IDA7IHQgPCBuVHJhaW47IHQrKykgewogICAgICAgIHMgKz0gd2VpZ2h0c1t0XVtpXSAqIG91dHB1dHNbdF07CiAgICAgIH0KICAgICAgbWVhbltpXSA9IHM7CiAgICB9CiAgICByZXR1cm4gbWVhbjsKICB9Cn0KCi8vIE1peGluIHRoZSBvcHRpbWl6ZXIgZnJlZS1mdW5jdGlvbnMgb250byB0aGUgcHJvdG90eXBlIHNvIHRoZXkgYXJlIGFsc28KLy8gcmVhY2hhYmxlIGFzIG1ldGhvZHMgKGUuZy4gYGdwLm9wdGltaXplUGFyYW1ldGVycyguLi4pYCkuIGBmaXRfcGFyYW1ldGVyc2AKLy8gYWJvdmUgY2FsbHMgdGhlIGltcG9ydGVkIGZyZWUgZnVuY3Rpb25zIGRpcmVjdGx5OyB0aGVzZSBhbGlhc2VzIGp1c3Qga2VlcCB0aGUKLy8gc3VyZmFjZSBjb25zaXN0ZW50IHdpdGggUE9SVF9TUEVDIMKnNyAoImltcG9ydCB0aGVuIGNhbGwgYXMgbWV0aG9kcyIpLgpHYXVzc2lhblByb2Nlc3MucHJvdG90eXBlLm9wdGltaXplUGFyYW1ldGVycyA9IGZ1bmN0aW9uIChtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKSB7CiAgcmV0dXJuIG9wdGltaXplUGFyYW1ldGVycyh0aGlzLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKTsKfTsKR2F1c3NpYW5Qcm9jZXNzLnByb3RvdHlwZS5zY2FsZWRPcHRpbWl6ZVBhcmFtZXRlcnMgPSBmdW5jdGlvbiAobWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSkgewogIHJldHVybiBzY2FsZWRPcHRpbWl6ZVBhcmFtZXRlcnModGhpcywgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSk7Cn07CkdhdXNzaWFuUHJvY2Vzcy5wcm90b3R5cGUuZ3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QgPSBmdW5jdGlvbiAoKSB7CiAgcmV0dXJuIGdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKHRoaXMpOwp9OwpHYXVzc2lhblByb2Nlc3MucHJvdG90eXBlLnNjYWxlZEdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kID0gZnVuY3Rpb24gKCkgewogIHJldHVybiBzY2FsZWRHcmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZCh0aGlzKTsKfTsKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gR2F1c3NpYW5Qcm9jZXNzQnVpbGRlcgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQnVpbGRlciB0byBzZXQgdGhlIHBhcmFtZXRlcnMgb2YgYSBHYXVzc2lhbiBwcm9jZXNzIChgYnVpbGRlci5yc2ApLgogKgogKiBDaGFpbmFibGUgc2V0dGVycyBjdWxtaW5hdGluZyBpbiBgdHJhaW4oKWAuIFByb2R1Y2VkIGJ5CiAqIGBHYXVzc2lhblByb2Nlc3MuYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpYC4KICoKICogRGVmYXVsdHMgKGBidWlsZGVyLnJzOjY2YCk6CiAqICAgLSBjb25zdGFudCBwcmlvciAoMCB1bmxlc3MgZml0dGVkKQogKiAgIC0gYSBHYXVzc2lhbiBrZXJuZWwKICogICAtIG5vaXNlID0gMTAlIG9mIHRoZSBvdXRwdXQgc3RhbmRhcmQgZGV2aWF0aW9uCiAqICAgLSBkb2VzIG5vdCBmaXQgYW55IHBhcmFtZXRlcnMKICogICAtIGZpdCBydW5zIGZvciDiiaQgMTAwIGl0ZXJhdGlvbnMgLyAxIGhvdXIgdW5sZXNzIGFsbCBncmFkaWVudHMgYXJlIGJlbG93IDUlLgogKgogKiBTZXR0ZXJzIG11dGF0ZSBhbmQgcmV0dXJuIGB0aGlzYCAoUnVzdCByZXR1cm5zIGEgbmV3IHR5cGVkIGJ1aWxkZXI7IGZvciBKUyB3ZQogKiBrZWVwIGEgc2luZ2xlIG11dGFibGUgYnVpbGRlciDigJQgYmVoYXZpb3VyIGlzIGlkZW50aWNhbCBmb3IgdGhlIGZsdWVudCBBUEkpLgogKi8KY2xhc3MgR2F1c3NpYW5Qcm9jZXNzQnVpbGRlciB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSB0cmFpbmluZ0lucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSAgICAgdHJhaW5pbmdPdXRwdXRzCiAgICovCiAgY29uc3RydWN0b3IodHJhaW5pbmdJbnB1dHMsIHRyYWluaW5nT3V0cHV0cykgewogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgodHJhaW5pbmdJbnB1dHMpOwogICAgY29uc3Qgb3V0cHV0c1ZlY3RvciA9IHRvVmVjdG9yKHRyYWluaW5nT3V0cHV0cyk7CgogICAgLyoqIEB0eXBlIHtudW1iZXJbXVtdfSAqLwogICAgdGhpcy50cmFpbmluZ0lucHV0cyA9IGlucHV0c01hdHJpeDsKICAgIC8qKiBAdHlwZSB7bnVtYmVyW119ICovCiAgICB0aGlzLnRyYWluaW5nT3V0cHV0cyA9IG91dHB1dHNWZWN0b3I7CgogICAgLy8gRGVmYXVsdCBwcmlvcjogQ29uc3RhbnRQcmlvcigwKSAoZGltIGlzIGlnbm9yZWQgYnkgQ29uc3RhbnRQcmlvcikuCiAgICAvKiogQHR5cGUge29iamVjdH0gKi8KICAgIHRoaXMucHJpb3IgPSBDb25zdGFudFByaW9yLmRlZmF1bHQoaW5wdXRzTWF0cml4Lmxlbmd0aCA9PT0gMCA/IDAgOiBpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoKTsKICAgIC8vIERlZmF1bHQga2VybmVsOiBHYXVzc2lhbiAvIFNxdWFyZWRFeHAgd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMuCiAgICAvKiogQHR5cGUge29iamVjdH0gKi8KICAgIHRoaXMua2VybmVsID0gbmV3IEdhdXNzaWFuKCk7CiAgICAvLyBEZWZhdWx0IG5vaXNlOiAxMCUgb2YgdGhlIG91dHB1dCBzdGFuZGFyZCBkZXZpYXRpb24uCiAgICAvLyAgIHJvd192YXJpYW5jZShvdXRwdXRzKVswXSA9IM6jKHnhtaLiiJLIsynCsi9OICAoZGl2aWRlIGJ5IE4g4oCUIHNlZSBmaXRBbXBsaXR1ZGVWYXIpLgogICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovCiAgICB0aGlzLm5vaXNlID0gMC4xICogTWF0aC5zcXJ0KGZpdEFtcGxpdHVkZVZhcihvdXRwdXRzVmVjdG9yKSk7CiAgICAvKiogQHR5cGUge251bWJlcnxudWxsfSAqLwogICAgdGhpcy5jaG9sZXNreUVwc2lsb24gPSBudWxsOwoKICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi8KICAgIHRoaXMuc2hvdWxkRml0S2VybmVsID0gZmFsc2U7CiAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovCiAgICB0aGlzLnNob3VsZEZpdFByaW9yID0gZmFsc2U7CgogICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovCiAgICB0aGlzLm1heEl0ZXIgPSAxMDA7CiAgICAvKiogQHR5cGUge251bWJlcn0gKi8KICAgIHRoaXMuY29udmVyZ2VuY2VGcmFjdGlvbiA9IDAuMDU7CiAgICAvKiogQHR5cGUge251bWJlcn0gbWF4IGZpdHRpbmcgdGltZSBpbiBtaWxsaXNlY29uZHMgKi8KICAgIHRoaXMubWF4VGltZSA9IERFRkFVTFRfTUFYX1RJTUVfTVM7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gU0VUVEVSUyAoY2hhaW5hYmxlKQogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogU2V0cyBhIG5ldyBwcmlvci4KICAgKiBAcGFyYW0ge29iamVjdH0gcHJpb3IKICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBzZXRQcmlvcihwcmlvcikgewogICAgdGhpcy5wcmlvciA9IHByaW9yOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBTZXRzIHRoZSBub2lzZSBwYXJhbWV0ZXIgKHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgb3V0cHV0IG5vaXNlKS4KICAgKiBAcGFyYW0ge251bWJlcn0gbm9pc2UgKOKJpSAwKQogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIHNldE5vaXNlKG5vaXNlKSB7CiAgICBpZiAoIShub2lzZSA+PSAwKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBub2lzZSBwYXJhbWV0ZXIgc2hvdWxkIGJlIG5vbi1uZWdhdGl2ZSBidXQgd2UgdHJpZWQgdG8gc2V0IGl0IHRvICR7bm9pc2V9YCk7CiAgICB9CiAgICB0aGlzLm5vaXNlID0gbm9pc2U7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIENoYW5nZXMgdGhlIGtlcm5lbCBvZiB0aGUgR2F1c3NpYW4gcHJvY2Vzcy4KICAgKiBAcGFyYW0ge29iamVjdH0ga2VybmVsCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgc2V0S2VybmVsKGtlcm5lbCkgewogICAgdGhpcy5rZXJuZWwgPSBrZXJuZWw7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFNldHMgdGhlIENob2xlc2t5IGVwc2lsb24uIFdoZW4gYSBzdHJpY3RseSBwb3NpdGl2ZSB2YWx1ZSBpcyBnaXZlbiwgdGhlCiAgICogQ2hvbGVza3kgZGVjb21wb3NpdGlvbiBpcyBndWFyYW50ZWVkIHRvIHN1Y2NlZWQgKHRoZSB2YWx1ZSBpcyB1c2VkIGluCiAgICogcGxhY2Ugb2YgYSBub24tcG9zaXRpdmUgZGlhZ29uYWwgcGl2b3QpLiBgbnVsbGAgaWdub3JlcyBpdC4KICAgKiBAcGFyYW0ge251bWJlcnxudWxsfSBjaG9sZXNreUVwc2lsb24KICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBzZXRDaG9sZXNreUVwc2lsb24oY2hvbGVza3lFcHNpbG9uKSB7CiAgICB0aGlzLmNob2xlc2t5RXBzaWxvbiA9IGNob2xlc2t5RXBzaWxvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogTW9kaWZpZXMgdGhlIHN0b3BwaW5nIGNyaXRlcmlhIG9mIHRoZSBncmFkaWVudCBkZXNjZW50IHVzZWQgdG8gZml0IHRoZQogICAqIG5vaXNlIGFuZCBrZXJuZWwgcGFyYW1ldGVycy4KICAgKiBAcGFyYW0ge251bWJlcn0gbWF4SXRlcgogICAqIEBwYXJhbSB7bnVtYmVyfSBjb252ZXJnZW5jZUZyYWN0aW9uCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgc2V0Rml0UGFyYW1ldGVycyhtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uKSB7CiAgICB0aGlzLm1heEl0ZXIgPSBtYXhJdGVyOwogICAgdGhpcy5jb252ZXJnZW5jZUZyYWN0aW9uID0gY29udmVyZ2VuY2VGcmFjdGlvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQXNrcyBmb3IgdGhlIGtlcm5lbCBwYXJhbWV0ZXJzIHRvIGJlIGZpdHRlZCBvbiB0aGUgdHJhaW5pbmcgZGF0YSAoYXBwbGllZAogICAqIHdoZW4gYHRyYWluKClgIGlzIGNhbGxlZCkuCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgZml0S2VybmVsKCkgewogICAgdGhpcy5zaG91bGRGaXRLZXJuZWwgPSB0cnVlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBc2tzIGZvciB0aGUgcHJpb3IgdG8gYmUgZml0dGVkIG9uIHRoZSB0cmFpbmluZyBkYXRhIChhcHBsaWVkIHdoZW4KICAgKiBgdHJhaW4oKWAgaXMgY2FsbGVkKS4KICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBmaXRQcmlvcigpIHsKICAgIHRoaXMuc2hvdWxkRml0UHJpb3IgPSB0cnVlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gVFJBSU4KICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFRyYWlucyB0aGUgR2F1c3NpYW4gcHJvY2VzcywgZml0dGluZyB0aGUgcGFyYW1ldGVycyBpZiByZXF1ZXN0ZWQKICAgKiAoYGJ1aWxkZXIucnM6MTg5YCkuCiAgICoKICAgKiBTdGVwczoKICAgKiAgIDEuIGlmIGBzaG91bGRGaXRLZXJuZWxgIOKGkiBga2VybmVsLmhldXJpc3RpY0ZpdChpbnB1dHMsIG91dHB1dHMpYCB1c2luZyB0aGUKICAgKiAgICAgIFJBVyBvdXRwdXRzICh0aGUgYnVpbGRlciBoYXMgbm90IHN1YnRyYWN0ZWQgdGhlIHByaW9yIHlldCkuCiAgICogICAyLiBjb25zdHJ1Y3QgdGhlIEdhdXNzaWFuUHJvY2Vzcy4KICAgKiAgIDMuIGBncC5maXRfcGFyYW1ldGVycyhzaG91bGRGaXRQcmlvciwgc2hvdWxkRml0S2VybmVsLCDigKYpYC4KICAgKgogICAqIEByZXR1cm5zIHtHYXVzc2lhblByb2Nlc3N9CiAgICovCiAgdHJhaW4oKSB7CiAgICAvLyAxLiBLZXJuZWwgaGV1cmlzdGljIGZpdCAodXNlcyByYXcgb3V0cHV0cykuCiAgICBpZiAodGhpcy5zaG91bGRGaXRLZXJuZWwpIHsKICAgICAgdGhpcy5rZXJuZWwuaGV1cmlzdGljRml0KHRoaXMudHJhaW5pbmdJbnB1dHMsIHRoaXMudHJhaW5pbmdPdXRwdXRzKTsKICAgIH0KCiAgICAvLyAyLiBCdWlsZCB0aGUgR1AgKHRoaXMgcmVzaWR1YWxpc2VzIHRoZSBvdXRwdXRzIGFuZCBidWlsZHMgdGhlIENob2xlc2t5KS4KICAgIGNvbnN0IGdwID0gbmV3IEdhdXNzaWFuUHJvY2Vzcyh0aGlzLnByaW9yLCB0aGlzLmtlcm5lbCwgdGhpcy5ub2lzZSwgdGhpcy5jaG9sZXNreUVwc2lsb24sIHRoaXMudHJhaW5pbmdJbnB1dHMsIHRoaXMudHJhaW5pbmdPdXRwdXRzKTsKCiAgICAvLyAzLiBGaXQgb24gdGhlIHRyYWluaW5nIGRhdGEsIGlmIHJlcXVlc3RlZC4KICAgIGdwLmZpdF9wYXJhbWV0ZXJzKHRoaXMuc2hvdWxkRml0UHJpb3IsIHRoaXMuc2hvdWxkRml0S2VybmVsLCB0aGlzLm1heEl0ZXIsIHRoaXMuY29udmVyZ2VuY2VGcmFjdGlvbiwgdGhpcy5tYXhUaW1lKTsKICAgIHJldHVybiBncDsKICB9Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gTE9DQUwgQ09MVU1OIEhFTFBFUlMKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIFNxdWFyZWQgRXVjbGlkZWFuIG5vcm0gb2YgY29sdW1uIGBjYCBvZiBtYXRyaXggYE1gIChudW1iZXJbXVtdKS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBNCiAqIEBwYXJhbSB7bnVtYmVyfSBjCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBjb2x1bW5Ob3JtU3F1YXJlZChNLCBjKSB7CiAgbGV0IHMgPSAwOwogIGZvciAobGV0IHIgPSAwOyByIDwgTS5sZW5ndGg7IHIrKykgewogICAgY29uc3QgdiA9IE1bcl1bY107CiAgICBzICs9IHYgKiB2OwogIH0KICByZXR1cm4gczsKfQoKLyoqCiAqIERvdCBwcm9kdWN0IG9mIGNvbHVtbiBgY2Agb2YgQSB3aXRoIGNvbHVtbiBgY2Agb2YgQiAoYm90aCBudW1iZXJbXVtdKS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQgogKiBAcGFyYW0ge251bWJlcn0gYwogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gY29sdW1uRG90KEEsIEIsIGMpIHsKICBsZXQgcyA9IDA7CiAgZm9yIChsZXQgciA9IDA7IHIgPCBBLmxlbmd0aDsgcisrKSB7CiAgICBzICs9IEFbcl1bY10gKiBCW3JdW2NdOwogIH0KICByZXR1cm4gczsKfQoKLyoqDQogKiDlhYvliKnph5Hms5UoS3JpZ2luZynlhaflpJbmj5Lpu57mlbjlgLwNCiAqDQogKiDlhYvliKnph5Hms5XoqIjnrpfoiIflr6bpmpvpgYvnrpfnk7bpoLjllY/poYzlj6/oqbPopos6IGh0dHBzOi8vZ2l0aHViLmNvbS9sdmlzZWkvd2ViLWRldmVsb3Blci1yZXNvdXJjZXMvYmxvYi9tYXN0ZXIvd2ViYXNzZW1ibHkva3JpZ2luZy5tZA0KICoNCiAqIOiLpeaYr05vZGUuanPnq6/kvb/nlKjpoIjmm7Tpq5joqIjnrpfpgJ/luqbvvIzlj6/kvb/nlKh3LWtyaWdpbmc6IGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWtyaWdpbmcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9pbnRlcnAyS3JpZ2luZy50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzU3JjIOi8uOWFpeS6jOe2reW6p+aomeWKoOingOa4rOaVuOaTmum7numZo+WIl++8jOeCult7eDp4MSx5OnkxLHo6ejF9LHt4OngyLHk6eTIsejp6Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIlw0KICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHBzVGFyIOi8uOWFpeS6jOe2reW6p+aomem7numZo+WIl+aIlum7nueJqeS7tu+8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiX77yM5oiWe3g6eDEseTp5MX3pu57nianku7YNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tuS5i3jmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7bkuYt55qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlaPSd6J10g6Ly45YWl6bue54mp5Lu25LmLeuashOS9jeWtl+S4su+8jOeCuuingOa4rOWAvO+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2NhbGU9MV0g6Ly45YWl5q2j6KaP5YyW56+E5ZyN5pW45YC877yM5Zug6JmV55CG5aSa6YKK5b2i5pmC5pyJ5pW45YC85a656Kix6Kqk5beu77yM5pWF6aCI6YCa6YGO57iu5pS+5YC85Z+f5L6G5rib5bCR5ZWP6aGM77yM6aCQ6KitMeaYr+ato+imj+WMljDoh7Mx5LmL6ZaT77yM5L2/55Soc2NhbGVYWeWJh+aYr+ato+imj+WMlueCujDoh7NzY2FsZVhZ5LmL6ZaT77yM6aCQ6KitMQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQubWV0aG9kPSdmcmllZHJpY2gnXSDovLjlhaXlvoznq6/lvJXmk47lrZfkuLLvvIzlj6/pgbgnZnJpZWRyaWNoJyhHYXVzc2lhbiBQcm9jZXNzIFJlZ3Jlc3Npb27vvIzmoLjlh73mlbjvvIxrcmlnaW5nLWZyaWVkcmljaCnjgIEnaW52YWxsJyjntpPlhbhPcmRpbmFyeSBLcmlnaW5n77yM5Y2K6K6K55Ww5ZyW5pOs5ZCI77yMa3JpZ2luZy1pbnZhbGwva3JpZ2luZy5tanMp77yM6aCQ6KitJ2ZyaWVkcmljaCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0Lm1vZGVsPSdleHBvbmVudGlhbCddIOi8uOWFpeaTrOWQiOaooeW8j+Wtl+S4su+8jG1ldGhvZD0naW52YWxsJ+aZguWPr+mBuCdleHBvbmVudGlhbCfjgIEnZ2F1c3NpYW4n44CBJ3NwaGVyaWNhbCfvvJttZXRob2Q9J2ZyaWVkcmljaCfmmYInZ2F1c3NpYW4n5bCN5oeJU3F1YXJlZEV4cOOAgeWFtumkmCjlkKtzcGhlcmljYWwp5bCN5oeJRXhwb25lbnRpYWzvvIzpoJDoqK0nZXhwb25lbnRpYWwnDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zaWdtYTI9MF0g6Ly45YWl6Ieq5YuV5pOs5ZCI5Y+D5pW4c2lnbWEy5pW45YC877yM5YOFbWV0aG9kPSdpbnZhbGwn5pmC5pyJ5pWI77yM6aCQ6KitMA0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuYWxwaGE9MTAwXSDovLjlhaXoh6rli5Xmk6zlkIjlj4PmlbhhbHBoYeaVuOWAvO+8jOWDhW1ldGhvZD0naW52YWxsJ+aZguacieaViO+8jOmgkOiorTEwMA0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQubHM9MC41XSDovLjlhaVmcmllZHJpY2jmoLjlh73mlbhsZW5ndGhzY2FsZeaVuOWAvCjlsI3mh4nmraPopo/ljJblvozlgLzln58p77yM5YOFbWV0aG9kPSdmcmllZHJpY2gn5pmC5pyJ5pWI77yM6aCQ6KitMC41DQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5ub2lzZT0wLjAxXSDovLjlhaVmcmllZHJpY2jop4DmuKzlmarpn7PmqJnmupblt64o5bCN5oeJ5q2j6KaP5YyW5b6M5YC85Z+fKe+8jOWDhW1ldGhvZD0nZnJpZWRyaWNoJ+aZguacieaViO+8jOmgkOiorTAuMDENCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC5yZXR1cm5XaXRoVmFyaW9ncmFtPWZhbHNlXSDovLjlhaXmmK/lkKblm57lgrPmk6zlkIjljYrorornlbDmlbjntZDmnpzluIPmnpflgLzvvIxtZXRob2Q9J2ZyaWVkcmljaCfmmYJ2YXJpb2dyYW3lm57lgrNudWxs77yM6aCQ6KitZmFsc2UNCiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IOWbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpeS9v+eUqHJldHVybldpdGhWYXJpb2dyYW09dHJ1ZeWJh+WbnuWCs+eJqeS7tuizh+ioiu+8jOiLpeeZvOeUn+mMr+iqpOWJh+WbnuWCs+mMr+iqpOioiuaBr+eJqeS7tg0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCBwDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNSwgejogOTQuOTQ5MjU4OTg3ODQ1MjcgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI4MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyODMsIHk6IDIwNSwgejogMTE3LjE0ODk2MzEwNjk1MTQ3IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAxMTYwLA0KICogICAgIHk6IDM4MCwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDExNjAsIHk6IDM4MCwgejogODQuOTgzMTQ2NzIwMDUzMzQgfQ0KICoNCiAqIHBzID0gW3sgYTogMjQzLCBiOiAyMDYsIGM6IDk1IH0sIHsgYTogMjMzLCBiOiAyMjUsIGM6IDE0NiB9LCB7IGE6IDIxLCBiOiAzMjUsIGM6IDIyIH0sIHsgYTogOTUzLCBiOiAyOCwgYzogMjIzIH0sIHsgYTogMTA5MiwgYjogMjkwLCBjOiAzOSB9LCB7IGE6IDc0NCwgYjogMjAwLCBjOiAxOTEgfSwgeyBhOiAxNzQsIGI6IDMsIGM6IDIyIH0sIHsgYTogNTM3LCBiOiAzNjgsIGM6IDI0OSB9LCB7IGE6IDExNTEsIGI6IDM3MSwgYzogODYgfSwgeyBhOiA4MTQsIGI6IDI1MiwgYzogMTI1IH1dDQogKiBwID0gew0KICogICAgIGE6IDI0MywNCiAqICAgICBiOiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHAsIHsga2V5WDogJ2EnLCBrZXlZOiAnYicsIGtleVo6ICdjJyB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgYTogMjQzLCBiOiAyMDUsIGM6IDk0Ljk0OTI1ODk4Nzg0NTI3IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IFsNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI0MywNCiAqICAgICAgICAgeTogMjA1LA0KICogICAgIH0sDQogKiAgICAgew0KICogICAgICAgICB4OiAyODMsDQogKiAgICAgICAgIHk6IDIwNSwNCiAqICAgICB9LA0KICogXQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNSwgejogOTQuOTQ5MjU4OTg3ODQ1MjcgfSwNCiAqIC8vICAgeyB4OiAyODMsIHk6IDIwNSwgejogMTE3LjE0ODk2MzEwNjk1MTQ3IH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwLCB7IHNjYWxlOiAxMDAwLCBtZXRob2Q6ICdpbnZhbGwnIH0pIC8vc2NhbGUtcm9idXN054K6aW52YWxs5bCI5bGsLCBmcmllZHJpY2jlm7rlrpprZXJuZWzpnZ5zY2FsZS1yb2J1c3QNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA1LCB6OiA5NC44ODQ3OTk0ODQxODg3OCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCwgeyBtb2RlbDogJ2dhdXNzaWFuJyB9KSAvL2ZyaWVkcmljaOm7mOiqjSwgZ2F1c3NpYW7lsI3mh4lTcXVhcmVkRXhw5qC4DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNSwgejogMTE4LjkwNTgyNTAwNzQ3OTgzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwLCB7IHNpZ21hMjogMC4wMDEsIGFscGhhOiA3MCwgbWV0aG9kOiAnaW52YWxsJyB9KSAvL3NpZ21hMi9hbHBoYeeCumludmFsbOWNiuiuiueVsOWcluaTrOWQiOWPg+aVuCwgZnJpZWRyaWNo5LiN6YGp55SoDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNSwgejogOTAuODg3MDI5NDkyNzYzNDMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHAsIHsgcmV0dXJuV2l0aFZhcmlvZ3JhbTogdHJ1ZSwgbWV0aG9kOiAnaW52YWxsJyB9KSAvL3ZhcmlvZ3JhbeeCumludmFsbOWwiOWxrCwgZnJpZWRyaWNo5Zue5YKzbnVsbA0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsNCiAqIC8vICAgcmVzdWx0OiB7IHg6IDI0MywgeTogMjA1LCB6OiA5NC44ODQ3OTk0ODQxODcyMSB9LA0KICogLy8gICB2YXJpb2dyYW06IHsNCiAqIC8vICAgICB0OiBbDQogKiAvLyAgICAgICAwLjMyMTU4NTkwMzA4MzcwMDQ0LA0KICogLy8gICAgICAgMC41NDYyNTU1MDY2MDc5Mjk1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODg1NDYyNTU1MDY2MDc5MywNCiAqIC8vICAgICAgIDAuMDc0ODg5ODY3ODQxNDA5NjksDQogKiAvLyAgICAgICAwLjc0NDQ5MzM5MjA3MDQ4NDYsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuMjgxOTM4MzI1OTkxMTg5NDUsDQogKiAvLyAgICAgICAwLjQ1Mzc0NDQ5MzM5MjA3MDQ2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICB4OiBbDQogKiAvLyAgICAgICAwLjE5NjQ2MDE3Njk5MTE1MDQ1LA0KICogLy8gICAgICAgMC4xODc2MTA2MTk0NjkwMjY1NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjgyNDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjk0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuNjM5ODIzMDA4ODQ5NTU3NiwNCiAqIC8vICAgICAgIDAuMTM1Mzk4MjMwMDg4NDk1NTgsDQogKiAvLyAgICAgICAwLjQ1NjYzNzE2ODE0MTU5Mjk0LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNzAxNzY5OTExNTA0NDI0OA0KICogLy8gICAgIF0sDQogKiAvLyAgICAgeTogWw0KICogLy8gICAgICAgMC41MTY4MTQxNTkyOTIwMzU0LA0KICogLy8gICAgICAgMC41MzM2MjgzMTg1ODQwNzA4LA0KICogLy8gICAgICAgMC42MjIxMjM4OTM4MDUzMDk3LA0KICogLy8gICAgICAgMC4zNTkyOTIwMzUzOTgyMzAwNywNCiAqIC8vICAgICAgIDAuNTkxMTUwNDQyNDc3ODc2MSwNCiAqIC8vICAgICAgIDAuNTExNTA0NDI0Nzc4NzYxLA0KICogLy8gICAgICAgMC4zMzcxNjgxNDE1OTI5MjAzNiwNCiAqIC8vICAgICAgIDAuNjYwMTc2OTkxMTUwNDQyNSwNCiAqIC8vICAgICAgIDAuNjYyODMxODU4NDA3MDc5NywNCiAqIC8vICAgICAgIDAuNTU3NTIyMTIzODkzODA1Mw0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbnVnZ2V0OiAwLjMzNTI4NTM0OTIzNDI4MTQ0LA0KICogLy8gICAgIHJhbmdlOiAwLjk4MTgyNzQyMDQxMjA0ODgsDQogKiAvLyAgICAgc2lsbDogMC40NTg0NTgwMzMzNDQzMDc1LA0KICogLy8gICAgIEE6IDAuMzMzMzMzMzMzMzMzMzMzMywNCiAqIC8vICAgICBuOiAxMCwNCiAqIC8vICAgICBtb2RlbDogW0Z1bmN0aW9uOiBrcmlnaW5nX3ZhcmlvZ3JhbV9leHBvbmVudGlhbF0sDQogKiAvLyAgICAgc3ZwZDogeyBkYXRhOiBbQXJyYXldLCBiYXJzOiBbQXJyYXldIH0sDQogKiAvLyAgICAgSzogWw0KICogLy8gICAgICAgICAgLTc1Ljg1MTcwMDQxNzUyNDUsICAgICAgIDY3LjkyNTcyMjkyMzQ4NCwgLTAuMTYzMzU4NDEwMzY5NjQ2NzcsDQogKiAvLyAgICAgICAgMC4yNDEzMTUxODk3ODI3MDg3NywgIC0wLjA0MjM0MjQ2ODY1MDQ4NzMyLCAgIDAuODc3MDUxODM5NjMyODkxMiwNCiAqIC8vICAgICAgICAgIDUuNjE2OTYwMzYyMTcwMjc5LCAgICAgMS42MjE2NTk2Mzc0NDAyMjcsIDAuMDI3ODg4MDAxNjUxODk0NjM1LA0KICogLy8gICAgICAgLTAuMjE0MTU4NTM0MTY2NTI4MDMsICAgICA2Ny45MjU3MjI5MjM0ODQwMiwgICAtNzUuNjE3ODY0Nzg4MjQ4NjgsDQogKiAvLyAgICAgICAgICA1LjQxMzIzMjA3OTcyNzA2NCwgICAwLjA0OTA2OTQzNDM4Mzg1OTU4LCAgMC4wMzY3OTExMzIyOTM0ODQ2NSwNCiAqIC8vICAgICAgIC0wLjExODQ3MTM5MzUyNjk4Njc3LCAgICAwLjMxNDIwMTI3NjcyOTc5MTcsICAgMS45NTMxMDc4ODU0NDMwMDI0LA0KICogLy8gICAgICAgIDAuMTQyMTYzNzc4NTQwNTUzNDMsIC0wLjAyNjUwMzEwNDY3MjUyNTE3NCwgICAtMC4xNjMzNTg0MTAzNjk2NTEsDQogKiAvLyAgICAgICAgICA1LjQxMzIzMjA3OTcyNzA2NywgICAtMTAuMzQxMDg4NzQxNjAyNDc1LCAgICAwLjcwNzY5MDI1NjQxNTIwNSwNCiAqIC8vICAgICAgICAgMC4yNzE3MjU5NDc3NDgxMzc1LCAgICAtMC4wMzI3NTEzMzgzMjc4MTgsICAgMi40MDIxNTEwNDY3NzM0NDA2LA0KICogLy8gICAgICAgICAxLjEwMzk1MjkzMDMyMDQ5NTgsICAgIDAuOTM0MzI0MTE5OTYyNjcxMSwgIDAuMTc1OTM5MTA2NzcxOTk1NTMsDQogKiAvLyAgICAgICAgMC4yNDEzMTUxODk3ODI2ODgyMywgICAwLjA0OTA2OTQzNDM4Mzg4NDUzLCAgIDAuNzA3NjkwMjU2NDE1MjAwNiwNCiAqIC8vICAgICAgICAtMTEuMTk1ODk1ODA5MzMyODE4LCAgICAzLjYzMTgzMjY3NjcxNjgyNjcsICAgMy4wOTM1Mzg2NTA4ODg3MDM1LA0KICogLy8gICAgICAgICAxLjA0NTE1NTM0OTk1NjgxMzYsICAgMC4wNzY4MTExNTE1OTAyNTE5OCwgICAwLjU1MDA1MjA5ODEyNTM0MTYsDQogKiAvLyAgICAgICAgICAyLjE3NjkyODIwNzcxMDA0OCwgIC0wLjA0MjM0MjQ2ODY1MDQ5MDU1LCAgMC4wMzY3OTExMzIyOTM0ODU3OCwNCiAqIC8vICAgICAgICAwLjI3MTcyNTk0Nzc0ODEzODEzLCAgICAzLjYzMTgzMjY3NjcxNjgxODgsICAtMjEuODMzOTkxODMzMzk3NTI2LA0KICogLy8gICAgICAgIC0wLjM3MDM1NDQ1NjcwMzE3ODQsICAgIDAuMTYzMTk0MDc5NzA4NjgxNCwgICAwLjE0Nzg0ODUyODUzMDIxMjEsDQogKiAvLyAgICAgICAgIDE0LjU5MjY2MTE1MzY0NjM0OSwgICAgIDMuNTI5NjQwNzU5NjYwOTQ5LCAgICAwLjg3NzA1MTgzOTYzMjg4NCwNCiAqIC8vICAgICAgIC0wLjExODQ3MTM5MzUyNjk3MTExLCAtMC4wMzI3NTEzMzgzMjc4MTk2ODYsICAgMy4wOTM1Mzg2NTA4ODg2OTg2LA0KICogLy8gICAgICAgLTAuMzcwMzU0NDU2NzAzMTgwNzMsICAgLTIzLjQyODM4NTA1NzgwMzY5NSwgICAwLjgzNDY5MDkwNzU5ODQ5NTIsDQogKiAvLyAgICAgICAgICAzLjY4MzgwMDQxNTQ4NTc3OCwgIC0wLjA3MDk0NTI4NjU5OTY4MTUyLCAgIDE1LjYzMDgzNDc4MjczNTcyMiwNCiAqIC8vICAgICAgICAgIDUuNjE2OTYwMzYyMTcwMjM4LCAgIDAuMzE0MjAxMjc2NzI5ODMyNTYsICAgMi40MDIxNTEwNDY3NzM0Mzk3LA0KICogLy8gICAgICAgICAgMS4wNDUxNTUzNDk5NTY4MTUsICAgMC4xNjMxOTQwNzk3MDg2ODUyNywgICAwLjgzNDY5MDkwNzU5ODQ5MjMsDQogKiAvLyAgICAgICAgIC0xMS4xNTk2NzY0MzU3NDcyOCwgICAwLjQ3OTgwNTA1NzI3NjIzOTA3LCAgIDAuNzUyNTExOTYzOTg2OTQ3MywNCiAqIC8vICAgICAgICAtMC4wMzk5MDIwMjE2MjYxMzg0LCAgICAxLjYyMTY1OTYzNzQ0MDI3MzksICAgMS45NTMxMDc4ODU0NDI5NTMzLA0KICogLy8gICAgICAgICAxLjEwMzk1MjkzMDMyMDQ5NjIsICAgMC4wNzY4MTExNTE1OTAyNDk2MiwgICAwLjE0Nzg0ODUyODUzMDIwMTMsDQogKiAvLyAgICAgICAgIDMuNjgzODAwNDE1NDg1NzkzNSwgICAgICAwLjQ3OTgwNTA1NzI3NjI0LCAgLTExLjU5NDU1NTkzMDc1MzgzNSwNCiAqIC8vICAgICAgICAgMC45MjM3Mjg0MjE0MTQwMjI2LCAgICAxLjg5NDc4NTk3NzIyMjMzMDgsIDAuMDI3ODg4MDAxNjUxOTE3Mzc3LA0KICogLy8gICAgICAgIDAuMTQyMTYzNzc4NTQwNTM0NzIsICAgIDAuOTM0MzI0MTE5OTYyNjczMiwgICAwLjU1MDA1MjA5ODEyNTM0NzYsDQogKiAvLyAgICAgICAgIDE0LjU5MjY2MTE1MzY0NjM0NywgICAtMC4wNzA5NDUyODY1OTk2NzM1LCAgIDAuNzUyNTExOTYzOTg2OTQ4NiwNCiAqIC8vICAgICAgICAgMC45MjM3Mjg0MjE0MTQwMTExLCAgIC0xOC4yNTEyMzAyNDU2NTMzMTgsICAgIDAuODM3OTU5NjkzMzkxODA5LA0KICogLy8gICAgICAgLTAuMjE0MTU4NTM0MTY2NTQ2OTMsIC0wLjAyNjUwMzEwNDY3MjUxNzg3NCwgICAwLjE3NTkzOTEwNjc3MTk5ODksDQogKiAvLyAgICAgICAgICAyLjE3NjkyODIwNzcxMDA1MywgICAgIDMuNTI5NjQwNzU5NjYwOTUyLCAgIDE1LjYzMDgzNDc4MjczNTcwNCwNCiAqIC8vICAgICAgIC0wLjAzOTkwMjAyMTYyNjEzNzQ0LCAgICAgMS44OTQ3ODU5NzcyMjIzNDMsICAgMC44Mzc5NTk2OTMzOTE4MTQ4LA0KICogLy8gICAgICAgICAtMjMuODkyMDQwMTcxNDUyODENCiAqIC8vICAgICBdLA0KICogLy8gICAgIE06IFsNCiAqIC8vICAgICAgIDE1LjEwNzc3NTUyODE3MzgwMiwNCiAqIC8vICAgICAgIC0xNy41MjM1NTMxNjQwMjQzNywNCiAqIC8vICAgICAgIDQuOTc0Mjc5NzY3NjY4ODI5LA0KICogLy8gICAgICAgLTYuMDE0MzcwODM4NjI4MzU5LA0KICogLy8gICAgICAgNy4xNzUwOTUyOTQ3ODk0MDIsDQogKiAvLyAgICAgICAtMy43NTcyNjU3MzM5ODA3MTgzLA0KICogLy8gICAgICAgNC4yMTA5MjA1MjExNTc3ODgsDQogKiAvLyAgICAgICAtNi4wNjQzMjMxNDM4NjMwMTMsDQogKiAvLyAgICAgICAtMi4yMjgwNzI0NDUyOTUyNDg3LA0KICogLy8gICAgICAgNS4wMzU3ODUzODU1NDkxMTcNCiAqIC8vICAgICBdDQogKiAvLyAgIH0NCiAqIC8vIH0NCiAqDQogKi8KZnVuY3Rpb24gaW50ZXJwMktyaWdpbmcocHNTcmMsIHBzVGFyLCBvcHQgPSB7fSkgewogIC8vY2hlY2sgcHNTcmMKICBpZiAoIWlzZWFycihwc1NyYykpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzU3JjIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXknCiAgICB9OwogIH0KCiAgLy9jaGVjayBwc1RhcgogIGlmICghaXNlb2JqKHBzVGFyKSAmJiAhaXNlYXJyKHBzVGFyKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNUYXIgaXMgbm90IGFuIGVmZmVjdGl2ZSBvYmplY3Qgb3IgYXJyYXknCiAgICB9OwogIH0KCiAgLy9pc09uZQogIGxldCBpc09uZSA9IGlzZW9iaihwc1Rhcik7CiAgaWYgKGlzT25lKSB7CiAgICBwc1RhciA9IFtwc1Rhcl07CiAgfQoKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleVoKICBsZXQga2V5WiA9IGdldChvcHQsICdrZXlaJyk7CiAgaWYgKCFpc2VzdHIoa2V5WikpIHsKICAgIGtleVogPSAneic7CiAgfQoKICAvL3NjYWxlCiAgbGV0IHNjYWxlID0gZ2V0KG9wdCwgJ3NjYWxlJyk7CiAgaWYgKCFpc251bShzY2FsZSkpIHsKICAgIHNjYWxlID0gMTsKICB9CiAgc2NhbGUgPSBjZGJsKHNjYWxlKTsKCiAgLy9tZXRob2QKICBsZXQgbWV0aG9kID0gZ2V0KG9wdCwgJ21ldGhvZCcpOwogIGlmIChtZXRob2QgIT09ICdmcmllZHJpY2gnICYmIG1ldGhvZCAhPT0gJ2ludmFsbCcpIHsKICAgIG1ldGhvZCA9ICdmcmllZHJpY2gnOwogIH0KCiAgLy9rcmlnaW5nTW9kZWwKICBsZXQga3JpZ2luZ01vZGVsID0gZ2V0KG9wdCwgJ21vZGVsJyk7CiAgaWYgKGtyaWdpbmdNb2RlbCAhPT0gJ2V4cG9uZW50aWFsJyAmJiBrcmlnaW5nTW9kZWwgIT09ICdnYXVzc2lhbicgJiYga3JpZ2luZ01vZGVsICE9PSAnc3BoZXJpY2FsJykgewogICAga3JpZ2luZ01vZGVsID0gJ2V4cG9uZW50aWFsJzsKICB9CgogIC8va3JpZ2luZ1NpZ21hMgogIGxldCBrcmlnaW5nU2lnbWEyID0gZ2V0KG9wdCwgJ3NpZ21hMicpOwogIGlmICghaXNudW0oa3JpZ2luZ1NpZ21hMikpIHsKICAgIGtyaWdpbmdTaWdtYTIgPSAwOwogIH0KICBrcmlnaW5nU2lnbWEyID0gY2RibChrcmlnaW5nU2lnbWEyKTsKCiAgLy9rcmlnaW5nQWxwaGEKICBsZXQga3JpZ2luZ0FscGhhID0gZ2V0KG9wdCwgJ2FscGhhJyk7CiAgaWYgKCFpc251bShrcmlnaW5nQWxwaGEpKSB7CiAgICBrcmlnaW5nQWxwaGEgPSAxMDA7CiAgfQogIGtyaWdpbmdBbHBoYSA9IGNkYmwoa3JpZ2luZ0FscGhhKTsKCiAgLy9scywgZnJpZWRyaWNo5qC45Ye95pW4bGVuZ3Roc2NhbGUKICBsZXQgbHMgPSBnZXQob3B0LCAnbHMnKTsKICBpZiAoIWlzbnVtKGxzKSkgewogICAgbHMgPSAwLjU7CiAgfQogIGxzID0gY2RibChscyk7CgogIC8vbm9pc2UsIGZyaWVkcmljaOingOa4rOWZqumfs+aomea6luW3rgogIGxldCBub2lzZSA9IGdldChvcHQsICdub2lzZScpOwogIGlmICghaXNudW0obm9pc2UpKSB7CiAgICBub2lzZSA9IDAuMDE7CiAgfQogIG5vaXNlID0gY2RibChub2lzZSk7CgogIC8vcmV0dXJuV2l0aFZhcmlvZ3JhbQogIGxldCByZXR1cm5XaXRoVmFyaW9ncmFtID0gZ2V0KG9wdCwgJ3JldHVybldpdGhWYXJpb2dyYW0nKTsKICBpZiAoIWlzYm9sKHJldHVybldpdGhWYXJpb2dyYW0pKSB7CiAgICByZXR1cm5XaXRoVmFyaW9ncmFtID0gZmFsc2U7CiAgfQogIC8vIGNvbnNvbGUubG9nKCdyZXR1cm5XaXRoVmFyaW9ncmFtJywgcmV0dXJuV2l0aFZhcmlvZ3JhbSkKCiAgLy9wdHNYWVp0b0FycgogIHBzU3JjID0gcHRzWFladG9BcnIocHNTcmMsIG9wdCk7CgogIC8vY2hlY2sgcHNTcmMKICBpZiAoc2l6ZShwc1NyYykgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzU3JjIGhhcyBubyBlZmZlY3RpdmUgZGF0YScKICAgIH07CiAgfQogIC8vIGNvbnNvbGUubG9nKCdwdHNYWVp0b0FyciBwc1NyYycsIHBzU3JjKQoKICAvL3B0c1hZdG9BcnIKICBwc1RhciA9IHB0c1hZdG9BcnIocHNUYXIsIG9wdCk7CgogIC8vY2hlY2sgcHNUYXIKICBpZiAoc2l6ZShwc1RhcikgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzVGFyIGhhcyBubyBlZmZlY3RpdmUgZGF0YScKICAgIH07CiAgfQogIC8vIGNvbnNvbGUubG9nKCdwdHNYWXRvQXJyIHBzVGFyJywgcHNUYXIpCgogIC8vaW50ZXJwMk5vcm1hbGl6ZQogIGxldCBpdG5tID0gaW50ZXJwMk5vcm1hbGl6ZShwc1NyYywgewogICAgc2NhbGUKICB9KTsKICBwc1NyYyA9IGl0bm0ucHM7IC8v6KSH5a+r5q2j6KaP5YyW5pW45pOaCiAgbGV0IG52ID0gaXRubS5udjsKICBsZXQgaW52ID0gaXRubS5pbnY7CgogIC8va3BLbm93bgogIGxldCBrcEtub3duID0ge307CiAgZm9yRWFjaChwc1NyYywgdiA9PiB7CiAgICBsZXQgayA9IGAke3YueH0tJHt2Lnl9YDsgLy/lt7LntpPooqvmraPopo/ljJboh7N4LHkKICAgIGtwS25vd25ba10gPSB2Lno7IC8v5bey57aT6KKr5q2j6KaP5YyW6IezeCx5LHoKICB9KTsKCiAgLy92YXJpb2dyYW0sIHByZWRpY3Q6IOS+nW1ldGhvZOWIh+aPm+W+jOerr+W8leaTjgogIGxldCB2YXJpb2dyYW0gPSBudWxsOyAvL2ZyaWVkcmljaOeEoeWNiuiuiueVsOWcluamguW/tSwg5Zue5YKz5pmC57at5oyBbnVsbAogIGxldCBwcmVkaWN0OyAvLyhueCwgbnkpID0+IG56CiAgaWYgKG1ldGhvZCA9PT0gJ2ZyaWVkcmljaCcpIHsKICAgIC8vaW5wdXRzLCBvdXRwdXRzICjlt7LmraPopo/ljJYpCiAgICBsZXQgaW5wdXRzID0gW107CiAgICBsZXQgb3V0cHV0cyA9IFtdOwogICAgZm9yRWFjaChwc1NyYywgdiA9PiB7CiAgICAgIGlucHV0cy5wdXNoKFt2LngsIHYueV0pOwogICAgICBvdXRwdXRzLnB1c2godi56KTsKICAgIH0pOwoKICAgIC8va2VybmVsLCBtb2RlbOWwjeaHieaguOWHveaVuDogZ2F1c3NpYW4tPlNxdWFyZWRFeHAsIOWFtumkmCjlkKtzcGhlcmljYWwpLT5FeHBvbmVudGlhbAogICAgbGV0IGtlcm5lbDsKICAgIGlmIChrcmlnaW5nTW9kZWwgPT09ICdnYXVzc2lhbicpIHsKICAgICAga2VybmVsID0gbmV3IFNxdWFyZWRFeHAobHMsIDEpOwogICAgfSBlbHNlIHsKICAgICAga2VybmVsID0gbmV3IEV4cG9uZW50aWFsKGxzLCAxKTsKICAgIH0KCiAgICAvL2dwLCDlm7rlrpprZXJuZWzkuI3lgZpBREFN5YSq5YyWKOizh+aWmeW3suato+imj+WMliwg5Zu65a6abGVuZ3Roc2NhbGXljbPlkIjnkIYpCiAgICBsZXQgZ3AgPSBHYXVzc2lhblByb2Nlc3MuYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpLnNldEtlcm5lbChrZXJuZWwpLnNldE5vaXNlKG5vaXNlKS50cmFpbigpOwoKICAgIC8vcHJlZGljdAogICAgcHJlZGljdCA9IChueCwgbnkpID0+IGdwLnByZWRpY3QoW254LCBueV0pOwogIH0gZWxzZSB7CiAgICAvL3gsIHksIHQKICAgIGxldCB4ID0gW107CiAgICBsZXQgeSA9IFtdOwogICAgbGV0IHQgPSBbXTsKICAgIGZvckVhY2gocHNTcmMsIHYgPT4gewogICAgICB4LnB1c2godi54KTsKICAgICAgeS5wdXNoKHYueSk7CiAgICAgIHQucHVzaCh2LnopOwogICAgfSk7CgogICAgLy92YXJpb2dyYW0KICAgIHZhcmlvZ3JhbSA9IGtyaWdpbmcudHJhaW4odCwgeCwgeSwga3JpZ2luZ01vZGVsLCBrcmlnaW5nU2lnbWEyLCBrcmlnaW5nQWxwaGEpOwogICAgLy8gY29uc29sZS5sb2coJ3ZhcmlvZ3JhbScsIHZhcmlvZ3JhbSkKCiAgICAvL3ByZWRpY3QKICAgIHByZWRpY3QgPSAobngsIG55KSA9PiBrcmlnaW5nLnByZWRpY3QobngsIG55LCB2YXJpb2dyYW0pOwogIH0KCiAgLy9rcGR0CiAgbGV0IGtwZHQgPSAobngsIG55KSA9PiB7CiAgICAvL2NoZWNrCiAgICBsZXQgayA9IGAke254fS0ke255fWA7IC8v5bey57aT6KKr5q2j6KaP5YyW6IezeCx5CiAgICBpZiAoaGFza2V5KGtwS25vd24sIGspKSB7CiAgICAgIHJldHVybiBrcEtub3duW2tdOwogICAgfQoKICAgIC8vcHJlZGljdAogICAgbGV0IG56ID0gcHJlZGljdChueCwgbnkpOwoKICAgIC8vc2F2ZQogICAga3BLbm93bltrXSA9IG56OwogICAgcmV0dXJuIG56OwogIH07CgogIC8vaXR2CiAgbGV0IGl0diA9IHAgPT4gewogICAgLy94LCBueAogICAgbGV0IHggPSBwLng7CiAgICBsZXQgbnggPSBudih4LCAneCcpOwogICAgaWYgKCFpc051bWJlcihueCkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG54WyR7bnh9XWApOyAvL3gseemgkOacn+mDveaYr+acieWAvAogICAgfQoKICAgIC8veSwgbnkKICAgIGxldCB5ID0gcC55OwogICAgbGV0IG55ID0gbnYoeSwgJ3knKTsKICAgIGlmICghaXNOdW1iZXIobnkpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBueVske255fV1gKTsgLy94LHnpoJDmnJ/pg73mmK/mnInlgLwKICAgIH0KCiAgICAvL256LCB6CiAgICBsZXQgbnogPSBrcGR0KG54LCBueSk7CiAgICBsZXQgeiA9IGludihueiwgJ3onKTsKICAgIGlmICghaXNOdW1iZXIoeikpIHsKICAgICAgeiA9IG51bGw7IC8veumgiOaUr+aPtOWPr+iDveeEoeazleWFp+aPkgogICAgfQoKICAgIC8vIGNvbnNvbGUubG9nKCd4JywgeCwgJ3knLCB5LCAneicsIHopCiAgICAvLyBjb25zb2xlLmxvZygnbngnLCBueCwgJ255JywgbnksICdueicsIG56KQoKICAgIC8vcgogICAgbGV0IHIgPSB7CiAgICAgIFtrZXlYXTogeCwKICAgICAgW2tleVldOiB5LAogICAgICBba2V5Wl06IHoKICAgIH07CiAgICByZXR1cm4gcjsKICB9OwoKICAvL3IKICBsZXQgcjsKICBpZiAoaXNPbmUpIHsKICAgIGxldCBwID0gcHNUYXJbMF07CiAgICByID0gaXR2KHApOwogIH0gZWxzZSB7CiAgICByID0gW107CiAgICBmb3JFYWNoKHBzVGFyLCBwID0+IHsKICAgICAgci5wdXNoKGl0dihwKSk7CiAgICB9KTsKICB9CgogIC8vcmV0dXJuV2l0aFZhcmlvZ3JhbQogIGlmIChyZXR1cm5XaXRoVmFyaW9ncmFtKSB7CiAgICByID0gewogICAgICByZXN1bHQ6IHIsCiAgICAgIHZhcmlvZ3JhbQogICAgfTsKICB9CiAgcmV0dXJuIHI7Cn0KCi8qKg0KICog6Yed5bCN5LiN6KaP5YmH5LqM57at5pW45pOa6YCy6KGM5oyH5a6a5YWn5o+S6bue5pW45YC8DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvaW50ZXJwMi50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzU3JjIOi8uOWFpem7numZo+WIl++8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiXDQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gcHNUYXIg6Ly45YWl6bue6Zmj5YiX5oiW6bue54mp5Lu277yM54K6W3t4OngxLHk6eTF9LHt4OngyLHk6eTJ9LC4uLl3pu57nianku7bkuYvpmaPliJfvvIzmiJZ7eDp4MSx5Onkxfem7nueJqeS7tg0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlYPSd4J10g6Ly45YWl6bue54mp5Lu25LmLeOW6p+aomeashOS9jeWtl+S4su+8jOmgkOiorSd4Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neSddIOi8uOWFpem7nueJqeS7tuS5i3nluqfmqJnmrITkvY3lrZfkuLLvvIzpoJDoqK0neScNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVo9J3onXSDovLjlhaXpu57nianku7bkuYt65bqn5qiZ5oiW5YC85qyE5L2N5a2X5Liy77yM6aCQ6KitJ3onDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zY2FsZT0xXSDovLjlhaXmraPopo/ljJbnr4TlnI3mlbjlgLzvvIzlm6DomZXnkIblpJrpgorlvaLmmYLmnInmlbjlgLzlrrnoqLHoqqTlt67vvIzmlYXpoIjpgJrpgY7nuK7mlL7lgLzln5/kvobmuJvlsJHllY/poYzvvIzpoJDoqK0x5piv5q2j6KaP5YyWMOiHszHkuYvplpPvvIzkvb/nlKhzY2FsZVhZ5YmH5piv5q2j6KaP5YyW54K6MOiHs3NjYWxlWFnkuYvplpPvvIzpoJDoqK0xDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5tZXRob2Q9J25hdHVyYWxOZWlnaGJvciddIOi8uOWFpeWFp+aPkuaWueazleWtl+S4su+8jOWPr+mBuCduYXR1cmFsTmVpZ2hib3In44CBJ2tyaWdpbmcn77yM6aCQ6KitJ25hdHVyYWxOZWlnaGJvcifvvJttZXRob2Q9J2tyaWdpbmcn5pmC5ZG85Y+raW50ZXJwMktyaWdpbmfkuKblm7rlrprkvb/nlKjlhbZmcmllZHJpY2jlvJXmk44o57aTaW50ZXJwMueEoeazlemBuOeUqGludmFsbOW8leaTjikNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0Lm1vZGVsPSdleHBvbmVudGlhbCddIOi8uOWFpeiLpW1ldGhvZD0na3JpZ2luZyfmmYLkuYvmoLjlh73mlbjlsI3mh4nmqKHlvI/lrZfkuLLvvIwnZ2F1c3NpYW4n5bCN5oeJU3F1YXJlZEV4cOOAgeWFtumkmCjlkKsnZXhwb25lbnRpYWwn44CBJ3NwaGVyaWNhbCcp5bCN5oeJRXhwb25lbnRpYWzvvIzpoJDoqK0nZXhwb25lbnRpYWwnDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5scz0wLjVdIOi8uOWFpeiLpW1ldGhvZD0na3JpZ2luZyfmmYLkuYtmcmllZHJpY2jmoLjlh73mlbhsZW5ndGhzY2FsZeaVuOWAvCjlsI3mh4nmraPopo/ljJblvozlgLzln58p77yM6aCQ6KitMC41DQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5ub2lzZT0wLjAxXSDovLjlhaXoi6VtZXRob2Q9J2tyaWdpbmcn5pmC5LmLZnJpZWRyaWNo6KeA5ris5Zmq6Z+z5qiZ5rqW5beuKOWwjeaHieato+imj+WMluW+jOWAvOWfnynvvIzpoJDoqK0wLjAxDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zaWdtYTI9MF0gKOWDheiIimludmFsbOW8leaTjuS5i+WNiuiuiueVsOWcluaTrOWQiOWPg+aVuO+8jOWboGludGVycDLkuYtrcmlnaW5n5Zu65a6a6LWwZnJpZWRyaWNo5pWF5LiN55Sf5pWIKSDovLjlhaXoh6rli5Xmk6zlkIjlj4PmlbhzaWdtYTLmlbjlgLzvvIzpoJDoqK0wDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5hbHBoYT0xMDBdICjlg4XoiIppbnZhbGzlvJXmk47kuYvljYrorornlbDlnJbmk6zlkIjlj4PmlbjvvIzlm6BpbnRlcnAy5LmLa3JpZ2luZ+WbuuWumui1sGZyaWVkcmljaOaVheS4jeeUn+aViCkg6Ly45YWl6Ieq5YuV5pOs5ZCI5Y+D5pW4YWxwaGHmlbjlgLzvvIzpoJDoqK0xMDANCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC5yZXR1cm5XaXRoVmFyaW9ncmFtPWZhbHNlXSAo5YOF6IiKaW52YWxs5byV5pOO5Y+D5pW477yM5ZugaW50ZXJwMuS5i2tyaWdpbmflm7rlrprotbBmcmllZHJpY2jmlYXkuI3nlJ/mlYjvvIxmcmllZHJpY2jnhKHljYrorornlbDlnJYpIOi8uOWFpeaYr+WQpuWbnuWCs+aTrOWQiOWNiuiuiueVsOaVuOe1kOaenOW4g+ael+WAvO+8jOmgkOiorWZhbHNlDQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQudXNlU3luYz1mYWxzZV0g6Ly45YWl5piv5ZCm5L2/55So5ZCM5q2l5Ye95pW45biD5p6X5YC877yM6aCQ6KitZmFsc2UNCiAqIEByZXR1cm5zIHtQcm9taXNlfEFycmF5fE9iamVjdH0g5Zue5YKzUHJvbWlzZeaIlum7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpXVzZVN5bmM9ZmFsc2XliYflm57lgrNQcm9taXNl77yMcmVzb2x2ZeeCuuWbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jHJlamVjdOeCuuWkseaVl+ioiuaBr++8jOiLpXVzZVN5bmM9dHJ1ZeWJh+WbnuWCs+m7nueJqeS7tumZo+WIl+aIlum7nueJqeS7tu+8jOiLpeeZvOeUn+mMr+iqpOWJh+WbnuWCs+mMr+iqpOioiuaBr+eJqeS7tg0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcHMNCiAqIGxldCBwDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjgzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjgzLCB5OiAyMDcsIHo6IDExNC40MzA0MDQyMTk1MTkwOCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTE2MCwNCiAqICAgICB5OiAzODAsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDExNjAsIHk6IDM4MCwgejogbnVsbCB9DQogKg0KICogcHMgPSBbeyBhOiAyNDMsIGI6IDIwNiwgYzogOTUgfSwgeyBhOiAyMzMsIGI6IDIyNSwgYzogMTQ2IH0sIHsgYTogMjEsIGI6IDMyNSwgYzogMjIgfSwgeyBhOiA5NTMsIGI6IDI4LCBjOiAyMjMgfSwgeyBhOiAxMDkyLCBiOiAyOTAsIGM6IDM5IH0sIHsgYTogNzQ0LCBiOiAyMDAsIGM6IDE5MSB9LCB7IGE6IDE3NCwgYjogMywgYzogMjIgfSwgeyBhOiA1MzcsIGI6IDM2OCwgYzogMjQ5IH0sIHsgYTogMTE1MSwgYjogMzcxLCBjOiA4NiB9LCB7IGE6IDgxNCwgYjogMjUyLCBjOiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgYTogMjQzLA0KICogICAgIGI6IDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwLCB7IGtleVg6ICdhJywga2V5WTogJ2InLCBrZXlaOiAnYycgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IGE6IDI0MywgYjogMjA3LCBjOiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSBbDQogKiAgICAgew0KICogICAgICAgICB4OiAyNDMsDQogKiAgICAgICAgIHk6IDIwNywNCiAqICAgICB9LA0KICogICAgIHsNCiAqICAgICAgICAgeDogMjgzLA0KICogICAgICAgICB5OiAyMDcsDQogKiAgICAgfSwNCiAqIF0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfSwNCiAqIC8vICAgeyB4OiAyODMsIHk6IDIwNywgejogMTE0LjQzMDQwNDIxOTUxOTA4IH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHAsIHsgbWV0aG9kOiAna3JpZ2luZycgfSkgLy9tZXRob2Q9J2tyaWdpbmcn6LWwaW50ZXJwMktyaWdpbmcsIOm7mOiqjWZyaWVkcmljaOW8leaTjg0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjQ5ODQ2MjM1MTA4MTIzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDAuMDAwMjQzLCB5OiAwLjAwMDIwNiwgejogOTUgfSwgeyB4OiAwLjAwMDIzMywgeTogMC4wMDAyMjUsIHo6IDE0NiB9LCB7IHg6IDAuMDAwMDIxLCB5OiAwLjAwMDMyNSwgejogMjIgfSwgeyB4OiAwLjAwMDk1MywgeTogMC4wMDAwMjgsIHo6IDIyMyB9LCB7IHg6IDAuMDAxMDkyLCB5OiAwLjAwMDI5LCB6OiAzOSB9LCB7IHg6IDAuMDAwNzQ0LCB5OiAwLjAwMDIwMCwgejogMTkxIH0sIHsgeDogMC4wMDAxNzQsIHk6IDAuMDAwMDAzLCB6OiAyMiB9LCB7IHg6IDAuMDAwNTM3LCB5OiAwLjAwMDM2OCwgejogMjQ5IH0sIHsgeDogMC4wMDExNTEsIHk6IDAuMDAwMzcxLCB6OiA4NiB9LCB7IHg6IDAuMDAwODE0LCB5OiAwLjAwMDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDAuMDAwMjQzLA0KICogICAgIHk6IDAuMDAwMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAwLjAwMDI0MywgeTogMC4wMDAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2NzggfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCwgeyBzY2FsZTogMTAwMCB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODU1IH0NCiAqDQogKiAvL2ZvciBpbnRlcnAyLndrLnVtZC5qcw0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyKHBzLCBwLCB7IHVzZVN5bmM6IHRydWUgfSkgLy/kvb/nlKhpbnRlcnAyLndrLnVtZC5qc+WJh+S4jeaUr+aPtHN5bmPmqKHlvI8NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICovCmZ1bmN0aW9uIGludGVycDIocHNTcmMsIHBzVGFyLCBvcHQgPSB7fSkgewogIC8vbWV0aG9kCiAgbGV0IG1ldGhvZCA9IGdldChvcHQsICdtZXRob2QnKTsKICBpZiAobWV0aG9kICE9PSAnbmF0dXJhbE5laWdoYm9yJyAmJiBtZXRob2QgIT09ICdrcmlnaW5nJykgewogICAgbWV0aG9kID0gJ25hdHVyYWxOZWlnaGJvcic7CiAgfQoKICAvL3VzZVN5bmMKICBsZXQgdXNlU3luYyA9IGdldChvcHQsICd1c2VTeW5jJyk7CiAgaWYgKCFpc2JvbCh1c2VTeW5jKSkgewogICAgdXNlU3luYyA9IGZhbHNlOwogIH0KCiAgLy9fc3luYwogIGxldCBfc3luYyA9ICgpID0+IHsKICAgIGxldCByID0gbnVsbDsKICAgIHRyeSB7CiAgICAgIGlmIChtZXRob2QgPT09ICduYXR1cmFsTmVpZ2hib3InKSB7CiAgICAgICAgciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHNTcmMsIHBzVGFyLCBvcHQpOwogICAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PT0gJ2tyaWdpbmcnKSB7CiAgICAgICAgciA9IGludGVycDJLcmlnaW5nKHBzU3JjLCBwc1Rhciwgb3B0KTsKICAgICAgfQogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIHIgPSB7CiAgICAgICAgZXJyOiBlcnIudG9TdHJpbmcoKQogICAgICB9OwogICAgfQogICAgcmV0dXJuIHI7CiAgfTsKCiAgLy9fYXN5bmMKICBsZXQgX2FzeW5jID0gYXN5bmMgKCkgPT4gewogICAgbGV0IHIgPSBudWxsOwogICAgdHJ5IHsKICAgICAgciA9IF9zeW5jKCk7CiAgICAgIGxldCBlcnIgPSBnZXQociwgJ2VycicpOwogICAgICBpZiAoaXNlc3RyKGVycikpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gcjsKICAgICAgfQogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIGNvbnNvbGUubG9nKGVycik7CiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIudG9TdHJpbmcoKSk7CiAgICB9CiAgfTsKICBpZiAodXNlU3luYykgewogICAgcmV0dXJuIF9zeW5jKCk7CiAgfSBlbHNlIHsKICAgIHJldHVybiBfYXN5bmMoKTsKICB9Cn0KCgoKbGV0IGluc3RhbmNlID0gbnVsbApmdW5jdGlvbiBpbml0KGlucHV0KXsKCiAgICAvL2luaXQKICAgIGxldCByCiAgICAKICAgICAgICByID0gewogICAgICAgICAgICBtYWluOiBpbnRlcnAyCiAgICAgICAgfQogICAgICAgIAoKICAgIC8vb24KICAgIAoKICAgIC8vc2F2ZQogICAgaW5zdGFuY2UgPSByCgp9CgpmdW5jdGlvbiBzZW5kTWVzc2FnZShkYXRhKSB7CiAgICAKICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKGRhdGEpCiAgICAgICAgCn0KCmFzeW5jIGZ1bmN0aW9uIHJ1bihkYXRhKSB7CiAgICAvLyBjb25zb2xlLmxvZygnaW5uZXIgd29ya2VyIHJ1bicsZGF0YSkKCiAgICAvL21vZGUKICAgIGxldCBtb2RlID0gZGF0YS5tb2RlCgogICAgLy9jaGVjawogICAgaWYobW9kZSAhPT0gJ2luaXQnICYmIG1vZGUgIT09ICdjYWxsJyl7CiAgICAgICAgcmV0dXJuCiAgICB9CgogICAgLy9pbml0CiAgICBpZihtb2RlID09PSAnaW5pdCcpewogICAgICAgIAogICAgICAgIHRyeXsKCiAgICAgICAgICAgIC8vdHlwZQogICAgICAgICAgICBsZXQgdHlwZSA9IGRhdGEudHlwZQoKICAgICAgICAgICAgLy9pbnB1dAogICAgICAgICAgICBsZXQgaW5wdXQgPSBkYXRhLmlucHV0CiAgICAKICAgICAgICAgICAgLy9pbnN0YW5jZQogICAgICAgICAgICBpZih0eXBlID09PSAnZnVuY3Rpb24nKXsKICAgICAgICAgICAgICAgIGluaXQoLi4uaW5wdXQpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZih0eXBlID09PSAnb2JqZWN0Jyl7CiAgICAgICAgICAgICAgICBpbnN0YW5jZSA9IGludGVycDIKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgY2F0Y2goZXJyKXsKICAgICAgICAKICAgICAgICAgICAgLy9zZW5kTWVzc2FnZQogICAgICAgICAgICBsZXQgcmVzID0gewogICAgICAgICAgICAgICAgbW9kZTogJ2VtaXQnLAogICAgICAgICAgICAgICAgZXZOYW1lOiAnZXJyb3InLAogICAgICAgICAgICAgICAgbXNnOiBlcnIsCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VuZE1lc3NhZ2UocmVzKQoKICAgICAgICB9CiAgICAgICAgICAgIAogICAgfQoKICAgIC8vY2hlY2sKICAgIGlmKG1vZGUgPT09ICdjYWxsJyl7CiAgICAgICAgbGV0IHN0YXRlID0gJycKICAgICAgICBsZXQgbXNnID0gbnVsbAoKICAgICAgICB0cnl7CgogICAgICAgICAgICAvL2Z1bgogICAgICAgICAgICBsZXQgZnVuID0gaW5zdGFuY2VbZGF0YS5mdW5dCgogICAgICAgICAgICAvL2lucHV0CiAgICAgICAgICAgIGxldCBpbnB1dCA9IGRhdGEuaW5wdXQKCiAgICAgICAgICAgIC8vZXhlYwogICAgICAgICAgICBhd2FpdCBmdW4oLi4uaW5wdXQpCiAgICAgICAgICAgICAgICAudGhlbigoc3VjKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU9J3N1Y2Nlc3MnCiAgICAgICAgICAgICAgICAgICAgbXNnPXN1YwogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU9J2Vycm9yJwogICAgICAgICAgICAgICAgICAgIG1zZz1lcnIKICAgICAgICAgICAgICAgIH0pCgogICAgICAgIH0KICAgICAgICBjYXRjaChlcnIpewogICAgICAgICAgICBzdGF0ZSA9ICdlcnJvcicKICAgICAgICAgICAgbXNnID0gZXJyCiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vc2VuZE1lc3NhZ2UKICAgICAgICBsZXQgcmVzID0gewogICAgICAgICAgICBtb2RlOiAncmV0dXJuJywKICAgICAgICAgICAgaWQ6IGRhdGEuaWQsCiAgICAgICAgICAgIGZ1bjogZGF0YS5mdW4sCiAgICAgICAgICAgIHN0YXRlLAogICAgICAgICAgICBtc2csCiAgICAgICAgfQogICAgICAgIHNlbmRNZXNzYWdlKHJlcykKCiAgICB9Cgp9CgpmdW5jdGlvbiByZWN2TWVzc2FnZShkYXRhKSB7CiAgICAvLyBjb25zb2xlLmxvZygnaW5uZXIgd29ya2VyIHJlY3Y6JywgZGF0YSkKCiAgICAvL2RhdGFSZWN2CiAgICBsZXQgZGF0YVJlY3YgPSBkYXRhCgogICAgLy9ydW4KICAgIHJ1bihkYXRhUmVjdikKCn0KCgogICAgICAgIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgcmVjdk1lc3NhZ2UoZS5kYXRhKQogICAgICAgIH0KICAgICAgICAKCnRyeXsKCiAgICAvL+WDheS7pXVuY2F1Z2h0RXhjZXB0aW9uTW9uaXRvcuiomOmMhCwg5LiN5Y+v6Ki75YaKdW5jYXVnaHRFeGNlcHRpb27oiId1bmhhbmRsZWRSZWplY3Rpb27nm6Pogb06CiAgICAvL+aWvHdvcmtlcuWFp+iou+WGiuatpOS6jOebo+iBveacg+mYu+atok5vZGXpoJDoqK3nmoR3b3JrZXLntYLmraLooYzngrosIOS9v3dvcmtlcuW0qea9sOW+jOS7jeWtmOa0u+epuui9iSwKICAgIC8v5aSW5bGk5pS25LiN5YiwZXJyb3IvZXhpdOS6i+S7tiwgcGVuZGluZyBwcm9taXNl5rC45LmF5oe4572uLCDkuJTlrZjmtLvmrq3lsY13b3JrZXLmnIPku6Tlrr/kuLvnqIvluo/nhKHms5XpgIDlh7o7CiAgICAvL+enu+mZpOW+jHdvcmtlcuS+nemgkOioreihjOeCuuatu+S6oSwgZXJyb3Lkuovku7blgrPoh7PlpJblsaQsIOeUseWkluWxpOaVtOaJuXJlamVjdCBwZW5kaW5nCiAgICAvLyBwcm9jZXNzLm9uKCd1bmhhbmRsZWRSZWplY3Rpb24nLCAoZXJyKSA9PiB7CiAgICAvLyAgICAgY29uc29sZS5sb2coJ2lubmVyOnVuaGFuZGxlZFJlamVjdGlvbicsIGVycikKICAgIC8vIH0pCiAgICAvLyBwcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIChlcnIpID0+IHsKICAgIC8vICAgICBjb25zb2xlLmxvZygnaW5uZXI6dW5jYXVnaHRFeGNlcHRpb24nLCBlcnIpCiAgICAvLyB9KQogICAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb25Nb25pdG9yJywgKGVycikgPT4gewogICAgICAgIGNvbnNvbGUubG9nKCdpbm5lcjp1bmNhdWdodEV4Y2VwdGlvbk1vbml0b3InLCBlcnIpCiAgICB9KQoKfQpjYXRjaChlcnIpe30KCg==`;//code
|
|
394
|
+
let codeB64=`CgoKJ3VzZSBzdHJpY3QnOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQXJyYXkoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNBcnJheSgnYWJjJyk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNBcnJheShfLm5vb3ApOwogKiAvLyA9PiBmYWxzZQogKi8KdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5Owp2YXIgaXNBcnJheSQxID0gaXNBcnJheTsKCi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovCnZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwgJiYgZ2xvYmFsLk9iamVjdCA9PT0gT2JqZWN0ICYmIGdsb2JhbDsKdmFyIGZyZWVHbG9iYWwkMSA9IGZyZWVHbG9iYWw7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqLwp2YXIgZnJlZVNlbGYgPSB0eXBlb2Ygc2VsZiA9PSAnb2JqZWN0JyAmJiBzZWxmICYmIHNlbGYuT2JqZWN0ID09PSBPYmplY3QgJiYgc2VsZjsKCi8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqLwp2YXIgcm9vdCA9IGZyZWVHbG9iYWwkMSB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpOwp2YXIgcm9vdCQxID0gcm9vdDsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgU3ltYm9sID0gcm9vdCQxLlN5bWJvbDsKdmFyIFN5bWJvbCQxID0gU3ltYm9sOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kYiA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDggPSBvYmplY3RQcm90byRiLmhhc093blByb3BlcnR5OwoKLyoqCiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUKICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpCiAqIG9mIHZhbHVlcy4KICovCnZhciBuYXRpdmVPYmplY3RUb1N0cmluZyQxID0gb2JqZWN0UHJvdG8kYi50b1N0cmluZzsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3ltVG9TdHJpbmdUYWckMSA9IFN5bWJvbCQxID8gU3ltYm9sJDEudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJhdyBgdG9TdHJpbmdUYWdgLgogKi8KZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7CiAgdmFyIGlzT3duID0gaGFzT3duUHJvcGVydHkkOC5jYWxsKHZhbHVlLCBzeW1Ub1N0cmluZ1RhZyQxKSwKICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnJDFdOwogIHRyeSB7CiAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXSA9IHVuZGVmaW5lZDsKICAgIHZhciB1bm1hc2tlZCA9IHRydWU7CiAgfSBjYXRjaCAoZSkge30KICB2YXIgcmVzdWx0ID0gbmF0aXZlT2JqZWN0VG9TdHJpbmckMS5jYWxsKHZhbHVlKTsKICBpZiAodW5tYXNrZWQpIHsKICAgIGlmIChpc093bikgewogICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXSA9IHRhZzsKICAgIH0gZWxzZSB7CiAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZyQxXTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kYSA9IE9iamVjdC5wcm90b3R5cGU7CgovKioKICogVXNlZCB0byByZXNvbHZlIHRoZQogKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZykKICogb2YgdmFsdWVzLgogKi8KdmFyIG5hdGl2ZU9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8kYS50b1N0cmluZzsKCi8qKgogKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy4KICovCmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7CiAgcmV0dXJuIG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBudWxsVGFnID0gJ1tvYmplY3QgTnVsbF0nLAogIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nOwoKLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovCnZhciBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCQxID8gU3ltYm9sJDEudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldFRhZ2Agd2l0aG91dCBmYWxsYmFja3MgZm9yIGJ1Z2d5IGVudmlyb25tZW50cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuCiAqLwpmdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7CiAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkVGFnIDogbnVsbFRhZzsKICB9CiAgcmV0dXJuIHN5bVRvU3RyaW5nVGFnICYmIHN5bVRvU3RyaW5nVGFnIGluIE9iamVjdCh2YWx1ZSkgPyBnZXRSYXdUYWcodmFsdWUpIDogb2JqZWN0VG9TdHJpbmcodmFsdWUpOwp9CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgCiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgIm9iamVjdCIuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzT2JqZWN0TGlrZSh7fSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApOwogKiAvLyA9PiBmYWxzZQogKgogKiBfLmlzT2JqZWN0TGlrZShudWxsKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JzsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgc3ltYm9sVGFnJDEgPSAnW29iamVjdCBTeW1ib2xdJzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3ltYm9sLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNTeW1ib2woU3ltYm9sLml0ZXJhdG9yKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzU3ltYm9sKCdhYmMnKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fCBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHN5bWJvbFRhZyQxOwp9CgovKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovCnZhciByZUlzRGVlcFByb3AgPSAvXC58XFsoPzpbXltcXV0qfChbIiddKSg/Oig/IVwxKVteXFxdfFxcLikqP1wxKVxdLywKICByZUlzUGxhaW5Qcm9wID0gL15cdyokLzsKCi8qKgogKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUgYW5kIG5vdCBhIHByb3BlcnR5IHBhdGguCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHsKICBpZiAoaXNBcnJheSQxKHZhbHVlKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKICBpZiAodHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nIHx8IHZhbHVlID09IG51bGwgfHwgaXNTeW1ib2wodmFsdWUpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgcmV0dXJuIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkgfHwgIXJlSXNEZWVwUHJvcC50ZXN0KHZhbHVlKSB8fCBvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiBPYmplY3Qob2JqZWN0KTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZQogKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpCiAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYCkKICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzT2JqZWN0KHt9KTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc09iamVjdChfLm5vb3ApOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNPYmplY3QobnVsbCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkgewogIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlOwogIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGFzeW5jVGFnID0gJ1tvYmplY3QgQXN5bmNGdW5jdGlvbl0nLAogIGZ1bmNUYWckMSA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsCiAgZ2VuVGFnID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJywKICBwcm94eVRhZyA9ICdbb2JqZWN0IFByb3h5XSc7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzRnVuY3Rpb24oXyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0Z1bmN0aW9uKC9hYmMvKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHsKICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3IKICAvLyBpbiBTYWZhcmkgOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheXMgYW5kIG90aGVyIGNvbnN0cnVjdG9ycy4KICB2YXIgdGFnID0gYmFzZUdldFRhZyh2YWx1ZSk7CiAgcmV0dXJuIHRhZyA9PSBmdW5jVGFnJDEgfHwgdGFnID09IGdlblRhZyB8fCB0YWcgPT0gYXN5bmNUYWcgfHwgdGFnID09IHByb3h5VGFnOwp9CgovKiogVXNlZCB0byBkZXRlY3Qgb3ZlcnJlYWNoaW5nIGNvcmUtanMgc2hpbXMuICovCnZhciBjb3JlSnNEYXRhID0gcm9vdCQxWydfX2NvcmUtanNfc2hhcmVkX18nXTsKdmFyIGNvcmVKc0RhdGEkMSA9IGNvcmVKc0RhdGE7CgovKiogVXNlZCB0byBkZXRlY3QgbWV0aG9kcyBtYXNxdWVyYWRpbmcgYXMgbmF0aXZlLiAqLwp2YXIgbWFza1NyY0tleSA9IGZ1bmN0aW9uICgpIHsKICB2YXIgdWlkID0gL1teLl0rJC8uZXhlYyhjb3JlSnNEYXRhJDEgJiYgY29yZUpzRGF0YSQxLmtleXMgJiYgY29yZUpzRGF0YSQxLmtleXMuSUVfUFJPVE8gfHwgJycpOwogIHJldHVybiB1aWQgPyAnU3ltYm9sKHNyYylfMS4nICsgdWlkIDogJyc7Cn0oKTsKCi8qKgogKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBpdHMgc291cmNlIG1hc2tlZC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc01hc2tlZChmdW5jKSB7CiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiBtYXNrU3JjS2V5IGluIGZ1bmM7Cn0KCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIGZ1bmNQcm90byQxID0gRnVuY3Rpb24ucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqLwp2YXIgZnVuY1RvU3RyaW5nJDEgPSBmdW5jUHJvdG8kMS50b1N0cmluZzsKCi8qKgogKiBDb252ZXJ0cyBgZnVuY2AgdG8gaXRzIHNvdXJjZSBjb2RlLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzb3VyY2UgY29kZS4KICovCmZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHsKICBpZiAoZnVuYyAhPSBudWxsKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gZnVuY1RvU3RyaW5nJDEuY2FsbChmdW5jKTsKICAgIH0gY2F0Y2ggKGUpIHt9CiAgICB0cnkgewogICAgICByZXR1cm4gZnVuYyArICcnOwogICAgfSBjYXRjaCAoZSkge30KICB9CiAgcmV0dXJuICcnOwp9CgovKioKICogVXNlZCB0byBtYXRjaCBgUmVnRXhwYAogKiBbc3ludGF4IGNoYXJhY3RlcnNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXBhdHRlcm5zKS4KICovCnZhciByZVJlZ0V4cENoYXIgPSAvW1xcXiQuKis/KClbXF17fXxdL2c7CgovKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSkuICovCnZhciByZUlzSG9zdEN0b3IgPSAvXlxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXF0kLzsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZSwKICBvYmplY3RQcm90byQ5ID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi8KdmFyIGZ1bmNUb1N0cmluZyA9IGZ1bmNQcm90by50b1N0cmluZzsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkNyA9IG9iamVjdFByb3RvJDkuaGFzT3duUHJvcGVydHk7CgovKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqLwp2YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgKyBmdW5jVG9TdHJpbmcuY2FsbChoYXNPd25Qcm9wZXJ0eSQ3KS5yZXBsYWNlKHJlUmVnRXhwQ2hhciwgJ1xcJCYnKS5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcKCl8IGZvciAuKz8oPz1cXFxdKS9nLCAnJDEuKj8nKSArICckJyk7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNOYXRpdmVgIHdpdGhvdXQgYmFkIHNoaW0gY2hlY2tzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sCiAqICBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNOYXRpdmUodmFsdWUpIHsKICBpZiAoIWlzT2JqZWN0KHZhbHVlKSB8fCBpc01hc2tlZCh2YWx1ZSkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgdmFyIHBhdHRlcm4gPSBpc0Z1bmN0aW9uKHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3I7CiAgcmV0dXJuIHBhdHRlcm4udGVzdCh0b1NvdXJjZSh2YWx1ZSkpOwp9CgovKioKICogR2V0cyB0aGUgdmFsdWUgYXQgYGtleWAgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlLgogKi8KZnVuY3Rpb24gZ2V0VmFsdWUob2JqZWN0LCBrZXkpIHsKICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTsKfQoKLyoqCiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIG1ldGhvZCB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC4KICovCmZ1bmN0aW9uIGdldE5hdGl2ZShvYmplY3QsIGtleSkgewogIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTsKICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkOwp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBuYXRpdmVDcmVhdGUgPSBnZXROYXRpdmUoT2JqZWN0LCAnY3JlYXRlJyk7CnZhciBuYXRpdmVDcmVhdGUkMSA9IG5hdGl2ZUNyZWF0ZTsKCi8qKgogKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBoYXNoLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBjbGVhcgogKiBAbWVtYmVyT2YgSGFzaAogKi8KZnVuY3Rpb24gaGFzaENsZWFyKCkgewogIHRoaXMuX19kYXRhX18gPSBuYXRpdmVDcmVhdGUkMSA/IG5hdGl2ZUNyZWF0ZSQxKG51bGwpIDoge307CiAgdGhpcy5zaXplID0gMDsKfQoKLyoqCiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBoYXNoLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBkZWxldGUKICogQG1lbWJlck9mIEhhc2gKICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gbW9kaWZ5LgogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzaERlbGV0ZShrZXkpIHsKICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldOwogIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDsKICByZXR1cm4gcmVzdWx0Owp9CgovKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovCnZhciBIQVNIX1VOREVGSU5FRCQyID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kOCA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDYgPSBvYmplY3RQcm90byQ4Lmhhc093blByb3BlcnR5OwoKLyoqCiAqIEdldHMgdGhlIGhhc2ggdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIEhhc2gKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS4KICovCmZ1bmN0aW9uIGhhc2hHZXQoa2V5KSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fOwogIGlmIChuYXRpdmVDcmVhdGUkMSkgewogICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTsKICAgIHJldHVybiByZXN1bHQgPT09IEhBU0hfVU5ERUZJTkVEJDIgPyB1bmRlZmluZWQgOiByZXN1bHQ7CiAgfQogIHJldHVybiBoYXNPd25Qcm9wZXJ0eSQ2LmNhbGwoZGF0YSwga2V5KSA/IGRhdGFba2V5XSA6IHVuZGVmaW5lZDsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNyA9IE9iamVjdC5wcm90b3R5cGU7CgovKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi8KdmFyIGhhc093blByb3BlcnR5JDUgPSBvYmplY3RQcm90byQ3Lmhhc093blByb3BlcnR5OwoKLyoqCiAqIENoZWNrcyBpZiBhIGhhc2ggdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBoYXNoSGFzKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXzsKICByZXR1cm4gbmF0aXZlQ3JlYXRlJDEgPyBkYXRhW2tleV0gIT09IHVuZGVmaW5lZCA6IGhhc093blByb3BlcnR5JDUuY2FsbChkYXRhLCBrZXkpOwp9CgovKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovCnZhciBIQVNIX1VOREVGSU5FRCQxID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nOwoKLyoqCiAqIFNldHMgdGhlIGhhc2ggYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBIYXNoCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LgogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGhhc2ggaW5zdGFuY2UuCiAqLwpmdW5jdGlvbiBoYXNoU2V0KGtleSwgdmFsdWUpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187CiAgdGhpcy5zaXplICs9IHRoaXMuaGFzKGtleSkgPyAwIDogMTsKICBkYXRhW2tleV0gPSBuYXRpdmVDcmVhdGUkMSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gSEFTSF9VTkRFRklORUQkMSA6IHZhbHVlOwogIHJldHVybiB0aGlzOwp9CgovKioKICogQ3JlYXRlcyBhIGhhc2ggb2JqZWN0LgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBIYXNoKGVudHJpZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDsKICB0aGlzLmNsZWFyKCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdOwogICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTsKICB9Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC4KSGFzaC5wcm90b3R5cGUuY2xlYXIgPSBoYXNoQ2xlYXI7Ckhhc2gucHJvdG90eXBlWydkZWxldGUnXSA9IGhhc2hEZWxldGU7Ckhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7Ckhhc2gucHJvdG90eXBlLmhhcyA9IGhhc2hIYXM7Ckhhc2gucHJvdG90eXBlLnNldCA9IGhhc2hTZXQ7CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS4KICoKICogQHByaXZhdGUKICogQG5hbWUgY2xlYXIKICogQG1lbWJlck9mIExpc3RDYWNoZQogKi8KZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7CiAgdGhpcy5fX2RhdGFfXyA9IFtdOwogIHRoaXMuc2l6ZSA9IDA7Cn0KCi8qKgogKiBQZXJmb3JtcyBhCiAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pCiAqIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBlcXVpdmFsZW50LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLgogKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEgfTsKICogdmFyIG90aGVyID0geyAnYSc6IDEgfTsKICoKICogXy5lcShvYmplY3QsIG9iamVjdCk7CiAqIC8vID0+IHRydWUKICoKICogXy5lcShvYmplY3QsIG90aGVyKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5lcSgnYScsICdhJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5lcSgnYScsIE9iamVjdCgnYScpKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5lcShOYU4sIE5hTik7CiAqIC8vID0+IHRydWUKICovCmZ1bmN0aW9uIGVxKHZhbHVlLCBvdGhlcikgewogIHJldHVybiB2YWx1ZSA9PT0gb3RoZXIgfHwgdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjsKfQoKLyoqCiAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBga2V5YCBpcyBmb3VuZCBpbiBgYXJyYXlgIG9mIGtleS12YWx1ZSBwYWlycy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuCiAqIEBwYXJhbSB7Kn0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC4KICovCmZ1bmN0aW9uIGFzc29jSW5kZXhPZihhcnJheSwga2V5KSB7CiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsKICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgIGlmIChlcShhcnJheVtsZW5ndGhdWzBdLCBrZXkpKSB7CiAgICAgIHJldHVybiBsZW5ndGg7CiAgICB9CiAgfQogIHJldHVybiAtMTsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgc3BsaWNlID0gYXJyYXlQcm90by5zcGxpY2U7CgovKioKICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGxpc3QgY2FjaGUuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGRlbGV0ZQogKiBAbWVtYmVyT2YgTGlzdENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLAogICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTsKICBpZiAoaW5kZXggPCAwKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHZhciBsYXN0SW5kZXggPSBkYXRhLmxlbmd0aCAtIDE7CiAgaWYgKGluZGV4ID09IGxhc3RJbmRleCkgewogICAgZGF0YS5wb3AoKTsKICB9IGVsc2UgewogICAgc3BsaWNlLmNhbGwoZGF0YSwgaW5kZXgsIDEpOwogIH0KICAtLXRoaXMuc2l6ZTsKICByZXR1cm4gdHJ1ZTsKfQoKLyoqCiAqIEdldHMgdGhlIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7CiAgcmV0dXJuIGluZGV4IDwgMCA/IHVuZGVmaW5lZCA6IGRhdGFbaW5kZXhdWzFdOwp9CgovKioKICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBoYXMKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlSGFzKGtleSkgewogIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xOwp9CgovKioKICogU2V0cyB0aGUgbGlzdCBjYWNoZSBga2V5YCB0byBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBzZXQKICogQG1lbWJlck9mIExpc3RDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gbGlzdENhY2hlU2V0KGtleSwgdmFsdWUpIHsKICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sCiAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpOwogIGlmIChpbmRleCA8IDApIHsKICAgICsrdGhpcy5zaXplOwogICAgZGF0YS5wdXNoKFtrZXksIHZhbHVlXSk7CiAgfSBlbHNlIHsKICAgIGRhdGFbaW5kZXhdWzFdID0gdmFsdWU7CiAgfQogIHJldHVybiB0aGlzOwp9CgovKioKICogQ3JlYXRlcyBhbiBsaXN0IGNhY2hlIG9iamVjdC4KICoKICogQHByaXZhdGUKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLgogKi8KZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDsKICB0aGlzLmNsZWFyKCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdOwogICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTsKICB9Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBMaXN0Q2FjaGVgLgpMaXN0Q2FjaGUucHJvdG90eXBlLmNsZWFyID0gbGlzdENhY2hlQ2xlYXI7Ckxpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlOwpMaXN0Q2FjaGUucHJvdG90eXBlLmdldCA9IGxpc3RDYWNoZUdldDsKTGlzdENhY2hlLnByb3RvdHlwZS5oYXMgPSBsaXN0Q2FjaGVIYXM7Ckxpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0OwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgTWFwID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ01hcCcpOwp2YXIgTWFwJDEgPSBNYXA7CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbWFwLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBjbGVhcgogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICovCmZ1bmN0aW9uIG1hcENhY2hlQ2xlYXIoKSB7CiAgdGhpcy5zaXplID0gMDsKICB0aGlzLl9fZGF0YV9fID0gewogICAgJ2hhc2gnOiBuZXcgSGFzaCgpLAogICAgJ21hcCc6IG5ldyAoTWFwJDEgfHwgTGlzdENhY2hlKSgpLAogICAgJ3N0cmluZyc6IG5ldyBIYXNoKCkKICB9Owp9CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHVzZSBhcyB1bmlxdWUgb2JqZWN0IGtleS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc0tleWFibGUodmFsdWUpIHsKICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKICByZXR1cm4gdHlwZSA9PSAnc3RyaW5nJyB8fCB0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicgPyB2YWx1ZSAhPT0gJ19fcHJvdG9fXycgOiB2YWx1ZSA9PT0gbnVsbDsKfQoKLyoqCiAqIEdldHMgdGhlIGRhdGEgZm9yIGBtYXBgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gbWFwIFRoZSBtYXAgdG8gcXVlcnkuCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXAgZGF0YS4KICovCmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHsKICB2YXIgZGF0YSA9IG1hcC5fX2RhdGFfXzsKICByZXR1cm4gaXNLZXlhYmxlKGtleSkgPyBkYXRhW3R5cGVvZiBrZXkgPT0gJ3N0cmluZycgPyAnc3RyaW5nJyA6ICdoYXNoJ10gOiBkYXRhLm1hcDsKfQoKLyoqCiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGRlbGV0ZQogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIG1hcENhY2hlRGVsZXRlKGtleSkgewogIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7CiAgdGhpcy5zaXplIC09IHJlc3VsdCA/IDEgOiAwOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBHZXRzIHRoZSBtYXAgdmFsdWUgZm9yIGBrZXlgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBnZXQKICogQG1lbWJlck9mIE1hcENhY2hlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZUdldChrZXkpIHsKICByZXR1cm4gZ2V0TWFwRGF0YSh0aGlzLCBrZXkpLmdldChrZXkpOwp9CgovKioKICogQ2hlY2tzIGlmIGEgbWFwIHZhbHVlIGZvciBga2V5YCBleGlzdHMuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGhhcwogKiBAbWVtYmVyT2YgTWFwQ2FjaGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIG1hcENhY2hlSGFzKGtleSkgewogIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuaGFzKGtleSk7Cn0KCi8qKgogKiBTZXRzIHRoZSBtYXAgYGtleWAgdG8gYHZhbHVlYC4KICoKICogQHByaXZhdGUKICogQG5hbWUgc2V0CiAqIEBtZW1iZXJPZiBNYXBDYWNoZQogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC4KICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuCiAqLwpmdW5jdGlvbiBtYXBDYWNoZVNldChrZXksIHZhbHVlKSB7CiAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksCiAgICBzaXplID0gZGF0YS5zaXplOwogIGRhdGEuc2V0KGtleSwgdmFsdWUpOwogIHRoaXMuc2l6ZSArPSBkYXRhLnNpemUgPT0gc2l6ZSA/IDAgOiAxOwogIHJldHVybiB0aGlzOwp9CgovKioKICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7CiAgdGhpcy5jbGVhcigpOwogIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7CiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTsKICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7CiAgfQp9CgovLyBBZGQgbWV0aG9kcyB0byBgTWFwQ2FjaGVgLgpNYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyOwpNYXBDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbWFwQ2FjaGVEZWxldGU7Ck1hcENhY2hlLnByb3RvdHlwZS5nZXQgPSBtYXBDYWNoZUdldDsKTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzOwpNYXBDYWNoZS5wcm90b3R5cGUuc2V0ID0gbWFwQ2FjaGVTZXQ7CgovKiogRXJyb3IgbWVzc2FnZSBjb25zdGFudHMuICovCnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7CgovKioKICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgbWVtb2l6ZXMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuIElmIGByZXNvbHZlcmAgaXMKICogcHJvdmlkZWQsIGl0IGRldGVybWluZXMgdGhlIGNhY2hlIGtleSBmb3Igc3RvcmluZyB0aGUgcmVzdWx0IGJhc2VkIG9uIHRoZQogKiBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgZmlyc3QgYXJndW1lbnQKICogcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uIGlzIHVzZWQgYXMgdGhlIG1hcCBjYWNoZSBrZXkuIFRoZSBgZnVuY2AKICogaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24uCiAqCiAqICoqTm90ZToqKiBUaGUgY2FjaGUgaXMgZXhwb3NlZCBhcyB0aGUgYGNhY2hlYCBwcm9wZXJ0eSBvbiB0aGUgbWVtb2l6ZWQKICogZnVuY3Rpb24uIEl0cyBjcmVhdGlvbiBtYXkgYmUgY3VzdG9taXplZCBieSByZXBsYWNpbmcgdGhlIGBfLm1lbW9pemUuQ2FjaGVgCiAqIGNvbnN0cnVjdG9yIHdpdGggb25lIHdob3NlIGluc3RhbmNlcyBpbXBsZW1lbnQgdGhlCiAqIFtgTWFwYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcHJvcGVydGllcy1vZi10aGUtbWFwLXByb3RvdHlwZS1vYmplY3QpCiAqIG1ldGhvZCBpbnRlcmZhY2Ugb2YgYGNsZWFyYCwgYGRlbGV0ZWAsIGBnZXRgLCBgaGFzYCwgYW5kIGBzZXRgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgRnVuY3Rpb24KICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgb3V0cHV0IG1lbW9pemVkLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzb2x2ZXJdIFRoZSBmdW5jdGlvbiB0byByZXNvbHZlIHRoZSBjYWNoZSBrZXkuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG1lbW9pemVkIGZ1bmN0aW9uLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9OwogKiB2YXIgb3RoZXIgPSB7ICdjJzogMywgJ2QnOiA0IH07CiAqCiAqIHZhciB2YWx1ZXMgPSBfLm1lbW9pemUoXy52YWx1ZXMpOwogKiB2YWx1ZXMob2JqZWN0KTsKICogLy8gPT4gWzEsIDJdCiAqCiAqIHZhbHVlcyhvdGhlcik7CiAqIC8vID0+IFszLCA0XQogKgogKiBvYmplY3QuYSA9IDI7CiAqIHZhbHVlcyhvYmplY3QpOwogKiAvLyA9PiBbMSwgMl0KICoKICogLy8gTW9kaWZ5IHRoZSByZXN1bHQgY2FjaGUuCiAqIHZhbHVlcy5jYWNoZS5zZXQob2JqZWN0LCBbJ2EnLCAnYiddKTsKICogdmFsdWVzKG9iamVjdCk7CiAqIC8vID0+IFsnYScsICdiJ10KICoKICogLy8gUmVwbGFjZSBgXy5tZW1vaXplLkNhY2hlYC4KICogXy5tZW1vaXplLkNhY2hlID0gV2Vha01hcDsKICovCmZ1bmN0aW9uIG1lbW9pemUoZnVuYywgcmVzb2x2ZXIpIHsKICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJyB8fCByZXNvbHZlciAhPSBudWxsICYmIHR5cGVvZiByZXNvbHZlciAhPSAnZnVuY3Rpb24nKSB7CiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7CiAgfQogIHZhciBtZW1vaXplZCA9IGZ1bmN0aW9uICgpIHsKICAgIHZhciBhcmdzID0gYXJndW1lbnRzLAogICAgICBrZXkgPSByZXNvbHZlciA/IHJlc29sdmVyLmFwcGx5KHRoaXMsIGFyZ3MpIDogYXJnc1swXSwKICAgICAgY2FjaGUgPSBtZW1vaXplZC5jYWNoZTsKICAgIGlmIChjYWNoZS5oYXMoa2V5KSkgewogICAgICByZXR1cm4gY2FjaGUuZ2V0KGtleSk7CiAgICB9CiAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTsKICAgIG1lbW9pemVkLmNhY2hlID0gY2FjaGUuc2V0KGtleSwgcmVzdWx0KSB8fCBjYWNoZTsKICAgIHJldHVybiByZXN1bHQ7CiAgfTsKICBtZW1vaXplZC5jYWNoZSA9IG5ldyAobWVtb2l6ZS5DYWNoZSB8fCBNYXBDYWNoZSkoKTsKICByZXR1cm4gbWVtb2l6ZWQ7Cn0KCi8vIEV4cG9zZSBgTWFwQ2FjaGVgLgptZW1vaXplLkNhY2hlID0gTWFwQ2FjaGU7CgovKiogVXNlZCBhcyB0aGUgbWF4aW11bSBtZW1vaXplIGNhY2hlIHNpemUuICovCnZhciBNQVhfTUVNT0laRV9TSVpFID0gNTAwOwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tZW1vaXplYCB3aGljaCBjbGVhcnMgdGhlIG1lbW9pemVkIGZ1bmN0aW9uJ3MKICogY2FjaGUgd2hlbiBpdCBleGNlZWRzIGBNQVhfTUVNT0laRV9TSVpFYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgb3V0cHV0IG1lbW9pemVkLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIG1lbW9pemVDYXBwZWQoZnVuYykgewogIHZhciByZXN1bHQgPSBtZW1vaXplKGZ1bmMsIGZ1bmN0aW9uIChrZXkpIHsKICAgIGlmIChjYWNoZS5zaXplID09PSBNQVhfTUVNT0laRV9TSVpFKSB7CiAgICAgIGNhY2hlLmNsZWFyKCk7CiAgICB9CiAgICByZXR1cm4ga2V5OwogIH0pOwogIHZhciBjYWNoZSA9IHJlc3VsdC5jYWNoZTsKICByZXR1cm4gcmVzdWx0Owp9CgovKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovCnZhciByZVByb3BOYW1lID0gL1teLltcXV0rfFxbKD86KC0/XGQrKD86XC5cZCspPyl8KFsiJ10pKCg/Oig/IVwyKVteXFxdfFxcLikqPylcMilcXXwoPz0oPzpcLnxcW1xdKSg/OlwufFxbXF18JCkpL2c7CgovKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi8KdmFyIHJlRXNjYXBlQ2hhciA9IC9cXChcXCk/L2c7CgovKioKICogQ29udmVydHMgYHN0cmluZ2AgdG8gYSBwcm9wZXJ0eSBwYXRoIGFycmF5LgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LgogKi8KdmFyIHN0cmluZ1RvUGF0aCA9IG1lbW9pemVDYXBwZWQoZnVuY3Rpb24gKHN0cmluZykgewogIHZhciByZXN1bHQgPSBbXTsKICBpZiAoc3RyaW5nLmNoYXJDb2RlQXQoMCkgPT09IDQ2IC8qIC4gKi8pIHsKICAgIHJlc3VsdC5wdXNoKCcnKTsKICB9CiAgc3RyaW5nLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24gKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdWJTdHJpbmcpIHsKICAgIHJlc3VsdC5wdXNoKHF1b3RlID8gc3ViU3RyaW5nLnJlcGxhY2UocmVFc2NhcGVDaGFyLCAnJDEnKSA6IG51bWJlciB8fCBtYXRjaCk7CiAgfSk7CiAgcmV0dXJuIHJlc3VsdDsKfSk7CnZhciBzdHJpbmdUb1BhdGgkMSA9IHN0cmluZ1RvUGF0aDsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWFwYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUKICogc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuCiAqLwpmdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLAogICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBJTkZJTklUWSQyID0gMSAvIDA7CgovKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi8KdmFyIHN5bWJvbFByb3RvJDEgPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnByb3RvdHlwZSA6IHVuZGVmaW5lZCwKICBzeW1ib2xUb1N0cmluZyA9IHN5bWJvbFByb3RvJDEgPyBzeW1ib2xQcm90byQxLnRvU3RyaW5nIDogdW5kZWZpbmVkOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvU3RyaW5nYCB3aGljaCBkb2Vzbid0IGNvbnZlcnQgbnVsbGlzaAogKiB2YWx1ZXMgdG8gZW1wdHkgc3RyaW5ncy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RyaW5nLgogKi8KZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7CiAgLy8gRXhpdCBlYXJseSBmb3Igc3RyaW5ncyB0byBhdm9pZCBhIHBlcmZvcm1hbmNlIGhpdCBpbiBzb21lIGVudmlyb25tZW50cy4KICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKSB7CiAgICByZXR1cm4gdmFsdWU7CiAgfQogIGlmIChpc0FycmF5JDEodmFsdWUpKSB7CiAgICAvLyBSZWN1cnNpdmVseSBjb252ZXJ0IHZhbHVlcyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLgogICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCBiYXNlVG9TdHJpbmcpICsgJyc7CiAgfQogIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHsKICAgIHJldHVybiBzeW1ib2xUb1N0cmluZyA/IHN5bWJvbFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7CiAgfQogIHZhciByZXN1bHQgPSB2YWx1ZSArICcnOwogIHJldHVybiByZXN1bHQgPT0gJzAnICYmIDEgLyB2YWx1ZSA9PSAtSU5GSU5JVFkkMiA/ICctMCcgOiByZXN1bHQ7Cn0KCi8qKgogKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgZm9yIGBudWxsYAogKiBhbmQgYHVuZGVmaW5lZGAgdmFsdWVzLiBUaGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy4KICogQGV4YW1wbGUKICoKICogXy50b1N0cmluZyhudWxsKTsKICogLy8gPT4gJycKICoKICogXy50b1N0cmluZygtMCk7CiAqIC8vID0+ICctMCcKICoKICogXy50b1N0cmluZyhbMSwgMiwgM10pOwogKiAvLyA9PiAnMSwyLDMnCiAqLwpmdW5jdGlvbiB0b1N0cmluZyh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiBiYXNlVG9TdHJpbmcodmFsdWUpOwp9CgovKioKICogQ2FzdHMgYHZhbHVlYCB0byBhIHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LgogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNhc3QgcHJvcGVydHkgcGF0aCBhcnJheS4KICovCmZ1bmN0aW9uIGNhc3RQYXRoKHZhbHVlLCBvYmplY3QpIHsKICBpZiAoaXNBcnJheSQxKHZhbHVlKSkgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICByZXR1cm4gaXNLZXkodmFsdWUsIG9iamVjdCkgPyBbdmFsdWVdIDogc3RyaW5nVG9QYXRoJDEodG9TdHJpbmcodmFsdWUpKTsKfQoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBJTkZJTklUWSQxID0gMSAvIDA7CgovKioKICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBrZXkgaWYgaXQncyBub3QgYSBzdHJpbmcgb3Igc3ltYm9sLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7c3RyaW5nfHN5bWJvbH0gUmV0dXJucyB0aGUga2V5LgogKi8KZnVuY3Rpb24gdG9LZXkodmFsdWUpIHsKICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IGlzU3ltYm9sKHZhbHVlKSkgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICB2YXIgcmVzdWx0ID0gdmFsdWUgKyAnJzsKICByZXR1cm4gcmVzdWx0ID09ICcwJyAmJiAxIC8gdmFsdWUgPT0gLUlORklOSVRZJDEgPyAnLTAnIDogcmVzdWx0Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZ2V0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZmF1bHQgdmFsdWVzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS4KICovCmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoKSB7CiAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7CiAgdmFyIGluZGV4ID0gMCwKICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoOwogIHdoaWxlIChvYmplY3QgIT0gbnVsbCAmJiBpbmRleCA8IGxlbmd0aCkgewogICAgb2JqZWN0ID0gb2JqZWN0W3RvS2V5KHBhdGhbaW5kZXgrK10pXTsKICB9CiAgcmV0dXJuIGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCA/IG9iamVjdCA6IHVuZGVmaW5lZDsKfQoKLyoqCiAqIEdldHMgdGhlIHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzCiAqIGB1bmRlZmluZWRgLCB0aGUgYGRlZmF1bHRWYWx1ZWAgaXMgcmV0dXJuZWQgaW4gaXRzIHBsYWNlLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAzLjcuMAogKiBAY2F0ZWdvcnkgT2JqZWN0CiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC4KICogQHBhcmFtIHsqfSBbZGVmYXVsdFZhbHVlXSBUaGUgdmFsdWUgcmV0dXJuZWQgZm9yIGB1bmRlZmluZWRgIHJlc29sdmVkIHZhbHVlcy4KICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9OwogKgogKiBfLmdldChvYmplY3QsICdhWzBdLmIuYycpOwogKiAvLyA9PiAzCiAqCiAqIF8uZ2V0KG9iamVjdCwgWydhJywgJzAnLCAnYicsICdjJ10pOwogKiAvLyA9PiAzCiAqCiAqIF8uZ2V0KG9iamVjdCwgJ2EuYi5jJywgJ2RlZmF1bHQnKTsKICogLy8gPT4gJ2RlZmF1bHQnCiAqLwpmdW5jdGlvbiBnZXQob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHsKICB2YXIgcmVzdWx0ID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7CiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdFZhbHVlIDogcmVzdWx0Owp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBib29sVGFnJDIgPSAnW29iamVjdCBCb29sZWFuXSc7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGJvb2xlYW4gcHJpbWl0aXZlIG9yIG9iamVjdC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYm9vbGVhbiwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQm9vbGVhbihmYWxzZSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0Jvb2xlYW4obnVsbCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0Jvb2xlYW4odmFsdWUpIHsKICByZXR1cm4gdmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09IGZhbHNlIHx8IGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYm9vbFRhZyQyOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCumJvb2xlYW4NCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2JvbC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNib2woZmFsc2UpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2JvbCh2KSB7CiAgcmV0dXJuIGlzQm9vbGVhbih2KTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrlrZfkuLINCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc3N0ci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIoMCkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzc3RyKCcwJykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIoJycpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc3N0cih2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IFN0cmluZ10nOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuacieaViOWtl+S4sg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzZXN0ci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNlc3RyKCcxLjI1JykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNlc3RyKDEyNSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXN0cignJykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2VzdHIodikgewogIC8vY2hlY2sKICBpZiAoaXNzdHIodikpIHsKICAgIGlmICh2ICE9PSAnJykgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvcgogKiBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLgogKi8KZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICByZXR1cm4gYXJyYXk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgbWV0aG9kcyBsaWtlIGBfLmZvckluYCBhbmQgYF8uZm9yT3duYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkgewogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHsKICAgIHZhciBpbmRleCA9IC0xLAogICAgICBpdGVyYWJsZSA9IE9iamVjdChvYmplY3QpLAogICAgICBwcm9wcyA9IGtleXNGdW5jKG9iamVjdCksCiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDsKICAgIHdoaWxlIChsZW5ndGgtLSkgewogICAgICB2YXIga2V5ID0gcHJvcHNbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF07CiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgcmV0dXJuIG9iamVjdDsKICB9Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JPd25gIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYG9iamVjdGAKICogcHJvcGVydGllcyByZXR1cm5lZCBieSBga2V5c0Z1bmNgIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuCiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC4KICovCnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpOwp2YXIgYmFzZUZvciQxID0gYmFzZUZvcjsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50aW1lc2Agd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzCiAqIG9yIG1heCBhcnJheSBsZW5ndGggY2hlY2tzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHJlc3VsdHMuCiAqLwpmdW5jdGlvbiBiYXNlVGltZXMobiwgaXRlcmF0ZWUpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IEFycmF5KG4pOwogIHdoaWxlICgrK2luZGV4IDwgbikgewogICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqLwp2YXIgYXJnc1RhZyQyID0gJ1tvYmplY3QgQXJndW1lbnRzXSc7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNBcmd1bWVudHNgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LAogKi8KZnVuY3Rpb24gYmFzZUlzQXJndW1lbnRzKHZhbHVlKSB7CiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZyQyOwp9CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQ2ID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkNCA9IG9iamVjdFByb3RvJDYuaGFzT3duUHJvcGVydHk7CgovKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi8KdmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlJDEgPSBvYmplY3RQcm90byQ2LnByb3BlcnR5SXNFbnVtZXJhYmxlOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxpa2VseSBhbiBgYXJndW1lbnRzYCBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsCiAqICBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pOwogKiAvLyA9PiBmYWxzZQogKi8KdmFyIGlzQXJndW1lbnRzID0gYmFzZUlzQXJndW1lbnRzKGZ1bmN0aW9uICgpIHsKICByZXR1cm4gYXJndW1lbnRzOwp9KCkpID8gYmFzZUlzQXJndW1lbnRzIDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkkNC5jYWxsKHZhbHVlLCAnY2FsbGVlJykgJiYgIXByb3BlcnR5SXNFbnVtZXJhYmxlJDEuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpOwp9Owp2YXIgaXNBcmd1bWVudHMkMSA9IGlzQXJndW1lbnRzOwoKLyoqCiAqIFRoaXMgbWV0aG9kIHJldHVybnMgYGZhbHNlYC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4xMy4wCiAqIEBjYXRlZ29yeSBVdGlsCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8udGltZXMoMiwgXy5zdHViRmFsc2UpOwogKiAvLyA9PiBbZmFsc2UsIGZhbHNlXQogKi8KZnVuY3Rpb24gc3R1YkZhbHNlKCkgewogIHJldHVybiBmYWxzZTsKfQoKLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi8KdmFyIGZyZWVFeHBvcnRzJDEgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovCnZhciBmcmVlTW9kdWxlJDEgPSBmcmVlRXhwb3J0cyQxICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlOwoKLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi8KdmFyIG1vZHVsZUV4cG9ydHMkMSA9IGZyZWVNb2R1bGUkMSAmJiBmcmVlTW9kdWxlJDEuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHMkMTsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyQxID8gcm9vdCQxLkJ1ZmZlciA6IHVuZGVmaW5lZDsKCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi8KdmFyIG5hdGl2ZUlzQnVmZmVyID0gQnVmZmVyID8gQnVmZmVyLmlzQnVmZmVyIDogdW5kZWZpbmVkOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjMuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBidWZmZXIsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc0J1ZmZlcihuZXcgQnVmZmVyKDIpKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQnVmZmVyKG5ldyBVaW50OEFycmF5KDIpKTsKICogLy8gPT4gZmFsc2UKICovCnZhciBpc0J1ZmZlciA9IG5hdGl2ZUlzQnVmZmVyIHx8IHN0dWJGYWxzZTsKdmFyIGlzQnVmZmVyJDEgPSBpc0J1ZmZlcjsKCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgTUFYX1NBRkVfSU5URUdFUiQxID0gOTAwNzE5OTI1NDc0MDk5MTsKCi8qKiBVc2VkIHRvIGRldGVjdCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy4gKi8KdmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXGQqKSQvOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPU1BWF9TQUZFX0lOVEVHRVJdIFRoZSB1cHBlciBib3VuZHMgb2YgYSB2YWxpZCBpbmRleC4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNJbmRleCh2YWx1ZSwgbGVuZ3RoKSB7CiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyBNQVhfU0FGRV9JTlRFR0VSJDEgOiBsZW5ndGg7CiAgcmV0dXJuICEhbGVuZ3RoICYmICh0eXBlID09ICdudW1iZXInIHx8IHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7Cn0KCi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqLwp2YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGxlbmd0aC4KICoKICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24KICogW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvbGVuZ3RoKS4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgbGVuZ3RoLCBlbHNlIGBmYWxzZWAuCiAqIEBleGFtcGxlCiAqCiAqIF8uaXNMZW5ndGgoMyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0xlbmd0aChOdW1iZXIuTUlOX1ZBTFVFKTsKICogLy8gPT4gZmFsc2UKICoKICogXy5pc0xlbmd0aChJbmZpbml0eSk7CiAqIC8vID0+IGZhbHNlCiAqCiAqIF8uaXNMZW5ndGgoJzMnKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzTGVuZ3RoKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGFyZ3NUYWckMSA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLAogIGFycmF5VGFnJDEgPSAnW29iamVjdCBBcnJheV0nLAogIGJvb2xUYWckMSA9ICdbb2JqZWN0IEJvb2xlYW5dJywKICBkYXRlVGFnJDEgPSAnW29iamVjdCBEYXRlXScsCiAgZXJyb3JUYWckMSA9ICdbb2JqZWN0IEVycm9yXScsCiAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsCiAgbWFwVGFnJDMgPSAnW29iamVjdCBNYXBdJywKICBudW1iZXJUYWckMiA9ICdbb2JqZWN0IE51bWJlcl0nLAogIG9iamVjdFRhZyQyID0gJ1tvYmplY3QgT2JqZWN0XScsCiAgcmVnZXhwVGFnJDEgPSAnW29iamVjdCBSZWdFeHBdJywKICBzZXRUYWckMyA9ICdbb2JqZWN0IFNldF0nLAogIHN0cmluZ1RhZyQyID0gJ1tvYmplY3QgU3RyaW5nXScsCiAgd2Vha01hcFRhZyQxID0gJ1tvYmplY3QgV2Vha01hcF0nOwp2YXIgYXJyYXlCdWZmZXJUYWckMSA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsCiAgZGF0YVZpZXdUYWckMiA9ICdbb2JqZWN0IERhdGFWaWV3XScsCiAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLAogIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJywKICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsCiAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsCiAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsCiAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsCiAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJywKICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLAogIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7CgovKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovCnZhciB0eXBlZEFycmF5VGFncyA9IHt9Owp0eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlOwp0eXBlZEFycmF5VGFnc1thcmdzVGFnJDFdID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWckMV0gPSB0eXBlZEFycmF5VGFnc1thcnJheUJ1ZmZlclRhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tkYXRhVmlld1RhZyQyXSA9IHR5cGVkQXJyYXlUYWdzW2RhdGVUYWckMV0gPSB0eXBlZEFycmF5VGFnc1tlcnJvclRhZyQxXSA9IHR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnJDNdID0gdHlwZWRBcnJheVRhZ3NbbnVtYmVyVGFnJDJdID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnJDJdID0gdHlwZWRBcnJheVRhZ3NbcmVnZXhwVGFnJDFdID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnJDNdID0gdHlwZWRBcnJheVRhZ3Nbc3RyaW5nVGFnJDJdID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZyQxXSA9IGZhbHNlOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzVHlwZWRBcnJheWAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHR5cGVkIGFycmF5LCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNUeXBlZEFycmF5KHZhbHVlKSB7CiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW2Jhc2VHZXRUYWcodmFsdWUpXTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuYXJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0b3JpbmcgbWV0YWRhdGEuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNhcCBhcmd1bWVudHMgZm9yLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBiYXNlVW5hcnkoZnVuYykgewogIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHsKICAgIHJldHVybiBmdW5jKHZhbHVlKTsKICB9Owp9CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqLwp2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7CgovKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovCnZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7CgovKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqLwp2YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0czsKCi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgcHJvY2Vzc2AgZnJvbSBOb2RlLmpzLiAqLwp2YXIgZnJlZVByb2Nlc3MgPSBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwkMS5wcm9jZXNzOwoKLyoqIFVzZWQgdG8gYWNjZXNzIGZhc3RlciBOb2RlLmpzIGhlbHBlcnMuICovCnZhciBub2RlVXRpbCA9IGZ1bmN0aW9uICgpIHsKICB0cnkgewogICAgLy8gVXNlIGB1dGlsLnR5cGVzYCBmb3IgTm9kZS5qcyAxMCsuCiAgICB2YXIgdHlwZXMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUucmVxdWlyZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUoJ3V0aWwnKS50eXBlczsKICAgIGlmICh0eXBlcykgewogICAgICByZXR1cm4gdHlwZXM7CiAgICB9CgogICAgLy8gTGVnYWN5IGBwcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKWAgZm9yIE5vZGUuanMgPCAxMC4KICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTsKICB9IGNhdGNoIChlKSB7fQp9KCk7CnZhciBub2RlVXRpbCQxID0gbm9kZVV0aWw7CgovKiBOb2RlLmpzIGhlbHBlciByZWZlcmVuY2VzLiAqLwp2YXIgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsJDEgJiYgbm9kZVV0aWwkMS5pc1R5cGVkQXJyYXk7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAzLjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc1R5cGVkQXJyYXkoW10pOwogKiAvLyA9PiBmYWxzZQogKi8KdmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5Owp2YXIgaXNUeXBlZEFycmF5JDEgPSBpc1R5cGVkQXJyYXk7CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQ1ID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkMyA9IG9iamVjdFByb3RvJDUuaGFzT3duUHJvcGVydHk7CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiB0aGUgYXJyYXktbGlrZSBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS4KICogQHBhcmFtIHtib29sZWFufSBpbmhlcml0ZWQgU3BlY2lmeSByZXR1cm5pbmcgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVzLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLgogKi8KZnVuY3Rpb24gYXJyYXlMaWtlS2V5cyh2YWx1ZSwgaW5oZXJpdGVkKSB7CiAgdmFyIGlzQXJyID0gaXNBcnJheSQxKHZhbHVlKSwKICAgIGlzQXJnID0gIWlzQXJyICYmIGlzQXJndW1lbnRzJDEodmFsdWUpLAogICAgaXNCdWZmID0gIWlzQXJyICYmICFpc0FyZyAmJiBpc0J1ZmZlciQxKHZhbHVlKSwKICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkkMSh2YWx1ZSksCiAgICBza2lwSW5kZXhlcyA9IGlzQXJyIHx8IGlzQXJnIHx8IGlzQnVmZiB8fCBpc1R5cGUsCiAgICByZXN1bHQgPSBza2lwSW5kZXhlcyA/IGJhc2VUaW1lcyh2YWx1ZS5sZW5ndGgsIFN0cmluZykgOiBbXSwKICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7CiAgZm9yICh2YXIga2V5IGluIHZhbHVlKSB7CiAgICBpZiAoKGluaGVyaXRlZCB8fCBoYXNPd25Qcm9wZXJ0eSQzLmNhbGwodmFsdWUsIGtleSkpICYmICEoc2tpcEluZGV4ZXMgJiYgKAogICAgLy8gU2FmYXJpIDkgaGFzIGVudW1lcmFibGUgYGFyZ3VtZW50cy5sZW5ndGhgIGluIHN0cmljdCBtb2RlLgogICAga2V5ID09ICdsZW5ndGgnIHx8CiAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy4KICAgIGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykgfHwKICAgIC8vIFBoYW50b21KUyAyIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIHR5cGVkIGFycmF5cy4KICAgIGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykgfHwKICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy4KICAgIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSkpIHsKICAgICAgcmVzdWx0LnB1c2goa2V5KTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8kNCA9IE9iamVjdC5wcm90b3R5cGU7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcHJvdG90eXBlLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkgewogIHZhciBDdG9yID0gdmFsdWUgJiYgdmFsdWUuY29uc3RydWN0b3IsCiAgICBwcm90byA9IHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgfHwgb2JqZWN0UHJvdG8kNDsKICByZXR1cm4gdmFsdWUgPT09IHByb3RvOwp9CgovKioKICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBUaGUgYXJndW1lbnQgdHJhbnNmb3JtLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIG92ZXJBcmcoZnVuYywgdHJhbnNmb3JtKSB7CiAgcmV0dXJuIGZ1bmN0aW9uIChhcmcpIHsKICAgIHJldHVybiBmdW5jKHRyYW5zZm9ybShhcmcpKTsKICB9Owp9CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovCnZhciBuYXRpdmVLZXlzID0gb3ZlckFyZyhPYmplY3Qua2V5cywgT2JqZWN0KTsKdmFyIG5hdGl2ZUtleXMkMSA9IG5hdGl2ZUtleXM7CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQzID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqLwp2YXIgaGFzT3duUHJvcGVydHkkMiA9IG9iamVjdFByb3RvJDMuaGFzT3duUHJvcGVydHk7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ua2V5c2Agd2hpY2ggZG9lc24ndCB0cmVhdCBzcGFyc2UgYXJyYXlzIGFzIGRlbnNlLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuCiAqLwpmdW5jdGlvbiBiYXNlS2V5cyhvYmplY3QpIHsKICBpZiAoIWlzUHJvdG90eXBlKG9iamVjdCkpIHsKICAgIHJldHVybiBuYXRpdmVLZXlzJDEob2JqZWN0KTsKICB9CiAgdmFyIHJlc3VsdCA9IFtdOwogIGZvciAodmFyIGtleSBpbiBPYmplY3Qob2JqZWN0KSkgewogICAgaWYgKGhhc093blByb3BlcnR5JDIuY2FsbChvYmplY3QsIGtleSkgJiYga2V5ICE9ICdjb25zdHJ1Y3RvcicpIHsKICAgICAgcmVzdWx0LnB1c2goa2V5KTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UuIEEgdmFsdWUgaXMgY29uc2lkZXJlZCBhcnJheS1saWtlIGlmIGl0J3MKICogbm90IGEgZnVuY3Rpb24gYW5kIGhhcyBhIGB2YWx1ZS5sZW5ndGhgIHRoYXQncyBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiBvcgogKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZSwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzQXJyYXlMaWtlKFsxLCAyLCAzXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc0FycmF5TGlrZShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQXJyYXlMaWtlKCdhYmMnKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmlzQXJyYXlMaWtlKF8ubm9vcCk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBpc0FycmF5TGlrZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgIWlzRnVuY3Rpb24odmFsdWUpOwp9CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuCiAqCiAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLiBTZWUgdGhlCiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cykKICogZm9yIG1vcmUgZGV0YWlscy4KICoKICogQHN0YXRpYwogKiBAc2luY2UgMC4xLjAKICogQG1lbWJlck9mIF8KICogQGNhdGVnb3J5IE9iamVjdAogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuCiAqIEBleGFtcGxlCiAqCiAqIGZ1bmN0aW9uIEZvbygpIHsKICogICB0aGlzLmEgPSAxOwogKiAgIHRoaXMuYiA9IDI7CiAqIH0KICoKICogRm9vLnByb3RvdHlwZS5jID0gMzsKICoKICogXy5rZXlzKG5ldyBGb28pOwogKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpCiAqCiAqIF8ua2V5cygnaGknKTsKICogLy8gPT4gWycwJywgJzEnXQogKi8KZnVuY3Rpb24ga2V5cyhvYmplY3QpIHsKICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JPd25gIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC4KICovCmZ1bmN0aW9uIGJhc2VGb3JPd24ob2JqZWN0LCBpdGVyYXRlZSkgewogIHJldHVybiBvYmplY3QgJiYgYmFzZUZvciQxKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpOwp9CgovKioKICogQ3JlYXRlcyBhIGBiYXNlRWFjaGAgb3IgYGJhc2VFYWNoUmlnaHRgIGZ1bmN0aW9uLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi4KICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uCiAqLwpmdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7CiAgcmV0dXJuIGZ1bmN0aW9uIChjb2xsZWN0aW9uLCBpdGVyYXRlZSkgewogICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkgewogICAgICByZXR1cm4gY29sbGVjdGlvbjsKICAgIH0KICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHsKICAgICAgcmV0dXJuIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTsKICAgIH0KICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aCwKICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMSwKICAgICAgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7CiAgICB3aGlsZSAoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpIHsKICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2luZGV4XSwgaW5kZXgsIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGNvbGxlY3Rpb247CiAgfTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC4KICovCnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pOwp2YXIgYmFzZUVhY2gkMSA9IGJhc2VFYWNoOwoKLyoqCiAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGl0IHJlY2VpdmVzLgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS4KICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07CiAqCiAqIGNvbnNvbGUubG9nKF8uaWRlbnRpdHkob2JqZWN0KSA9PT0gb2JqZWN0KTsKICogLy8gPT4gdHJ1ZQogKi8KZnVuY3Rpb24gaWRlbnRpdHkkMSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZTsKfQoKLyoqCiAqIENhc3RzIGB2YWx1ZWAgdG8gYGlkZW50aXR5YCBpZiBpdCdzIG5vdCBhIGZ1bmN0aW9uLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgY2FzdCBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGNhc3RGdW5jdGlvbih2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogaWRlbnRpdHkkMTsKfQoKLyoqCiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggZWxlbWVudC4KICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS4KICogSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLgogKgogKiAqKk5vdGU6KiogQXMgd2l0aCBvdGhlciAiQ29sbGVjdGlvbnMiIG1ldGhvZHMsIG9iamVjdHMgd2l0aCBhICJsZW5ndGgiCiAqIHByb3BlcnR5IGFyZSBpdGVyYXRlZCBsaWtlIGFycmF5cy4gVG8gYXZvaWQgdGhpcyBiZWhhdmlvciB1c2UgYF8uZm9ySW5gCiAqIG9yIGBfLmZvck93bmAgZm9yIG9iamVjdCBpdGVyYXRpb24uCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBhbGlhcyBlYWNoCiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLgogKiBAc2VlIF8uZm9yRWFjaFJpZ2h0CiAqIEBleGFtcGxlCiAqCiAqIF8uZm9yRWFjaChbMSwgMl0sIGZ1bmN0aW9uKHZhbHVlKSB7CiAqICAgY29uc29sZS5sb2codmFsdWUpOwogKiB9KTsKICogLy8gPT4gTG9ncyBgMWAgdGhlbiBgMmAuCiAqCiAqIF8uZm9yRWFjaCh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHsKICogICBjb25zb2xlLmxvZyhrZXkpOwogKiB9KTsKICogLy8gPT4gTG9ncyAnYScgdGhlbiAnYicgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkuCiAqLwpmdW5jdGlvbiBmb3JFYWNoKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7CiAgdmFyIGZ1bmMgPSBpc0FycmF5JDEoY29sbGVjdGlvbikgPyBhcnJheUVhY2ggOiBiYXNlRWFjaCQxOwogIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGNhc3RGdW5jdGlvbihpdGVyYXRlZSkpOwp9CgovKioKICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgc3RhY2suCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGNsZWFyCiAqIEBtZW1iZXJPZiBTdGFjawogKi8KZnVuY3Rpb24gc3RhY2tDbGVhcigpIHsKICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZSgpOwogIHRoaXMuc2l6ZSA9IDA7Cn0KCi8qKgogKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgc3RhY2suCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGRlbGV0ZQogKiBAbWVtYmVyT2YgU3RhY2sKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIHN0YWNrRGVsZXRlKGtleSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXywKICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7CiAgdGhpcy5zaXplID0gZGF0YS5zaXplOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGdldAogKiBAbWVtYmVyT2YgU3RhY2sKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS4KICovCmZ1bmN0aW9uIHN0YWNrR2V0KGtleSkgewogIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpOwp9CgovKioKICogQ2hlY2tzIGlmIGEgc3RhY2sgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQG5hbWUgaGFzCiAqIEBtZW1iZXJPZiBTdGFjawogKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gc3RhY2tIYXMoa2V5KSB7CiAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKGtleSk7Cn0KCi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqLwp2YXIgTEFSR0VfQVJSQVlfU0laRSA9IDIwMDsKCi8qKgogKiBTZXRzIHRoZSBzdGFjayBga2V5YCB0byBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBzZXQKICogQG1lbWJlck9mIFN0YWNrCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LgogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIHN0YWNrIGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gc3RhY2tTZXQoa2V5LCB2YWx1ZSkgewogIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXzsKICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkgewogICAgdmFyIHBhaXJzID0gZGF0YS5fX2RhdGFfXzsKICAgIGlmICghTWFwJDEgfHwgcGFpcnMubGVuZ3RoIDwgTEFSR0VfQVJSQVlfU0laRSAtIDEpIHsKICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pOwogICAgICB0aGlzLnNpemUgPSArK2RhdGEuc2l6ZTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBkYXRhID0gdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZShwYWlycyk7CiAgfQogIGRhdGEuc2V0KGtleSwgdmFsdWUpOwogIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTsKICByZXR1cm4gdGhpczsKfQoKLyoqCiAqIENyZWF0ZXMgYSBzdGFjayBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuCiAqLwpmdW5jdGlvbiBTdGFjayhlbnRyaWVzKSB7CiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZShlbnRyaWVzKTsKICB0aGlzLnNpemUgPSBkYXRhLnNpemU7Cn0KCi8vIEFkZCBtZXRob2RzIHRvIGBTdGFja2AuClN0YWNrLnByb3RvdHlwZS5jbGVhciA9IHN0YWNrQ2xlYXI7ClN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTsKU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0OwpTdGFjay5wcm90b3R5cGUuaGFzID0gc3RhY2tIYXM7ClN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDsKCi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi8KdmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nOwoKLyoqCiAqIEFkZHMgYHZhbHVlYCB0byB0aGUgYXJyYXkgY2FjaGUuCiAqCiAqIEBwcml2YXRlCiAqIEBuYW1lIGFkZAogKiBAbWVtYmVyT2YgU2V0Q2FjaGUKICogQGFsaWFzIHB1c2gKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2FjaGUuCiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLgogKi8KZnVuY3Rpb24gc2V0Q2FjaGVBZGQodmFsdWUpIHsKICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpOwogIHJldHVybiB0aGlzOwp9CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLgogKgogKiBAcHJpdmF0ZQogKiBAbmFtZSBoYXMKICogQG1lbWJlck9mIFNldENhY2hlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBzZXRDYWNoZUhhcyh2YWx1ZSkgewogIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyh2YWx1ZSk7Cn0KCi8qKgogKgogKiBDcmVhdGVzIGFuIGFycmF5IGNhY2hlIG9iamVjdCB0byBzdG9yZSB1bmlxdWUgdmFsdWVzLgogKgogKiBAcHJpdmF0ZQogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS4KICovCmZ1bmN0aW9uIFNldENhY2hlKHZhbHVlcykgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gdmFsdWVzID09IG51bGwgPyAwIDogdmFsdWVzLmxlbmd0aDsKICB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlKCk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHRoaXMuYWRkKHZhbHVlc1tpbmRleF0pOwogIH0KfQoKLy8gQWRkIG1ldGhvZHMgdG8gYFNldENhY2hlYC4KU2V0Q2FjaGUucHJvdG90eXBlLmFkZCA9IFNldENhY2hlLnByb3RvdHlwZS5wdXNoID0gc2V0Q2FjaGVBZGQ7ClNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhczsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlCiAqIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjaywKICogIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGFycmF5U29tZShhcnJheSwgcHJlZGljYXRlKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIGBjYWNoZWAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IGNhY2hlIFRoZSBjYWNoZSB0byBxdWVyeS4KICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGNhY2hlSGFzKGNhY2hlLCBrZXkpIHsKICByZXR1cm4gY2FjaGUuaGFzKGtleSk7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNSA9IDEsCiAgQ09NUEFSRV9VTk9SREVSRURfRkxBRyQzID0gMjsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yCiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLgogKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy4KICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuCiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBhcnJheWAgYW5kIGBvdGhlcmAgb2JqZWN0cy4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykgewogIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNSwKICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCwKICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aDsKICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzUGFydGlhbCAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuCiAgdmFyIGFyclN0YWNrZWQgPSBzdGFjay5nZXQoYXJyYXkpOwogIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTsKICBpZiAoYXJyU3RhY2tlZCAmJiBvdGhTdGFja2VkKSB7CiAgICByZXR1cm4gYXJyU3RhY2tlZCA9PSBvdGhlciAmJiBvdGhTdGFja2VkID09IGFycmF5OwogIH0KICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IHRydWUsCiAgICBzZWVuID0gYml0bWFzayAmIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMyA/IG5ldyBTZXRDYWNoZSgpIDogdW5kZWZpbmVkOwogIHN0YWNrLnNldChhcnJheSwgb3RoZXIpOwogIHN0YWNrLnNldChvdGhlciwgYXJyYXkpOwoKICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuCiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHsKICAgIHZhciBhcnJWYWx1ZSA9IGFycmF5W2luZGV4XSwKICAgICAgb3RoVmFsdWUgPSBvdGhlcltpbmRleF07CiAgICBpZiAoY3VzdG9taXplcikgewogICAgICB2YXIgY29tcGFyZWQgPSBpc1BhcnRpYWwgPyBjdXN0b21pemVyKG90aFZhbHVlLCBhcnJWYWx1ZSwgaW5kZXgsIG90aGVyLCBhcnJheSwgc3RhY2spIDogY3VzdG9taXplcihhcnJWYWx1ZSwgb3RoVmFsdWUsIGluZGV4LCBhcnJheSwgb3RoZXIsIHN0YWNrKTsKICAgIH0KICAgIGlmIChjb21wYXJlZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIGlmIChjb21wYXJlZCkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICBpZiAoc2VlbikgewogICAgICBpZiAoIWFycmF5U29tZShvdGhlciwgZnVuY3Rpb24gKG90aFZhbHVlLCBvdGhJbmRleCkgewogICAgICAgIGlmICghY2FjaGVIYXMoc2Vlbiwgb3RoSW5kZXgpICYmIChhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spKSkgewogICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7CiAgICAgICAgfQogICAgICB9KSkgewogICAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9IGVsc2UgaWYgKCEoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHsKICAgICAgcmVzdWx0ID0gZmFsc2U7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBzdGFja1snZGVsZXRlJ10oYXJyYXkpOwogIHN0YWNrWydkZWxldGUnXShvdGhlcik7CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovCnZhciBVaW50OEFycmF5ID0gcm9vdCQxLlVpbnQ4QXJyYXk7CnZhciBVaW50OEFycmF5JDEgPSBVaW50OEFycmF5OwoKLyoqCiAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy4KICovCmZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICByZXN1bHQgPSBBcnJheShtYXAuc2l6ZSk7CiAgbWFwLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHsKICAgIHJlc3VsdFsrK2luZGV4XSA9IFtrZXksIHZhbHVlXTsKICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ29udmVydHMgYHNldGAgdG8gYW4gYXJyYXkgb2YgaXRzIHZhbHVlcy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgdmFsdWVzLgogKi8KZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIHJlc3VsdCA9IEFycmF5KHNldC5zaXplKTsKICBzZXQuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHsKICAgIHJlc3VsdFsrK2luZGV4XSA9IHZhbHVlOwogIH0pOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckNCA9IDEsCiAgQ09NUEFSRV9VTk9SREVSRURfRkxBRyQyID0gMjsKCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsCiAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJywKICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsCiAgbWFwVGFnJDIgPSAnW29iamVjdCBNYXBdJywKICBudW1iZXJUYWckMSA9ICdbb2JqZWN0IE51bWJlcl0nLAogIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLAogIHNldFRhZyQyID0gJ1tvYmplY3QgU2V0XScsCiAgc3RyaW5nVGFnJDEgPSAnW29iamVjdCBTdHJpbmddJywKICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJzsKdmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJywKICBkYXRhVmlld1RhZyQxID0gJ1tvYmplY3QgRGF0YVZpZXddJzsKCi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqLwp2YXIgc3ltYm9sUHJvdG8gPSBTeW1ib2wkMSA/IFN5bWJvbCQxLnByb3RvdHlwZSA6IHVuZGVmaW5lZCwKICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkOwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2YKICogdGhlIHNhbWUgYHRvU3RyaW5nVGFnYC4KICoKICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZgogKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuCiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgdGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7CiAgc3dpdGNoICh0YWcpIHsKICAgIGNhc2UgZGF0YVZpZXdUYWckMToKICAgICAgaWYgKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGggfHwgb2JqZWN0LmJ5dGVPZmZzZXQgIT0gb3RoZXIuYnl0ZU9mZnNldCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBvYmplY3QgPSBvYmplY3QuYnVmZmVyOwogICAgICBvdGhlciA9IG90aGVyLmJ1ZmZlcjsKICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6CiAgICAgIGlmIChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoIHx8ICFlcXVhbEZ1bmMobmV3IFVpbnQ4QXJyYXkkMShvYmplY3QpLCBuZXcgVWludDhBcnJheSQxKG90aGVyKSkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGJvb2xUYWc6CiAgICBjYXNlIGRhdGVUYWc6CiAgICBjYXNlIG51bWJlclRhZyQxOgogICAgICAvLyBDb2VyY2UgYm9vbGVhbnMgdG8gYDFgIG9yIGAwYCBhbmQgZGF0ZXMgdG8gbWlsbGlzZWNvbmRzLgogICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLgogICAgICByZXR1cm4gZXEoK29iamVjdCwgK290aGVyKTsKICAgIGNhc2UgZXJyb3JUYWc6CiAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7CiAgICBjYXNlIHJlZ2V4cFRhZzoKICAgIGNhc2Ugc3RyaW5nVGFnJDE6CiAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MsIHByaW1pdGl2ZXMgYW5kIG9iamVjdHMsCiAgICAgIC8vIGFzIGVxdWFsLiBTZWUgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXJlZ2V4cC5wcm90b3R5cGUudG9zdHJpbmcKICAgICAgLy8gZm9yIG1vcmUgZGV0YWlscy4KICAgICAgcmV0dXJuIG9iamVjdCA9PSBvdGhlciArICcnOwogICAgY2FzZSBtYXBUYWckMjoKICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5OwogICAgY2FzZSBzZXRUYWckMjoKICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyQ0OwogICAgICBjb252ZXJ0IHx8IChjb252ZXJ0ID0gc2V0VG9BcnJheSk7CiAgICAgIGlmIChvYmplY3Quc2l6ZSAhPSBvdGhlci5zaXplICYmICFpc1BhcnRpYWwpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgLy8gQXNzdW1lIGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLgogICAgICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldChvYmplY3QpOwogICAgICBpZiAoc3RhY2tlZCkgewogICAgICAgIHJldHVybiBzdGFja2VkID09IG90aGVyOwogICAgICB9CiAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRyQyOwoKICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuCiAgICAgIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTsKICAgICAgdmFyIHJlc3VsdCA9IGVxdWFsQXJyYXlzKGNvbnZlcnQob2JqZWN0KSwgY29udmVydChvdGhlciksIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spOwogICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIGNhc2Ugc3ltYm9sVGFnOgogICAgICBpZiAoc3ltYm9sVmFsdWVPZikgewogICAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mLmNhbGwob2JqZWN0KSA9PSBzeW1ib2xWYWx1ZU9mLmNhbGwob3RoZXIpOwogICAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqCiAqIEFwcGVuZHMgdGhlIGVsZW1lbnRzIG9mIGB2YWx1ZXNgIHRvIGBhcnJheWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuCiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuCiAqLwpmdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCwKICAgIG9mZnNldCA9IGFycmF5Lmxlbmd0aDsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgYXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gdmFsdWVzW2luZGV4XTsKICB9CiAgcmV0dXJuIGFycmF5Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldEFsbEtleXNgIGFuZCBgZ2V0QWxsS2V5c0luYCB3aGljaCB1c2VzCiAqIGBrZXlzRnVuY2AgYW5kIGBzeW1ib2xzRnVuY2AgdG8gZ2V0IHRoZSBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIGFuZAogKiBzeW1ib2xzIG9mIGBvYmplY3RgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuCiAqIEBwYXJhbSB7RnVuY3Rpb259IHN5bWJvbHNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIHN5bWJvbHMgb2YgYG9iamVjdGAuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuCiAqLwpmdW5jdGlvbiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXNGdW5jLCBzeW1ib2xzRnVuYykgewogIHZhciByZXN1bHQgPSBrZXlzRnVuYyhvYmplY3QpOwogIHJldHVybiBpc0FycmF5JDEob2JqZWN0KSA/IHJlc3VsdCA6IGFycmF5UHVzaChyZXN1bHQsIHN5bWJvbHNGdW5jKG9iamVjdCkpOwp9CgovKioKICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZpbHRlcmAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yCiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LgogKi8KZnVuY3Rpb24gYXJyYXlGaWx0ZXIoYXJyYXksIHByZWRpY2F0ZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsCiAgICByZXNJbmRleCA9IDAsCiAgICByZXN1bHQgPSBbXTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdOwogICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGFycmF5KSkgewogICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgYXJyYXkuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMTMuMAogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBlbXB0eSBhcnJheS4KICogQGV4YW1wbGUKICoKICogdmFyIGFycmF5cyA9IF8udGltZXMoMiwgXy5zdHViQXJyYXkpOwogKgogKiBjb25zb2xlLmxvZyhhcnJheXMpOwogKiAvLyA9PiBbW10sIFtdXQogKgogKiBjb25zb2xlLmxvZyhhcnJheXNbMF0gPT09IGFycmF5c1sxXSk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBzdHViQXJyYXkoKSB7CiAgcmV0dXJuIFtdOwp9CgovKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovCnZhciBvYmplY3RQcm90byQyID0gT2JqZWN0LnByb3RvdHlwZTsKCi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqLwp2YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90byQyLnByb3BlcnR5SXNFbnVtZXJhYmxlOwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqLwp2YXIgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHN5bWJvbHMuCiAqLwp2YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24gKG9iamVjdCkgewogIGlmIChvYmplY3QgPT0gbnVsbCkgewogICAgcmV0dXJuIFtdOwogIH0KICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTsKICByZXR1cm4gYXJyYXlGaWx0ZXIobmF0aXZlR2V0U3ltYm9scyhvYmplY3QpLCBmdW5jdGlvbiAoc3ltYm9sKSB7CiAgICByZXR1cm4gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmplY3QsIHN5bWJvbCk7CiAgfSk7Cn07CnZhciBnZXRTeW1ib2xzJDEgPSBnZXRTeW1ib2xzOwoKLyoqCiAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy4KICovCmZ1bmN0aW9uIGdldEFsbEtleXMob2JqZWN0KSB7CiAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5cywgZ2V0U3ltYm9scyQxKTsKfQoKLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovCnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyQzID0gMTsKCi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi8KdmFyIG9iamVjdFByb3RvJDEgPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSQxID0gb2JqZWN0UHJvdG8kMS5oYXNPd25Qcm9wZXJ0eTsKCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvcgogKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLgogKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy4KICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuCiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHsKICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHJDMsCiAgICBvYmpQcm9wcyA9IGdldEFsbEtleXMob2JqZWN0KSwKICAgIG9iakxlbmd0aCA9IG9ialByb3BzLmxlbmd0aCwKICAgIG90aFByb3BzID0gZ2V0QWxsS2V5cyhvdGhlciksCiAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7CiAgaWYgKG9iakxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIWlzUGFydGlhbCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgaW5kZXggPSBvYmpMZW5ndGg7CiAgd2hpbGUgKGluZGV4LS0pIHsKICAgIHZhciBrZXkgPSBvYmpQcm9wc1tpbmRleF07CiAgICBpZiAoIShpc1BhcnRpYWwgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eSQxLmNhbGwob3RoZXIsIGtleSkpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgLy8gQ2hlY2sgdGhhdCBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC4KICB2YXIgb2JqU3RhY2tlZCA9IHN0YWNrLmdldChvYmplY3QpOwogIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTsKICBpZiAob2JqU3RhY2tlZCAmJiBvdGhTdGFja2VkKSB7CiAgICByZXR1cm4gb2JqU3RhY2tlZCA9PSBvdGhlciAmJiBvdGhTdGFja2VkID09IG9iamVjdDsKICB9CiAgdmFyIHJlc3VsdCA9IHRydWU7CiAgc3RhY2suc2V0KG9iamVjdCwgb3RoZXIpOwogIHN0YWNrLnNldChvdGhlciwgb2JqZWN0KTsKICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7CiAgd2hpbGUgKCsraW5kZXggPCBvYmpMZW5ndGgpIHsKICAgIGtleSA9IG9ialByb3BzW2luZGV4XTsKICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLAogICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07CiAgICBpZiAoY3VzdG9taXplcikgewogICAgICB2YXIgY29tcGFyZWQgPSBpc1BhcnRpYWwgPyBjdXN0b21pemVyKG90aFZhbHVlLCBvYmpWYWx1ZSwga2V5LCBvdGhlciwgb2JqZWN0LCBzdGFjaykgOiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSwga2V5LCBvYmplY3QsIG90aGVyLCBzdGFjayk7CiAgICB9CiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS4KICAgIGlmICghKGNvbXBhcmVkID09PSB1bmRlZmluZWQgPyBvYmpWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spIDogY29tcGFyZWQpKSB7CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTsKICB9CiAgaWYgKHJlc3VsdCAmJiAhc2tpcEN0b3IpIHsKICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLAogICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7CgogICAgLy8gTm9uIGBPYmplY3RgIG9iamVjdCBpbnN0YW5jZXMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1YWwuCiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmICdjb25zdHJ1Y3RvcicgaW4gb2JqZWN0ICYmICdjb25zdHJ1Y3RvcicgaW4gb3RoZXIgJiYgISh0eXBlb2Ygb2JqQ3RvciA9PSAnZnVuY3Rpb24nICYmIG9iakN0b3IgaW5zdGFuY2VvZiBvYmpDdG9yICYmIHR5cGVvZiBvdGhDdG9yID09ICdmdW5jdGlvbicgJiYgb3RoQ3RvciBpbnN0YW5jZW9mIG90aEN0b3IpKSB7CiAgICAgIHJlc3VsdCA9IGZhbHNlOwogICAgfQogIH0KICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTsKICBzdGFja1snZGVsZXRlJ10ob3RoZXIpOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi8KdmFyIERhdGFWaWV3ID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ0RhdGFWaWV3Jyk7CnZhciBEYXRhVmlldyQxID0gRGF0YVZpZXc7CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBQcm9taXNlJDEgPSBnZXROYXRpdmUocm9vdCQxLCAnUHJvbWlzZScpOwp2YXIgUHJvbWlzZSQyID0gUHJvbWlzZSQxOwoKLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqLwp2YXIgU2V0ID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ1NldCcpOwp2YXIgU2V0JDEgPSBTZXQ7CgovKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovCnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKHJvb3QkMSwgJ1dlYWtNYXAnKTsKdmFyIFdlYWtNYXAkMSA9IFdlYWtNYXA7CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBtYXBUYWckMSA9ICdbb2JqZWN0IE1hcF0nLAogIG9iamVjdFRhZyQxID0gJ1tvYmplY3QgT2JqZWN0XScsCiAgcHJvbWlzZVRhZyA9ICdbb2JqZWN0IFByb21pc2VdJywKICBzZXRUYWckMSA9ICdbb2JqZWN0IFNldF0nLAogIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7CnZhciBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7CgovKiogVXNlZCB0byBkZXRlY3QgbWFwcywgc2V0cywgYW5kIHdlYWttYXBzLiAqLwp2YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXckMSksCiAgbWFwQ3RvclN0cmluZyA9IHRvU291cmNlKE1hcCQxKSwKICBwcm9taXNlQ3RvclN0cmluZyA9IHRvU291cmNlKFByb21pc2UkMiksCiAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCQxKSwKICB3ZWFrTWFwQ3RvclN0cmluZyA9IHRvU291cmNlKFdlYWtNYXAkMSk7CgovKioKICogR2V0cyB0aGUgYHRvU3RyaW5nVGFnYCBvZiBgdmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC4KICovCnZhciBnZXRUYWcgPSBiYXNlR2V0VGFnOwoKLy8gRmFsbGJhY2sgZm9yIGRhdGEgdmlld3MsIG1hcHMsIHNldHMsIGFuZCB3ZWFrIG1hcHMgaW4gSUUgMTEgYW5kIHByb21pc2VzIGluIE5vZGUuanMgPCA2LgppZiAoRGF0YVZpZXckMSAmJiBnZXRUYWcobmV3IERhdGFWaWV3JDEobmV3IEFycmF5QnVmZmVyKDEpKSkgIT0gZGF0YVZpZXdUYWcgfHwgTWFwJDEgJiYgZ2V0VGFnKG5ldyBNYXAkMSgpKSAhPSBtYXBUYWckMSB8fCBQcm9taXNlJDIgJiYgZ2V0VGFnKFByb21pc2UkMi5yZXNvbHZlKCkpICE9IHByb21pc2VUYWcgfHwgU2V0JDEgJiYgZ2V0VGFnKG5ldyBTZXQkMSgpKSAhPSBzZXRUYWckMSB8fCBXZWFrTWFwJDEgJiYgZ2V0VGFnKG5ldyBXZWFrTWFwJDEoKSkgIT0gd2Vha01hcFRhZykgewogIGdldFRhZyA9IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgdmFyIHJlc3VsdCA9IGJhc2VHZXRUYWcodmFsdWUpLAogICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyQxID8gdmFsdWUuY29uc3RydWN0b3IgOiB1bmRlZmluZWQsCiAgICAgIGN0b3JTdHJpbmcgPSBDdG9yID8gdG9Tb3VyY2UoQ3RvcikgOiAnJzsKICAgIGlmIChjdG9yU3RyaW5nKSB7CiAgICAgIHN3aXRjaCAoY3RvclN0cmluZykgewogICAgICAgIGNhc2UgZGF0YVZpZXdDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIGRhdGFWaWV3VGFnOwogICAgICAgIGNhc2UgbWFwQ3RvclN0cmluZzoKICAgICAgICAgIHJldHVybiBtYXBUYWckMTsKICAgICAgICBjYXNlIHByb21pc2VDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIHByb21pc2VUYWc7CiAgICAgICAgY2FzZSBzZXRDdG9yU3RyaW5nOgogICAgICAgICAgcmV0dXJuIHNldFRhZyQxOwogICAgICAgIGNhc2Ugd2Vha01hcEN0b3JTdHJpbmc6CiAgICAgICAgICByZXR1cm4gd2Vha01hcFRhZzsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9Owp9CnZhciBnZXRUYWckMSA9IGdldFRhZzsKCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUckMiA9IDE7CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsCiAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLAogIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nOwoKLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqLwp2YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlOwoKLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovCnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5OwoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXMKICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhcgogKiByZWZlcmVuY2VzIHRvIGJlIGNvbXBhcmVkLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS4KICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy4KICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLgogKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHsKICB2YXIgb2JqSXNBcnIgPSBpc0FycmF5JDEob2JqZWN0KSwKICAgIG90aElzQXJyID0gaXNBcnJheSQxKG90aGVyKSwKICAgIG9ialRhZyA9IG9iaklzQXJyID8gYXJyYXlUYWcgOiBnZXRUYWckMShvYmplY3QpLAogICAgb3RoVGFnID0gb3RoSXNBcnIgPyBhcnJheVRhZyA6IGdldFRhZyQxKG90aGVyKTsKICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZzsKICBvdGhUYWcgPSBvdGhUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG90aFRhZzsKICB2YXIgb2JqSXNPYmogPSBvYmpUYWcgPT0gb2JqZWN0VGFnLAogICAgb3RoSXNPYmogPSBvdGhUYWcgPT0gb2JqZWN0VGFnLAogICAgaXNTYW1lVGFnID0gb2JqVGFnID09IG90aFRhZzsKICBpZiAoaXNTYW1lVGFnICYmIGlzQnVmZmVyJDEob2JqZWN0KSkgewogICAgaWYgKCFpc0J1ZmZlciQxKG90aGVyKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBvYmpJc0FyciA9IHRydWU7CiAgICBvYmpJc09iaiA9IGZhbHNlOwogIH0KICBpZiAoaXNTYW1lVGFnICYmICFvYmpJc09iaikgewogICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKCkpOwogICAgcmV0dXJuIG9iaklzQXJyIHx8IGlzVHlwZWRBcnJheSQxKG9iamVjdCkgPyBlcXVhbEFycmF5cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTsKICB9CiAgaWYgKCEoYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHJDIpKSB7CiAgICB2YXIgb2JqSXNXcmFwcGVkID0gb2JqSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsICdfX3dyYXBwZWRfXycpLAogICAgICBvdGhJc1dyYXBwZWQgPSBvdGhJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCAnX193cmFwcGVkX18nKTsKICAgIGlmIChvYmpJc1dyYXBwZWQgfHwgb3RoSXNXcmFwcGVkKSB7CiAgICAgIHZhciBvYmpVbndyYXBwZWQgPSBvYmpJc1dyYXBwZWQgPyBvYmplY3QudmFsdWUoKSA6IG9iamVjdCwKICAgICAgICBvdGhVbndyYXBwZWQgPSBvdGhJc1dyYXBwZWQgPyBvdGhlci52YWx1ZSgpIDogb3RoZXI7CiAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjaygpKTsKICAgICAgcmV0dXJuIGVxdWFsRnVuYyhvYmpVbndyYXBwZWQsIG90aFVud3JhcHBlZCwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spOwogICAgfQogIH0KICBpZiAoIWlzU2FtZVRhZykgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2soKSk7CiAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzRXF1YWxgIHdoaWNoIHN1cHBvcnRzIHBhcnRpYWwgY29tcGFyaXNvbnMKICogYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHtib29sZWFufSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLgogKiAgMSAtIFVub3JkZXJlZCBjb21wYXJpc29uCiAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLgogKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgYW5kIGBvdGhlcmAgb2JqZWN0cy4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICovCmZ1bmN0aW9uIGJhc2VJc0VxdWFsKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spIHsKICBpZiAodmFsdWUgPT09IG90aGVyKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAhaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkgewogICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7CiAgfQogIHJldHVybiBiYXNlSXNFcXVhbERlZXAodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBiYXNlSXNFcXVhbCwgc3RhY2spOwp9CgovKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi8KdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHJDEgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMSA9IDI7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC4KICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC4KICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyB0byBtYXRjaC4KICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBpcyBhIG1hdGNoLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhLCBjdXN0b21pemVyKSB7CiAgdmFyIGluZGV4ID0gbWF0Y2hEYXRhLmxlbmd0aCwKICAgIGxlbmd0aCA9IGluZGV4LAogICAgbm9DdXN0b21pemVyID0gIWN1c3RvbWl6ZXI7CiAgaWYgKG9iamVjdCA9PSBudWxsKSB7CiAgICByZXR1cm4gIWxlbmd0aDsKICB9CiAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7CiAgd2hpbGUgKGluZGV4LS0pIHsKICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTsKICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSA/IGRhdGFbMV0gIT09IG9iamVjdFtkYXRhWzBdXSA6ICEoZGF0YVswXSBpbiBvYmplY3QpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdOwogICAgdmFyIGtleSA9IGRhdGFbMF0sCiAgICAgIG9ialZhbHVlID0gb2JqZWN0W2tleV0sCiAgICAgIHNyY1ZhbHVlID0gZGF0YVsxXTsKICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkgewogICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YXIgc3RhY2sgPSBuZXcgU3RhY2soKTsKICAgICAgaWYgKGN1c3RvbWl6ZXIpIHsKICAgICAgICB2YXIgcmVzdWx0ID0gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKTsKICAgICAgfQogICAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZCA/IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgQ09NUEFSRV9QQVJUSUFMX0ZMQUckMSB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUckMSwgY3VzdG9taXplciwgc3RhY2spIDogcmVzdWx0KSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gdHJ1ZTsKfQoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0CiAqICBlcXVhbGl0eSBjb21wYXJpc29ucywgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7CiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSAmJiAhaXNPYmplY3QodmFsdWUpOwp9CgovKioKICogR2V0cyB0aGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLgogKi8KZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkgewogIHZhciByZXN1bHQgPSBrZXlzKG9iamVjdCksCiAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoOwogIHdoaWxlIChsZW5ndGgtLSkgewogICAgdmFyIGtleSA9IHJlc3VsdFtsZW5ndGhdLAogICAgICB2YWx1ZSA9IG9iamVjdFtrZXldOwogICAgcmVzdWx0W2xlbmd0aF0gPSBba2V5LCB2YWx1ZSwgaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKV07CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYG1hdGNoZXNQcm9wZXJ0eWAgZm9yIHNvdXJjZSB2YWx1ZXMgc3VpdGFibGUKICogZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUoa2V5LCBzcmNWYWx1ZSkgewogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0KSB7CiAgICBpZiAob2JqZWN0ID09IG51bGwpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZSAmJiAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCBrZXkgaW4gT2JqZWN0KG9iamVjdCkpOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzYCB3aGljaCBkb2Vzbid0IGNsb25lIGBzb3VyY2VgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7CiAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpOwogIGlmIChtYXRjaERhdGEubGVuZ3RoID09IDEgJiYgbWF0Y2hEYXRhWzBdWzJdKSB7CiAgICByZXR1cm4gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUobWF0Y2hEYXRhWzBdWzBdLCBtYXRjaERhdGFbMF1bMV0pOwogIH0KICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBtYXRjaERhdGEpOwogIH07Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5oYXNJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlSGFzSW4ob2JqZWN0LCBrZXkpIHsKICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYga2V5IGluIE9iamVjdChvYmplY3QpOwp9CgovKioKICogQ2hlY2tzIGlmIGBwYXRoYCBleGlzdHMgb24gYG9iamVjdGAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS4KICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suCiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrIHByb3BlcnRpZXMuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgaGFzRnVuYykgewogIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpOwogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gcGF0aC5sZW5ndGgsCiAgICByZXN1bHQgPSBmYWxzZTsKICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkgewogICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKTsKICAgIGlmICghKHJlc3VsdCA9IG9iamVjdCAhPSBudWxsICYmIGhhc0Z1bmMob2JqZWN0LCBrZXkpKSkgewogICAgICBicmVhazsKICAgIH0KICAgIG9iamVjdCA9IG9iamVjdFtrZXldOwogIH0KICBpZiAocmVzdWx0IHx8ICsraW5kZXggIT0gbGVuZ3RoKSB7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICBsZW5ndGggPSBvYmplY3QgPT0gbnVsbCA/IDAgOiBvYmplY3QubGVuZ3RoOwogIHJldHVybiAhIWxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpICYmIChpc0FycmF5JDEob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyQxKG9iamVjdCkpOwp9CgovKioKICogQ2hlY2tzIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgb2YgYG9iamVjdGAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDQuMC4wCiAqIEBjYXRlZ29yeSBPYmplY3QKICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LgogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IF8uY3JlYXRlKHsgJ2EnOiBfLmNyZWF0ZSh7ICdiJzogMiB9KSB9KTsKICoKICogXy5oYXNJbihvYmplY3QsICdhJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5oYXNJbihvYmplY3QsICdhLmInKTsKICogLy8gPT4gdHJ1ZQogKgogKiBfLmhhc0luKG9iamVjdCwgWydhJywgJ2InXSk7CiAqIC8vID0+IHRydWUKICoKICogXy5oYXNJbihvYmplY3QsICdiJyk7CiAqIC8vID0+IGZhbHNlCiAqLwpmdW5jdGlvbiBoYXNJbihvYmplY3QsIHBhdGgpIHsKICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzUGF0aChvYmplY3QsIHBhdGgsIGJhc2VIYXNJbik7Cn0KCi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqLwp2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLAogIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lc24ndCBjbG9uZSBgc3JjVmFsdWVgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC4KICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VNYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHsKICBpZiAoaXNLZXkocGF0aCkgJiYgaXNTdHJpY3RDb21wYXJhYmxlKHNyY1ZhbHVlKSkgewogICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKHRvS2V5KHBhdGgpLCBzcmNWYWx1ZSk7CiAgfQogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0KSB7CiAgICB2YXIgb2JqVmFsdWUgPSBnZXQob2JqZWN0LCBwYXRoKTsKICAgIHJldHVybiBvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmIG9ialZhbHVlID09PSBzcmNWYWx1ZSA/IGhhc0luKG9iamVjdCwgcGF0aCkgOiBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIENPTVBBUkVfUEFSVElBTF9GTEFHIHwgQ09NUEFSRV9VTk9SREVSRURfRkxBRyk7CiAgfTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHsKICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCkgewogICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07CiAgfTsKfQoKLyoqCiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVByb3BlcnR5YCB3aGljaCBzdXBwb3J0cyBkZWVwIHBhdGhzLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi4KICovCmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eURlZXAocGF0aCkgewogIHJldHVybiBmdW5jdGlvbiAob2JqZWN0KSB7CiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgpOwogIH07Cn0KCi8qKgogKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDIuNC4wCiAqIEBjYXRlZ29yeSBVdGlsCiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLgogKiBAZXhhbXBsZQogKgogKiB2YXIgb2JqZWN0cyA9IFsKICogICB7ICdhJzogeyAnYic6IDIgfSB9LAogKiAgIHsgJ2EnOiB7ICdiJzogMSB9IH0KICogXTsKICoKICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iJykpOwogKiAvLyA9PiBbMiwgMV0KICoKICogXy5tYXAoXy5zb3J0Qnkob2JqZWN0cywgXy5wcm9wZXJ0eShbJ2EnLCAnYiddKSksICdhLmInKTsKICogLy8gPT4gWzEsIDJdCiAqLwpmdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7CiAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHRvS2V5KHBhdGgpKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7Cn0KCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pdGVyYXRlZWAuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gW3ZhbHVlPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGFuIGl0ZXJhdGVlLgogKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGl0ZXJhdGVlLgogKi8KZnVuY3Rpb24gYmFzZUl0ZXJhdGVlKHZhbHVlKSB7CiAgLy8gRG9uJ3Qgc3RvcmUgdGhlIGB0eXBlb2ZgIHJlc3VsdCBpbiBhIHZhcmlhYmxlIHRvIGF2b2lkIGEgSklUIGJ1ZyBpbiBTYWZhcmkgOS4KICAvLyBTZWUgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE1NjAzNCBmb3IgbW9yZSBkZXRhaWxzLgogIGlmICh0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJykgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgcmV0dXJuIGlkZW50aXR5JDE7CiAgfQogIGlmICh0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpIHsKICAgIHJldHVybiBpc0FycmF5JDEodmFsdWUpID8gYmFzZU1hdGNoZXNQcm9wZXJ0eSh2YWx1ZVswXSwgdmFsdWVbMV0pIDogYmFzZU1hdGNoZXModmFsdWUpOwogIH0KICByZXR1cm4gcHJvcGVydHkodmFsdWUpOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWFwYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LgogKi8KZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkgewogIHZhciBpbmRleCA9IC0xLAogICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTsKICBiYXNlRWFjaCQxKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7CiAgICByZXN1bHRbKytpbmRleF0gPSBpdGVyYXRlZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKTsKICB9KTsKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiB2YWx1ZXMgYnkgcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIHRocnUKICogYGl0ZXJhdGVlYC4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6CiAqICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS4KICoKICogTWFueSBsb2Rhc2ggbWV0aG9kcyBhcmUgZ3VhcmRlZCB0byB3b3JrIGFzIGl0ZXJhdGVlcyBmb3IgbWV0aG9kcyBsaWtlCiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLgogKgogKiBUaGUgZ3VhcmRlZCBtZXRob2RzIGFyZToKICogYGFyeWAsIGBjaHVua2AsIGBjdXJyeWAsIGBjdXJyeVJpZ2h0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGV2ZXJ5YCwKICogYGZpbGxgLCBgaW52ZXJ0YCwgYHBhcnNlSW50YCwgYHJhbmRvbWAsIGByYW5nZWAsIGByYW5nZVJpZ2h0YCwgYHJlcGVhdGAsCiAqIGBzYW1wbGVTaXplYCwgYHNsaWNlYCwgYHNvbWVgLCBgc29ydEJ5YCwgYHNwbGl0YCwgYHRha2VgLCBgdGFrZVJpZ2h0YCwKICogYHRlbXBsYXRlYCwgYHRyaW1gLCBgdHJpbUVuZGAsIGB0cmltU3RhcnRgLCBhbmQgYHdvcmRzYAogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAwLjEuMAogKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbgogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuCiAqIEBleGFtcGxlCiAqCiAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7CiAqICAgcmV0dXJuIG4gKiBuOwogKiB9CiAqCiAqIF8ubWFwKFs0LCA4XSwgc3F1YXJlKTsKICogLy8gPT4gWzE2LCA2NF0KICoKICogXy5tYXAoeyAnYSc6IDQsICdiJzogOCB9LCBzcXVhcmUpOwogKiAvLyA9PiBbMTYsIDY0XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKQogKgogKiB2YXIgdXNlcnMgPSBbCiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sCiAqICAgeyAndXNlcic6ICdmcmVkJyB9CiAqIF07CiAqCiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLgogKiBfLm1hcCh1c2VycywgJ3VzZXInKTsKICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddCiAqLwpmdW5jdGlvbiBtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHsKICB2YXIgZnVuYyA9IGlzQXJyYXkkMShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDsKICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBiYXNlSXRlcmF0ZWUoaXRlcmF0ZWUpKTsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnN1bWAgYW5kIGBfLnN1bUJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yCiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS4KICovCmZ1bmN0aW9uIGJhc2VTdW0oYXJyYXksIGl0ZXJhdGVlKSB7CiAgdmFyIHJlc3VsdCwKICAgIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciBjdXJyZW50ID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdKTsKICAgIGlmIChjdXJyZW50ICE9PSB1bmRlZmluZWQpIHsKICAgICAgcmVzdWx0ID0gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBjdXJyZW50IDogcmVzdWx0ICsgY3VycmVudDsKICAgIH0KICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENvbXB1dGVzIHRoZSBzdW0gb2YgdGhlIHZhbHVlcyBpbiBgYXJyYXlgLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSAzLjQuMAogKiBAY2F0ZWdvcnkgTWF0aAogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uCiAqIEBleGFtcGxlCiAqCiAqIF8uc3VtKFs0LCAyLCA4LCA2XSk7CiAqIC8vID0+IDIwCiAqLwpmdW5jdGlvbiBzdW0kMShhcnJheSkgewogIHJldHVybiBhcnJheSAmJiBhcnJheS5sZW5ndGggPyBiYXNlU3VtKGFycmF5LCBpZGVudGl0eSQxKSA6IDA7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3RyaW5nYCBwcmltaXRpdmUgb3Igb2JqZWN0LgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzdHJpbmcsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogXy5pc1N0cmluZygnYWJjJyk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc1N0cmluZygxKTsKICogLy8gPT4gZmFsc2UKICovCmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCAhaXNBcnJheSQxKHZhbHVlKSAmJiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHN0cmluZ1RhZzsKfQoKLyoqCiAqIEdldHMgdGhlIHNpemUgb2YgYW4gQVNDSUkgYHN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS4KICovCnZhciBhc2NpaVNpemUgPSBiYXNlUHJvcGVydHkoJ2xlbmd0aCcpOwp2YXIgYXNjaWlTaXplJDEgPSBhc2NpaVNpemU7CgovKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2hhcmFjdGVyIGNsYXNzZXMuICovCnZhciByc0FzdHJhbFJhbmdlJDEgPSAnXFx1ZDgwMC1cXHVkZmZmJywKICByc0NvbWJvTWFya3NSYW5nZSQxID0gJ1xcdTAzMDAtXFx1MDM2ZicsCiAgcmVDb21ib0hhbGZNYXJrc1JhbmdlJDEgPSAnXFx1ZmUyMC1cXHVmZTJmJywKICByc0NvbWJvU3ltYm9sc1JhbmdlJDEgPSAnXFx1MjBkMC1cXHUyMGZmJywKICByc0NvbWJvUmFuZ2UkMSA9IHJzQ29tYm9NYXJrc1JhbmdlJDEgKyByZUNvbWJvSGFsZk1hcmtzUmFuZ2UkMSArIHJzQ29tYm9TeW1ib2xzUmFuZ2UkMSwKICByc1ZhclJhbmdlJDEgPSAnXFx1ZmUwZVxcdWZlMGYnOwoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNhcHR1cmUgZ3JvdXBzLiAqLwp2YXIgcnNaV0okMSA9ICdcXHUyMDBkJzsKCi8qKiBVc2VkIHRvIGRldGVjdCBzdHJpbmdzIHdpdGggW3plcm8td2lkdGggam9pbmVycyBvciBjb2RlIHBvaW50cyBmcm9tIHRoZSBhc3RyYWwgcGxhbmVzXShodHRwOi8vZWV2LmVlL2Jsb2cvMjAxNS8wOS8xMi9kYXJrLWNvcm5lcnMtb2YtdW5pY29kZS8pLiAqLwp2YXIgcmVIYXNVbmljb2RlID0gUmVnRXhwKCdbJyArIHJzWldKJDEgKyByc0FzdHJhbFJhbmdlJDEgKyByc0NvbWJvUmFuZ2UkMSArIHJzVmFyUmFuZ2UkMSArICddJyk7CgovKioKICogQ2hlY2tzIGlmIGBzdHJpbmdgIGNvbnRhaW5zIFVuaWNvZGUgc3ltYm9scy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHN5bWJvbCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaGFzVW5pY29kZShzdHJpbmcpIHsKICByZXR1cm4gcmVIYXNVbmljb2RlLnRlc3Qoc3RyaW5nKTsKfQoKLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNoYXJhY3RlciBjbGFzc2VzLiAqLwp2YXIgcnNBc3RyYWxSYW5nZSA9ICdcXHVkODAwLVxcdWRmZmYnLAogIHJzQ29tYm9NYXJrc1JhbmdlID0gJ1xcdTAzMDAtXFx1MDM2ZicsCiAgcmVDb21ib0hhbGZNYXJrc1JhbmdlID0gJ1xcdWZlMjAtXFx1ZmUyZicsCiAgcnNDb21ib1N5bWJvbHNSYW5nZSA9ICdcXHUyMGQwLVxcdTIwZmYnLAogIHJzQ29tYm9SYW5nZSA9IHJzQ29tYm9NYXJrc1JhbmdlICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlICsgcnNDb21ib1N5bWJvbHNSYW5nZSwKICByc1ZhclJhbmdlID0gJ1xcdWZlMGVcXHVmZTBmJzsKCi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi8KdmFyIHJzQXN0cmFsID0gJ1snICsgcnNBc3RyYWxSYW5nZSArICddJywKICByc0NvbWJvID0gJ1snICsgcnNDb21ib1JhbmdlICsgJ10nLAogIHJzRml0eiA9ICdcXHVkODNjW1xcdWRmZmItXFx1ZGZmZl0nLAogIHJzTW9kaWZpZXIgPSAnKD86JyArIHJzQ29tYm8gKyAnfCcgKyByc0ZpdHogKyAnKScsCiAgcnNOb25Bc3RyYWwgPSAnW14nICsgcnNBc3RyYWxSYW5nZSArICddJywKICByc1JlZ2lvbmFsID0gJyg/OlxcdWQ4M2NbXFx1ZGRlNi1cXHVkZGZmXSl7Mn0nLAogIHJzU3VyclBhaXIgPSAnW1xcdWQ4MDAtXFx1ZGJmZl1bXFx1ZGMwMC1cXHVkZmZmXScsCiAgcnNaV0ogPSAnXFx1MjAwZCc7CgovKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgcmVnZXhlcy4gKi8KdmFyIHJlT3B0TW9kID0gcnNNb2RpZmllciArICc/JywKICByc09wdFZhciA9ICdbJyArIHJzVmFyUmFuZ2UgKyAnXT8nLAogIHJzT3B0Sm9pbiA9ICcoPzonICsgcnNaV0ogKyAnKD86JyArIFtyc05vbkFzdHJhbCwgcnNSZWdpb25hbCwgcnNTdXJyUGFpcl0uam9pbignfCcpICsgJyknICsgcnNPcHRWYXIgKyByZU9wdE1vZCArICcpKicsCiAgcnNTZXEgPSByc09wdFZhciArIHJlT3B0TW9kICsgcnNPcHRKb2luLAogIHJzU3ltYm9sID0gJyg/OicgKyBbcnNOb25Bc3RyYWwgKyByc0NvbWJvICsgJz8nLCByc0NvbWJvLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyLCByc0FzdHJhbF0uam9pbignfCcpICsgJyknOwoKLyoqIFVzZWQgdG8gbWF0Y2ggW3N0cmluZyBzeW1ib2xzXShodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC11bmljb2RlKS4gKi8KdmFyIHJlVW5pY29kZSA9IFJlZ0V4cChyc0ZpdHogKyAnKD89JyArIHJzRml0eiArICcpfCcgKyByc1N5bWJvbCArIHJzU2VxLCAnZycpOwoKLyoqCiAqIEdldHMgdGhlIHNpemUgb2YgYSBVbmljb2RlIGBzdHJpbmdgLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuCiAqLwpmdW5jdGlvbiB1bmljb2RlU2l6ZShzdHJpbmcpIHsKICB2YXIgcmVzdWx0ID0gcmVVbmljb2RlLmxhc3RJbmRleCA9IDA7CiAgd2hpbGUgKHJlVW5pY29kZS50ZXN0KHN0cmluZykpIHsKICAgICsrcmVzdWx0OwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogR2V0cyB0aGUgbnVtYmVyIG9mIHN5bWJvbHMgaW4gYHN0cmluZ2AuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS4KICovCmZ1bmN0aW9uIHN0cmluZ1NpemUoc3RyaW5nKSB7CiAgcmV0dXJuIGhhc1VuaWNvZGUoc3RyaW5nKSA/IHVuaWNvZGVTaXplKHN0cmluZykgOiBhc2NpaVNpemUkMShzdHJpbmcpOwp9CgovKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovCnZhciBtYXBUYWcgPSAnW29iamVjdCBNYXBdJywKICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJzsKCi8qKgogKiBHZXRzIHRoZSBzaXplIG9mIGBjb2xsZWN0aW9uYCBieSByZXR1cm5pbmcgaXRzIGxlbmd0aCBmb3IgYXJyYXktbGlrZQogKiB2YWx1ZXMgb3IgdGhlIG51bWJlciBvZiBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBmb3Igb2JqZWN0cy4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IENvbGxlY3Rpb24KICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbGxlY3Rpb24gc2l6ZS4KICogQGV4YW1wbGUKICoKICogXy5zaXplKFsxLCAyLCAzXSk7CiAqIC8vID0+IDMKICoKICogXy5zaXplKHsgJ2EnOiAxLCAnYic6IDIgfSk7CiAqIC8vID0+IDIKICoKICogXy5zaXplKCdwZWJibGVzJyk7CiAqIC8vID0+IDcKICovCmZ1bmN0aW9uIHNpemUoY29sbGVjdGlvbikgewogIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHsKICAgIHJldHVybiAwOwogIH0KICBpZiAoaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHsKICAgIHJldHVybiBpc1N0cmluZyhjb2xsZWN0aW9uKSA/IHN0cmluZ1NpemUoY29sbGVjdGlvbikgOiBjb2xsZWN0aW9uLmxlbmd0aDsKICB9CiAgdmFyIHRhZyA9IGdldFRhZyQxKGNvbGxlY3Rpb24pOwogIGlmICh0YWcgPT0gbWFwVGFnIHx8IHRhZyA9PSBzZXRUYWcpIHsKICAgIHJldHVybiBjb2xsZWN0aW9uLnNpemU7CiAgfQogIHJldHVybiBiYXNlS2V5cyhjb2xsZWN0aW9uKS5sZW5ndGg7Cn0KCi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi8KdmFyIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nOwoKLyoqCiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTnVtYmVyYCBwcmltaXRpdmUgb3Igb2JqZWN0LgogKgogKiAqKk5vdGU6KiogVG8gZXhjbHVkZSBgSW5maW5pdHlgLCBgLUluZmluaXR5YCwgYW5kIGBOYU5gLCB3aGljaCBhcmUKICogY2xhc3NpZmllZCBhcyBudW1iZXJzLCB1c2UgdGhlIGBfLmlzRmluaXRlYCBtZXRob2QuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG51bWJlciwgZWxzZSBgZmFsc2VgLgogKiBAZXhhbXBsZQogKgogKiBfLmlzTnVtYmVyKDMpOwogKiAvLyA9PiB0cnVlCiAqCiAqIF8uaXNOdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc051bWJlcihJbmZpbml0eSk7CiAqIC8vID0+IHRydWUKICoKICogXy5pc051bWJlcignMycpOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNOdW1iZXIodmFsdWUpIHsKICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInIHx8IGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gbnVtYmVyVGFnOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuueJqeS7tg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzb2JqLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc29iaih7fSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNvYmooeyBhOiAxMjMgfSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzb2JqKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgT2JqZWN0XSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pyJ5pWI54mp5Lu2DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNvYmoudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZW9iaih7fSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZW9iaih7IGE6IDEyMyB9KSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNlb2JqKHYpIHsKICBpZiAoaXNvYmoodikpIHsKICAgIGZvciAobGV0IGsgaW4gdikgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuumZo+WIlw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzYXJyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2FycihbXSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNhcnIoW3t9XSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzYXJyKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgQXJyYXldJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrp1bmRlZmluZWQNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc3VuZGVmaW5lZC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXN1bmRlZmluZWQodW5kZWZpbmVkKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXN1bmRlZmluZWQodikgewogIGxldCBjID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHYpOwogIHJldHVybiBjID09PSAnW29iamVjdCBVbmRlZmluZWRdJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrpudWxsDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNudWxsLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc251bGwobnVsbCkpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzbnVsbCh2KSB7CiAgbGV0IGMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodik7CiAgcmV0dXJuIGMgPT09ICdbb2JqZWN0IE51bGxdJzsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnqbrnianku7YNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc29iajAudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzb2JqMCh7fSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNvYmowKHsgYTogMTIzIH0pKQ0KICogLy8gPT4gZmFsc2UNCiAqDQogKi8KZnVuY3Rpb24gaXNvYmowKHYpIHsKICBpZiAoaXNvYmoodikpIHsKICAgIGZvciAobGV0IGsgaW4gdikgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKioNCiAqIOWIpOaWt+aYr+WQpueCuuepuuWtl+S4sg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2lzc3RyMC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIwKCcnKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc3N0cjAoJzAnKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICogY29uc29sZS5sb2coaXNzdHIwKCdhYmMxMjUnKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzc3RyMCh2KSB7CiAgaWYgKGlzc3RyKHYpKSB7CiAgICBpZiAodiA9PT0gJycpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrnhKHlhaflrrnpmaPliJcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2FycjAudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzYXJyKFtdKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2Fycihbe31dKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzYXJyMCh2KSB7CiAgaWYgKGlzYXJyKHYpKSB7CiAgICBpZiAodi5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLy8gaW1wb3J0IGlzTmFOIGZyb20gJ2xvZGFzaC1lcy9pc05hTi5qcycKCi8qKg0KICog5Yik5pa35piv5ZCm54K6TmFODQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNuYW4udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbmFuKE5hTikpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGlzbmFuKHYpIHsKICAvLyByZXR1cm4gaXNOYU4odikKICByZXR1cm4gdiAhPT0gdjsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrlu6PnvqnnhKHmlYgNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc2VyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VyKCcxMmE1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoJycpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoW10pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoW3t9XSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoWycnXSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoe30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIobnVsbCkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNlcih1bmRlZmluZWQpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZXIoTmFOKSkNCiAqIC8vID0+IHRydWUNCiAqDQogKi8KZnVuY3Rpb24gaXNlcih2KSB7CiAgaWYgKGlzdW5kZWZpbmVkKHYpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKGlzbnVsbCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc29iajAodikpIHsKICAgIHJldHVybiB0cnVlOwogIH0KICBpZiAoaXNzdHIwKHYpKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaWYgKGlzYXJyMCh2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGlmIChpc25hbih2KSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrmnInmlYjpmaPliJfvvIzplbfluqboh7PlsJHlpKfmlrznrYnmlrwx77yM5ZCE5YWD57Sg6Iez5bCR55qG54K65pyJ5pWIDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNlYXJyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3c2VtaQ0KICogQHBhcmFtIHsqfSB2IOi8uOWFpeS7u+aEj+izh+aWmQ0KICogQHJldHVybnMge0Jvb2xlYW59IOWbnuWCs+WIpOaWt+W4g+ael+WAvA0KICogQGV4YW1wbGUNCiAqDQogKiBjb25zb2xlLmxvZyhpc2VhcnIoW3t9XSkpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZWFycihbeyBhOiAxMjMgfV0pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2VhcnIodikgewogIC8vY2hlY2sKICBpZiAoIWlzYXJyKHYpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICAvL2NoZWNrIGxlbmd0aAogIGlmICh2Lmxlbmd0aCA9PT0gMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy9jaGVjayBsZW5ndGg9MQogIGlmICh2Lmxlbmd0aCA9PT0gMSkgewogICAgaWYgKGlzZXIodlswXSkpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogIH0KICByZXR1cm4gdHJ1ZTsKfQoKLyoqDQogKiDliKTmlrfmmK/lkKbngrrmlbjlrZcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9pc25ici50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygd3NlbWkNCiAqIEBwYXJhbSB7Kn0gdiDovLjlhaXku7vmhI/os4fmlpkNCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaXNuYnIoMS4yNSkpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNuYnIoJzEuMjUnKSkNCiAqIC8vID0+IGZhbHNlDQogKg0KICovCmZ1bmN0aW9uIGlzbmJyKHYpIHsKICBsZXQgYyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KTsKICByZXR1cm4gYyA9PT0gJ1tvYmplY3QgTnVtYmVyXSc7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65pW45a2XDQogKg0KICog5rOo5oSP77ya5pys5Ye95byP5LiN5pSv5o+0QmlnSW5077yMdHlwZW9mIEJpZ0ludOWAvOeCuidiaWdpbnQn6ICM6Z2eJ251bWJlcifmlYVpc25icuWIpOWumueCumZhbHNl44CCDQogKiBCaWdJbnToiIdOdW1iZXLlnKhKU+eCuuS6kuS4jeebuOWuueeahOeul+ihk+WfnyhgMW4gKyAxYOOAgWBNYXRoLmZsb29yKDFuKWAg55qG5pOyVHlwZUVycm9yKe+8jA0KICog6ICMaXNudW3nmoTpmrHlkKvlpZHntITmmK/jgIzpgJrpgY7lvozlj6/lgZpOdW1iZXLnrpfooZPpgYvnrpfjgI3vvIx3c2VtaeWFp+mAvjYw6JmVY2FsbHNpdGXkvp3os7TmraTlpZHntIQNCiAqICjlpoJhcnJNYXgvYXJyTWluL3JvdW5kL3JhbmRvbVJhbmdl562JKe+8jOiLpeaUvuWvrGlzbnVt6KqNQmlnSW505bCH5bCO6Ie06YCZ5LqbY2FsbHNpdGXln7fooYzmnJ/pjK/oqqTjgIINCiAqIOatpOioreioiOiIh2xvZGFzaCBgXy5pc051bWJlcmAg5bCHQmlnSW505o6S6Zmk55qE6JmV55CG5LiA6Ie044CCQmlnSW506KuL5Y+m5L2c542o56uL5Yik5pa344CCDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNudW0udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKDApKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKDEuMjUpKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzbnVtKCctMTI1JykpDQogKiAvLyA9PiB0cnVlDQogKg0KICogY29uc29sZS5sb2coaXNudW0oMTIzbikpDQogKiAvLyA9PiBmYWxzZSAoQmlnSW505LiN6KKr6KaW54K65pW45a2XLCDoqbPopovkuIrmlrnoqqrmmI4pDQogKg0KICovCmZ1bmN0aW9uIGlzbnVtKHYpIHsKICBsZXQgYiA9IGZhbHNlOwogIGlmIChpc2VzdHIodikpIHsKICAgIGIgPSAhaXNOYU4oTnVtYmVyKHYpKTsKICB9IGVsc2UgaWYgKGlzbmJyKHYpKSB7CiAgICAvL+azqOaEj05hTueCuk51bWJlciwg5pWFaXNuYnLlm57lgrN0cnVlCiAgICBpZiAoaXNuYW4odikpIHsKICAgICAgcmV0dXJuIGZhbHNlOyAvL+atpOiZleWIpOWumueCuuacieaViOaVuOWtlywg5pWFTmFO6aCI5YmU6ZmkCiAgICB9IGVsc2UgewogICAgICBiID0gdHJ1ZTsKICAgIH0KICB9CiAgcmV0dXJuIGI7Cn0KCi8qKg0KICog5Yik5pa35piv5ZCm54K65Ye95pW4DQogKg0KICog5aeU5rS+bG9kYXNo5LmLaXNGdW5jdGlvbu+8jOS4gOiIrOWHveaVuOOAgeeuremgreWHveaVuOOAgWFzeW5j5Ye95pW444CBZ2VuZXJhdG9y5Ye95pW46IiHY2xhc3Pnmobngrp0cnVl77ybYXN5bmMgZ2VuZXJhdG9y5Ye95pW4KGFzeW5jIGZ1bmN0aW9uKinmlrxsb2Rhc2ggNOWIpOeCumZhbHNl77yM5bGs5YW25bey55+l6ZmQ5Yi2DQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3dzZW1pL2Jsb2IvbWFzdGVyL3Rlc3QvaXNmdW4udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0geyp9IHYg6Ly45YWl5Lu75oSP6LOH5paZDQogKiBAcmV0dXJucyB7Qm9vbGVhbn0g5Zue5YKz5Yik5pa35biD5p6X5YC8DQogKiBAZXhhbXBsZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZnVuKCcxLjI1JykpDQogKiAvLyA9PiBmYWxzZQ0KICoNCiAqIGNvbnNvbGUubG9nKGlzZnVuKGZ1bmN0aW9uKCkge30pKQ0KICogLy8gPT4gdHJ1ZQ0KICoNCiAqLwpmdW5jdGlvbiBpc2Z1bih2KSB7CiAgcmV0dXJuIGlzRnVuY3Rpb24odik7Cn0KCi8qKiBVc2VkIHRvIG1hdGNoIGEgc2luZ2xlIHdoaXRlc3BhY2UgY2hhcmFjdGVyLiAqLwp2YXIgcmVXaGl0ZXNwYWNlID0gL1xzLzsKCi8qKgogKiBVc2VkIGJ5IGBfLnRyaW1gIGFuZCBgXy50cmltRW5kYCB0byBnZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vbi13aGl0ZXNwYWNlCiAqIGNoYXJhY3RlciBvZiBgc3RyaW5nYC4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IG5vbi13aGl0ZXNwYWNlIGNoYXJhY3Rlci4KICovCmZ1bmN0aW9uIHRyaW1tZWRFbmRJbmRleChzdHJpbmcpIHsKICB2YXIgaW5kZXggPSBzdHJpbmcubGVuZ3RoOwogIHdoaWxlIChpbmRleC0tICYmIHJlV2hpdGVzcGFjZS50ZXN0KHN0cmluZy5jaGFyQXQoaW5kZXgpKSkge30KICByZXR1cm4gaW5kZXg7Cn0KCi8qKiBVc2VkIHRvIG1hdGNoIGxlYWRpbmcgd2hpdGVzcGFjZS4gKi8KdmFyIHJlVHJpbVN0YXJ0ID0gL15ccysvOwoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRyaW1gLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS4KICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuCiAqLwpmdW5jdGlvbiBiYXNlVHJpbShzdHJpbmcpIHsKICByZXR1cm4gc3RyaW5nID8gc3RyaW5nLnNsaWNlKDAsIHRyaW1tZWRFbmRJbmRleChzdHJpbmcpICsgMSkucmVwbGFjZShyZVRyaW1TdGFydCwgJycpIDogc3RyaW5nOwp9CgovKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi8KdmFyIE5BTiQxID0gMCAvIDA7CgovKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqLwp2YXIgcmVJc0JhZEhleCA9IC9eWy0rXTB4WzAtOWEtZl0rJC9pOwoKLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqLwp2YXIgcmVJc0JpbmFyeSA9IC9eMGJbMDFdKyQvaTsKCi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqLwp2YXIgcmVJc09jdGFsID0gL14wb1swLTddKyQvaTsKCi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovCnZhciBmcmVlUGFyc2VJbnQgPSBwYXJzZUludDsKCi8qKgogKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLgogKgogKiBAc3RhdGljCiAqIEBtZW1iZXJPZiBfCiAqIEBzaW5jZSA0LjAuMAogKiBAY2F0ZWdvcnkgTGFuZwogKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLgogKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBudW1iZXIuCiAqIEBleGFtcGxlCiAqCiAqIF8udG9OdW1iZXIoMy4yKTsKICogLy8gPT4gMy4yCiAqCiAqIF8udG9OdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7CiAqIC8vID0+IDVlLTMyNAogKgogKiBfLnRvTnVtYmVyKEluZmluaXR5KTsKICogLy8gPT4gSW5maW5pdHkKICoKICogXy50b051bWJlcignMy4yJyk7CiAqIC8vID0+IDMuMgogKi8KZnVuY3Rpb24gdG9OdW1iZXIodmFsdWUpIHsKICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7CiAgICByZXR1cm4gdmFsdWU7CiAgfQogIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHsKICAgIHJldHVybiBOQU4kMTsKICB9CiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkgewogICAgdmFyIG90aGVyID0gdHlwZW9mIHZhbHVlLnZhbHVlT2YgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnZhbHVlT2YoKSA6IHZhbHVlOwogICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyBvdGhlciArICcnIDogb3RoZXI7CiAgfQogIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHsKICAgIHJldHVybiB2YWx1ZSA9PT0gMCA/IHZhbHVlIDogK3ZhbHVlOwogIH0KICB2YWx1ZSA9IGJhc2VUcmltKHZhbHVlKTsKICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpOwogIHJldHVybiBpc0JpbmFyeSB8fCByZUlzT2N0YWwudGVzdCh2YWx1ZSkgPyBmcmVlUGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpIDogcmVJc0JhZEhleC50ZXN0KHZhbHVlKSA/IE5BTiQxIDogK3ZhbHVlOwp9CgovKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi8KdmFyIElORklOSVRZID0gMSAvIDAsCiAgTUFYX0lOVEVHRVIgPSAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwODsKCi8qKgogKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgZmluaXRlIG51bWJlci4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4xMi4wCiAqIEBjYXRlZ29yeSBMYW5nCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBudW1iZXIuCiAqIEBleGFtcGxlCiAqCiAqIF8udG9GaW5pdGUoMy4yKTsKICogLy8gPT4gMy4yCiAqCiAqIF8udG9GaW5pdGUoTnVtYmVyLk1JTl9WQUxVRSk7CiAqIC8vID0+IDVlLTMyNAogKgogKiBfLnRvRmluaXRlKEluZmluaXR5KTsKICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDgKICoKICogXy50b0Zpbml0ZSgnMy4yJyk7CiAqIC8vID0+IDMuMgogKi8KZnVuY3Rpb24gdG9GaW5pdGUodmFsdWUpIHsKICBpZiAoIXZhbHVlKSB7CiAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6IDA7CiAgfQogIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpOwogIGlmICh2YWx1ZSA9PT0gSU5GSU5JVFkgfHwgdmFsdWUgPT09IC1JTkZJTklUWSkgewogICAgdmFyIHNpZ24gPSB2YWx1ZSA8IDAgPyAtMSA6IDE7CiAgICByZXR1cm4gc2lnbiAqIE1BWF9JTlRFR0VSOwogIH0KICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gdmFsdWUgOiAwOwp9CgovKioNCiAqIOaVuOWtl+aIluWtl+S4sui9iea1rum7nuaVuA0KICog6Iul6Ly45YWl6Z2e5pW45a2X5YmH5Zue5YKzMA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93c2VtaS9ibG9iL21hc3Rlci90ZXN0L2NkYmwudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0ge051bWJlcnxTdHJpbmd9IHYg6Ly45YWl5pW45a2X5oiW5a2X5LiyDQogKiBAcmV0dXJucyB7TnVtYmVyfSDlm57lgrPmlbjlrZcNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coY2RibCgnMjUnKSkNCiAqIC8vID0+IDI1DQogKg0KICovCmZ1bmN0aW9uIGNkYmwodikgewogIC8vY2hlY2sKICBpZiAoIWlzbnVtKHYpKSB7CiAgICByZXR1cm4gMDsKICB9CiAgbGV0IHIgPSB0b0Zpbml0ZSh2KTsKICByZXR1cm4gcjsKfQoKLyoqDQogKiDliKTmlrfnianku7bmmK/lkKbmnIlrZXnlsazmgKcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvd3NlbWkvYmxvYi9tYXN0ZXIvdGVzdC9oYXNrZXkudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHdzZW1pDQogKiBAcGFyYW0ge09iamVjdH0gb2JqIOi8uOWFpeeJqeS7tg0KICogQHBhcmFtIHtTdHJpbmd9IGtleSDovLjlhaXopoHmn6Xmib7nmoRrZXnlrZfkuLINCiAqIEByZXR1cm5zIHtCb29sZWFufSDlm57lgrPliKTmlrfluIPmnpflgLwNCiAqIEBleGFtcGxlDQogKg0KICogY29uc29sZS5sb2coaGFza2V5KHsgYTogMTIzLCBiOiAneHl6JywgYzogJzQ1b3AnLCBkOiBudWxsIH0sICdhJykpDQogKiAvLyA9PiB0cnVlDQogKg0KICovCmZ1bmN0aW9uIGhhc2tleShvYmosIGtleSkgewogIC8vY2hlY2sKICBpZiAoIWlzb2JqKG9iaikpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CiAgaWYgKCFpc2VzdHIoa2V5KSAmJiAhaXNudW0oa2V5KSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICByZXR1cm4ga2V5IGluIG9iajsKfQoKLyoqDQogKiDmj5Dlj5bpu57pmaPliJflhafkuYvpu55bMCwxXeaIlnt4LHl95oiW5oyH5a6a6Y215YC85oiQ54K66buee3gseX3nianku7bpmaPliJcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9wdHNYWXRvQXJyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcHMg6Ly45YWl6bue6Zmj5YiX77yM54K6W3t4OngxLHk6eTF9LHt4OngyLHk6eTJ9LC4uLl3pu57nianku7bkuYvpmaPliJfvvIzmiJZbW3gxLHkxXSxbeDIseTJdLC4uLl3pu57luqfmqJnpmaPliJfkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tnjluqfmqJnpjbXlrZfkuLLvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7Z55bqn5qiZ6Y215a2X5Liy77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlJbmQ9J2luZCddIOi8uOWFpem7nueJqeS7tuaMh+aomemNteWtl+S4su+8jOmgkOiorSdpbmQnDQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQucmV0dXJuT2JqQXJyYXk9dHJ1ZV0g6Ly45YWl5piv5ZCm5Zue5YKz54mp5Lu26Zmj5YiX77yM6IuldHJ1ZeS7o+ihqOWbnuWCs+m7nueCuueJqeS7tnt4LHl95LmL6Zmj5YiX77yM6IulZmFsc2Xlm57lgrPpu57pmaPliJdbeCx5XeS5i+mZo+WIl++8jOmgkOiorXRydWUNCiAqIEByZXR1cm5zIHtBcnJheX0g5Zue5YKz6bue6Zmj5YiXDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHINCiAqDQogKiBwcyA9IFtbMjQzLCAyMDZdLCBbMjMzLCAyMjVdLCBbMjEsIDMyNV1dDQogKiByID0gcHRzWFl0b0FycihwcykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDYsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCBpbmQ6IDEgfSwNCiAqIC8vICAgeyB4OiAyMSwgeTogMzI1LCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgJ3gnOiAyNDMsICd5JzogMjA2IH0sIHsgJ3gnOiAyMzMsICd5JzogMjI1IH0sIHsgJ3gnOiAyMSwgJ3knOiAzMjUgfV0NCiAqIHIgPSBwdHNYWXRvQXJyKHBzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNiwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIGluZDogMSB9LA0KICogLy8gICB7IHg6IDIxLCB5OiAzMjUsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyAnYSc6IDI0MywgJ2InOiAyMDYgfSwgeyAnYSc6IDIzMywgJ2InOiAyMjUgfSwgeyAnYSc6IDIxLCAnYic6IDMyNSB9XQ0KICogciA9IHB0c1hZdG9BcnIocHMsIHsga2V5WDogJ2EnLCBrZXlZOiAnYicgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDYsIGluZDogMCB9LA0KICogLy8gICB7IHg6IDIzMywgeTogMjI1LCBpbmQ6IDEgfSwNCiAqIC8vICAgeyB4OiAyMSwgeTogMzI1LCBpbmQ6IDIgfQ0KICogLy8gXQ0KICoNCiAqLwpmdW5jdGlvbiBwdHNYWXRvQXJyKHBzLCBvcHQgPSB7fSkgewogIC8v6Iul54Sh5pW45pOa5Zue5YKz56m66Zmj5YiXCiAgaWYgKHNpemUocHMpIDw9IDApIHsKICAgIHJldHVybiBbXTsKICB9CgogIC8va2V5WAogIGxldCBrZXlYID0gZ2V0KG9wdCwgJ2tleVgnKTsKICBpZiAoIWlzZXN0cihrZXlYKSkgewogICAga2V5WCA9ICd4JzsKICB9CgogIC8va2V5WQogIGxldCBrZXlZID0gZ2V0KG9wdCwgJ2tleVknKTsKICBpZiAoIWlzZXN0cihrZXlZKSkgewogICAga2V5WSA9ICd5JzsKICB9CgogIC8va2V5SW5kCiAgbGV0IGtleUluZCA9IGdldChvcHQsICdrZXlJbmQnLCAnJyk7CiAgaWYgKCFpc2VzdHIoa2V5SW5kKSkgewogICAga2V5SW5kID0gJ2luZCc7CiAgfQoKICAvL3JldHVybk9iakFycmF5CiAgbGV0IHJldHVybk9iakFycmF5ID0gZ2V0KG9wdCwgJ3JldHVybk9iakFycmF5Jyk7CiAgaWYgKCFpc2JvbChyZXR1cm5PYmpBcnJheSkpIHsKICAgIHJldHVybk9iakFycmF5ID0gdHJ1ZTsKICB9CgogIC8vcnMKICBsZXQgcnMgPSBbXTsKICBmb3JFYWNoKHBzLCAodiwgaykgPT4gewogICAgbGV0IHggPSBudWxsOwogICAgbGV0IHkgPSBudWxsOwogICAgaWYgKGlzYXJyKHYpICYmIHNpemUodikgPj0gMikgewogICAgICB4ID0gZ2V0KHYsIDApOwogICAgICB5ID0gZ2V0KHYsIDEpOwogICAgfSBlbHNlIHsKICAgICAgeCA9IGdldCh2LCBrZXlYLCBudWxsKTsKICAgICAgeSA9IGdldCh2LCBrZXlZLCBudWxsKTsKICAgIH0KICAgIGlmIChpc251bSh4KSAmJiBpc251bSh5KSkgewogICAgICB4ID0gdG9OdW1iZXIoeCk7CiAgICAgIHkgPSB0b051bWJlcih5KTsKICAgICAgcnMucHVzaCh7CiAgICAgICAgeCwKICAgICAgICB5LAogICAgICAgIFtrZXlJbmRdOiBrCiAgICAgIH0pOwogICAgfQogIH0pOwoKICAvL3JldHVybk9iakFycmF5CiAgaWYgKCFyZXR1cm5PYmpBcnJheSkgewogICAgcnMgPSBtYXAocnMsIHYgPT4gewogICAgICByZXR1cm4gW3YueCwgdi55LCB2W2tleUluZF1dOwogICAgfSk7CiAgfQogIHJldHVybiByczsKfQoKLyoqDQogKiDmj5Dlj5bpu57pmaPliJflhafkuYvpu55bMCwxLDJd5oiWe3gseSx6feaIluaMh+WumumNteWAvOaIkOeCuum7nnt4LHksen3nianku7bpmaPliJcNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9wdHNYWVp0b0Fyci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzIOi8uOWFpem7numZo+WIl++8jOeCult7eDp4MSx5OnkxLHo6ejF9LHt4OngyLHk6eTIsejp6Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIl++8jOaIlltbeDEseTEsejFdLFt4Mix5Mix6Ml0sLi4uXem7nuW6p+aomemZo+WIl+S5i+mZo+WIlw0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlYPSd4J10g6Ly45YWl6bue54mp5Lu2eOW6p+aomemNteWtl+S4su+8jOmgkOiorSd4Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neSddIOi8uOWFpem7nueJqeS7tnnluqfmqJnpjbXlrZfkuLLvvIzpoJDoqK0neScNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3onXSDovLjlhaXpu57nianku7Z65bqn5qiZ6Y215a2X5Liy77yM6aCQ6KitJ3onDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlJbmQ9J2luZCddIOi8uOWFpem7nueJqeS7tuaMh+aomemNteWtl+S4su+8jOmgkOiorSdpbmQnDQogKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHQucmV0dXJuT2JqQXJyYXk9dHJ1ZV0g6Ly45YWl5piv5ZCm5Zue5YKz54mp5Lu26Zmj5YiX77yM6IuldHJ1ZeS7o+ihqOWbnuWCs+m7nueCuueJqeS7tnt4LHksen3kuYvpmaPliJfvvIzoi6VmYWxzZeWbnuWCs+m7numZo+WIl1t4LHksel3kuYvpmaPliJfvvIzpoJDoqK10cnVlDQogKiBAcmV0dXJucyB7QXJyYXl9IOWbnuWCs+m7nnt4LHksen3pmaPliJcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBzDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW1syNDMsIDIwNiwgOTVdLCBbMjMzLCAyMjUsIDE0Nl0sIFsyMSwgMzI1LCAyMl1dDQogKiByID0gcHRzWFladG9BcnIocHMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA2LCB6OiA5NSwgaW5kOiAwIH0sDQogKiAvLyAgIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiwgaW5kOiAxIH0sDQogKiAvLyAgIHsgeDogMjEsIHk6IDMyNSwgejogMjIsIGluZDogMiB9DQogKiAvLyBdDQogKg0KICogcHMgPSBbeyAneCc6IDI0MywgJ3knOiAyMDYsICd6JzogOTUgfSwgeyAneCc6IDIzMywgJ3knOiAyMjUsICd6JzogMTQ2IH0sIHsgJ3gnOiAyMSwgJ3knOiAzMjUsICd6JzogMjIgfV0NCiAqIHIgPSBwdHNYWVp0b0FycihwcykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDYsIHo6IDk1LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2LCBpbmQ6IDEgfSwNCiAqIC8vICAgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7ICdhJzogMjQzLCAnYic6IDIwNiwgJ2MnOiA5NSB9LCB7ICdhJzogMjMzLCAnYic6IDIyNSwgJ2MnOiAxNDYgfSwgeyAnYSc6IDIxLCAnYic6IDMyNSwgJ2MnOiAyMiB9XQ0KICogciA9IHB0c1hZWnRvQXJyKHBzLCB7IGtleVg6ICdhJywga2V5WTogJ2InLCBrZXlaOiAnYycgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsgeDogMjQzLCB5OiAyMDYsIHo6IDk1LCBpbmQ6IDAgfSwNCiAqIC8vICAgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2LCBpbmQ6IDEgfSwNCiAqIC8vICAgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiwgaW5kOiAyIH0NCiAqIC8vIF0NCiAqDQogKi8KZnVuY3Rpb24gcHRzWFladG9BcnIocHMsIG9wdCA9IHt9KSB7CiAgLy/oi6XnhKHmlbjmk5rlm57lgrPnqbrpmaPliJcKICBpZiAoc2l6ZShwcykgPD0gMCkgewogICAgcmV0dXJuIFtdOwogIH0KCiAgLy9rZXlYCiAgbGV0IGtleVggPSBnZXQob3B0LCAna2V5WCcpOwogIGlmICghaXNlc3RyKGtleVgpKSB7CiAgICBrZXlYID0gJ3gnOwogIH0KCiAgLy9rZXlZCiAgbGV0IGtleVkgPSBnZXQob3B0LCAna2V5WScpOwogIGlmICghaXNlc3RyKGtleVkpKSB7CiAgICBrZXlZID0gJ3knOwogIH0KCiAgLy9rZXlaCiAgbGV0IGtleVogPSBnZXQob3B0LCAna2V5WicsICcnKTsKICBpZiAoIWlzZXN0cihrZXlaKSkgewogICAga2V5WiA9ICd6JzsKICB9CgogIC8va2V5SW5kCiAgbGV0IGtleUluZCA9IGdldChvcHQsICdrZXlJbmQnLCAnJyk7CiAgaWYgKCFpc2VzdHIoa2V5SW5kKSkgewogICAga2V5SW5kID0gJ2luZCc7CiAgfQoKICAvL3JldHVybk9iakFycmF5CiAgbGV0IHJldHVybk9iakFycmF5ID0gZ2V0KG9wdCwgJ3JldHVybk9iakFycmF5Jyk7CiAgaWYgKCFpc2JvbChyZXR1cm5PYmpBcnJheSkpIHsKICAgIHJldHVybk9iakFycmF5ID0gdHJ1ZTsKICB9CgogIC8vcnMKICBsZXQgcnMgPSBbXTsKICBmb3JFYWNoKHBzLCAodiwgaykgPT4gewogICAgbGV0IHggPSBudWxsOwogICAgbGV0IHkgPSBudWxsOwogICAgbGV0IHogPSBudWxsOwogICAgaWYgKGlzYXJyKHYpICYmIHNpemUodikgPj0gMykgewogICAgICB4ID0gZ2V0KHYsIDApOwogICAgICB5ID0gZ2V0KHYsIDEpOwogICAgICB6ID0gZ2V0KHYsIDIpOwogICAgfSBlbHNlIHsKICAgICAgeCA9IGdldCh2LCBrZXlYLCBudWxsKTsKICAgICAgeSA9IGdldCh2LCBrZXlZLCBudWxsKTsKICAgICAgeiA9IGdldCh2LCBrZXlaLCBudWxsKTsKICAgIH0KICAgIGlmIChpc251bSh4KSAmJiBpc251bSh5KSAmJiBpc251bSh6KSkgewogICAgICB4ID0gdG9OdW1iZXIoeCk7CiAgICAgIHkgPSB0b051bWJlcih5KTsKICAgICAgeiA9IHRvTnVtYmVyKHopOwogICAgICBycy5wdXNoKHsKICAgICAgICB4LAogICAgICAgIHksCiAgICAgICAgeiwKICAgICAgICBba2V5SW5kXTogawogICAgICB9KTsKICAgIH0KICB9KTsKCiAgLy9yZXR1cm5PYmpBcnJheQogIGlmICghcmV0dXJuT2JqQXJyYXkpIHsKICAgIHJzID0gbWFwKHJzLCB2ID0+IHsKICAgICAgcmV0dXJuIFt2LngsIHYueSwgdi56LCB2W2tleUluZF1dOwogICAgfSk7CiAgfQogIHJldHVybiByczsKfQoKLyoqCiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5tYXhgIGFuZCBgXy5taW5gIHdoaWNoIGFjY2VwdHMgYQogKiBgY29tcGFyYXRvcmAgdG8gZGV0ZXJtaW5lIHRoZSBleHRyZW11bSB2YWx1ZS4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGl0ZXJhdGlvbi4KICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyYXRvciBUaGUgY29tcGFyYXRvciB1c2VkIHRvIGNvbXBhcmUgdmFsdWVzLgogKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZXh0cmVtdW0gdmFsdWUuCiAqLwpmdW5jdGlvbiBiYXNlRXh0cmVtdW0oYXJyYXksIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7CiAgdmFyIGluZGV4ID0gLTEsCiAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSwKICAgICAgY3VycmVudCA9IGl0ZXJhdGVlKHZhbHVlKTsKICAgIGlmIChjdXJyZW50ICE9IG51bGwgJiYgKGNvbXB1dGVkID09PSB1bmRlZmluZWQgPyBjdXJyZW50ID09PSBjdXJyZW50ICYmICFpc1N5bWJvbChjdXJyZW50KSA6IGNvbXBhcmF0b3IoY3VycmVudCwgY29tcHV0ZWQpKSkgewogICAgICB2YXIgY29tcHV0ZWQgPSBjdXJyZW50LAogICAgICAgIHJlc3VsdCA9IHZhbHVlOwogICAgfQogIH0KICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubHRgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAsCiAqICBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlTHQodmFsdWUsIG90aGVyKSB7CiAgcmV0dXJuIHZhbHVlIDwgb3RoZXI7Cn0KCi8qKgogKiBDb21wdXRlcyB0aGUgbWluaW11bSB2YWx1ZSBvZiBgYXJyYXlgLiBJZiBgYXJyYXlgIGlzIGVtcHR5IG9yIGZhbHNleSwKICogYHVuZGVmaW5lZGAgaXMgcmV0dXJuZWQuCiAqCiAqIEBzdGF0aWMKICogQHNpbmNlIDAuMS4wCiAqIEBtZW1iZXJPZiBfCiAqIEBjYXRlZ29yeSBNYXRoCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtaW5pbXVtIHZhbHVlLgogKiBAZXhhbXBsZQogKgogKiBfLm1pbihbNCwgMiwgOCwgNl0pOwogKiAvLyA9PiAyCiAqCiAqIF8ubWluKFtdKTsKICogLy8gPT4gdW5kZWZpbmVkCiAqLwpmdW5jdGlvbiBtaW4oYXJyYXkpIHsKICByZXR1cm4gYXJyYXkgJiYgYXJyYXkubGVuZ3RoID8gYmFzZUV4dHJlbXVtKGFycmF5LCBpZGVudGl0eSQxLCBiYXNlTHQpIDogdW5kZWZpbmVkOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZ3RgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIGBvdGhlcmAsCiAqICBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBiYXNlR3QodmFsdWUsIG90aGVyKSB7CiAgcmV0dXJuIHZhbHVlID4gb3RoZXI7Cn0KCi8qKgogKiBDb21wdXRlcyB0aGUgbWF4aW11bSB2YWx1ZSBvZiBgYXJyYXlgLiBJZiBgYXJyYXlgIGlzIGVtcHR5IG9yIGZhbHNleSwKICogYHVuZGVmaW5lZGAgaXMgcmV0dXJuZWQuCiAqCiAqIEBzdGF0aWMKICogQHNpbmNlIDAuMS4wCiAqIEBtZW1iZXJPZiBfCiAqIEBjYXRlZ29yeSBNYXRoCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlLgogKiBAZXhhbXBsZQogKgogKiBfLm1heChbNCwgMiwgOCwgNl0pOwogKiAvLyA9PiA4CiAqCiAqIF8ubWF4KFtdKTsKICogLy8gPT4gdW5kZWZpbmVkCiAqLwpmdW5jdGlvbiBtYXgoYXJyYXkpIHsKICByZXR1cm4gYXJyYXkgJiYgYXJyYXkubGVuZ3RoID8gYmFzZUV4dHJlbXVtKGFycmF5LCBpZGVudGl0eSQxLCBiYXNlR3QpIDogdW5kZWZpbmVkOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmlsdGVyYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LgogKi8KZnVuY3Rpb24gYmFzZUZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHsKICB2YXIgcmVzdWx0ID0gW107CiAgYmFzZUVhY2gkMShjb2xsZWN0aW9uLCBmdW5jdGlvbiAodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7CiAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikpIHsKICAgICAgcmVzdWx0LnB1c2godmFsdWUpOwogICAgfQogIH0pOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIGFuIGFycmF5IG9mIGFsbCBlbGVtZW50cwogKiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRocmVlCiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLgogKgogKiAqKk5vdGU6KiogVW5saWtlIGBfLnJlbW92ZWAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci4KICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS4KICogQHNlZSBfLnJlamVjdAogKiBAZXhhbXBsZQogKgogKiB2YXIgdXNlcnMgPSBbCiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sCiAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9CiAqIF07CiAqCiAqIF8uZmlsdGVyKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pOwogKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXQogKgogKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLgogKiBfLmZpbHRlcih1c2VycywgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0pOwogKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddCiAqCiAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC4KICogXy5maWx0ZXIodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTsKICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ10KICoKICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuCiAqIF8uZmlsdGVyKHVzZXJzLCAnYWN0aXZlJyk7CiAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J10KICoKICogLy8gQ29tYmluaW5nIHNldmVyYWwgcHJlZGljYXRlcyB1c2luZyBgXy5vdmVyRXZlcnlgIG9yIGBfLm92ZXJTb21lYC4KICogXy5maWx0ZXIodXNlcnMsIF8ub3ZlclNvbWUoW3sgJ2FnZSc6IDM2IH0sIFsnYWdlJywgNDBdXSkpOwogKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAnYmFybmV5J10KICovCmZ1bmN0aW9uIGZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHsKICB2YXIgZnVuYyA9IGlzQXJyYXkkMShjb2xsZWN0aW9uKSA/IGFycmF5RmlsdGVyIDogYmFzZUZpbHRlcjsKICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBiYXNlSXRlcmF0ZWUocHJlZGljYXRlKSk7Cn0KCi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi8KdmFyIG5hdGl2ZUNlaWwgPSBNYXRoLmNlaWwsCiAgbmF0aXZlTWF4ID0gTWF0aC5tYXg7CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmFuZ2VgIGFuZCBgXy5yYW5nZVJpZ2h0YCB3aGljaCBkb2Vzbid0CiAqIGNvZXJjZSBhcmd1bWVudHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLgogKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLgogKiBAcGFyYW0ge251bWJlcn0gc3RlcCBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS4KICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuCiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy4KICovCmZ1bmN0aW9uIGJhc2VSYW5nZShzdGFydCwgZW5kLCBzdGVwLCBmcm9tUmlnaHQpIHsKICB2YXIgaW5kZXggPSAtMSwKICAgIGxlbmd0aCA9IG5hdGl2ZU1heChuYXRpdmVDZWlsKChlbmQgLSBzdGFydCkgLyAoc3RlcCB8fCAxKSksIDApLAogICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTsKICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgIHJlc3VsdFtmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XSA9IHN0YXJ0OwogICAgc3RhcnQgKz0gc3RlcDsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC4KICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC4KICogQHBhcmFtIHsqfSBvYmplY3QgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBvYmplY3QgYXJndW1lbnQuCiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsCiAqICBlbHNlIGBmYWxzZWAuCiAqLwpmdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkgewogIGlmICghaXNPYmplY3Qob2JqZWN0KSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2YXIgdHlwZSA9IHR5cGVvZiBpbmRleDsKICBpZiAodHlwZSA9PSAnbnVtYmVyJyA/IGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkgOiB0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdCkgewogICAgcmV0dXJuIGVxKG9iamVjdFtpbmRleF0sIHZhbHVlKTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKioKICogQ3JlYXRlcyBhIGBfLnJhbmdlYCBvciBgXy5yYW5nZVJpZ2h0YCBmdW5jdGlvbi4KICoKICogQHByaXZhdGUKICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuCiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJhbmdlIGZ1bmN0aW9uLgogKi8KZnVuY3Rpb24gY3JlYXRlUmFuZ2UoZnJvbVJpZ2h0KSB7CiAgcmV0dXJuIGZ1bmN0aW9uIChzdGFydCwgZW5kLCBzdGVwKSB7CiAgICBpZiAoc3RlcCAmJiB0eXBlb2Ygc3RlcCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChzdGFydCwgZW5kLCBzdGVwKSkgewogICAgICBlbmQgPSBzdGVwID0gdW5kZWZpbmVkOwogICAgfQogICAgLy8gRW5zdXJlIHRoZSBzaWduIG9mIGAtMGAgaXMgcHJlc2VydmVkLgogICAgc3RhcnQgPSB0b0Zpbml0ZShzdGFydCk7CiAgICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHsKICAgICAgZW5kID0gc3RhcnQ7CiAgICAgIHN0YXJ0ID0gMDsKICAgIH0gZWxzZSB7CiAgICAgIGVuZCA9IHRvRmluaXRlKGVuZCk7CiAgICB9CiAgICBzdGVwID0gc3RlcCA9PT0gdW5kZWZpbmVkID8gc3RhcnQgPCBlbmQgPyAxIDogLTEgOiB0b0Zpbml0ZShzdGVwKTsKICAgIHJldHVybiBiYXNlUmFuZ2Uoc3RhcnQsIGVuZCwgc3RlcCwgZnJvbVJpZ2h0KTsKICB9Owp9CgovKioKICogQ3JlYXRlcyBhbiBhcnJheSBvZiBudW1iZXJzIChwb3NpdGl2ZSBhbmQvb3IgbmVnYXRpdmUpIHByb2dyZXNzaW5nIGZyb20KICogYHN0YXJ0YCB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIGBlbmRgLiBBIHN0ZXAgb2YgYC0xYCBpcyB1c2VkIGlmIGEgbmVnYXRpdmUKICogYHN0YXJ0YCBpcyBzcGVjaWZpZWQgd2l0aG91dCBhbiBgZW5kYCBvciBgc3RlcGAuIElmIGBlbmRgIGlzIG5vdCBzcGVjaWZpZWQsCiAqIGl0J3Mgc2V0IHRvIGBzdGFydGAgd2l0aCBgc3RhcnRgIHRoZW4gc2V0IHRvIGAwYC4KICoKICogKipOb3RlOioqIEphdmFTY3JpcHQgZm9sbG93cyB0aGUgSUVFRS03NTQgc3RhbmRhcmQgZm9yIHJlc29sdmluZwogKiBmbG9hdGluZy1wb2ludCB2YWx1ZXMgd2hpY2ggY2FuIHByb2R1Y2UgdW5leHBlY3RlZCByZXN1bHRzLgogKgogKiBAc3RhdGljCiAqIEBzaW5jZSAwLjEuMAogKiBAbWVtYmVyT2YgXwogKiBAY2F0ZWdvcnkgVXRpbAogKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuCiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuCiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RlcD0xXSBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5nZSBvZiBudW1iZXJzLgogKiBAc2VlIF8uaW5SYW5nZSwgXy5yYW5nZVJpZ2h0CiAqIEBleGFtcGxlCiAqCiAqIF8ucmFuZ2UoNCk7CiAqIC8vID0+IFswLCAxLCAyLCAzXQogKgogKiBfLnJhbmdlKC00KTsKICogLy8gPT4gWzAsIC0xLCAtMiwgLTNdCiAqCiAqIF8ucmFuZ2UoMSwgNSk7CiAqIC8vID0+IFsxLCAyLCAzLCA0XQogKgogKiBfLnJhbmdlKDAsIDIwLCA1KTsKICogLy8gPT4gWzAsIDUsIDEwLCAxNV0KICoKICogXy5yYW5nZSgwLCAtNCwgLTEpOwogKiAvLyA9PiBbMCwgLTEsIC0yLCAtM10KICoKICogXy5yYW5nZSgxLCA0LCAwKTsKICogLy8gPT4gWzEsIDEsIDFdCiAqCiAqIF8ucmFuZ2UoMCk7CiAqIC8vID0+IFtdCiAqLwp2YXIgcmFuZ2UgPSBjcmVhdGVSYW5nZSgpOwp2YXIgcmFuZ2UkMSA9IHJhbmdlOwoKLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovCnZhciBOQU4gPSAwIC8gMDsKCi8qKgogKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tZWFuYCBhbmQgYF8ubWVhbkJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yCiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuCiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG1lYW4uCiAqLwpmdW5jdGlvbiBiYXNlTWVhbihhcnJheSwgaXRlcmF0ZWUpIHsKICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7CiAgcmV0dXJuIGxlbmd0aCA/IGJhc2VTdW0oYXJyYXksIGl0ZXJhdGVlKSAvIGxlbmd0aCA6IE5BTjsKfQoKLyoqCiAqIENvbXB1dGVzIHRoZSBtZWFuIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgNC4wLjAKICogQGNhdGVnb3J5IE1hdGgKICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci4KICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbWVhbi4KICogQGV4YW1wbGUKICoKICogXy5tZWFuKFs0LCAyLCA4LCA2XSk7CiAqIC8vID0+IDUKICovCmZ1bmN0aW9uIG1lYW4oYXJyYXkpIHsKICByZXR1cm4gYmFzZU1lYW4oYXJyYXksIGlkZW50aXR5JDEpOwp9CgpmdW5jdGlvbiBub3JtYWxpemVBcnJheUNvcmUoYXJyKSB7CiAgLy9jaGVjayBwc1NyYwogIGlmICghaXNlYXJyKGFycikpIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ2FyciBpcyBub3QgYW4gZWZmZWN0aXZlIGFycmF5JwogICAgfTsKICB9CgogIC8vdjAKICBsZXQgdjAgPSBnZXQoYXJyLCAwKTsKCiAgLy9uCiAgbGV0IG4gPSAwOyAvLzFkIGFycmF5CiAgaWYgKGlzZWFycih2MCkpIHsKICAgIG4gPSBzaXplKHYwKTsgLy9uZCBhcnJheQogIH0KCiAgLy9lYXJyCiAgbGV0IGVhcnIgPSBbXTsKICBpZiAobiA9PT0gMCkgewogICAgZWFyciA9IGZpbHRlcihhcnIsIGlzbnVtKTsKICAgIGVhcnIgPSBtYXAoZWFyciwgY2RibCk7CiAgfSBlbHNlIHsKICAgIGZvckVhY2goYXJyLCB2cyA9PiB7CiAgICAgIC8vYgogICAgICBsZXQgYiA9IHRydWU7CiAgICAgIGxldCBjcyA9IFtdOwogICAgICBmb3JFYWNoKHJhbmdlJDEobiksIGkgPT4gewogICAgICAgIC8vdgogICAgICAgIGxldCB2ID0gZ2V0KHZzLCBpKTsKCiAgICAgICAgLy9jaGVjawogICAgICAgIGlmICghaXNudW0odikpIHsKICAgICAgICAgIGIgPSBmYWxzZTsKICAgICAgICAgIC8v6Lez5Ye65o+b5LiL5LiA5YCLCiAgICAgICAgfQoKICAgICAgICAvL3B1c2gKICAgICAgICBjcy5wdXNoKGNkYmwodikpOwogICAgICB9KTsKCiAgICAgIC8vY2hlY2sKICAgICAgaWYgKGIpIHsKICAgICAgICBlYXJyLnB1c2goY3MpOwogICAgICB9CiAgICB9KTsKICB9CgogIC8vY2hlY2sKICBpZiAoc2l6ZShlYXJyKSA9PT0gMCkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAnYXJyIGhhcyBubyBlZmZlY3RpdmUgZGF0YScKICAgIH07CiAgfQoKICAvL3N0YQogIGxldCBzdGEgPSBhcnIgPT4gewogICAgbGV0IHJtaW4gPSBtaW4oYXJyKTsKICAgIGxldCBybWF4ID0gbWF4KGFycik7CiAgICByZXR1cm4gewogICAgICBtaW46IHJtaW4sCiAgICAgIG1heDogcm1heCwKICAgICAgcmFuZ2U6IHJtYXggLSBybWluLAogICAgICBtaWQ6IChybWF4ICsgcm1pbikgLyAyLAogICAgICBhdmc6IG1lYW4oYXJyKQogICAgfTsKICB9OwoKICAvL25tYXJyCiAgbGV0IG5tYXJyID0gKGFyciwgcm1pbiwgcm1heCwgcnJuZykgPT4gewogICAgcmV0dXJuIG1hcChhcnIsIHYgPT4gewogICAgICByZXR1cm4gKHYgLSBybWluKSAvIHJybmc7CiAgICB9KTsKICB9OwoKICAvL25tCiAgbGV0IG5tID0gYXJyID0+IHsKICAgIGxldCBzID0gc3RhKGFycik7CiAgICBsZXQgYXJydCA9IG5tYXJyKGFyciwgcy5taW4sIHMubWF4LCBzLnJhbmdlKTsKICAgIHJldHVybiB7CiAgICAgIGFycjogYXJydCwKICAgICAgLi4ucwogICAgfTsKICB9OwoKICAvL3IKICBsZXQgciA9IG51bGw7CiAgaWYgKG4gPT09IDApIHsKICAgIHIgPSBubShlYXJyKTsKICB9IGVsc2UgewogICAgciA9IG1hcChyYW5nZSQxKG4pLCBpID0+IHsKICAgICAgbGV0IGVhcnJ0ID0gbWFwKGVhcnIsIGkpOwogICAgICByZXR1cm4gbm0oZWFycnQpOwogICAgfSk7CiAgfQogIHJldHVybiByOwp9CgovKioNCiAqIOmHneWwjeS4gOe2reaIluS6jOe2remZo+WIl+ato+imj+WMlg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L25vcm1hbGl6ZUFycmF5LnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gYXJyIOi8uOWFpeizh+aWmemZo+WIl++8jOeCult4MSx4MiwuLi5d5LmL5LiA57at6Zmj5YiX77yM5oiWW1t4MSx5MV0sW3gyLHkyXSwuLi5d5LmL5LqM57at6Zmj5YiXDQogKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSDlm57lgrPmraPopo/ljJbmlbjmk5rkuYvnianku7bmiJbpmaPliJcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IGFycg0KICogbGV0IHINCiAqDQogKiBhcnIgPSBbDQogKiAgICAgWzI0MywgMjA2LCA5NV0sDQogKiAgICAgWzIzMywgMjI1LCAxNDZdLA0KICogICAgIFsyMSwgMzI1LCAyMl0sDQogKiAgICAgWzk1MywgMjgsIDIyM10sDQogKiAgICAgWzEwOTIsIDI5MCwgMzldLA0KICogICAgIFs3NDQsIDIwMCwgMTkxXSwNCiAqICAgICBbMTc0LCAzLCAyMl0sDQogKiAgICAgWzUzNywgMzY4LCAyNDldLA0KICogICAgIFsxMTUxLCAzNzEsIDg2XSwNCiAqICAgICBbODE0LCAyNTIsIDEyNV0NCiAqIF0NCiAqIHIgPSBub3JtYWxpemVBcnJheShhcnIpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjE5NjQ2MDE3Njk5MTE1MDQ1LA0KICogLy8gICAgICAgMC4xODc2MTA2MTk0NjkwMjY1NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjgyNDc3ODc2MTA2MTk0NjksDQogKiAvLyAgICAgICAwLjk0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuNjM5ODIzMDA4ODQ5NTU3NiwNCiAqIC8vICAgICAgIDAuMTM1Mzk4MjMwMDg4NDk1NTgsDQogKiAvLyAgICAgICAwLjQ1NjYzNzE2ODE0MTU5Mjk0LA0KICogLy8gICAgICAgMSwNCiAqIC8vICAgICAgIDAuNzAxNzY5OTExNTA0NDI0OA0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAyMSwNCiAqIC8vICAgICBtYXg6IDExNTEsDQogKiAvLyAgICAgcmFuZ2U6IDExMzAsDQogKiAvLyAgICAgYXZnOiA1OTYuMg0KICogLy8gICB9LA0KICogLy8gICB7DQogKiAvLyAgICAgYXJyOiBbDQogKiAvLyAgICAgICAwLjU1MTYzMDQzNDc4MjYwODYsDQogKiAvLyAgICAgICAwLjYwMzI2MDg2OTU2NTIxNzQsDQogKiAvLyAgICAgICAwLjg3NSwNCiAqIC8vICAgICAgIDAuMDY3OTM0NzgyNjA4Njk1NjUsDQogKiAvLyAgICAgICAwLjc3OTg5MTMwNDM0NzgyNiwNCiAqIC8vICAgICAgIDAuNTM1MzI2MDg2OTU2NTIxNywNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjk5MTg0NzgyNjA4Njk1NjUsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC42NzY2MzA0MzQ3ODI2MDg2DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDMsDQogKiAvLyAgICAgbWF4OiAzNzEsDQogKiAvLyAgICAgcmFuZ2U6IDM2OCwNCiAqIC8vICAgICBhdmc6IDIyNi44DQogKiAvLyAgIH0sDQogKiAvLyAgIHsNCiAqIC8vICAgICBhcnI6IFsNCiAqIC8vICAgICAgIDAuMzIxNTg1OTAzMDgzNzAwNDQsDQogKiAvLyAgICAgICAwLjU0NjI1NTUwNjYwNzkyOTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44ODU0NjI1NTUwNjYwNzkzLA0KICogLy8gICAgICAgMC4wNzQ4ODk4Njc4NDE0MDk2OSwNCiAqIC8vICAgICAgIDAuNzQ0NDkzMzkyMDcwNDg0NiwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC4yODE5MzgzMjU5OTExODk0NSwNCiAqIC8vICAgICAgIDAuNDUzNzQ0NDkzMzkyMDcwNDYNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMjIsDQogKiAvLyAgICAgbWF4OiAyNDksDQogKiAvLyAgICAgcmFuZ2U6IDIyNywNCiAqIC8vICAgICBhdmc6IDExOS44DQogKiAvLyAgIH0NCiAqIC8vIF0NCiAqDQogKiBhcnIgPSBbDQogKiAgICAgMjQzLCAyMzMsIDIxLA0KICogICAgIDk1MywgMTA5MiwgNzQ0LA0KICogICAgIDE3NCwgNTM3LCAxMTUxLA0KICogICAgIDgxNA0KICogXQ0KICogciA9IG5vcm1hbGl6ZUFycmF5KGFycikNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7DQogKiAvLyAgIGFycjogWw0KICogLy8gICAgIDAuMTk2NDYwMTc2OTkxMTUwNDUsDQogKiAvLyAgICAgMC4xODc2MTA2MTk0NjkwMjY1NSwNCiAqIC8vICAgICAwLA0KICogLy8gICAgIDAuODI0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAwLjk0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAwLjYzOTgyMzAwODg0OTU1NzYsDQogKiAvLyAgICAgMC4xMzUzOTgyMzAwODg0OTU1OCwNCiAqIC8vICAgICAwLjQ1NjYzNzE2ODE0MTU5Mjk0LA0KICogLy8gICAgIDEsDQogKiAvLyAgICAgMC43MDE3Njk5MTE1MDQ0MjQ4DQogKiAvLyAgIF0sDQogKiAvLyAgIG1pbjogMjEsDQogKiAvLyAgIG1heDogMTE1MSwNCiAqIC8vICAgcmFuZ2U6IDExMzAsDQogKiAvLyAgIGF2ZzogNTk2LjINCiAqIC8vIH0NCiAqDQogKiBhcnIgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHIgPSBub3JtYWxpemVBcnJheShhcnIsIFsneCcsICd5JywgJ3onXSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBbDQogKiAvLyAgIHsNCiAqIC8vICAgICBhcnI6IFsNCiAqIC8vICAgICAgIDAuMTk2NDYwMTc2OTkxMTUwNDUsDQogKiAvLyAgICAgICAwLjE4NzYxMDYxOTQ2OTAyNjU1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODI0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuOTQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgICAgMC42Mzk4MjMwMDg4NDk1NTc2LA0KICogLy8gICAgICAgMC4xMzUzOTgyMzAwODg0OTU1OCwNCiAqIC8vICAgICAgIDAuNDU2NjM3MTY4MTQxNTkyOTQsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC43MDE3Njk5MTE1MDQ0MjQ4DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBtaW46IDIxLA0KICogLy8gICAgIG1heDogMTE1MSwNCiAqIC8vICAgICByYW5nZTogMTEzMCwNCiAqIC8vICAgICBhdmc6IDU5Ni4yDQogKiAvLyAgIH0sDQogKiAvLyAgIHsNCiAqIC8vICAgICBhcnI6IFsNCiAqIC8vICAgICAgIDAuNTUxNjMwNDM0NzgyNjA4NiwNCiAqIC8vICAgICAgIDAuNjAzMjYwODY5NTY1MjE3NCwNCiAqIC8vICAgICAgIDAuODc1LA0KICogLy8gICAgICAgMC4wNjc5MzQ3ODI2MDg2OTU2NSwNCiAqIC8vICAgICAgIDAuNzc5ODkxMzA0MzQ3ODI2LA0KICogLy8gICAgICAgMC41MzUzMjYwODY5NTY1MjE3LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuOTkxODQ3ODI2MDg2OTU2NSwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjY3NjYzMDQzNDc4MjYwODYNCiAqIC8vICAgICBdLA0KICogLy8gICAgIG1pbjogMywNCiAqIC8vICAgICBtYXg6IDM3MSwNCiAqIC8vICAgICByYW5nZTogMzY4LA0KICogLy8gICAgIGF2ZzogMjI2LjgNCiAqIC8vICAgfSwNCiAqIC8vICAgew0KICogLy8gICAgIGFycjogWw0KICogLy8gICAgICAgMC4zMjE1ODU5MDMwODM3MDA0NCwNCiAqIC8vICAgICAgIDAuNTQ2MjU1NTA2NjA3OTI5NSwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAwLjg4NTQ2MjU1NTA2NjA3OTMsDQogKiAvLyAgICAgICAwLjA3NDg4OTg2Nzg0MTQwOTY5LA0KICogLy8gICAgICAgMC43NDQ0OTMzOTIwNzA0ODQ2LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDEsDQogKiAvLyAgICAgICAwLjI4MTkzODMyNTk5MTE4OTQ1LA0KICogLy8gICAgICAgMC40NTM3NDQ0OTMzOTIwNzA0Ng0KICogLy8gICAgIF0sDQogKiAvLyAgICAgbWluOiAyMiwNCiAqIC8vICAgICBtYXg6IDI0OSwNCiAqIC8vICAgICByYW5nZTogMjI3LA0KICogLy8gICAgIGF2ZzogMTE5LjgNCiAqIC8vICAgfQ0KICogLy8gXQ0KICoNCiAqLwpmdW5jdGlvbiBub3JtYWxpemVBcnJheShhcnIsIGtleXMgPSBbXSkgewogIC8vY2hlY2sgcHNTcmMKICBpZiAoIWlzZWFycihhcnIpKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdhcnIgaXMgbm90IGFuIGVmZmVjdGl2ZSBhcnJheScKICAgIH07CiAgfQoKICAvL2tleXMKICBpZiAoc2l6ZShrZXlzKSA+IDApIHsKICAgIC8vY2hlY2sKICAgIGxldCB2MCA9IGdldChhcnIsIDApOwogICAgaWYgKCFpc2VvYmoodjApKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgZXJyOiAnYXJyIGlzIG5vdCBhbiBlZmZlY3RpdmUgYXJyYXkgb2Ygb2JqZWN0cycKICAgICAgfTsKICAgIH0KCiAgICAvL2FycnQsIOaPkOWPluaMh+WummtleXMKICAgIGxldCBhcnJ0ID0gW107CiAgICBmb3JFYWNoKGFyciwgZHQgPT4gewogICAgICBsZXQgY3MgPSBbXTsKICAgICAgZm9yRWFjaChrZXlzLCBrID0+IHsKICAgICAgICBjcy5wdXNoKGdldChkdCwgaywgJycpKTsKICAgICAgfSk7CiAgICAgIGFycnQucHVzaChjcyk7CiAgICB9KTsKCiAgICAvL3NhdmUKICAgIGFyciA9IGFycnQ7CiAgfQoKICAvL25vcm1hbGl6ZUFycmF5Q29yZQogIGxldCByID0gbm9ybWFsaXplQXJyYXlDb3JlKGFycik7CiAgcmV0dXJuIHI7Cn0KCi8qKg0KICog5YWn5o+S55So5q2j6KaP5YyW5pW45pOaDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvaW50ZXJwMk5vcm1hbGl6ZS50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzIOi8uOWFpeS6jOe2reW6p+aomeWKoOingOa4rOaVuOaTmum7numZo+WIl++8jOeCult7eDp4MSx5OnkxLHo6ejF9LHt4OngyLHk6eTIsejp6Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIlw0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlYPSd4J10g6Ly45YWl6bue54mp5Lu25LmLeOashOS9jeWtl+S4su+8jOeCuuW6p+aome+8jOmgkOiorSd4Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neSddIOi8uOWFpem7nueJqeS7tuS5i3nmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neScNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVo9J3onXSDovLjlhaXpu57nianku7bkuYt65qyE5L2N5a2X5Liy77yM54K66KeA5ris5YC877yM6aCQ6KitJ3onDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlJbmQ9J2luZCddIOi8uOWFpem7nueJqeS7tuS5i2luZOashOS9jeWtl+S4su+8jOato+imj+WMluW+jOWPr+WPjeafpeWOn+Wni+aVuOaTmuS5i+aMh+aome+8jOmgkOiorSdpbmQnDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zY2FsZT0xXSDovLjlhaXmraPopo/ljJbnr4TlnI3mlbjlgLzvvIzlm6DomZXnkIblpJrpgorlvaLmmYLmnInmlbjlgLzlrrnoqLHoqqTlt67vvIzmlYXpoIjpgJrpgY7nuK7mlL7lgLzln5/kvobmuJvlsJHllY/poYzvvIzpoJDoqK0x5piv5q2j6KaP5YyWMOiHszHkuYvplpPvvIzkvb/nlKhzY2FsZVhZ5YmH5piv5q2j6KaP5YyW54K6MOiHs3NjYWxlWFnkuYvplpPvvIzpoJDoqK0xDQogKiBAcmV0dXJucyB7T2JqZWN0fSDlm57lgrPmraPopo/ljJbmlbjmk5rnianku7YNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBzDQogKiBsZXQgcg0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiByID0gaW50ZXJwMk5vcm1hbGl6ZShwcykNCiAqIGRlbGV0ZSByLm52DQogKiBkZWxldGUgci5pbnYNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4geyJwcyI6W3sieCI6MC4xOTY0NjAxNzY5OTExNTA0NSwieSI6MC41MTY4MTQxNTkyOTIwMzU0LCJ6IjowLjMyMTU4NTkwMzA4MzcwMDQ0LCJpbmQiOm51bGx9LHsieCI6MC4xODc2MTA2MTk0NjkwMjY1NSwieSI6MC41MzM2MjgzMTg1ODQwNzA4LCJ6IjowLjU0NjI1NTUwNjYwNzkyOTUsImluZCI6bnVsbH0seyJ4IjowLCJ5IjowLjYyMjEyMzg5MzgwNTMwOTcsInoiOjAsImluZCI6bnVsbH0seyJ4IjowLjgyNDc3ODc2MTA2MTk0NjksInkiOjAuMzU5MjkyMDM1Mzk4MjMwMDcsInoiOjAuODg1NDYyNTU1MDY2MDc5MywiaW5kIjpudWxsfSx7IngiOjAuOTQ3Nzg3NjEwNjE5NDY5LCJ5IjowLjU5MTE1MDQ0MjQ3Nzg3NjEsInoiOjAuMDc0ODg5ODY3ODQxNDA5NjksImluZCI6bnVsbH0seyJ4IjowLjYzOTgyMzAwODg0OTU1NzYsInkiOjAuNTExNTA0NDI0Nzc4NzYxLCJ6IjowLjc0NDQ5MzM5MjA3MDQ4NDYsImluZCI6bnVsbH0seyJ4IjowLjEzNTM5ODIzMDA4ODQ5NTU4LCJ5IjowLjMzNzE2ODE0MTU5MjkyMDM2LCJ6IjowLCJpbmQiOm51bGx9LHsieCI6MC40NTY2MzcxNjgxNDE1OTI5NCwieSI6MC42NjAxNzY5OTExNTA0NDI1LCJ6IjoxLCJpbmQiOm51bGx9LHsieCI6MSwieSI6MC42NjI4MzE4NTg0MDcwNzk3LCJ6IjowLjI4MTkzODMyNTk5MTE4OTQ1LCJpbmQiOm51bGx9LHsieCI6MC43MDE3Njk5MTE1MDQ0MjQ4LCJ5IjowLjU1NzUyMjEyMzg5MzgwNTMsInoiOjAuNDUzNzQ0NDkzMzkyMDcwNDYsImluZCI6bnVsbH1dLCJwc01pbk1heCI6eyJ4bWluIjowLCJ4bWF4IjoxLCJ5bWluIjowLjMzNzE2ODE0MTU5MjkyMDM2LCJ5bWF4IjowLjY2MjgzMTg1ODQwNzA3OTcsInptaW4iOjAsInptYXgiOjF9LCJzdCI6eyJ4Ijp7Im1pbiI6MjEsIm1heCI6MTE1MSwicmFuZ2UiOjExMzB9LCJ5Ijp7Im1pbiI6LTM3OCwibWF4Ijo3NTIsInJhbmdlIjoxMTMwfSwieiI6eyJtaW4iOjIyLCJtYXgiOjI0OSwicmFuZ2UiOjIyN319fQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiByID0gaW50ZXJwMk5vcm1hbGl6ZShwcywgeyBzY2FsZTogMTAwIH0pDQogKiBkZWxldGUgci5udg0KICogZGVsZXRlIHIuaW52DQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IHsicHMiOlt7IngiOjE5LjY0NjAxNzY5OTExNTA0NSwieSI6NTEuNjgxNDE1OTI5MjAzNTQ2LCJ6IjozMi4xNTg1OTAzMDgzNzAwNDQsImluZCI6bnVsbH0seyJ4IjoxOC43NjEwNjE5NDY5MDI2NTQsInkiOjUzLjM2MjgzMTg1ODQwNzA4LCJ6Ijo1NC42MjU1NTA2NjA3OTI5NSwiaW5kIjpudWxsfSx7IngiOjAsInkiOjYyLjIxMjM4OTM4MDUzMDk3LCJ6IjowLCJpbmQiOm51bGx9LHsieCI6ODIuNDc3ODc2MTA2MTk0NjksInkiOjM1LjkyOTIwMzUzOTgyMzAxLCJ6Ijo4OC41NDYyNTU1MDY2MDc5MywiaW5kIjpudWxsfSx7IngiOjk0Ljc3ODc2MTA2MTk0NjkxLCJ5Ijo1OS4xMTUwNDQyNDc3ODc2MSwieiI6Ny40ODg5ODY3ODQxNDA5NjksImluZCI6bnVsbH0seyJ4Ijo2My45ODIzMDA4ODQ5NTU3NTUsInkiOjUxLjE1MDQ0MjQ3Nzg3NjEsInoiOjc0LjQ0OTMzOTIwNzA0ODQ1LCJpbmQiOm51bGx9LHsieCI6MTMuNTM5ODIzMDA4ODQ5NTU4LCJ5IjozMy43MTY4MTQxNTkyOTIwMzUsInoiOjAsImluZCI6bnVsbH0seyJ4Ijo0NS42NjM3MTY4MTQxNTkyOTQsInkiOjY2LjAxNzY5OTExNTA0NDI1LCJ6IjoxMDAsImluZCI6bnVsbH0seyJ4IjoxMDAsInkiOjY2LjI4MzE4NTg0MDcwNzk3LCJ6IjoyOC4xOTM4MzI1OTkxMTg5NDUsImluZCI6bnVsbH0seyJ4Ijo3MC4xNzY5OTExNTA0NDI0OCwieSI6NTUuNzUyMjEyMzg5MzgwNTMsInoiOjQ1LjM3NDQ0OTMzOTIwNzA1LCJpbmQiOm51bGx9XSwicHNNaW5NYXgiOnsieG1pbiI6MCwieG1heCI6MTAwLCJ5bWluIjozMy43MTY4MTQxNTkyOTIwMzUsInltYXgiOjY2LjI4MzE4NTg0MDcwNzk3LCJ6bWluIjowLCJ6bWF4IjoxMDB9LCJzdCI6eyJ4Ijp7Im1pbiI6MjEsIm1heCI6MTE1MSwicmFuZ2UiOjExMzB9LCJ5Ijp7Im1pbiI6LTM3OCwibWF4Ijo3NTIsInJhbmdlIjoxMTMwfSwieiI6eyJtaW4iOjIyLCJtYXgiOjI0OSwicmFuZ2UiOjIyN319fQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1LCBpbmQ6IDEwMSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYsIGluZDogMTAyIH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIsIGluZDogMTAzIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzLCBpbmQ6IDEwNCB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzksIGluZDogMTA1IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSwgaW5kOiAxMDYgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyLCBpbmQ6IDEwNyB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDksIGluZDogMTA4IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiwgaW5kOiAxMDkgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1LCBpbmQ6IDExMCB9XQ0KICogciA9IGludGVycDJOb3JtYWxpemUocHMsIHsga2V5SW5kOiAnaW5kJyB9KQ0KICogZGVsZXRlIHIubnYNCiAqIGRlbGV0ZSByLmludg0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiB7InBzIjpbeyJ4IjowLjE5NjQ2MDE3Njk5MTE1MDQ1LCJ5IjowLjUxNjgxNDE1OTI5MjAzNTQsInoiOjAuMzIxNTg1OTAzMDgzNzAwNDQsImluZCI6MTAxfSx7IngiOjAuMTg3NjEwNjE5NDY5MDI2NTUsInkiOjAuNTMzNjI4MzE4NTg0MDcwOCwieiI6MC41NDYyNTU1MDY2MDc5Mjk1LCJpbmQiOjEwMn0seyJ4IjowLCJ5IjowLjYyMjEyMzg5MzgwNTMwOTcsInoiOjAsImluZCI6MTAzfSx7IngiOjAuODI0Nzc4NzYxMDYxOTQ2OSwieSI6MC4zNTkyOTIwMzUzOTgyMzAwNywieiI6MC44ODU0NjI1NTUwNjYwNzkzLCJpbmQiOjEwNH0seyJ4IjowLjk0Nzc4NzYxMDYxOTQ2OSwieSI6MC41OTExNTA0NDI0Nzc4NzYxLCJ6IjowLjA3NDg4OTg2Nzg0MTQwOTY5LCJpbmQiOjEwNX0seyJ4IjowLjYzOTgyMzAwODg0OTU1NzYsInkiOjAuNTExNTA0NDI0Nzc4NzYxLCJ6IjowLjc0NDQ5MzM5MjA3MDQ4NDYsImluZCI6MTA2fSx7IngiOjAuMTM1Mzk4MjMwMDg4NDk1NTgsInkiOjAuMzM3MTY4MTQxNTkyOTIwMzYsInoiOjAsImluZCI6MTA3fSx7IngiOjAuNDU2NjM3MTY4MTQxNTkyOTQsInkiOjAuNjYwMTc2OTkxMTUwNDQyNSwieiI6MSwiaW5kIjoxMDh9LHsieCI6MSwieSI6MC42NjI4MzE4NTg0MDcwNzk3LCJ6IjowLjI4MTkzODMyNTk5MTE4OTQ1LCJpbmQiOjEwOX0seyJ4IjowLjcwMTc2OTkxMTUwNDQyNDgsInkiOjAuNTU3NTIyMTIzODkzODA1MywieiI6MC40NTM3NDQ0OTMzOTIwNzA0NiwiaW5kIjoxMTB9XSwicHNNaW5NYXgiOnsieG1pbiI6MCwieG1heCI6MSwieW1pbiI6MC4zMzcxNjgxNDE1OTI5MjAzNiwieW1heCI6MC42NjI4MzE4NTg0MDcwNzk3LCJ6bWluIjowLCJ6bWF4IjoxfSwic3QiOnsieCI6eyJtaW4iOjIxLCJtYXgiOjExNTEsInJhbmdlIjoxMTMwfSwieSI6eyJtaW4iOi0zNzgsIm1heCI6NzUyLCJyYW5nZSI6MTEzMH0sInoiOnsibWluIjoyMiwibWF4IjoyNDksInJhbmdlIjoyMjd9fX0NCiAqDQogKi8KZnVuY3Rpb24gaW50ZXJwMk5vcm1hbGl6ZShwcywgb3B0ID0ge30pIHsKICAvL2tleVgKICBsZXQga2V5WCA9IGdldChvcHQsICdrZXlYJyk7CiAgaWYgKCFpc2VzdHIoa2V5WCkpIHsKICAgIGtleVggPSAneCc7CiAgfQoKICAvL2tleVkKICBsZXQga2V5WSA9IGdldChvcHQsICdrZXlZJyk7CiAgaWYgKCFpc2VzdHIoa2V5WSkpIHsKICAgIGtleVkgPSAneSc7CiAgfQoKICAvL2tleVoKICBsZXQga2V5WiA9IGdldChvcHQsICdrZXlaJywgJycpOwogIGlmICghaXNlc3RyKGtleVopKSB7CiAgICBrZXlaID0gJ3onOwogIH0KCiAgLy9rZXlJbmQKICBsZXQga2V5SW5kID0gZ2V0KG9wdCwgJ2tleUluZCcsICcnKTsKICBpZiAoIWlzZXN0cihrZXlJbmQpKSB7CiAgICBrZXlJbmQgPSAnaW5kJzsKICB9CgogIC8vc2NhbGUKICBsZXQgc2NhbGUgPSBnZXQob3B0LCAnc2NhbGUnKTsKICBpZiAoIWlzbnVtKHNjYWxlKSkgewogICAgc2NhbGUgPSAxOwogIH0KICBzY2FsZSA9IGNkYmwoc2NhbGUpOwogIGlmIChzY2FsZSA8PSAwKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYHNjYWxlIG5lZWQgPj0gMGApOwogIH0KICAvLyBjb25zb2xlLmxvZygnc2NhbGUnLCBzY2FsZSkKCiAgLy9ueCwgbnksIG56CiAgbGV0IG54ID0gbm9ybWFsaXplQXJyYXkobWFwKHBzLCBrZXlYKSk7CiAgbGV0IG55ID0gbm9ybWFsaXplQXJyYXkobWFwKHBzLCBrZXlZKSk7CiAgbGV0IG56ID0gbm9ybWFsaXplQXJyYXkobWFwKHBzLCBrZXlaKSk7CiAgLy8gY29uc29sZS5sb2coJ254JywgbngpCiAgLy8gY29uc29sZS5sb2coJ255JywgbnkpCiAgLy8gY29uc29sZS5sb2coJ256JywgbnopCgogIC8vcmFuZ2VYWQogIGxldCByYW5nZVhZID0gTWF0aC5tYXgobngucmFuZ2UsIG55LnJhbmdlKTsKCiAgLy9yYW5nZVhZSGFsZgogIGxldCByYW5nZVhZSGFsZiA9IHJhbmdlWFkgLyAyOwoKICAvL3N0LCB4LHnkvb/nlKjlkIzntrLmoLzlsLrlr7jnuK7mlL4KICBsZXQgc3QgPSB7CiAgICB4OiB7CiAgICAgIG1pbjogbngubWlkIC0gcmFuZ2VYWUhhbGYsCiAgICAgIG1heDogbngubWlkICsgcmFuZ2VYWUhhbGYsCiAgICAgIHJhbmdlOiByYW5nZVhZCiAgICB9LAogICAgeTogewogICAgICBtaW46IG55Lm1pZCAtIHJhbmdlWFlIYWxmLAogICAgICBtYXg6IG55Lm1pZCArIHJhbmdlWFlIYWxmLAogICAgICByYW5nZTogcmFuZ2VYWQogICAgfSwKICAgIHo6IHsKICAgICAgbWluOiBuei5taW4sCiAgICAgIG1heDogbnoubWF4LAogICAgICByYW5nZTogbnoucmFuZ2UKICAgIH0KICB9OwogIC8vIGNvbnNvbGUubG9nKCdzdCcsIHN0KQoKICAvL252CiAgbGV0IG52ID0gKHYsIGRpcikgPT4gewogICAgaWYgKCFpc051bWJlcih2KSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGlmIChzdFtkaXJdLnJhbmdlIDw9IDApIHsKICAgICAgcmV0dXJuIHY7CiAgICB9CiAgICByZXR1cm4gKHYgLSBzdFtkaXJdLm1pbikgLyBzdFtkaXJdLnJhbmdlICogc2NhbGU7CiAgfTsKCiAgLy9pbnYKICBsZXQgaW52ID0gKGl2LCBkaXIpID0+IHsKICAgIGlmICghaXNOdW1iZXIoaXYpKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgaWYgKHNjYWxlIDw9IDApIHsKICAgICAgcmV0dXJuIGl2OwogICAgfQogICAgcmV0dXJuIGl2IC8gc2NhbGUgKiBzdFtkaXJdLnJhbmdlICsgc3RbZGlyXS5taW47CiAgfTsKCiAgLy9ub3JtYWxpemUgcHMKICBwcyA9IG1hcChwcywgdiA9PiB7CiAgICBsZXQgeCA9IG52KHZba2V5WF0sICd4Jyk7CiAgICBsZXQgeSA9IG52KHZba2V5WV0sICd5Jyk7CiAgICBsZXQgeiA9IG52KHZba2V5Wl0sICd6Jyk7CiAgICBsZXQgaW5kID0gZ2V0KHYsIGtleUluZCwgbnVsbCk7CiAgICByZXR1cm4gewogICAgICBba2V5WF06IHgsCiAgICAgIFtrZXlZXTogeSwKICAgICAgW2tleVpdOiB6LAogICAgICBba2V5SW5kXTogaW5kCiAgICB9OwogIH0pOwogIC8vIGNvbnNvbGUubG9nKCdub3JtYWxpemUgcHMnLCBwcykKCiAgLy9wc01pbk1heAogIGxldCBwc3ggPSBtYXAocHMsIGtleVgpOwogIGxldCBwc3hNaW4gPSBtaW4ocHN4KTsKICBsZXQgcHN4TWF4ID0gbWF4KHBzeCk7CiAgbGV0IHBzeSA9IG1hcChwcywga2V5WSk7CiAgbGV0IHBzeU1pbiA9IG1pbihwc3kpOwogIGxldCBwc3lNYXggPSBtYXgocHN5KTsKICBsZXQgcHN6ID0gbWFwKHBzLCBrZXlaKTsKICBsZXQgcHN6TWluID0gbWluKHBzeik7CiAgbGV0IHBzek1heCA9IG1heChwc3opOwogIGxldCBwc01pbk1heCA9IHsKICAgIHhtaW46IHBzeE1pbiwKICAgIHhtYXg6IHBzeE1heCwKICAgIHltaW46IHBzeU1pbiwKICAgIHltYXg6IHBzeU1heCwKICAgIHptaW46IHBzek1pbiwKICAgIHptYXg6IHBzek1heAogIH07CiAgcmV0dXJuIHsKICAgIHBzLAogICAgcHNNaW5NYXgsCiAgICBzdCwKICAgIG52LAogICAgaW52CiAgfTsKfQoKLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovCnZhciBzcHJlYWRhYmxlU3ltYm9sID0gU3ltYm9sJDEgPyBTeW1ib2wkMS5pc0NvbmNhdFNwcmVhZGFibGUgOiB1bmRlZmluZWQ7CgovKioKICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBmbGF0dGVuYWJsZSBgYXJndW1lbnRzYCBvYmplY3Qgb3IgYXJyYXkuCiAqCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLgogKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBmbGF0dGVuYWJsZSwgZWxzZSBgZmFsc2VgLgogKi8KZnVuY3Rpb24gaXNGbGF0dGVuYWJsZSh2YWx1ZSkgewogIHJldHVybiBpc0FycmF5JDEodmFsdWUpIHx8IGlzQXJndW1lbnRzJDEodmFsdWUpIHx8ICEhKHNwcmVhZGFibGVTeW1ib2wgJiYgdmFsdWUgJiYgdmFsdWVbc3ByZWFkYWJsZVN5bWJvbF0pOwp9CgovKioKICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmxhdHRlbmAgd2l0aCBzdXBwb3J0IGZvciByZXN0cmljdGluZyBmbGF0dGVuaW5nLgogKgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi4KICogQHBhcmFtIHtudW1iZXJ9IGRlcHRoIFRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aC4KICogQHBhcmFtIHtib29sZWFufSBbcHJlZGljYXRlPWlzRmxhdHRlbmFibGVdIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uCiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzU3RyaWN0XSBSZXN0cmljdCB0byB2YWx1ZXMgdGhhdCBwYXNzIGBwcmVkaWNhdGVgIGNoZWNrcy4KICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLgogKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuCiAqLwpmdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgZGVwdGgsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCkgewogIHZhciBpbmRleCA9IC0xLAogICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOwogIHByZWRpY2F0ZSB8fCAocHJlZGljYXRlID0gaXNGbGF0dGVuYWJsZSk7CiAgcmVzdWx0IHx8IChyZXN1bHQgPSBbXSk7CiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHsKICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTsKICAgIGlmIChkZXB0aCA+IDAgJiYgcHJlZGljYXRlKHZhbHVlKSkgewogICAgICBpZiAoZGVwdGggPiAxKSB7CiAgICAgICAgLy8gUmVjdXJzaXZlbHkgZmxhdHRlbiBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS4KICAgICAgICBiYXNlRmxhdHRlbih2YWx1ZSwgZGVwdGggLSAxLCBwcmVkaWNhdGUsIGlzU3RyaWN0LCByZXN1bHQpOwogICAgICB9IGVsc2UgewogICAgICAgIGFycmF5UHVzaChyZXN1bHQsIHZhbHVlKTsKICAgICAgfQogICAgfSBlbHNlIGlmICghaXNTdHJpY3QpIHsKICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gdmFsdWU7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBGbGF0dGVucyBgYXJyYXlgIGEgc2luZ2xlIGxldmVsIGRlZXAuCiAqCiAqIEBzdGF0aWMKICogQG1lbWJlck9mIF8KICogQHNpbmNlIDAuMS4wCiAqIEBjYXRlZ29yeSBBcnJheQogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi4KICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LgogKiBAZXhhbXBsZQogKgogKiBfLmZsYXR0ZW4oWzEsIFsyLCBbMywgWzRdXSwgNV1dKTsKICogLy8gPT4gWzEsIDIsIFszLCBbNF1dLCA1XQogKi8KZnVuY3Rpb24gZmxhdHRlbihhcnJheSkgewogIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDsKICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIDEpIDogW107Cn0KCi8qKg0KICog6KiI566X5pW45pOa5YWn6bue54mp5Lu25rex5bqmDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvZ2V0UG9pbnREZXB0aC50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7T2JqZWN0fSBwIOi8uOWFpem7nuW6p+aomeeJqeS7tg0KICogQHJldHVybnMge0ludGVnZXJ9IOWbnuWCs+a3seW6puaVtOaVuA0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcA0KICogbGV0IHINCiAqDQogKiB0cnkgew0KICogICAgIHAgPSBbW1tbWzEsIDIuNV0sIFsxLjEsIDIuM11dXV1dDQogKiAgICAgciA9IGdldFBvaW50RGVwdGgocCkNCiAqIH0NCiAqIGNhdGNoIChlcnIpIHsNCiAqICAgICByID0gZXJyLm1lc3NhZ2UNCiAqIH0NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBpbnZhbGlkIHBbW1tbW1sxLDIuNV0sWzEuMSwyLjNdXV1dXV0NCiAqDQogKiBwID0gW1tbWzEsIDIuNV0sIFsxLjEsIDIuM11dXV0NCiAqIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMw0KICoNCiAqIHAgPSBbW1tbMSwgMi41XV1dXQ0KICogciA9IGdldFBvaW50RGVwdGgocCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAzDQogKg0KICogcCA9IFtbWzEsIDIuNV1dXQ0KICogciA9IGdldFBvaW50RGVwdGgocCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAyDQogKg0KICogcCA9IFtbMSwgMi41XV0NCiAqIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMQ0KICoNCiAqIHRyeSB7DQogKiAgICAgcCA9IFt7IHg6IDEsIHk6IDIuNSB9XQ0KICogICAgIHIgPSBnZXRQb2ludERlcHRoKHApDQogKiB9DQogKiBjYXRjaCAoZXJyKSB7DQogKiAgICAgciA9IGVyci5tZXNzYWdlDQogKiB9DQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gaW52YWxpZCBwW1t7IngiOjEsInkiOjIuNX1dXQ0KICoNCiAqLwpmdW5jdGlvbiBnZXRQb2ludERlcHRoKHApIHsKICBsZXQgdjEgPSBnZXQocCwgJzAnLCBudWxsKTsKICBsZXQgaXAxID0gc2l6ZSh2MSk7CiAgbGV0IHQxID0gaXNOdW1iZXIodjEpOwogIGxldCB2MiA9IGdldChwLCAnMC4wJywgbnVsbCk7CiAgbGV0IGlwMiA9IHNpemUodjIpOwogIGxldCB0MiA9IGlzTnVtYmVyKHYyKTsKICBsZXQgdjMgPSBnZXQocCwgJzAuMC4wJywgbnVsbCk7CiAgbGV0IGlwMyA9IHNpemUodjMpOwogIGxldCB0MyA9IGlzTnVtYmVyKHYzKTsKICBsZXQgdjQgPSBnZXQocCwgJzAuMC4wLjAnLCBudWxsKTsKICAvLyBsZXQgaXA0ID0gc2l6ZSh2NCkKICBsZXQgdDQgPSBpc051bWJlcih2NCk7CiAgaWYgKGlwMyA9PT0gMiAmJiB0NCkgewogICAgcmV0dXJuIDM7CiAgfQogIGlmIChpcDIgPT09IDIgJiYgdDMpIHsKICAgIHJldHVybiAyOwogIH0KICBpZiAoaXAxID09PSAyICYmIHQyKSB7CiAgICByZXR1cm4gMTsKICB9CiAgaWYgKGlwMSA9PT0gMCAmJiB0MSkgewogICAgcmV0dXJuIDA7CiAgfQogIC8vIGNvbnNvbGUubG9nKCd2MScsIHYxLCAnaXAxJywgaXAxLCAndDInLCB0MikKICAvLyBjb25zb2xlLmxvZygndjInLCB2MiwgJ2lwMicsIGlwMiwgJ3QzJywgdDMpCiAgLy8gY29uc29sZS5sb2coJ3YzJywgdjMsICdpcDMnLCBpcDMsICd0NCcsIHQ0KQogIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBwWyR7SlNPTi5zdHJpbmdpZnkocCl9XWApOwp9CgovKioNCiAqIOi9ieaPm1JpbmdTdHJpbmfjgIFwb2x5Z29u44CBTXVsdGlQb2x5Z29u5oiQ54K6UG9seWdvbg0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L3RvUG9seWdvbi50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHYg6Ly45YWl6LOH5paZ6Zmj5YiXDQogKiBAcmV0dXJucyB7QXJyYXl9IOWbnuWCs+izh+aWmemZo+WIlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcnMNCiAqIGxldCByDQogKg0KICogcnMgPSBbIC8vcmluZ1N0cmluZw0KICogICAgIFswLCAwXSwNCiAqICAgICBbMTAwLCAwXSwNCiAqICAgICBbMTAwLCAxXSwNCiAqICAgICBbMCwgMV0sDQogKiAgICAgWzAsIDBdLCAvL+mWieWQiA0KICogXQ0KICogciA9IHRvUG9seWdvbihycykNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMCwwXSxbMTAwLDBdLFsxMDAsMV0sWzAsMV0sWzAsMF1dXQ0KICoNCiAqIHJzID0gWyAvL3JpbmdTdHJpbmcNCiAqICAgICBbMCwgMF0sDQogKiAgICAgWzEwMCwgMF0sDQogKiAgICAgWzEwMCwgMV0sDQogKiAgICAgWzAsIDFdLA0KICogXQ0KICogciA9IHRvUG9seWdvbihycykNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMCwwXSxbMTAwLDBdLFsxMDAsMV0sWzAsMV1dXQ0KICoNCiAqIHJzID0gWyAvL3BvbHlnb24NCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IHRvUG9seWdvbihycykNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMCwwXSxbMTAwLDBdLFsxMDAsMV0sWzAsMV1dXQ0KICoNCiAqIHJzID0gWyAvL3BvbHlnb24NCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwLCAwXSwNCiAqICAgICAgICAgWzEwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSB0b1BvbHlnb24ocnMpDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEwLDBdLFsxMCwxXSxbMCwxXV1dDQogKg0KICogcnMgPSBbIC8vcG9seWdvbg0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdLA0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAsIDBdLA0KICogICAgICAgICBbMTAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IHRvUG9seWdvbihycykNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMCwwXSxbMTAwLDBdLFsxMDAsMV0sWzAsMV1dLFtbMCwwXSxbMTAsMF0sWzEwLDFdLFswLDFdXV0NCiAqDQogKiBycyA9IFsgLy9tdWx0aVBvbHlnb24NCiAqICAgICBbDQogKiAgICAgICAgIFsNCiAqICAgICAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgICAgICBbMCwgMV0sDQogKiAgICAgICAgIF0sDQogKiAgICAgICAgIFsNCiAqICAgICAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgICAgIFsxMCwgMF0sDQogKiAgICAgICAgICAgICBbMTAsIDFdLA0KICogICAgICAgICAgICAgWzAsIDFdLA0KICogICAgICAgICBdDQogKiAgICAgXQ0KICogXQ0KICogciA9IHRvUG9seWdvbihycykNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbMCwwXSxbMTAwLDBdLFsxMDAsMV0sWzAsMV1dLFtbMCwwXSxbMTAsMF0sWzEwLDFdLFswLDFdXV0NCiAqDQogKi8KZnVuY3Rpb24gdG9Qb2x5Z29uKHYpIHsKICBsZXQgZCA9IGdldFBvaW50RGVwdGgodik7CiAgaWYgKGQgPT09IDMpIHsKICAgIHJldHVybiBmbGF0dGVuKHYpOwogIH0gZWxzZSBpZiAoZCA9PT0gMikgewogICAgcmV0dXJuIHY7CiAgfSBlbHNlIGlmIChkID09PSAxKSB7CiAgICByZXR1cm4gW3ZdOwogIH0gZWxzZSBpZiAoZCA9PT0gMCkgewogICAgcmV0dXJuIFtdOwogIH0KICByZXR1cm4gdjsKfQoKLyoqDQogKiDoqIjnrpdSaW5nU3RyaW5n6Z2i56mNDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvZ2V0QXJlYVJpbmdTdHJpbmcudGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBycyDovLjlhaVSaW5nU3RyaW5n6LOH5paZ6Zmj5YiX77yM54K6W1t4MSx5MV0sW3gyLHkyXSwuLi5d5qeL5oiQ5LmL6Zmj5YiXDQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC51c2VBYnM9dHJ1ZV0g6Ly45YWl6Z2i56mN5piv5ZCm5Y+W57WV5bCN5YC877yM6aCQ6KitdHJ1ZQ0KICogQHJldHVybnMge051bWJlcn0g5Zue5YKz6Z2i56mN5pW45a2XDQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBycw0KICogbGV0IHINCiAqDQogKiBycyA9IFsNCiAqICAgICBbMCwgMF0sDQogKiAgICAgWzEwMCwgMF0sDQogKiAgICAgWzEwMCwgMV0sDQogKiAgICAgWzAsIDFdLA0KICogICAgIFswLCAwXSwgLy/plonlkIgNCiAqIF0NCiAqIHIgPSBnZXRBcmVhUmluZ1N0cmluZyhycykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMDANCiAqDQogKiBycyA9IFsNCiAqICAgICBbMCwgMF0sDQogKiAgICAgWzEwMCwgMF0sDQogKiAgICAgWzEwMCwgMV0sDQogKiAgICAgWzAsIDFdLA0KICogXQ0KICogciA9IGdldEFyZWFSaW5nU3RyaW5nKHJzKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDEwMA0KICoNCiAqIHJzID0gWw0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAwLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gZ2V0QXJlYVJpbmdTdHJpbmcocnMpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMA0KICoNCiAqLwpmdW5jdGlvbiBnZXRBcmVhUmluZ1N0cmluZyhycywgb3B0ID0ge30pIHsKICAvL3VzZUFicwogIGxldCB1c2VBYnMgPSBnZXQob3B0LCAndXNlQWJzJyk7CiAgaWYgKCFpc2JvbCh1c2VBYnMpKSB7CiAgICB1c2VBYnMgPSB0cnVlOwogIH0KCiAgLy9jaGVjawogIGlmICghaXNlYXJyKHJzKSkgewogICAgcmV0dXJuIDA7CiAgfQoKICAvL2VycwogIGxldCBlcnMgPSBbXTsKICBmb3JFYWNoKHJzLCB2ID0+IHsKICAgIGlmIChzaXplKHYpID09PSAyKSB7CiAgICAgIGlmIChpc251bSh2WzBdKSAmJiBpc251bSh2WzFdKSkgewogICAgICAgIGVycy5wdXNoKFtjZGJsKHZbMF0pLCBjZGJsKHZbMV0pXSk7CiAgICAgIH0KICAgIH0KICB9KTsKCiAgLy9jaGVjawogIGlmICghaXNlYXJyKGVycykpIHsKICAgIHJldHVybiAwOwogIH0KCiAgLy9hcmVhCiAgbGV0IGkgPSAtMTsKICBsZXQgbiA9IHNpemUoZXJzKTsKICBsZXQgYTsKICBsZXQgYiA9IGVyc1tuIC0gMV07CiAgbGV0IGFyZWEgPSAwOwogIHdoaWxlICgrK2kgPCBuKSB7CiAgICBhID0gYjsKICAgIGIgPSBlcnNbaV07CiAgICBhcmVhICs9IGFbMV0gKiBiWzBdIC0gYVswXSAqIGJbMV07CiAgfQogIGxldCByID0gYXJlYSAvIDI7CgogIC8vdXNlQWJzCiAgaWYgKHVzZUFicykgewogICAgciA9IE1hdGguYWJzKHIpOwogIH0KICByZXR1cm4gcjsKfQoKLy8gaW1wb3J0IGdldCBmcm9tICdsb2Rhc2gtZXMvZ2V0LmpzJwoKLyoqDQogKiDoqIjnrpdQb2x5Z29u6Z2i56mNDQogKiDlvpfopoHogIPmha7lpJrljYDln5/jgIHliZTpmaTljYDln5/kuYvntYTlkIg6IGh0dHA6Ly9lc3JpLmdpdGh1Yi5pby9nZW9tZXRyeS1hcGktamF2YS9kb2MvUG9seWdvbi5odG1sDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvZ2V0QXJlYVBvbHlnb24udGVzdC5tanMgR2l0aHVifQ0KICogQG1lbWJlck9mIHctZ2lzDQogKiBAcGFyYW0ge0FycmF5fSBwZyDovLjlhaVQb2x5Z29u6LOH5paZ6Zmj5YiX77yM54K6W1tbeDEseTFdLFt4Mix5Ml0sLi4uXV3mp4vmiJDkuYvpmaPliJcNCiAqIEByZXR1cm5zIHtOdW1iZXJ9IOWbnuWCs+mdouepjeaVuOWtlw0KICogQGV4YW1wbGUNCiAqDQogKiBsZXQgcGcNCiAqIGxldCByDQogKg0KICogcGcgPSBbDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqICAgICBbMCwgMF0sIC8v6ZaJ5ZCIDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gMTAwDQogKg0KICogcGcgPSBbDQogKiAgICAgWzAsIDBdLA0KICogICAgIFsxMDAsIDBdLA0KICogICAgIFsxMDAsIDFdLA0KICogICAgIFswLCAxXSwNCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiAxMDANCiAqDQogKiBwZyA9IFsNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDEwMA0KICoNCiAqIHBnID0gWw0KICogICAgIFsNCiAqICAgICAgICAgWzAsIDBdLA0KICogICAgICAgICBbMTAsIDBdLA0KICogICAgICAgICBbMTAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXQ0KICogXQ0KICogciA9IGdldEFyZWFQb2x5Z29uKHBnKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IDEwDQogKg0KICogcGcgPSBbDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDBdLA0KICogICAgICAgICBbMTAwLCAxXSwNCiAqICAgICAgICAgWzAsIDFdLA0KICogICAgIF0sDQogKiAgICAgWw0KICogICAgICAgICBbMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMF0sDQogKiAgICAgICAgIFsxMCwgMV0sDQogKiAgICAgICAgIFswLCAxXSwNCiAqICAgICBdDQogKiBdDQogKiByID0gZ2V0QXJlYVBvbHlnb24ocGcpDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gOTANCiAqDQogKiBwZyA9IFsNCiAqICAgICBbDQogKiAgICAgICAgIFswLCAwXSwNCiAqICAgICAgICAgWzEwMCwgMF0sDQogKiAgICAgICAgIFsxMDAsIDFdLA0KICogICAgICAgICBbMCwgMV0sDQogKiAgICAgXSwNCiAqICAgICBbIC8v56ysIDIgUmluZ1N0cmluZyDoiIfnrKwgMSBSaW5nU3RyaW5nIOS4jemHjeeWiiwg5L2GcG9seWdvbuesrDHlgIvngrrkuLvopoHljYAsIOWFtuW+jOeCuuWJlOmZpOWNgCwg5q2k54K65pyJ5ZWP6aGM5aSa6YKK5b2iDQogKiAgICAgICAgIFsyMDAsIDBdLA0KICogICAgICAgICBbMjEwLCAwXSwNCiAqICAgICAgICAgWzIxMCwgMV0sDQogKiAgICAgICAgIFsyMDAsIDFdLA0KICogICAgIF0NCiAqIF0NCiAqIHIgPSBnZXRBcmVhUG9seWdvbihwZykNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiA5MCwg5a+m6Zqb54K6MTEwDQogKg0KICovCmZ1bmN0aW9uIGdldEFyZWFQb2x5Z29uKHBnLCBvcHQgPSB7fSkgewogIC8vIC8vZXBzaWxvbgogIC8vIGxldCBlcHNpbG9uID0gZ2V0KG9wdCwgJ2Vwc2lsb24nLCAwLjAwMDAwMDAwMDAwMSkKCiAgLy9jaGVjawogIGlmICghaXNlYXJyKHBnKSkgewogICAgcmV0dXJuIDA7CiAgfQoKICAvL3RvUG9seWdvbgogIHBnID0gdG9Qb2x5Z29uKHBnKTsKICAvLyBjb25zb2xlLmxvZygndG9Qb2x5Z29uIHBnJywgcGcpCgogIC8vcgogIGxldCByID0gMDsKICBmb3JFYWNoKHBnLCAodiwgaykgPT4gewogICAgLy9wb2x5Z29u54K65aSa5YCL5aSa6YKK5b2i57WE5oiQLCDnrKwx5YCL54K65Li76KaB5Y2ALCDkuYvlvozngrrliZTpmaTljYAKICAgIGxldCBhID0gZ2V0QXJlYVJpbmdTdHJpbmcodik7CiAgICBpZiAoayA9PT0gMCkgewogICAgICByID0gYTsKICAgIH0gZWxzZSB7CiAgICAgIHIgLT0gYTsKICAgIH0KICB9KTsKCiAgLy9jaGVjawogIGlmIChyIDwgMCkgewogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiByOwp9CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIHVzZWQgc3RyaWN0bHkgZm9yIGxvZ2dpbmcgdGhlIHByb2Nlc3Npbmcgb2YgdGhlIGFsZ29yaXRobS4uLiBvbmx5IHVzZWZ1bCBpZiB5b3UgaW50ZW5kIG9uCi8vIGxvb2tpbmcgdW5kZXIgdGhlIGNvdmVycyAoZm9yIHByZXR0eSBVSSdzIG9yIGRlYnVnZ2luZykKLy8KCmZ1bmN0aW9uIEJ1aWxkTG9nJDEoKSB7CiAgdmFyIG15OwogIHZhciBuZXh0U2VnbWVudElkID0gMDsKICB2YXIgY3VyVmVydCA9IGZhbHNlOwogIGZ1bmN0aW9uIHB1c2godHlwZSwgZGF0YSkgewogICAgbXkubGlzdC5wdXNoKHsKICAgICAgdHlwZTogdHlwZSwKICAgICAgZGF0YTogZGF0YSA/IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSkpIDogdm9pZCAwCiAgICB9KTsKICAgIHJldHVybiBteTsKICB9CiAgbXkgPSB7CiAgICBsaXN0OiBbXSwKICAgIHNlZ21lbnRJZDogZnVuY3Rpb24gKCkgewogICAgICByZXR1cm4gbmV4dFNlZ21lbnRJZCsrOwogICAgfSwKICAgIGNoZWNrSW50ZXJzZWN0aW9uOiBmdW5jdGlvbiAoc2VnMSwgc2VnMikgewogICAgICByZXR1cm4gcHVzaCgnY2hlY2snLCB7CiAgICAgICAgc2VnMTogc2VnMSwKICAgICAgICBzZWcyOiBzZWcyCiAgICAgIH0pOwogICAgfSwKICAgIHNlZ21lbnRDaG9wOiBmdW5jdGlvbiAoc2VnLCBlbmQpIHsKICAgICAgcHVzaCgnZGl2X3NlZycsIHsKICAgICAgICBzZWc6IHNlZywKICAgICAgICBwdDogZW5kCiAgICAgIH0pOwogICAgICByZXR1cm4gcHVzaCgnY2hvcCcsIHsKICAgICAgICBzZWc6IHNlZywKICAgICAgICBwdDogZW5kCiAgICAgIH0pOwogICAgfSwKICAgIHN0YXR1c1JlbW92ZTogZnVuY3Rpb24gKHNlZykgewogICAgICByZXR1cm4gcHVzaCgncG9wX3NlZycsIHsKICAgICAgICBzZWc6IHNlZwogICAgICB9KTsKICAgIH0sCiAgICBzZWdtZW50VXBkYXRlOiBmdW5jdGlvbiAoc2VnKSB7CiAgICAgIHJldHVybiBwdXNoKCdzZWdfdXBkYXRlJywgewogICAgICAgIHNlZzogc2VnCiAgICAgIH0pOwogICAgfSwKICAgIHNlZ21lbnROZXc6IGZ1bmN0aW9uIChzZWcsIHByaW1hcnkpIHsKICAgICAgcmV0dXJuIHB1c2goJ25ld19zZWcnLCB7CiAgICAgICAgc2VnOiBzZWcsCiAgICAgICAgcHJpbWFyeTogcHJpbWFyeQogICAgICB9KTsKICAgIH0sCiAgICBzZWdtZW50UmVtb3ZlOiBmdW5jdGlvbiAoc2VnKSB7CiAgICAgIHJldHVybiBwdXNoKCdyZW1fc2VnJywgewogICAgICAgIHNlZzogc2VnCiAgICAgIH0pOwogICAgfSwKICAgIHRlbXBTdGF0dXM6IGZ1bmN0aW9uIChzZWcsIGFib3ZlLCBiZWxvdykgewogICAgICByZXR1cm4gcHVzaCgndGVtcF9zdGF0dXMnLCB7CiAgICAgICAgc2VnOiBzZWcsCiAgICAgICAgYWJvdmU6IGFib3ZlLAogICAgICAgIGJlbG93OiBiZWxvdwogICAgICB9KTsKICAgIH0sCiAgICByZXdpbmQ6IGZ1bmN0aW9uIChzZWcpIHsKICAgICAgcmV0dXJuIHB1c2goJ3Jld2luZCcsIHsKICAgICAgICBzZWc6IHNlZwogICAgICB9KTsKICAgIH0sCiAgICBzdGF0dXM6IGZ1bmN0aW9uIChzZWcsIGFib3ZlLCBiZWxvdykgewogICAgICByZXR1cm4gcHVzaCgnc3RhdHVzJywgewogICAgICAgIHNlZzogc2VnLAogICAgICAgIGFib3ZlOiBhYm92ZSwKICAgICAgICBiZWxvdzogYmVsb3cKICAgICAgfSk7CiAgICB9LAogICAgdmVydDogZnVuY3Rpb24gKHgpIHsKICAgICAgaWYgKHggPT09IGN1clZlcnQpIHJldHVybiBteTsKICAgICAgY3VyVmVydCA9IHg7CiAgICAgIHJldHVybiBwdXNoKCd2ZXJ0JywgewogICAgICAgIHg6IHgKICAgICAgfSk7CiAgICB9LAogICAgbG9nOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSBkYXRhID0gSlNPTi5zdHJpbmdpZnkoZGF0YSwgZmFsc2UsICcgICcpOwogICAgICByZXR1cm4gcHVzaCgnbG9nJywgewogICAgICAgIHR4dDogZGF0YQogICAgICB9KTsKICAgIH0sCiAgICByZXNldDogZnVuY3Rpb24gKCkgewogICAgICByZXR1cm4gcHVzaCgncmVzZXQnKTsKICAgIH0sCiAgICBzZWxlY3RlZDogZnVuY3Rpb24gKHNlZ3MpIHsKICAgICAgcmV0dXJuIHB1c2goJ3NlbGVjdGVkJywgewogICAgICAgIHNlZ3M6IHNlZ3MKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5TdGFydDogZnVuY3Rpb24gKHNlZykgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fc3RhcnQnLCB7CiAgICAgICAgc2VnOiBzZWcKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5SZW1vdmVIZWFkOiBmdW5jdGlvbiAoaW5kZXgsIHB0KSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9yZW1faGVhZCcsIHsKICAgICAgICBpbmRleDogaW5kZXgsCiAgICAgICAgcHQ6IHB0CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluUmVtb3ZlVGFpbDogZnVuY3Rpb24gKGluZGV4LCBwdCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fcmVtX3RhaWwnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4LAogICAgICAgIHB0OiBwdAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbk5ldzogZnVuY3Rpb24gKHB0MSwgcHQyKSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9uZXcnLCB7CiAgICAgICAgcHQxOiBwdDEsCiAgICAgICAgcHQyOiBwdDIKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5NYXRjaDogZnVuY3Rpb24gKGluZGV4KSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9tYXRjaCcsIHsKICAgICAgICBpbmRleDogaW5kZXgKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5DbG9zZTogZnVuY3Rpb24gKGluZGV4KSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9jbG9zZScsIHsKICAgICAgICBpbmRleDogaW5kZXgKICAgICAgfSk7CiAgICB9LAogICAgY2hhaW5BZGRIZWFkOiBmdW5jdGlvbiAoaW5kZXgsIHB0KSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9hZGRfaGVhZCcsIHsKICAgICAgICBpbmRleDogaW5kZXgsCiAgICAgICAgcHQ6IHB0CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluQWRkVGFpbDogZnVuY3Rpb24gKGluZGV4LCBwdCkgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fYWRkX3RhaWwnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4LAogICAgICAgIHB0OiBwdAogICAgICB9KTsKICAgIH0sCiAgICBjaGFpbkNvbm5lY3Q6IGZ1bmN0aW9uIChpbmRleDEsIGluZGV4MikgewogICAgICByZXR1cm4gcHVzaCgnY2hhaW5fY29uJywgewogICAgICAgIGluZGV4MTogaW5kZXgxLAogICAgICAgIGluZGV4MjogaW5kZXgyCiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluUmV2ZXJzZTogZnVuY3Rpb24gKGluZGV4KSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9yZXYnLCB7CiAgICAgICAgaW5kZXg6IGluZGV4CiAgICAgIH0pOwogICAgfSwKICAgIGNoYWluSm9pbjogZnVuY3Rpb24gKGluZGV4MSwgaW5kZXgyKSB7CiAgICAgIHJldHVybiBwdXNoKCdjaGFpbl9qb2luJywgewogICAgICAgIGluZGV4MTogaW5kZXgxLAogICAgICAgIGluZGV4MjogaW5kZXgyCiAgICAgIH0pOwogICAgfSwKICAgIGRvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgcmV0dXJuIHB1c2goJ2RvbmUnKTsKICAgIH0KICB9OwogIHJldHVybiBteTsKfQp2YXIgYnVpbGRMb2ckMSA9IEJ1aWxkTG9nJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIHByb3ZpZGVzIHRoZSByYXcgY29tcHV0YXRpb24gZnVuY3Rpb25zIHRoYXQgdGFrZXMgZXBzaWxvbiBpbnRvIGFjY291bnQKLy8KLy8gemVybyBpcyBkZWZpbmVkIHRvIGJlIGJldHdlZW4gKC1lcHNpbG9uLCBlcHNpbG9uKSBleGNsdXNpdmUKLy8KCmZ1bmN0aW9uIEVwc2lsb24kMShlcHMpIHsKICBpZiAodHlwZW9mIGVwcyAhPT0gJ251bWJlcicpIGVwcyA9IDAuMDAwMDAwMDAwMTsgLy8gc2FuZSBkZWZhdWx0PyBzdXJlIHdoeSBub3QKICB2YXIgbXkgPSB7CiAgICBlcHNpbG9uOiBmdW5jdGlvbiAodikgewogICAgICBpZiAodHlwZW9mIHYgPT09ICdudW1iZXInKSBlcHMgPSB2OwogICAgICByZXR1cm4gZXBzOwogICAgfSwKICAgIHBvaW50QWJvdmVPck9uTGluZTogZnVuY3Rpb24gKHB0LCBsZWZ0LCByaWdodCkgewogICAgICB2YXIgQXggPSBsZWZ0WzBdOwogICAgICB2YXIgQXkgPSBsZWZ0WzFdOwogICAgICB2YXIgQnggPSByaWdodFswXTsKICAgICAgdmFyIEJ5ID0gcmlnaHRbMV07CiAgICAgIHZhciBDeCA9IHB0WzBdOwogICAgICB2YXIgQ3kgPSBwdFsxXTsKICAgICAgcmV0dXJuIChCeCAtIEF4KSAqIChDeSAtIEF5KSAtIChCeSAtIEF5KSAqIChDeCAtIEF4KSA+PSAtZXBzOwogICAgfSwKICAgIHBvaW50QmV0d2VlbjogZnVuY3Rpb24gKHAsIGxlZnQsIHJpZ2h0KSB7CiAgICAgIC8vIHAgbXVzdCBiZSBjb2xsaW5lYXIgd2l0aCBsZWZ0LT5yaWdodAogICAgICAvLyByZXR1cm5zIGZhbHNlIGlmIHAgPT0gbGVmdCwgcCA9PSByaWdodCwgb3IgbGVmdCA9PSByaWdodAogICAgICB2YXIgZF9weV9seSA9IHBbMV0gLSBsZWZ0WzFdOwogICAgICB2YXIgZF9yeF9seCA9IHJpZ2h0WzBdIC0gbGVmdFswXTsKICAgICAgdmFyIGRfcHhfbHggPSBwWzBdIC0gbGVmdFswXTsKICAgICAgdmFyIGRfcnlfbHkgPSByaWdodFsxXSAtIGxlZnRbMV07CiAgICAgIHZhciBkb3QgPSBkX3B4X2x4ICogZF9yeF9seCArIGRfcHlfbHkgKiBkX3J5X2x5OwogICAgICAvLyBpZiBgZG90YCBpcyAwLCB0aGVuIGBwYCA9PSBgbGVmdGAgb3IgYGxlZnRgID09IGByaWdodGAgKHJlamVjdCkKICAgICAgLy8gaWYgYGRvdGAgaXMgbGVzcyB0aGFuIDAsIHRoZW4gYHBgIGlzIHRvIHRoZSBsZWZ0IG9mIGBsZWZ0YCAocmVqZWN0KQogICAgICBpZiAoZG90IDwgZXBzKSByZXR1cm4gZmFsc2U7CiAgICAgIHZhciBzcWxlbiA9IGRfcnhfbHggKiBkX3J4X2x4ICsgZF9yeV9seSAqIGRfcnlfbHk7CiAgICAgIC8vIGlmIGBkb3RgID4gYHNxbGVuYCwgdGhlbiBgcGAgaXMgdG8gdGhlIHJpZ2h0IG9mIGByaWdodGAgKHJlamVjdCkKICAgICAgLy8gdGhlcmVmb3JlLCBpZiBgZG90IC0gc3FsZW5gIGlzIGdyZWF0ZXIgdGhhbiAwLCB0aGVuIGBwYCBpcyB0byB0aGUgcmlnaHQgb2YgYHJpZ2h0YCAocmVqZWN0KQogICAgICBpZiAoZG90IC0gc3FsZW4gPiAtZXBzKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfSwKICAgIHBvaW50c1NhbWVYOiBmdW5jdGlvbiAocDEsIHAyKSB7CiAgICAgIHJldHVybiBNYXRoLmFicyhwMVswXSAtIHAyWzBdKSA8IGVwczsKICAgIH0sCiAgICBwb2ludHNTYW1lWTogZnVuY3Rpb24gKHAxLCBwMikgewogICAgICByZXR1cm4gTWF0aC5hYnMocDFbMV0gLSBwMlsxXSkgPCBlcHM7CiAgICB9LAogICAgcG9pbnRzU2FtZTogZnVuY3Rpb24gKHAxLCBwMikgewogICAgICByZXR1cm4gbXkucG9pbnRzU2FtZVgocDEsIHAyKSAmJiBteS5wb2ludHNTYW1lWShwMSwgcDIpOwogICAgfSwKICAgIHBvaW50c0NvbXBhcmU6IGZ1bmN0aW9uIChwMSwgcDIpIHsKICAgICAgLy8gcmV0dXJucyAtMSBpZiBwMSBpcyBzbWFsbGVyLCAxIGlmIHAyIGlzIHNtYWxsZXIsIDAgaWYgZXF1YWwKICAgICAgaWYgKG15LnBvaW50c1NhbWVYKHAxLCBwMikpIHJldHVybiBteS5wb2ludHNTYW1lWShwMSwgcDIpID8gMCA6IHAxWzFdIDwgcDJbMV0gPyAtMSA6IDE7CiAgICAgIHJldHVybiBwMVswXSA8IHAyWzBdID8gLTEgOiAxOwogICAgfSwKICAgIHBvaW50c0NvbGxpbmVhcjogZnVuY3Rpb24gKHB0MSwgcHQyLCBwdDMpIHsKICAgICAgLy8gZG9lcyBwdDEtPnB0Mi0+cHQzIG1ha2UgYSBzdHJhaWdodCBsaW5lPwogICAgICAvLyBlc3NlbnRpYWxseSB0aGlzIGlzIGp1c3QgY2hlY2tpbmcgdG8gc2VlIGlmIHRoZSBzbG9wZShwdDEtPnB0MikgPT09IHNsb3BlKHB0Mi0+cHQzKQogICAgICAvLyBpZiBzbG9wZXMgYXJlIGVxdWFsLCB0aGVuIHRoZXkgbXVzdCBiZSBjb2xsaW5lYXIsIGJlY2F1c2UgdGhleSBzaGFyZSBwdDIKICAgICAgdmFyIGR4MSA9IHB0MVswXSAtIHB0MlswXTsKICAgICAgdmFyIGR5MSA9IHB0MVsxXSAtIHB0MlsxXTsKICAgICAgdmFyIGR4MiA9IHB0MlswXSAtIHB0M1swXTsKICAgICAgdmFyIGR5MiA9IHB0MlsxXSAtIHB0M1sxXTsKICAgICAgcmV0dXJuIE1hdGguYWJzKGR4MSAqIGR5MiAtIGR4MiAqIGR5MSkgPCBlcHM7CiAgICB9LAogICAgbGluZXNJbnRlcnNlY3Q6IGZ1bmN0aW9uIChhMCwgYTEsIGIwLCBiMSkgewogICAgICAvLyByZXR1cm5zIGZhbHNlIGlmIHRoZSBsaW5lcyBhcmUgY29pbmNpZGVudCAoZS5nLiwgcGFyYWxsZWwgb3Igb24gdG9wIG9mIGVhY2ggb3RoZXIpCiAgICAgIC8vCiAgICAgIC8vIHJldHVybnMgYW4gb2JqZWN0IGlmIHRoZSBsaW5lcyBpbnRlcnNlY3Q6CiAgICAgIC8vICAgewogICAgICAvLyAgICAgcHQ6IFt4LCB5XSwgICAgd2hlcmUgdGhlIGludGVyc2VjdGlvbiBwb2ludCBpcyBhdAogICAgICAvLyAgICAgYWxvbmdBOiB3aGVyZSBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYWxvbmcgQSwKICAgICAgLy8gICAgIGFsb25nQjogd2hlcmUgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGFsb25nIEIKICAgICAgLy8gICB9CiAgICAgIC8vCiAgICAgIC8vICBhbG9uZ0EgYW5kIGFsb25nQiB3aWxsIGVhY2ggYmUgb25lIG9mOiAtMiwgLTEsIDAsIDEsIDIKICAgICAgLy8KICAgICAgLy8gIHdpdGggdGhlIGZvbGxvd2luZyBtZWFuaW5nOgogICAgICAvLwogICAgICAvLyAgICAtMiAgIGludGVyc2VjdGlvbiBwb2ludCBpcyBiZWZvcmUgc2VnbWVudCdzIGZpcnN0IHBvaW50CiAgICAgIC8vICAgIC0xICAgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGRpcmVjdGx5IG9uIHNlZ21lbnQncyBmaXJzdCBwb2ludAogICAgICAvLyAgICAgMCAgIGludGVyc2VjdGlvbiBwb2ludCBpcyBiZXR3ZWVuIHNlZ21lbnQncyBmaXJzdCBhbmQgc2Vjb25kIHBvaW50cyAoZXhjbHVzaXZlKQogICAgICAvLyAgICAgMSAgIGludGVyc2VjdGlvbiBwb2ludCBpcyBkaXJlY3RseSBvbiBzZWdtZW50J3Mgc2Vjb25kIHBvaW50CiAgICAgIC8vICAgICAyICAgaW50ZXJzZWN0aW9uIHBvaW50IGlzIGFmdGVyIHNlZ21lbnQncyBzZWNvbmQgcG9pbnQKICAgICAgdmFyIGFkeCA9IGExWzBdIC0gYTBbMF07CiAgICAgIHZhciBhZHkgPSBhMVsxXSAtIGEwWzFdOwogICAgICB2YXIgYmR4ID0gYjFbMF0gLSBiMFswXTsKICAgICAgdmFyIGJkeSA9IGIxWzFdIC0gYjBbMV07CiAgICAgIHZhciBheGIgPSBhZHggKiBiZHkgLSBhZHkgKiBiZHg7CiAgICAgIGlmIChNYXRoLmFicyhheGIpIDwgZXBzKSByZXR1cm4gZmFsc2U7IC8vIGxpbmVzIGFyZSBjb2luY2lkZW50CgogICAgICB2YXIgZHggPSBhMFswXSAtIGIwWzBdOwogICAgICB2YXIgZHkgPSBhMFsxXSAtIGIwWzFdOwogICAgICB2YXIgQSA9IChiZHggKiBkeSAtIGJkeSAqIGR4KSAvIGF4YjsKICAgICAgdmFyIEIgPSAoYWR4ICogZHkgLSBhZHkgKiBkeCkgLyBheGI7CiAgICAgIHZhciByZXQgPSB7CiAgICAgICAgYWxvbmdBOiAwLAogICAgICAgIGFsb25nQjogMCwKICAgICAgICBwdDogW2EwWzBdICsgQSAqIGFkeCwgYTBbMV0gKyBBICogYWR5XQogICAgICB9OwoKICAgICAgLy8gY2F0ZWdvcml6ZSB3aGVyZSBpbnRlcnNlY3Rpb24gcG9pbnQgaXMgYWxvbmcgQSBhbmQgQgoKICAgICAgaWYgKEEgPD0gLWVwcykgcmV0LmFsb25nQSA9IC0yO2Vsc2UgaWYgKEEgPCBlcHMpIHJldC5hbG9uZ0EgPSAtMTtlbHNlIGlmIChBIC0gMSA8PSAtZXBzKSByZXQuYWxvbmdBID0gMDtlbHNlIGlmIChBIC0gMSA8IGVwcykgcmV0LmFsb25nQSA9IDE7ZWxzZSByZXQuYWxvbmdBID0gMjsKICAgICAgaWYgKEIgPD0gLWVwcykgcmV0LmFsb25nQiA9IC0yO2Vsc2UgaWYgKEIgPCBlcHMpIHJldC5hbG9uZ0IgPSAtMTtlbHNlIGlmIChCIC0gMSA8PSAtZXBzKSByZXQuYWxvbmdCID0gMDtlbHNlIGlmIChCIC0gMSA8IGVwcykgcmV0LmFsb25nQiA9IDE7ZWxzZSByZXQuYWxvbmdCID0gMjsKICAgICAgcmV0dXJuIHJldDsKICAgIH0sCiAgICBwb2ludEluc2lkZVJlZ2lvbjogZnVuY3Rpb24gKHB0LCByZWdpb24pIHsKICAgICAgdmFyIHggPSBwdFswXTsKICAgICAgdmFyIHkgPSBwdFsxXTsKICAgICAgdmFyIGxhc3RfeCA9IHJlZ2lvbltyZWdpb24ubGVuZ3RoIC0gMV1bMF07CiAgICAgIHZhciBsYXN0X3kgPSByZWdpb25bcmVnaW9uLmxlbmd0aCAtIDFdWzFdOwogICAgICB2YXIgaW5zaWRlID0gZmFsc2U7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVnaW9uLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGN1cnJfeCA9IHJlZ2lvbltpXVswXTsKICAgICAgICB2YXIgY3Vycl95ID0gcmVnaW9uW2ldWzFdOwoKICAgICAgICAvLyBpZiB5IGlzIGJldHdlZW4gY3Vycl95IGFuZCBsYXN0X3ksIGFuZAogICAgICAgIC8vIHggaXMgdG8gdGhlIHJpZ2h0IG9mIHRoZSBib3VuZGFyeSBjcmVhdGVkIGJ5IHRoZSBsaW5lCiAgICAgICAgaWYgKGN1cnJfeSAtIHkgPiBlcHMgIT0gbGFzdF95IC0geSA+IGVwcyAmJiAobGFzdF94IC0gY3Vycl94KSAqICh5IC0gY3Vycl95KSAvIChsYXN0X3kgLSBjdXJyX3kpICsgY3Vycl94IC0geCA+IGVwcykgaW5zaWRlID0gIWluc2lkZTsKICAgICAgICBsYXN0X3ggPSBjdXJyX3g7CiAgICAgICAgbGFzdF95ID0gY3Vycl95OwogICAgICB9CiAgICAgIHJldHVybiBpbnNpZGU7CiAgICB9CiAgfTsKICByZXR1cm4gbXk7Cn0KdmFyIGVwc2lsb24kMyA9IEVwc2lsb24kMTsKCi8vIChjKSBDb3B5cmlnaHQgMjAxNiwgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwovLyBNSVQgTGljZW5zZQovLyBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwoKLy8KLy8gc2ltcGxlIGxpbmtlZCBsaXN0IGltcGxlbWVudGF0aW9uIHRoYXQgYWxsb3dzIHlvdSB0byB0cmF2ZXJzZSBkb3duIG5vZGVzIGFuZCBzYXZlIHBvc2l0aW9ucwovLwoKdmFyIExpbmtlZExpc3QkMSA9IHsKICBjcmVhdGU6IGZ1bmN0aW9uICgpIHsKICAgIHZhciBteSA9IHsKICAgICAgcm9vdDogewogICAgICAgIHJvb3Q6IHRydWUsCiAgICAgICAgbmV4dDogbnVsbAogICAgICB9LAogICAgICBleGlzdHM6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgaWYgKG5vZGUgPT09IG51bGwgfHwgbm9kZSA9PT0gbXkucm9vdCkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9LAogICAgICBpc0VtcHR5OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIG15LnJvb3QubmV4dCA9PT0gbnVsbDsKICAgICAgfSwKICAgICAgZ2V0SGVhZDogZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBteS5yb290Lm5leHQ7CiAgICAgIH0sCiAgICAgIGluc2VydEJlZm9yZTogZnVuY3Rpb24gKG5vZGUsIGNoZWNrKSB7CiAgICAgICAgdmFyIGxhc3QgPSBteS5yb290OwogICAgICAgIHZhciBoZXJlID0gbXkucm9vdC5uZXh0OwogICAgICAgIHdoaWxlIChoZXJlICE9PSBudWxsKSB7CiAgICAgICAgICBpZiAoY2hlY2soaGVyZSkpIHsKICAgICAgICAgICAgbm9kZS5wcmV2ID0gaGVyZS5wcmV2OwogICAgICAgICAgICBub2RlLm5leHQgPSBoZXJlOwogICAgICAgICAgICBoZXJlLnByZXYubmV4dCA9IG5vZGU7CiAgICAgICAgICAgIGhlcmUucHJldiA9IG5vZGU7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KICAgICAgICAgIGxhc3QgPSBoZXJlOwogICAgICAgICAgaGVyZSA9IGhlcmUubmV4dDsKICAgICAgICB9CiAgICAgICAgbGFzdC5uZXh0ID0gbm9kZTsKICAgICAgICBub2RlLnByZXYgPSBsYXN0OwogICAgICAgIG5vZGUubmV4dCA9IG51bGw7CiAgICAgIH0sCiAgICAgIGZpbmRUcmFuc2l0aW9uOiBmdW5jdGlvbiAoY2hlY2spIHsKICAgICAgICB2YXIgcHJldiA9IG15LnJvb3Q7CiAgICAgICAgdmFyIGhlcmUgPSBteS5yb290Lm5leHQ7CiAgICAgICAgd2hpbGUgKGhlcmUgIT09IG51bGwpIHsKICAgICAgICAgIGlmIChjaGVjayhoZXJlKSkgYnJlYWs7CiAgICAgICAgICBwcmV2ID0gaGVyZTsKICAgICAgICAgIGhlcmUgPSBoZXJlLm5leHQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7CiAgICAgICAgICBiZWZvcmU6IHByZXYgPT09IG15LnJvb3QgPyBudWxsIDogcHJldiwKICAgICAgICAgIGFmdGVyOiBoZXJlLAogICAgICAgICAgaW5zZXJ0OiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICBub2RlLnByZXYgPSBwcmV2OwogICAgICAgICAgICBub2RlLm5leHQgPSBoZXJlOwogICAgICAgICAgICBwcmV2Lm5leHQgPSBub2RlOwogICAgICAgICAgICBpZiAoaGVyZSAhPT0gbnVsbCkgaGVyZS5wcmV2ID0gbm9kZTsKICAgICAgICAgICAgcmV0dXJuIG5vZGU7CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgfQogICAgfTsKICAgIHJldHVybiBteTsKICB9LAogIG5vZGU6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICBkYXRhLnByZXYgPSBudWxsOwogICAgZGF0YS5uZXh0ID0gbnVsbDsKICAgIGRhdGEucmVtb3ZlID0gZnVuY3Rpb24gKCkgewogICAgICBkYXRhLnByZXYubmV4dCA9IGRhdGEubmV4dDsKICAgICAgaWYgKGRhdGEubmV4dCkgZGF0YS5uZXh0LnByZXYgPSBkYXRhLnByZXY7CiAgICAgIGRhdGEucHJldiA9IG51bGw7CiAgICAgIGRhdGEubmV4dCA9IG51bGw7CiAgICB9OwogICAgcmV0dXJuIGRhdGE7CiAgfQp9Owp2YXIgbGlua2VkTGlzdCA9IExpbmtlZExpc3QkMTsKCi8vIChjKSBDb3B5cmlnaHQgMjAxNiwgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwovLyBNSVQgTGljZW5zZQovLyBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwoKLy8KLy8gdGhpcyBpcyB0aGUgY29yZSB3b3JrLWhvcnNlCi8vCgp2YXIgTGlua2VkTGlzdCA9IGxpbmtlZExpc3Q7CmZ1bmN0aW9uIEludGVyc2VjdGVyJDEoc2VsZkludGVyc2VjdGlvbiwgZXBzLCBidWlsZExvZykgewogIC8vIHNlbGZJbnRlcnNlY3Rpb24gaXMgdHJ1ZS9mYWxzZSBkZXBlbmRpbmcgb24gdGhlIHBoYXNlIG9mIHRoZSBvdmVyYWxsIGFsZ29yaXRobQoKICAvLwogIC8vIHNlZ21lbnQgY3JlYXRpb24KICAvLwoKICBmdW5jdGlvbiBzZWdtZW50TmV3KHN0YXJ0LCBlbmQpIHsKICAgIHJldHVybiB7CiAgICAgIGlkOiBidWlsZExvZyA/IGJ1aWxkTG9nLnNlZ21lbnRJZCgpIDogLTEsCiAgICAgIHN0YXJ0OiBzdGFydCwKICAgICAgZW5kOiBlbmQsCiAgICAgIG15RmlsbDogewogICAgICAgIGFib3ZlOiBudWxsLAogICAgICAgIC8vIGlzIHRoZXJlIGZpbGwgYWJvdmUgdXM/CiAgICAgICAgYmVsb3c6IG51bGwgLy8gaXMgdGhlcmUgZmlsbCBiZWxvdyB1cz8KICAgICAgfSwKCiAgICAgIG90aGVyRmlsbDogbnVsbAogICAgfTsKICB9CiAgZnVuY3Rpb24gc2VnbWVudENvcHkoc3RhcnQsIGVuZCwgc2VnKSB7CiAgICByZXR1cm4gewogICAgICBpZDogYnVpbGRMb2cgPyBidWlsZExvZy5zZWdtZW50SWQoKSA6IC0xLAogICAgICBzdGFydDogc3RhcnQsCiAgICAgIGVuZDogZW5kLAogICAgICBteUZpbGw6IHsKICAgICAgICBhYm92ZTogc2VnLm15RmlsbC5hYm92ZSwKICAgICAgICBiZWxvdzogc2VnLm15RmlsbC5iZWxvdwogICAgICB9LAogICAgICBvdGhlckZpbGw6IG51bGwKICAgIH07CiAgfQoKICAvLwogIC8vIGV2ZW50IGxvZ2ljCiAgLy8KCiAgdmFyIGV2ZW50X3Jvb3QgPSBMaW5rZWRMaXN0LmNyZWF0ZSgpOwogIGZ1bmN0aW9uIGV2ZW50Q29tcGFyZShwMV9pc1N0YXJ0LCBwMV8xLCBwMV8yLCBwMl9pc1N0YXJ0LCBwMl8xLCBwMl8yKSB7CiAgICAvLyBjb21wYXJlIHRoZSBzZWxlY3RlZCBwb2ludHMgZmlyc3QKICAgIHZhciBjb21wID0gZXBzLnBvaW50c0NvbXBhcmUocDFfMSwgcDJfMSk7CiAgICBpZiAoY29tcCAhPT0gMCkgcmV0dXJuIGNvbXA7CiAgICAvLyB0aGUgc2VsZWN0ZWQgcG9pbnRzIGFyZSB0aGUgc2FtZQoKICAgIGlmIChlcHMucG9pbnRzU2FtZShwMV8yLCBwMl8yKSkKICAgICAgLy8gaWYgdGhlIG5vbi1zZWxlY3RlZCBwb2ludHMgYXJlIHRoZSBzYW1lIHRvby4uLgogICAgICByZXR1cm4gMDsgLy8gdGhlbiB0aGUgc2VnbWVudHMgYXJlIGVxdWFsCgogICAgaWYgKHAxX2lzU3RhcnQgIT09IHAyX2lzU3RhcnQpCiAgICAgIC8vIGlmIG9uZSBpcyBhIHN0YXJ0IGFuZCB0aGUgb3RoZXIgaXNuJ3QuLi4KICAgICAgcmV0dXJuIHAxX2lzU3RhcnQgPyAxIDogLTE7IC8vIGZhdm9yIHRoZSBvbmUgdGhhdCBpc24ndCB0aGUgc3RhcnQKCiAgICAvLyBvdGhlcndpc2UsIHdlJ2xsIGhhdmUgdG8gY2FsY3VsYXRlIHdoaWNoIG9uZSBpcyBiZWxvdyB0aGUgb3RoZXIgbWFudWFsbHkKICAgIHJldHVybiBlcHMucG9pbnRBYm92ZU9yT25MaW5lKHAxXzIsIHAyX2lzU3RhcnQgPyBwMl8xIDogcDJfMiwKICAgIC8vIG9yZGVyIG1hdHRlcnMKICAgIHAyX2lzU3RhcnQgPyBwMl8yIDogcDJfMSkgPyAxIDogLTE7CiAgfQogIGZ1bmN0aW9uIGV2ZW50QWRkKGV2LCBvdGhlcl9wdCkgewogICAgZXZlbnRfcm9vdC5pbnNlcnRCZWZvcmUoZXYsIGZ1bmN0aW9uIChoZXJlKSB7CiAgICAgIC8vIHNob3VsZCBldiBiZSBpbnNlcnRlZCBiZWZvcmUgaGVyZT8KICAgICAgdmFyIGNvbXAgPSBldmVudENvbXBhcmUoZXYuaXNTdGFydCwgZXYucHQsIG90aGVyX3B0LCBoZXJlLmlzU3RhcnQsIGhlcmUucHQsIGhlcmUub3RoZXIucHQpOwogICAgICByZXR1cm4gY29tcCA8IDA7CiAgICB9KTsKICB9CiAgZnVuY3Rpb24gZXZlbnRBZGRTZWdtZW50U3RhcnQoc2VnLCBwcmltYXJ5KSB7CiAgICB2YXIgZXZfc3RhcnQgPSBMaW5rZWRMaXN0Lm5vZGUoewogICAgICBpc1N0YXJ0OiB0cnVlLAogICAgICBwdDogc2VnLnN0YXJ0LAogICAgICBzZWc6IHNlZywKICAgICAgcHJpbWFyeTogcHJpbWFyeSwKICAgICAgb3RoZXI6IG51bGwsCiAgICAgIHN0YXR1czogbnVsbAogICAgfSk7CiAgICBldmVudEFkZChldl9zdGFydCwgc2VnLmVuZCk7CiAgICByZXR1cm4gZXZfc3RhcnQ7CiAgfQogIGZ1bmN0aW9uIGV2ZW50QWRkU2VnbWVudEVuZChldl9zdGFydCwgc2VnLCBwcmltYXJ5KSB7CiAgICB2YXIgZXZfZW5kID0gTGlua2VkTGlzdC5ub2RlKHsKICAgICAgaXNTdGFydDogZmFsc2UsCiAgICAgIHB0OiBzZWcuZW5kLAogICAgICBzZWc6IHNlZywKICAgICAgcHJpbWFyeTogcHJpbWFyeSwKICAgICAgb3RoZXI6IGV2X3N0YXJ0LAogICAgICBzdGF0dXM6IG51bGwKICAgIH0pOwogICAgZXZfc3RhcnQub3RoZXIgPSBldl9lbmQ7CiAgICBldmVudEFkZChldl9lbmQsIGV2X3N0YXJ0LnB0KTsKICB9CiAgZnVuY3Rpb24gZXZlbnRBZGRTZWdtZW50KHNlZywgcHJpbWFyeSkgewogICAgdmFyIGV2X3N0YXJ0ID0gZXZlbnRBZGRTZWdtZW50U3RhcnQoc2VnLCBwcmltYXJ5KTsKICAgIGV2ZW50QWRkU2VnbWVudEVuZChldl9zdGFydCwgc2VnLCBwcmltYXJ5KTsKICAgIHJldHVybiBldl9zdGFydDsKICB9CiAgZnVuY3Rpb24gZXZlbnRVcGRhdGVFbmQoZXYsIGVuZCkgewogICAgLy8gc2xpZGVzIGFuIGVuZCBiYWNrd2FyZHMKICAgIC8vICAgKHN0YXJ0KS0tLS0tLS0tLS0tLShlbmQpICAgIHRvOgogICAgLy8gICAoc3RhcnQpLS0tKGVuZCkKCiAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnNlZ21lbnRDaG9wKGV2LnNlZywgZW5kKTsKICAgIGV2Lm90aGVyLnJlbW92ZSgpOwogICAgZXYuc2VnLmVuZCA9IGVuZDsKICAgIGV2Lm90aGVyLnB0ID0gZW5kOwogICAgZXZlbnRBZGQoZXYub3RoZXIsIGV2LnB0KTsKICB9CiAgZnVuY3Rpb24gZXZlbnREaXZpZGUoZXYsIHB0KSB7CiAgICB2YXIgbnMgPSBzZWdtZW50Q29weShwdCwgZXYuc2VnLmVuZCwgZXYuc2VnKTsKICAgIGV2ZW50VXBkYXRlRW5kKGV2LCBwdCk7CiAgICByZXR1cm4gZXZlbnRBZGRTZWdtZW50KG5zLCBldi5wcmltYXJ5KTsKICB9CiAgZnVuY3Rpb24gY2FsY3VsYXRlKHByaW1hcnlQb2x5SW52ZXJ0ZWQsIHNlY29uZGFyeVBvbHlJbnZlcnRlZCkgewogICAgLy8gaWYgc2VsZkludGVyc2VjdGlvbiBpcyB0cnVlIHRoZW4gdGhlcmUgaXMgbm8gc2Vjb25kYXJ5IHBvbHlnb24sIHNvIHRoYXQgaXNuJ3QgdXNlZAoKICAgIC8vCiAgICAvLyBzdGF0dXMgbG9naWMKICAgIC8vCgogICAgdmFyIHN0YXR1c19yb290ID0gTGlua2VkTGlzdC5jcmVhdGUoKTsKICAgIGZ1bmN0aW9uIHN0YXR1c0NvbXBhcmUoZXYxLCBldjIpIHsKICAgICAgdmFyIGExID0gZXYxLnNlZy5zdGFydDsKICAgICAgdmFyIGEyID0gZXYxLnNlZy5lbmQ7CiAgICAgIHZhciBiMSA9IGV2Mi5zZWcuc3RhcnQ7CiAgICAgIHZhciBiMiA9IGV2Mi5zZWcuZW5kOwogICAgICBpZiAoZXBzLnBvaW50c0NvbGxpbmVhcihhMSwgYjEsIGIyKSkgewogICAgICAgIGlmIChlcHMucG9pbnRzQ29sbGluZWFyKGEyLCBiMSwgYjIpKSByZXR1cm4gMTsgLy9ldmVudENvbXBhcmUodHJ1ZSwgYTEsIGEyLCB0cnVlLCBiMSwgYjIpOwogICAgICAgIHJldHVybiBlcHMucG9pbnRBYm92ZU9yT25MaW5lKGEyLCBiMSwgYjIpID8gMSA6IC0xOwogICAgICB9CiAgICAgIHJldHVybiBlcHMucG9pbnRBYm92ZU9yT25MaW5lKGExLCBiMSwgYjIpID8gMSA6IC0xOwogICAgfQogICAgZnVuY3Rpb24gc3RhdHVzRmluZFN1cnJvdW5kaW5nKGV2KSB7CiAgICAgIHJldHVybiBzdGF0dXNfcm9vdC5maW5kVHJhbnNpdGlvbihmdW5jdGlvbiAoaGVyZSkgewogICAgICAgIHZhciBjb21wID0gc3RhdHVzQ29tcGFyZShldiwgaGVyZS5ldik7CiAgICAgICAgcmV0dXJuIGNvbXAgPiAwOwogICAgICB9KTsKICAgIH0KICAgIGZ1bmN0aW9uIGNoZWNrSW50ZXJzZWN0aW9uKGV2MSwgZXYyKSB7CiAgICAgIC8vIHJldHVybnMgdGhlIHNlZ21lbnQgZXF1YWwgdG8gZXYxLCBvciBmYWxzZSBpZiBub3RoaW5nIGVxdWFsCgogICAgICB2YXIgc2VnMSA9IGV2MS5zZWc7CiAgICAgIHZhciBzZWcyID0gZXYyLnNlZzsKICAgICAgdmFyIGExID0gc2VnMS5zdGFydDsKICAgICAgdmFyIGEyID0gc2VnMS5lbmQ7CiAgICAgIHZhciBiMSA9IHNlZzIuc3RhcnQ7CiAgICAgIHZhciBiMiA9IHNlZzIuZW5kOwogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoZWNrSW50ZXJzZWN0aW9uKHNlZzEsIHNlZzIpOwogICAgICB2YXIgaSA9IGVwcy5saW5lc0ludGVyc2VjdChhMSwgYTIsIGIxLCBiMik7CiAgICAgIGlmIChpID09PSBmYWxzZSkgewogICAgICAgIC8vIHNlZ21lbnRzIGFyZSBwYXJhbGxlbCBvciBjb2luY2lkZW50CgogICAgICAgIC8vIGlmIHBvaW50cyBhcmVuJ3QgY29sbGluZWFyLCB0aGVuIHRoZSBzZWdtZW50cyBhcmUgcGFyYWxsZWwsIHNvIG5vIGludGVyc2VjdGlvbnMKICAgICAgICBpZiAoIWVwcy5wb2ludHNDb2xsaW5lYXIoYTEsIGEyLCBiMSkpIHJldHVybiBmYWxzZTsKICAgICAgICAvLyBvdGhlcndpc2UsIHNlZ21lbnRzIGFyZSBvbiB0b3Agb2YgZWFjaCBvdGhlciBzb21laG93IChha2EgY29pbmNpZGVudCkKCiAgICAgICAgaWYgKGVwcy5wb2ludHNTYW1lKGExLCBiMikgfHwgZXBzLnBvaW50c1NhbWUoYTIsIGIxKSkgcmV0dXJuIGZhbHNlOyAvLyBzZWdtZW50cyB0b3VjaCBhdCBlbmRwb2ludHMuLi4gbm8gaW50ZXJzZWN0aW9uCgogICAgICAgIHZhciBhMV9lcXVfYjEgPSBlcHMucG9pbnRzU2FtZShhMSwgYjEpOwogICAgICAgIHZhciBhMl9lcXVfYjIgPSBlcHMucG9pbnRzU2FtZShhMiwgYjIpOwogICAgICAgIGlmIChhMV9lcXVfYjEgJiYgYTJfZXF1X2IyKSByZXR1cm4gZXYyOyAvLyBzZWdtZW50cyBhcmUgZXhhY3RseSBlcXVhbAoKICAgICAgICB2YXIgYTFfYmV0d2VlbiA9ICFhMV9lcXVfYjEgJiYgZXBzLnBvaW50QmV0d2VlbihhMSwgYjEsIGIyKTsKICAgICAgICB2YXIgYTJfYmV0d2VlbiA9ICFhMl9lcXVfYjIgJiYgZXBzLnBvaW50QmV0d2VlbihhMiwgYjEsIGIyKTsKCiAgICAgICAgLy8gaGFuZHkgZm9yIGRlYnVnZ2luZzoKICAgICAgICAvLyBidWlsZExvZy5sb2coewogICAgICAgIC8vCWExX2VxdV9iMTogYTFfZXF1X2IxLAogICAgICAgIC8vCWEyX2VxdV9iMjogYTJfZXF1X2IyLAogICAgICAgIC8vCWExX2JldHdlZW46IGExX2JldHdlZW4sCiAgICAgICAgLy8JYTJfYmV0d2VlbjogYTJfYmV0d2VlbgogICAgICAgIC8vIH0pOwoKICAgICAgICBpZiAoYTFfZXF1X2IxKSB7CiAgICAgICAgICBpZiAoYTJfYmV0d2VlbikgewogICAgICAgICAgICAvLyAgKGExKS0tLShhMikKICAgICAgICAgICAgLy8gIChiMSktLS0tLS0tLS0tKGIyKQogICAgICAgICAgICBldmVudERpdmlkZShldjIsIGEyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vICAoYTEpLS0tLS0tLS0tLShhMikKICAgICAgICAgICAgLy8gIChiMSktLS0oYjIpCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MSwgYjIpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGV2MjsKICAgICAgICB9IGVsc2UgaWYgKGExX2JldHdlZW4pIHsKICAgICAgICAgIGlmICghYTJfZXF1X2IyKSB7CiAgICAgICAgICAgIC8vIG1ha2UgYTIgZXF1YWwgdG8gYjIKICAgICAgICAgICAgaWYgKGEyX2JldHdlZW4pIHsKICAgICAgICAgICAgICAvLyAgICAgICAgIChhMSktLS0oYTIpCiAgICAgICAgICAgICAgLy8gIChiMSktLS0tLS0tLS0tLS0tLS0tLShiMikKICAgICAgICAgICAgICBldmVudERpdmlkZShldjIsIGEyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAvLyAgICAgICAgIChhMSktLS0tLS0tLS0tKGEyKQogICAgICAgICAgICAgIC8vICAoYjEpLS0tLS0tLS0tLShiMikKICAgICAgICAgICAgICBldmVudERpdmlkZShldjEsIGIyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8vICAgICAgICAgKGExKS0tLShhMikKICAgICAgICAgIC8vICAoYjEpLS0tLS0tLS0tLShiMikKICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MiwgYTEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBvdGhlcndpc2UsIGxpbmVzIGludGVyc2VjdCBhdCBpLnB0LCB3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSBiZXR3ZWVuIHRoZSBlbmRwb2ludHMKCiAgICAgICAgLy8gaXMgQSBkaXZpZGVkIGJldHdlZW4gaXRzIGVuZHBvaW50cz8gKGV4Y2x1c2l2ZSkKICAgICAgICBpZiAoaS5hbG9uZ0EgPT09IDApIHsKICAgICAgICAgIGlmIChpLmFsb25nQiA9PT0gLTEpCiAgICAgICAgICAgIC8vIHllcywgYXQgZXhhY3RseSBiMQogICAgICAgICAgICBldmVudERpdmlkZShldjEsIGIxKTtlbHNlIGlmIChpLmFsb25nQiA9PT0gMCkKICAgICAgICAgICAgLy8geWVzLCBzb21ld2hlcmUgYmV0d2VlbiBCJ3MgZW5kcG9pbnRzCiAgICAgICAgICAgIGV2ZW50RGl2aWRlKGV2MSwgaS5wdCk7ZWxzZSBpZiAoaS5hbG9uZ0IgPT09IDEpCiAgICAgICAgICAgIC8vIHllcywgYXQgZXhhY3RseSBiMgogICAgICAgICAgICBldmVudERpdmlkZShldjEsIGIyKTsKICAgICAgICB9CgogICAgICAgIC8vIGlzIEIgZGl2aWRlZCBiZXR3ZWVuIGl0cyBlbmRwb2ludHM/IChleGNsdXNpdmUpCiAgICAgICAgaWYgKGkuYWxvbmdCID09PSAwKSB7CiAgICAgICAgICBpZiAoaS5hbG9uZ0EgPT09IC0xKQogICAgICAgICAgICAvLyB5ZXMsIGF0IGV4YWN0bHkgYTEKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBhMSk7ZWxzZSBpZiAoaS5hbG9uZ0EgPT09IDApCiAgICAgICAgICAgIC8vIHllcywgc29tZXdoZXJlIGJldHdlZW4gQSdzIGVuZHBvaW50cyAoZXhjbHVzaXZlKQogICAgICAgICAgICBldmVudERpdmlkZShldjIsIGkucHQpO2Vsc2UgaWYgKGkuYWxvbmdBID09PSAxKQogICAgICAgICAgICAvLyB5ZXMsIGF0IGV4YWN0bHkgYTIKICAgICAgICAgICAgZXZlbnREaXZpZGUoZXYyLCBhMik7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvLwogICAgLy8gbWFpbiBldmVudCBsb29wCiAgICAvLwogICAgdmFyIHNlZ21lbnRzID0gW107CiAgICB3aGlsZSAoIWV2ZW50X3Jvb3QuaXNFbXB0eSgpKSB7CiAgICAgIHZhciBldiA9IGV2ZW50X3Jvb3QuZ2V0SGVhZCgpOwogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLnZlcnQoZXYucHRbMF0pOwogICAgICBpZiAoZXYuaXNTdGFydCkgewogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuc2VnbWVudE5ldyhldi5zZWcsIGV2LnByaW1hcnkpOwogICAgICAgIHZhciBzdXJyb3VuZGluZyA9IHN0YXR1c0ZpbmRTdXJyb3VuZGluZyhldik7CiAgICAgICAgdmFyIGFib3ZlID0gc3Vycm91bmRpbmcuYmVmb3JlID8gc3Vycm91bmRpbmcuYmVmb3JlLmV2IDogbnVsbDsKICAgICAgICB2YXIgYmVsb3cgPSBzdXJyb3VuZGluZy5hZnRlciA/IHN1cnJvdW5kaW5nLmFmdGVyLmV2IDogbnVsbDsKICAgICAgICBpZiAoYnVpbGRMb2cpIHsKICAgICAgICAgIGJ1aWxkTG9nLnRlbXBTdGF0dXMoZXYuc2VnLCBhYm92ZSA/IGFib3ZlLnNlZyA6IGZhbHNlLCBiZWxvdyA/IGJlbG93LnNlZyA6IGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gY2hlY2tCb3RoSW50ZXJzZWN0aW9ucygpIHsKICAgICAgICAgIGlmIChhYm92ZSkgewogICAgICAgICAgICB2YXIgZXZlID0gY2hlY2tJbnRlcnNlY3Rpb24oZXYsIGFib3ZlKTsKICAgICAgICAgICAgaWYgKGV2ZSkgcmV0dXJuIGV2ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChiZWxvdykgcmV0dXJuIGNoZWNrSW50ZXJzZWN0aW9uKGV2LCBiZWxvdyk7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHZhciBldmUgPSBjaGVja0JvdGhJbnRlcnNlY3Rpb25zKCk7CiAgICAgICAgaWYgKGV2ZSkgewogICAgICAgICAgLy8gZXYgYW5kIGV2ZSBhcmUgZXF1YWwKICAgICAgICAgIC8vIHdlJ2xsIGtlZXAgZXZlIGFuZCB0aHJvdyBhd2F5IGV2CgogICAgICAgICAgLy8gbWVyZ2UgZXYuc2VnJ3MgZmlsbCBpbmZvcm1hdGlvbiBpbnRvIGV2ZS5zZWcKCiAgICAgICAgICBpZiAoc2VsZkludGVyc2VjdGlvbikgewogICAgICAgICAgICB2YXIgdG9nZ2xlOyAvLyBhcmUgd2UgYSB0b2dnbGluZyBlZGdlPwogICAgICAgICAgICBpZiAoZXYuc2VnLm15RmlsbC5iZWxvdyA9PT0gbnVsbCkgdG9nZ2xlID0gdHJ1ZTtlbHNlIHRvZ2dsZSA9IGV2LnNlZy5teUZpbGwuYWJvdmUgIT09IGV2LnNlZy5teUZpbGwuYmVsb3c7CgogICAgICAgICAgICAvLyBtZXJnZSB0d28gc2VnbWVudHMgdGhhdCBiZWxvbmcgdG8gdGhlIHNhbWUgcG9seWdvbgogICAgICAgICAgICAvLyB0aGluayBvZiB0aGlzIGFzIHNhbmR3aWNoaW5nIHR3byBzZWdtZW50cyB0b2dldGhlciwgd2hlcmUgYGV2ZS5zZWdgIGlzCiAgICAgICAgICAgIC8vIHRoZSBib3R0b20gLS0gdGhpcyB3aWxsIGNhdXNlIHRoZSBhYm92ZSBmaWxsIGZsYWcgdG8gdG9nZ2xlCiAgICAgICAgICAgIGlmICh0b2dnbGUpIGV2ZS5zZWcubXlGaWxsLmFib3ZlID0gIWV2ZS5zZWcubXlGaWxsLmFib3ZlOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gbWVyZ2UgdHdvIHNlZ21lbnRzIHRoYXQgYmVsb25nIHRvIGRpZmZlcmVudCBwb2x5Z29ucwogICAgICAgICAgICAvLyBlYWNoIHNlZ21lbnQgaGFzIGRpc3RpbmN0IGtub3dsZWRnZSwgc28gbm8gc3BlY2lhbCBsb2dpYyBpcyBuZWVkZWQKICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoaXMgY2FuIG9ubHkgaGFwcGVuIG9uY2UgcGVyIHNlZ21lbnQgaW4gdGhpcyBwaGFzZSwgYmVjYXVzZSB3ZQogICAgICAgICAgICAvLyBhcmUgZ3VhcmFudGVlZCB0aGF0IGFsbCBzZWxmLWludGVyc2VjdGlvbnMgYXJlIGdvbmUKICAgICAgICAgICAgZXZlLnNlZy5vdGhlckZpbGwgPSBldi5zZWcubXlGaWxsOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5zZWdtZW50VXBkYXRlKGV2ZS5zZWcpOwogICAgICAgICAgZXYub3RoZXIucmVtb3ZlKCk7CiAgICAgICAgICBldi5yZW1vdmUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGV2ZW50X3Jvb3QuZ2V0SGVhZCgpICE9PSBldikgewogICAgICAgICAgLy8gc29tZXRoaW5nIHdhcyBpbnNlcnRlZCBiZWZvcmUgdXMgaW4gdGhlIGV2ZW50IHF1ZXVlLCBzbyBsb29wIGJhY2sgYXJvdW5kIGFuZAogICAgICAgICAgLy8gcHJvY2VzcyBpdCBiZWZvcmUgY29udGludWluZwogICAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5yZXdpbmQoZXYuc2VnKTsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLy8KICAgICAgICAvLyBjYWxjdWxhdGUgZmlsbCBmbGFncwogICAgICAgIC8vCiAgICAgICAgaWYgKHNlbGZJbnRlcnNlY3Rpb24pIHsKICAgICAgICAgIHZhciB0b2dnbGU7IC8vIGFyZSB3ZSBhIHRvZ2dsaW5nIGVkZ2U/CiAgICAgICAgICBpZiAoZXYuc2VnLm15RmlsbC5iZWxvdyA9PT0gbnVsbCkKICAgICAgICAgICAgLy8gaWYgd2UgYXJlIGEgbmV3IHNlZ21lbnQuLi4KICAgICAgICAgICAgdG9nZ2xlID0gdHJ1ZTsgLy8gdGhlbiB3ZSB0b2dnbGUKICAgICAgICAgIGVsc2UKICAgICAgICAgICAgLy8gd2UgYXJlIGEgc2VnbWVudCB0aGF0IGhhcyBwcmV2aW91cyBrbm93bGVkZ2UgZnJvbSBhIGRpdmlzaW9uCiAgICAgICAgICAgIHRvZ2dsZSA9IGV2LnNlZy5teUZpbGwuYWJvdmUgIT09IGV2LnNlZy5teUZpbGwuYmVsb3c7IC8vIGNhbGN1bGF0ZSB0b2dnbGUKCiAgICAgICAgICAvLyBuZXh0LCBjYWxjdWxhdGUgd2hldGhlciB3ZSBhcmUgZmlsbGVkIGJlbG93IHVzCiAgICAgICAgICBpZiAoIWJlbG93KSB7CiAgICAgICAgICAgIC8vIGlmIG5vdGhpbmcgaXMgYmVsb3cgdXMuLi4KICAgICAgICAgICAgLy8gd2UgYXJlIGZpbGxlZCBiZWxvdyB1cyBpZiB0aGUgcG9seWdvbiBpcyBpbnZlcnRlZAogICAgICAgICAgICBldi5zZWcubXlGaWxsLmJlbG93ID0gcHJpbWFyeVBvbHlJbnZlcnRlZDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgd2Uga25vdyB0aGUgYW5zd2VyIC0tIGl0J3MgdGhlIHNhbWUgaWYgd2hhdGV2ZXIgaXMgYmVsb3cKICAgICAgICAgICAgLy8gdXMgaXMgZmlsbGVkIGFib3ZlIGl0CiAgICAgICAgICAgIGV2LnNlZy5teUZpbGwuYmVsb3cgPSBiZWxvdy5zZWcubXlGaWxsLmFib3ZlOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIHNpbmNlIG5vdyB3ZSBrbm93IGlmIHdlJ3JlIGZpbGxlZCBiZWxvdyB1cywgd2UgY2FuIGNhbGN1bGF0ZSB3aGV0aGVyCiAgICAgICAgICAvLyB3ZSdyZSBmaWxsZWQgYWJvdmUgdXMgYnkgYXBwbHlpbmcgdG9nZ2xlIHRvIHdoYXRldmVyIGlzIGJlbG93IHVzCiAgICAgICAgICBpZiAodG9nZ2xlKSBldi5zZWcubXlGaWxsLmFib3ZlID0gIWV2LnNlZy5teUZpbGwuYmVsb3c7ZWxzZSBldi5zZWcubXlGaWxsLmFib3ZlID0gZXYuc2VnLm15RmlsbC5iZWxvdzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gbm93IHdlIGZpbGwgaW4gYW55IG1pc3NpbmcgdHJhbnNpdGlvbiBpbmZvcm1hdGlvbiwgc2luY2Ugd2UgYXJlIGFsbC1rbm93aW5nCiAgICAgICAgICAvLyBhdCB0aGlzIHBvaW50CgogICAgICAgICAgaWYgKGV2LnNlZy5vdGhlckZpbGwgPT09IG51bGwpIHsKICAgICAgICAgICAgLy8gaWYgd2UgZG9uJ3QgaGF2ZSBvdGhlciBpbmZvcm1hdGlvbiwgdGhlbiB3ZSBuZWVkIHRvIGZpZ3VyZSBvdXQgaWYgd2UncmUKICAgICAgICAgICAgLy8gaW5zaWRlIHRoZSBvdGhlciBwb2x5Z29uCiAgICAgICAgICAgIHZhciBpbnNpZGU7CiAgICAgICAgICAgIGlmICghYmVsb3cpIHsKICAgICAgICAgICAgICAvLyBpZiBub3RoaW5nIGlzIGJlbG93IHVzLCB0aGVuIHdlJ3JlIGluc2lkZSBpZiB0aGUgb3RoZXIgcG9seWdvbiBpcwogICAgICAgICAgICAgIC8vIGludmVydGVkCiAgICAgICAgICAgICAgaW5zaWRlID0gZXYucHJpbWFyeSA/IHNlY29uZGFyeVBvbHlJbnZlcnRlZCA6IHByaW1hcnlQb2x5SW52ZXJ0ZWQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBzb21ldGhpbmcgaXMgYmVsb3cgdXMKICAgICAgICAgICAgICAvLyBzbyBjb3B5IHRoZSBiZWxvdyBzZWdtZW50J3Mgb3RoZXIgcG9seWdvbidzIGFib3ZlCiAgICAgICAgICAgICAgaWYgKGV2LnByaW1hcnkgPT09IGJlbG93LnByaW1hcnkpIGluc2lkZSA9IGJlbG93LnNlZy5vdGhlckZpbGwuYWJvdmU7ZWxzZSBpbnNpZGUgPSBiZWxvdy5zZWcubXlGaWxsLmFib3ZlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGV2LnNlZy5vdGhlckZpbGwgPSB7CiAgICAgICAgICAgICAgYWJvdmU6IGluc2lkZSwKICAgICAgICAgICAgICBiZWxvdzogaW5zaWRlCiAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChidWlsZExvZykgewogICAgICAgICAgYnVpbGRMb2cuc3RhdHVzKGV2LnNlZywgYWJvdmUgPyBhYm92ZS5zZWcgOiBmYWxzZSwgYmVsb3cgPyBiZWxvdy5zZWcgOiBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBpbnNlcnQgdGhlIHN0YXR1cyBhbmQgcmVtZW1iZXIgaXQgZm9yIGxhdGVyIHJlbW92YWwKICAgICAgICBldi5vdGhlci5zdGF0dXMgPSBzdXJyb3VuZGluZy5pbnNlcnQoTGlua2VkTGlzdC5ub2RlKHsKICAgICAgICAgIGV2OiBldgogICAgICAgIH0pKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2YXIgc3QgPSBldi5zdGF0dXM7CiAgICAgICAgaWYgKHN0ID09PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvbHlCb29sOiBaZXJvLWxlbmd0aCBzZWdtZW50IGRldGVjdGVkOyB5b3VyIGVwc2lsb24gaXMgJyArICdwcm9iYWJseSB0b28gc21hbGwgb3IgdG9vIGxhcmdlJyk7CiAgICAgICAgfQoKICAgICAgICAvLyByZW1vdmluZyB0aGUgc3RhdHVzIHdpbGwgY3JlYXRlIHR3byBuZXcgYWRqYWNlbnQgZWRnZXMsIHNvIHdlJ2xsIG5lZWQgdG8gY2hlY2sKICAgICAgICAvLyBmb3IgdGhvc2UKICAgICAgICBpZiAoc3RhdHVzX3Jvb3QuZXhpc3RzKHN0LnByZXYpICYmIHN0YXR1c19yb290LmV4aXN0cyhzdC5uZXh0KSkgY2hlY2tJbnRlcnNlY3Rpb24oc3QucHJldi5ldiwgc3QubmV4dC5ldik7CiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5zdGF0dXNSZW1vdmUoc3QuZXYuc2VnKTsKCiAgICAgICAgLy8gcmVtb3ZlIHRoZSBzdGF0dXMKICAgICAgICBzdC5yZW1vdmUoKTsKCiAgICAgICAgLy8gaWYgd2UndmUgcmVhY2hlZCB0aGlzIHBvaW50LCB3ZSd2ZSBjYWxjdWxhdGVkIGV2ZXJ5dGhpbmcgdGhlcmUgaXMgdG8ga25vdywgc28KICAgICAgICAvLyBzYXZlIHRoZSBzZWdtZW50IGZvciByZXBvcnRpbmcKICAgICAgICBpZiAoIWV2LnByaW1hcnkpIHsKICAgICAgICAgIC8vIG1ha2Ugc3VyZSBgc2VnLm15RmlsbGAgYWN0dWFsbHkgcG9pbnRzIHRvIHRoZSBwcmltYXJ5IHBvbHlnb24gdGhvdWdoCiAgICAgICAgICB2YXIgcyA9IGV2LnNlZy5teUZpbGw7CiAgICAgICAgICBldi5zZWcubXlGaWxsID0gZXYuc2VnLm90aGVyRmlsbDsKICAgICAgICAgIGV2LnNlZy5vdGhlckZpbGwgPSBzOwogICAgICAgIH0KICAgICAgICBzZWdtZW50cy5wdXNoKGV2LnNlZyk7CiAgICAgIH0KCiAgICAgIC8vIHJlbW92ZSB0aGUgZXZlbnQgYW5kIGNvbnRpbnVlCiAgICAgIGV2ZW50X3Jvb3QuZ2V0SGVhZCgpLnJlbW92ZSgpOwogICAgfQogICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5kb25lKCk7CiAgICByZXR1cm4gc2VnbWVudHM7CiAgfQoKICAvLyByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIEFQSSBkZXBlbmRpbmcgb24gd2hhdCB3ZSdyZSBkb2luZwogIGlmICghc2VsZkludGVyc2VjdGlvbikgewogICAgLy8gcGVyZm9ybWluZyBjb21iaW5hdGlvbiBvZiBwb2x5Z29ucywgc28gb25seSBkZWFsIHdpdGggYWxyZWFkeS1wcm9jZXNzZWQgc2VnbWVudHMKICAgIHJldHVybiB7CiAgICAgIGNhbGN1bGF0ZTogZnVuY3Rpb24gKHNlZ21lbnRzMSwgaW52ZXJ0ZWQxLCBzZWdtZW50czIsIGludmVydGVkMikgewogICAgICAgIC8vIHNlZ21lbnRzWCBjb21lIGZyb20gdGhlIHNlbGYtaW50ZXJzZWN0aW9uIEFQSSwgb3IgdGhpcyBBUEkKICAgICAgICAvLyBpbnZlcnRlZFggaXMgd2hldGhlciB3ZSB0cmVhdCB0aGF0IGxpc3Qgb2Ygc2VnbWVudHMgYXMgYW4gaW52ZXJ0ZWQgcG9seWdvbiBvciBub3QKICAgICAgICAvLyByZXR1cm5zIHNlZ21lbnRzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGZ1cnRoZXIgb3BlcmF0aW9ucwogICAgICAgIHNlZ21lbnRzMS5mb3JFYWNoKGZ1bmN0aW9uIChzZWcpIHsKICAgICAgICAgIGV2ZW50QWRkU2VnbWVudChzZWdtZW50Q29weShzZWcuc3RhcnQsIHNlZy5lbmQsIHNlZyksIHRydWUpOwogICAgICAgIH0pOwogICAgICAgIHNlZ21lbnRzMi5mb3JFYWNoKGZ1bmN0aW9uIChzZWcpIHsKICAgICAgICAgIGV2ZW50QWRkU2VnbWVudChzZWdtZW50Q29weShzZWcuc3RhcnQsIHNlZy5lbmQsIHNlZyksIGZhbHNlKTsKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gY2FsY3VsYXRlKGludmVydGVkMSwgaW52ZXJ0ZWQyKTsKICAgICAgfQogICAgfTsKICB9CgogIC8vIG90aGVyd2lzZSwgcGVyZm9ybWluZyBzZWxmLWludGVyc2VjdGlvbiwgc28gZGVhbCB3aXRoIHJlZ2lvbnMKICByZXR1cm4gewogICAgYWRkUmVnaW9uOiBmdW5jdGlvbiAocmVnaW9uKSB7CiAgICAgIC8vIHJlZ2lvbnMgYXJlIGEgbGlzdCBvZiBwb2ludHM6CiAgICAgIC8vICBbIFswLCAwXSwgWzEwMCwgMF0sIFs1MCwgMTAwXSBdCiAgICAgIC8vIHlvdSBjYW4gYWRkIG11bHRpcGxlIHJlZ2lvbnMgYmVmb3JlIHJ1bm5pbmcgY2FsY3VsYXRlCiAgICAgIHZhciBwdDE7CiAgICAgIHZhciBwdDIgPSByZWdpb25bcmVnaW9uLmxlbmd0aCAtIDFdOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lvbi5sZW5ndGg7IGkrKykgewogICAgICAgIHB0MSA9IHB0MjsKICAgICAgICBwdDIgPSByZWdpb25baV07CiAgICAgICAgdmFyIGZvcndhcmQgPSBlcHMucG9pbnRzQ29tcGFyZShwdDEsIHB0Mik7CiAgICAgICAgaWYgKGZvcndhcmQgPT09IDApCiAgICAgICAgICAvLyBwb2ludHMgYXJlIGVxdWFsLCBzbyB3ZSBoYXZlIGEgemVyby1sZW5ndGggc2VnbWVudAogICAgICAgICAgY29udGludWU7IC8vIGp1c3Qgc2tpcCBpdAoKICAgICAgICBldmVudEFkZFNlZ21lbnQoc2VnbWVudE5ldyhmb3J3YXJkIDwgMCA/IHB0MSA6IHB0MiwgZm9yd2FyZCA8IDAgPyBwdDIgOiBwdDEpLCB0cnVlKTsKICAgICAgfQogICAgfSwKICAgIGNhbGN1bGF0ZTogZnVuY3Rpb24gKGludmVydGVkKSB7CiAgICAgIC8vIGlzIHRoZSBwb2x5Z29uIGludmVydGVkPwogICAgICAvLyByZXR1cm5zIHNlZ21lbnRzCiAgICAgIHJldHVybiBjYWxjdWxhdGUoaW52ZXJ0ZWQsIGZhbHNlKTsKICAgIH0KICB9Owp9CnZhciBpbnRlcnNlY3RlciA9IEludGVyc2VjdGVyJDE7CgovLyAoYykgQ29weXJpZ2h0IDIwMTYsIFNlYW4gQ29ubmVsbHkgKEB2b2lkcWspLCBodHRwOi8vc3ludGhldGkuY2MKLy8gTUlUIExpY2Vuc2UKLy8gUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKCi8vCi8vIGNvbnZlcnRzIGEgbGlzdCBvZiBzZWdtZW50cyBpbnRvIGEgbGlzdCBvZiByZWdpb25zLCB3aGlsZSBhbHNvIHJlbW92aW5nIHVubmVjZXNzYXJ5IHZlcnRpY2llcwovLwoKZnVuY3Rpb24gU2VnbWVudENoYWluZXIkMShzZWdtZW50cywgZXBzLCBidWlsZExvZykgewogIHZhciBjaGFpbnMgPSBbXTsKICB2YXIgcmVnaW9ucyA9IFtdOwogIHNlZ21lbnRzLmZvckVhY2goZnVuY3Rpb24gKHNlZykgewogICAgdmFyIHB0MSA9IHNlZy5zdGFydDsKICAgIHZhciBwdDIgPSBzZWcuZW5kOwogICAgaWYgKGVwcy5wb2ludHNTYW1lKHB0MSwgcHQyKSkgewogICAgICBjb25zb2xlLndhcm4oJ1BvbHlCb29sOiBXYXJuaW5nOiBaZXJvLWxlbmd0aCBzZWdtZW50IGRldGVjdGVkOyB5b3VyIGVwc2lsb24gaXMgJyArICdwcm9iYWJseSB0b28gc21hbGwgb3IgdG9vIGxhcmdlJyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5TdGFydChzZWcpOwoKICAgIC8vIHNlYXJjaCBmb3IgdHdvIGNoYWlucyB0aGF0IHRoaXMgc2VnbWVudCBtYXRjaGVzCiAgICB2YXIgZmlyc3RfbWF0Y2ggPSB7CiAgICAgIGluZGV4OiAwLAogICAgICBtYXRjaGVzX2hlYWQ6IGZhbHNlLAogICAgICBtYXRjaGVzX3B0MTogZmFsc2UKICAgIH07CiAgICB2YXIgc2Vjb25kX21hdGNoID0gewogICAgICBpbmRleDogMCwKICAgICAgbWF0Y2hlc19oZWFkOiBmYWxzZSwKICAgICAgbWF0Y2hlc19wdDE6IGZhbHNlCiAgICB9OwogICAgdmFyIG5leHRfbWF0Y2ggPSBmaXJzdF9tYXRjaDsKICAgIGZ1bmN0aW9uIHNldE1hdGNoKGluZGV4LCBtYXRjaGVzX2hlYWQsIG1hdGNoZXNfcHQxKSB7CiAgICAgIC8vIHJldHVybiB0cnVlIGlmIHdlJ3ZlIG1hdGNoZWQgdHdpY2UKICAgICAgbmV4dF9tYXRjaC5pbmRleCA9IGluZGV4OwogICAgICBuZXh0X21hdGNoLm1hdGNoZXNfaGVhZCA9IG1hdGNoZXNfaGVhZDsKICAgICAgbmV4dF9tYXRjaC5tYXRjaGVzX3B0MSA9IG1hdGNoZXNfcHQxOwogICAgICBpZiAobmV4dF9tYXRjaCA9PT0gZmlyc3RfbWF0Y2gpIHsKICAgICAgICBuZXh0X21hdGNoID0gc2Vjb25kX21hdGNoOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBuZXh0X21hdGNoID0gbnVsbDsKICAgICAgcmV0dXJuIHRydWU7IC8vIHdlJ3ZlIG1hdGNoZWQgdHdpY2UsIHdlJ3JlIGRvbmUgaGVyZQogICAgfQoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hhaW5zLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBjaGFpbiA9IGNoYWluc1tpXTsKICAgICAgdmFyIGhlYWQgPSBjaGFpblswXTsKICAgICAgY2hhaW5bMV07CiAgICAgIHZhciB0YWlsID0gY2hhaW5bY2hhaW4ubGVuZ3RoIC0gMV07CiAgICAgIGNoYWluW2NoYWluLmxlbmd0aCAtIDJdOwogICAgICBpZiAoZXBzLnBvaW50c1NhbWUoaGVhZCwgcHQxKSkgewogICAgICAgIGlmIChzZXRNYXRjaChpLCB0cnVlLCB0cnVlKSkgYnJlYWs7CiAgICAgIH0gZWxzZSBpZiAoZXBzLnBvaW50c1NhbWUoaGVhZCwgcHQyKSkgewogICAgICAgIGlmIChzZXRNYXRjaChpLCB0cnVlLCBmYWxzZSkpIGJyZWFrOwogICAgICB9IGVsc2UgaWYgKGVwcy5wb2ludHNTYW1lKHRhaWwsIHB0MSkpIHsKICAgICAgICBpZiAoc2V0TWF0Y2goaSwgZmFsc2UsIHRydWUpKSBicmVhazsKICAgICAgfSBlbHNlIGlmIChlcHMucG9pbnRzU2FtZSh0YWlsLCBwdDIpKSB7CiAgICAgICAgaWYgKHNldE1hdGNoKGksIGZhbHNlLCBmYWxzZSkpIGJyZWFrOwogICAgICB9CiAgICB9CiAgICBpZiAobmV4dF9tYXRjaCA9PT0gZmlyc3RfbWF0Y2gpIHsKICAgICAgLy8gd2UgZGlkbid0IG1hdGNoIGFueXRoaW5nLCBzbyBjcmVhdGUgYSBuZXcgY2hhaW4KICAgICAgY2hhaW5zLnB1c2goW3B0MSwgcHQyXSk7CiAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5OZXcocHQxLCBwdDIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobmV4dF9tYXRjaCA9PT0gc2Vjb25kX21hdGNoKSB7CiAgICAgIC8vIHdlIG1hdGNoZWQgYSBzaW5nbGUgY2hhaW4KCiAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5NYXRjaChmaXJzdF9tYXRjaC5pbmRleCk7CgogICAgICAvLyBhZGQgdGhlIG90aGVyIHBvaW50IHRvIHRoZSBhcHBvcnByaWF0ZSBlbmQsIGFuZCBjaGVjayB0byBzZWUgaWYgd2UndmUgY2xvc2VkIHRoZQogICAgICAvLyBjaGFpbiBpbnRvIGEgbG9vcAoKICAgICAgdmFyIGluZGV4ID0gZmlyc3RfbWF0Y2guaW5kZXg7CiAgICAgIHZhciBwdCA9IGZpcnN0X21hdGNoLm1hdGNoZXNfcHQxID8gcHQyIDogcHQxOyAvLyBpZiB3ZSBtYXRjaGVkIHB0MSwgdGhlbiB3ZSBhZGQgcHQyLCBldGMKICAgICAgdmFyIGFkZFRvSGVhZCA9IGZpcnN0X21hdGNoLm1hdGNoZXNfaGVhZDsgLy8gaWYgd2UgbWF0Y2hlZCBhdCBoZWFkLCB0aGVuIGFkZCB0byB0aGUgaGVhZAoKICAgICAgdmFyIGNoYWluID0gY2hhaW5zW2luZGV4XTsKICAgICAgdmFyIGdyb3cgPSBhZGRUb0hlYWQgPyBjaGFpblswXSA6IGNoYWluW2NoYWluLmxlbmd0aCAtIDFdOwogICAgICB2YXIgZ3JvdzIgPSBhZGRUb0hlYWQgPyBjaGFpblsxXSA6IGNoYWluW2NoYWluLmxlbmd0aCAtIDJdOwogICAgICB2YXIgb3BwbyA9IGFkZFRvSGVhZCA/IGNoYWluW2NoYWluLmxlbmd0aCAtIDFdIDogY2hhaW5bMF07CiAgICAgIHZhciBvcHBvMiA9IGFkZFRvSGVhZCA/IGNoYWluW2NoYWluLmxlbmd0aCAtIDJdIDogY2hhaW5bMV07CiAgICAgIGlmIChlcHMucG9pbnRzQ29sbGluZWFyKGdyb3cyLCBncm93LCBwdCkpIHsKICAgICAgICAvLyBncm93IGlzbid0IG5lZWRlZCBiZWNhdXNlIGl0J3MgZGlyZWN0bHkgYmV0d2VlbiBncm93MiBhbmQgcHQ6CiAgICAgICAgLy8gZ3JvdzIgLS0tZ3Jvdy0tLT4gcHQKICAgICAgICBpZiAoYWRkVG9IZWFkKSB7CiAgICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmVtb3ZlSGVhZChmaXJzdF9tYXRjaC5pbmRleCwgcHQpOwogICAgICAgICAgY2hhaW4uc2hpZnQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJlbW92ZVRhaWwoZmlyc3RfbWF0Y2guaW5kZXgsIHB0KTsKICAgICAgICAgIGNoYWluLnBvcCgpOwogICAgICAgIH0KICAgICAgICBncm93ID0gZ3JvdzI7IC8vIG9sZCBncm93IGlzIGdvbmUuLi4gbmV3IGdyb3cgaXMgd2hhdCBncm93MiB3YXMKICAgICAgfQoKICAgICAgaWYgKGVwcy5wb2ludHNTYW1lKG9wcG8sIHB0KSkgewogICAgICAgIC8vIHdlJ3JlIGNsb3NpbmcgdGhlIGxvb3AsIHNvIHJlbW92ZSBjaGFpbiBmcm9tIGNoYWlucwogICAgICAgIGNoYWlucy5zcGxpY2UoaW5kZXgsIDEpOwogICAgICAgIGlmIChlcHMucG9pbnRzQ29sbGluZWFyKG9wcG8yLCBvcHBvLCBncm93KSkgewogICAgICAgICAgLy8gb3BwbyBpc24ndCBuZWVkZWQgYmVjYXVzZSBpdCdzIGRpcmVjdGx5IGJldHdlZW4gb3BwbzIgYW5kIGdyb3c6CiAgICAgICAgICAvLyBvcHBvMiAtLS1vcHBvLS0tPmdyb3cKICAgICAgICAgIGlmIChhZGRUb0hlYWQpIHsKICAgICAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJlbW92ZVRhaWwoZmlyc3RfbWF0Y2guaW5kZXgsIGdyb3cpOwogICAgICAgICAgICBjaGFpbi5wb3AoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVIZWFkKGZpcnN0X21hdGNoLmluZGV4LCBncm93KTsKICAgICAgICAgICAgY2hhaW4uc2hpZnQoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbkNsb3NlKGZpcnN0X21hdGNoLmluZGV4KTsKCiAgICAgICAgLy8gd2UgaGF2ZSBhIGNsb3NlZCBjaGFpbiEKICAgICAgICByZWdpb25zLnB1c2goY2hhaW4pOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgLy8gbm90IGNsb3NpbmcgYSBsb29wLCBzbyBqdXN0IGFkZCBpdCB0byB0aGUgYXBwb3JwcmlhdGUgc2lkZQogICAgICBpZiAoYWRkVG9IZWFkKSB7CiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbkFkZEhlYWQoZmlyc3RfbWF0Y2guaW5kZXgsIHB0KTsKICAgICAgICBjaGFpbi51bnNoaWZ0KHB0KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluQWRkVGFpbChmaXJzdF9tYXRjaC5pbmRleCwgcHQpOwogICAgICAgIGNoYWluLnB1c2gocHQpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBvdGhlcndpc2UsIHdlIG1hdGNoZWQgdHdvIGNoYWlucywgc28gd2UgbmVlZCB0byBjb21iaW5lIHRob3NlIGNoYWlucyB0b2dldGhlcgoKICAgIGZ1bmN0aW9uIHJldmVyc2VDaGFpbihpbmRleCkgewogICAgICBpZiAoYnVpbGRMb2cpIGJ1aWxkTG9nLmNoYWluUmV2ZXJzZShpbmRleCk7CiAgICAgIGNoYWluc1tpbmRleF0ucmV2ZXJzZSgpOyAvLyBnZWUsIHRoYXQncyBlYXN5CiAgICB9CgogICAgZnVuY3Rpb24gYXBwZW5kQ2hhaW4oaW5kZXgxLCBpbmRleDIpIHsKICAgICAgLy8gaW5kZXgxIGdldHMgaW5kZXgyIGFwcGVuZGVkIHRvIGl0LCBhbmQgaW5kZXgyIGlzIHJlbW92ZWQKICAgICAgdmFyIGNoYWluMSA9IGNoYWluc1tpbmRleDFdOwogICAgICB2YXIgY2hhaW4yID0gY2hhaW5zW2luZGV4Ml07CiAgICAgIHZhciB0YWlsID0gY2hhaW4xW2NoYWluMS5sZW5ndGggLSAxXTsKICAgICAgdmFyIHRhaWwyID0gY2hhaW4xW2NoYWluMS5sZW5ndGggLSAyXTsKICAgICAgdmFyIGhlYWQgPSBjaGFpbjJbMF07CiAgICAgIHZhciBoZWFkMiA9IGNoYWluMlsxXTsKICAgICAgaWYgKGVwcy5wb2ludHNDb2xsaW5lYXIodGFpbDIsIHRhaWwsIGhlYWQpKSB7CiAgICAgICAgLy8gdGFpbCBpc24ndCBuZWVkZWQgYmVjYXVzZSBpdCdzIGRpcmVjdGx5IGJldHdlZW4gdGFpbDIgYW5kIGhlYWQKICAgICAgICAvLyB0YWlsMiAtLS10YWlsLS0tPiBoZWFkCiAgICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpblJlbW92ZVRhaWwoaW5kZXgxLCB0YWlsKTsKICAgICAgICBjaGFpbjEucG9wKCk7CiAgICAgICAgdGFpbCA9IHRhaWwyOyAvLyBvbGQgdGFpbCBpcyBnb25lLi4uIG5ldyB0YWlsIGlzIHdoYXQgdGFpbDIgd2FzCiAgICAgIH0KCiAgICAgIGlmIChlcHMucG9pbnRzQ29sbGluZWFyKHRhaWwsIGhlYWQsIGhlYWQyKSkgewogICAgICAgIC8vIGhlYWQgaXNuJ3QgbmVlZGVkIGJlY2F1c2UgaXQncyBkaXJlY3RseSBiZXR3ZWVuIHRhaWwgYW5kIGhlYWQyCiAgICAgICAgLy8gdGFpbCAtLS1oZWFkLS0tPiBoZWFkMgogICAgICAgIGlmIChidWlsZExvZykgYnVpbGRMb2cuY2hhaW5SZW1vdmVIZWFkKGluZGV4MiwgaGVhZCk7CiAgICAgICAgY2hhaW4yLnNoaWZ0KCk7CiAgICAgIH0KICAgICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbkpvaW4oaW5kZXgxLCBpbmRleDIpOwogICAgICBjaGFpbnNbaW5kZXgxXSA9IGNoYWluMS5jb25jYXQoY2hhaW4yKTsKICAgICAgY2hhaW5zLnNwbGljZShpbmRleDIsIDEpOwogICAgfQogICAgdmFyIEYgPSBmaXJzdF9tYXRjaC5pbmRleDsKICAgIHZhciBTID0gc2Vjb25kX21hdGNoLmluZGV4OwogICAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5jaGFpbkNvbm5lY3QoRiwgUyk7CiAgICB2YXIgcmV2ZXJzZUYgPSBjaGFpbnNbRl0ubGVuZ3RoIDwgY2hhaW5zW1NdLmxlbmd0aDsgLy8gcmV2ZXJzZSB0aGUgc2hvcnRlciBjaGFpbiwgaWYgbmVlZGVkCiAgICBpZiAoZmlyc3RfbWF0Y2gubWF0Y2hlc19oZWFkKSB7CiAgICAgIGlmIChzZWNvbmRfbWF0Y2gubWF0Y2hlc19oZWFkKSB7CiAgICAgICAgaWYgKHJldmVyc2VGKSB7CiAgICAgICAgICAvLyA8PDw8IEYgPDw8PCAtLS0gPj4+PiBTID4+Pj4KICAgICAgICAgIHJldmVyc2VDaGFpbihGKTsKICAgICAgICAgIC8vID4+Pj4gRiA+Pj4+IC0tLSA+Pj4+IFMgPj4+PgogICAgICAgICAgYXBwZW5kQ2hhaW4oRiwgUyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIDw8PDwgRiA8PDw8IC0tLSA+Pj4+IFMgPj4+PgogICAgICAgICAgcmV2ZXJzZUNoYWluKFMpOwogICAgICAgICAgLy8gPDw8PCBGIDw8PDwgLS0tIDw8PDwgUyA8PDw8ICAgbG9naWNhbGx5IHNhbWUgYXM6CiAgICAgICAgICAvLyA+Pj4+IFMgPj4+PiAtLS0gPj4+PiBGID4+Pj4KICAgICAgICAgIGFwcGVuZENoYWluKFMsIEYpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyA8PDw8IEYgPDw8PCAtLS0gPDw8PCBTIDw8PDwgICBsb2dpY2FsbHkgc2FtZSBhczoKICAgICAgICAvLyA+Pj4+IFMgPj4+PiAtLS0gPj4+PiBGID4+Pj4KICAgICAgICBhcHBlbmRDaGFpbihTLCBGKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgaWYgKHNlY29uZF9tYXRjaC5tYXRjaGVzX2hlYWQpIHsKICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPj4+PiBTID4+Pj4KICAgICAgICBhcHBlbmRDaGFpbihGLCBTKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAocmV2ZXJzZUYpIHsKICAgICAgICAgIC8vID4+Pj4gRiA+Pj4+IC0tLSA8PDw8IFMgPDw8PAogICAgICAgICAgcmV2ZXJzZUNoYWluKEYpOwogICAgICAgICAgLy8gPDw8PCBGIDw8PDwgLS0tIDw8PDwgUyA8PDw8ICAgbG9naWNhbGx5IHNhbWUgYXM6CiAgICAgICAgICAvLyA+Pj4+IFMgPj4+PiAtLS0gPj4+PiBGID4+Pj4KICAgICAgICAgIGFwcGVuZENoYWluKFMsIEYpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyA+Pj4+IEYgPj4+PiAtLS0gPDw8PCBTIDw8PDwKICAgICAgICAgIHJldmVyc2VDaGFpbihTKTsKICAgICAgICAgIC8vID4+Pj4gRiA+Pj4+IC0tLSA+Pj4+IFMgPj4+PgogICAgICAgICAgYXBwZW5kQ2hhaW4oRiwgUyk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfSk7CiAgcmV0dXJuIHJlZ2lvbnM7Cn0KdmFyIHNlZ21lbnRDaGFpbmVyID0gU2VnbWVudENoYWluZXIkMTsKCi8vIChjKSBDb3B5cmlnaHQgMjAxNiwgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwovLyBNSVQgTGljZW5zZQovLyBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwoKLy8KLy8gZmlsdGVyIGEgbGlzdCBvZiBzZWdtZW50cyBiYXNlZCBvbiBib29sZWFuIG9wZXJhdGlvbnMKLy8KCmZ1bmN0aW9uIHNlbGVjdChzZWdtZW50cywgc2VsZWN0aW9uLCBidWlsZExvZykgewogIHZhciByZXN1bHQgPSBbXTsKICBzZWdtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzZWcpIHsKICAgIHZhciBpbmRleCA9IChzZWcubXlGaWxsLmFib3ZlID8gOCA6IDApICsgKHNlZy5teUZpbGwuYmVsb3cgPyA0IDogMCkgKyAoc2VnLm90aGVyRmlsbCAmJiBzZWcub3RoZXJGaWxsLmFib3ZlID8gMiA6IDApICsgKHNlZy5vdGhlckZpbGwgJiYgc2VnLm90aGVyRmlsbC5iZWxvdyA/IDEgOiAwKTsKICAgIGlmIChzZWxlY3Rpb25baW5kZXhdICE9PSAwKSB7CiAgICAgIC8vIGNvcHkgdGhlIHNlZ21lbnQgdG8gdGhlIHJlc3VsdHMsIHdoaWxlIGFsc28gY2FsY3VsYXRpbmcgdGhlIGZpbGwgc3RhdHVzCiAgICAgIHJlc3VsdC5wdXNoKHsKICAgICAgICBpZDogYnVpbGRMb2cgPyBidWlsZExvZy5zZWdtZW50SWQoKSA6IC0xLAogICAgICAgIHN0YXJ0OiBzZWcuc3RhcnQsCiAgICAgICAgZW5kOiBzZWcuZW5kLAogICAgICAgIG15RmlsbDogewogICAgICAgICAgYWJvdmU6IHNlbGVjdGlvbltpbmRleF0gPT09IDEsCiAgICAgICAgICAvLyAxIGlmIGZpbGxlZCBhYm92ZQogICAgICAgICAgYmVsb3c6IHNlbGVjdGlvbltpbmRleF0gPT09IDIgLy8gMiBpZiBmaWxsZWQgYmVsb3cKICAgICAgICB9LAoKICAgICAgICBvdGhlckZpbGw6IG51bGwKICAgICAgfSk7CiAgICB9CiAgfSk7CiAgaWYgKGJ1aWxkTG9nKSBidWlsZExvZy5zZWxlY3RlZChyZXN1bHQpOwogIHJldHVybiByZXN1bHQ7Cn0KdmFyIFNlZ21lbnRTZWxlY3RvciQxID0gewogIHVuaW9uOiBmdW5jdGlvbiAoc2VnbWVudHMsIGJ1aWxkTG9nKSB7CiAgICAvLyBwcmltYXJ5IHwgc2Vjb25kYXJ5CiAgICAvLyBhYm92ZTEgYmVsb3cxIGFib3ZlMiBiZWxvdzIgICAgS2VlcD8gICAgICAgICAgICAgICBWYWx1ZQogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICByZXR1cm4gc2VsZWN0KHNlZ21lbnRzLCBbMCwgMiwgMSwgMCwgMiwgMiwgMCwgMCwgMSwgMCwgMSwgMCwgMCwgMCwgMCwgMF0sIGJ1aWxkTG9nKTsKICB9LAogIGludGVyc2VjdDogZnVuY3Rpb24gKHNlZ21lbnRzLCBidWlsZExvZykgewogICAgLy8gcHJpbWFyeSAmIHNlY29uZGFyeQogICAgLy8gYWJvdmUxIGJlbG93MSBhYm92ZTIgYmVsb3cyICAgIEtlZXA/ICAgICAgICAgICAgICAgVmFsdWUKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgcmV0dXJuIHNlbGVjdChzZWdtZW50cywgWzAsIDAsIDAsIDAsIDAsIDIsIDAsIDIsIDAsIDAsIDEsIDEsIDAsIDIsIDEsIDBdLCBidWlsZExvZyk7CiAgfSwKICBkaWZmZXJlbmNlOiBmdW5jdGlvbiAoc2VnbWVudHMsIGJ1aWxkTG9nKSB7CiAgICAvLyBwcmltYXJ5IC0gc2Vjb25kYXJ5CiAgICAvLyBhYm92ZTEgYmVsb3cxIGFib3ZlMiBiZWxvdzIgICAgS2VlcD8gICAgICAgICAgICAgICBWYWx1ZQogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICByZXR1cm4gc2VsZWN0KHNlZ21lbnRzLCBbMCwgMCwgMCwgMCwgMiwgMCwgMiwgMCwgMSwgMSwgMCwgMCwgMCwgMSwgMiwgMF0sIGJ1aWxkTG9nKTsKICB9LAogIGRpZmZlcmVuY2VSZXY6IGZ1bmN0aW9uIChzZWdtZW50cywgYnVpbGRMb2cpIHsKICAgIC8vIHNlY29uZGFyeSAtIHByaW1hcnkKICAgIC8vIGFib3ZlMSBiZWxvdzEgYWJvdmUyIGJlbG93MiAgICBLZWVwPyAgICAgICAgICAgICAgIFZhbHVlCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAwICAgICAgMCAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMCAgID0+ICAgeWVzIGZpbGxlZCBhYm92ZSAgICAxCiAgICAvLyAgICAwICAgICAgMCAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDAgICAgICAxICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgeWVzIGZpbGxlZCBiZWxvdyAgICAyCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIHJldHVybiBzZWxlY3Qoc2VnbWVudHMsIFswLCAyLCAxLCAwLCAwLCAwLCAxLCAxLCAwLCAyLCAwLCAyLCAwLCAwLCAwLCAwXSwgYnVpbGRMb2cpOwogIH0sCiAgeG9yOiBmdW5jdGlvbiAoc2VnbWVudHMsIGJ1aWxkTG9nKSB7CiAgICAvLyBwcmltYXJ5IF4gc2Vjb25kYXJ5CiAgICAvLyBhYm92ZTEgYmVsb3cxIGFib3ZlMiBiZWxvdzIgICAgS2VlcD8gICAgICAgICAgICAgICBWYWx1ZQogICAgLy8gICAgMCAgICAgIDAgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMCAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAwICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMCAgICAgIDAgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDAgICAgICAwICAgPT4gICB5ZXMgZmlsbGVkIGJlbG93ICAgIDIKICAgIC8vICAgIDAgICAgICAxICAgICAgMCAgICAgIDEgICA9PiAgIG5vICAgICAgICAgICAgICAgICAgMAogICAgLy8gICAgMCAgICAgIDEgICAgICAxICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAwICAgICAgMSAgICAgIDEgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAwICAgICAgMCAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYWJvdmUgICAgMQogICAgLy8gICAgMSAgICAgIDAgICAgICAwICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMCAgICAgIDEgICAgICAwICAgPT4gICBubyAgICAgICAgICAgICAgICAgIDAKICAgIC8vICAgIDEgICAgICAwICAgICAgMSAgICAgIDEgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDEgICAgICAwICAgICAgMCAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICAvLyAgICAxICAgICAgMSAgICAgIDAgICAgICAxICAgPT4gICB5ZXMgZmlsbGVkIGFib3ZlICAgIDEKICAgIC8vICAgIDEgICAgICAxICAgICAgMSAgICAgIDAgICA9PiAgIHllcyBmaWxsZWQgYmVsb3cgICAgMgogICAgLy8gICAgMSAgICAgIDEgICAgICAxICAgICAgMSAgID0+ICAgbm8gICAgICAgICAgICAgICAgICAwCiAgICByZXR1cm4gc2VsZWN0KHNlZ21lbnRzLCBbMCwgMiwgMSwgMCwgMiwgMCwgMCwgMSwgMSwgMCwgMCwgMiwgMCwgMSwgMiwgMF0sIGJ1aWxkTG9nKTsKICB9Cn07CnZhciBzZWdtZW50U2VsZWN0b3IgPSBTZWdtZW50U2VsZWN0b3IkMTsKCi8vIChjKSBDb3B5cmlnaHQgMjAxNywgU2VhbiBDb25uZWxseSAoQHZvaWRxayksIGh0dHA6Ly9zeW50aGV0aS5jYwovLyBNSVQgTGljZW5zZQovLyBQcm9qZWN0IEhvbWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92b2lkcWsvcG9seWJvb2xqcwoKLy8KLy8gY29udmVydCBiZXR3ZWVuIFBvbHlCb29sIHBvbHlnb24gZm9ybWF0IGFuZCBHZW9KU09OIGZvcm1hdHMgKFBvbHlnb24gYW5kIE11bHRpUG9seWdvbikKLy8KCnZhciBHZW9KU09OJDEgPSB7CiAgLy8gY29udmVydCBhIEdlb0pTT04gb2JqZWN0IHRvIGEgUG9seUJvb2wgcG9seWdvbgogIHRvUG9seWdvbjogZnVuY3Rpb24gKFBvbHlCb29sLCBnZW9qc29uKSB7CiAgICAvLyBjb252ZXJ0cyBsaXN0IG9mIExpbmVTdHJpbmcncyB0byBzZWdtZW50cwogICAgZnVuY3Rpb24gR2VvUG9seShjb29yZHMpIHsKICAgICAgLy8gY2hlY2sgZm9yIGVtcHR5IGNvb3JkcwogICAgICBpZiAoY29vcmRzLmxlbmd0aCA8PSAwKSByZXR1cm4gUG9seUJvb2wuc2VnbWVudHMoewogICAgICAgIGludmVydGVkOiBmYWxzZSwKICAgICAgICByZWdpb25zOiBbXQogICAgICB9KTsKCiAgICAgIC8vIGNvbnZlcnQgTGluZVN0cmluZyB0byBzZWdtZW50cwogICAgICBmdW5jdGlvbiBMaW5lU3RyaW5nKGxzKSB7CiAgICAgICAgLy8gcmVtb3ZlIHRhaWwgd2hpY2ggc2hvdWxkIGJlIHRoZSBzYW1lIGFzIGhlYWQKICAgICAgICB2YXIgcmVnID0gbHMuc2xpY2UoMCwgbHMubGVuZ3RoIC0gMSk7CiAgICAgICAgcmV0dXJuIFBvbHlCb29sLnNlZ21lbnRzKHsKICAgICAgICAgIGludmVydGVkOiBmYWxzZSwKICAgICAgICAgIHJlZ2lvbnM6IFtyZWddCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIC8vIHRoZSBmaXJzdCBMaW5lU3RyaW5nIGlzIGNvbnNpZGVyZWQgdGhlIG91dHNpZGUKICAgICAgdmFyIG91dCA9IExpbmVTdHJpbmcoY29vcmRzWzBdKTsKCiAgICAgIC8vIHRoZSByZXN0IG9mIHRoZSBMaW5lU3RyaW5ncyBhcmUgY29uc2lkZXJlZCBpbnRlcmlvciBob2xlcywgc28gc3VidHJhY3QgdGhlbSBmcm9tIHRoZQogICAgICAvLyBjdXJyZW50IHJlc3VsdAogICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykgb3V0ID0gUG9seUJvb2wuc2VsZWN0RGlmZmVyZW5jZShQb2x5Qm9vbC5jb21iaW5lKG91dCwgTGluZVN0cmluZyhjb29yZHNbaV0pKSk7CiAgICAgIHJldHVybiBvdXQ7CiAgICB9CiAgICBpZiAoZ2VvanNvbi50eXBlID09PSAnUG9seWdvbicpIHsKICAgICAgLy8gc2luZ2xlIHBvbHlnb24sIHNvIGp1c3QgY29udmVydCBpdCBhbmQgd2UncmUgZG9uZQogICAgICByZXR1cm4gUG9seUJvb2wucG9seWdvbihHZW9Qb2x5KGdlb2pzb24uY29vcmRpbmF0ZXMpKTsKICAgIH0gZWxzZSBpZiAoZ2VvanNvbi50eXBlID09PSAnTXVsdGlQb2x5Z29uJykgewogICAgICAvLyBtdWx0aXBsZSBwb2x5Z29ucywgc28gdW5pb24gYWxsIHRoZSBwb2x5Z29ucyB0b2dldGhlcgogICAgICB2YXIgb3V0ID0gUG9seUJvb2wuc2VnbWVudHMoewogICAgICAgIGludmVydGVkOiBmYWxzZSwKICAgICAgICByZWdpb25zOiBbXQogICAgICB9KTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnZW9qc29uLmNvb3JkaW5hdGVzLmxlbmd0aDsgaSsrKSBvdXQgPSBQb2x5Qm9vbC5zZWxlY3RVbmlvbihQb2x5Qm9vbC5jb21iaW5lKG91dCwgR2VvUG9seShnZW9qc29uLmNvb3JkaW5hdGVzW2ldKSkpOwogICAgICByZXR1cm4gUG9seUJvb2wucG9seWdvbihvdXQpOwogICAgfQogICAgdGhyb3cgbmV3IEVycm9yKCdQb2x5Qm9vbDogQ2Fubm90IGNvbnZlcnQgR2VvSlNPTiBvYmplY3QgdG8gUG9seUJvb2wgcG9seWdvbicpOwogIH0sCiAgLy8gY29udmVydCBhIFBvbHlCb29sIHBvbHlnb24gdG8gYSBHZW9KU09OIG9iamVjdAogIGZyb21Qb2x5Z29uOiBmdW5jdGlvbiAoUG9seUJvb2wsIGVwcywgcG9seSkgewogICAgLy8gbWFrZSBzdXJlIG91dCBwb2x5Z29uIGlzIGNsZWFuCiAgICBwb2x5ID0gUG9seUJvb2wucG9seWdvbihQb2x5Qm9vbC5zZWdtZW50cyhwb2x5KSk7CgogICAgLy8gdGVzdCBpZiByMSBpcyBpbnNpZGUgcjIKICAgIGZ1bmN0aW9uIHJlZ2lvbkluc2lkZVJlZ2lvbihyMSwgcjIpIHsKICAgICAgLy8gd2UncmUgZ3VhcmFudGVlZCBubyBsaW5lcyBpbnRlcnNlY3QgKGJlY2F1c2UgdGhlIHBvbHlnb24gaXMgY2xlYW4pLCBidXQgYSB2ZXJ0ZXgKICAgICAgLy8gY291bGQgYmUgb24gdGhlIGVkZ2UgLS0gc28gd2UganVzdCBhdmVyYWdlIHB0WzBdIGFuZCBwdFsxXSB0byBwcm9kdWNlIGEgcG9pbnQgb24gdGhlCiAgICAgIC8vIGVkZ2Ugb2YgdGhlIGZpcnN0IGxpbmUsIHdoaWNoIGNhbm5vdCBiZSBvbiBhbiBlZGdlCiAgICAgIHJldHVybiBlcHMucG9pbnRJbnNpZGVSZWdpb24oWyhyMVswXVswXSArIHIxWzFdWzBdKSAqIDAuNSwgKHIxWzBdWzFdICsgcjFbMV1bMV0pICogMC41XSwgcjIpOwogICAgfQoKICAgIC8vIGNhbGN1bGF0ZSBpbnNpZGUgaGVpcmFyY2h5CiAgICAvLwogICAgLy8gIF9fX19fX19fX19fX19fX19fX19fXyAgIF9fX19fX18gICAgcm9vdHMgLT4gQSAgICAgICAtPiBGCiAgICAvLyB8ICAgICAgICAgIEEgICAgICAgICAgfCB8ICAgRiAgIHwgICAgICAgICAgICB8ICAgICAgICAgIHwKICAgIC8vIHwgIF9fX19fX18gICBfX19fX19fICB8IHwgIF9fXyAgfCAgICAgICAgICAgICstLSBCICAgICAgKy0tIEcKICAgIC8vIHwgfCAgIEIgICB8IHwgICBDICAgfCB8IHwgfCAgIHwgfCAgICAgICAgICAgIHwgICB8CiAgICAvLyB8IHwgIF9fXyAgfCB8ICBfX18gIHwgfCB8IHwgICB8IHwgICAgICAgICAgICB8ICAgKy0tIEQKICAgIC8vIHwgfCB8IEQgfCB8IHwgfCBFIHwgfCB8IHwgfCBHIHwgfCAgICAgICAgICAgIHwKICAgIC8vIHwgfCB8X19ffCB8IHwgfF9fX3wgfCB8IHwgfCAgIHwgfCAgICAgICAgICAgICstLSBDCiAgICAvLyB8IHxfX19fX19ffCB8X19fX19fX3wgfCB8IHxfX198IHwgICAgICAgICAgICAgICAgfAogICAgLy8gfF9fX19fX19fX19fX19fX19fX19fX3wgfF9fX19fX198ICAgICAgICAgICAgICAgICstLSBFCgogICAgZnVuY3Rpb24gbmV3Tm9kZShyZWdpb24pIHsKICAgICAgcmV0dXJuIHsKICAgICAgICByZWdpb246IHJlZ2lvbiwKICAgICAgICBjaGlsZHJlbjogW10KICAgICAgfTsKICAgIH0KICAgIHZhciByb290cyA9IG5ld05vZGUobnVsbCk7CiAgICBmdW5jdGlvbiBhZGRDaGlsZChyb290LCByZWdpb24pIHsKICAgICAgLy8gZmlyc3QgY2hlY2sgaWYgd2UncmUgaW5zaWRlIGFueSBjaGlsZHJlbgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJvb3QuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgY2hpbGQgPSByb290LmNoaWxkcmVuW2ldOwogICAgICAgIGlmIChyZWdpb25JbnNpZGVSZWdpb24ocmVnaW9uLCBjaGlsZC5yZWdpb24pKSB7CiAgICAgICAgICAvLyB3ZSBhcmUsIHNvIGluc2VydCBpbnNpZGUgdGhlbSBpbnN0ZWFkCiAgICAgICAgICBhZGRDaGlsZChjaGlsZCwgcmVnaW9uKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIG5vdCBpbnNpZGUgYW55IGNoaWxkcmVuLCBzbyBjaGVjayB0byBzZWUgaWYgYW55IGNoaWxkcmVuIGFyZSBpbnNpZGUgdXMKICAgICAgdmFyIG5vZGUgPSBuZXdOb2RlKHJlZ2lvbik7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcm9vdC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBjaGlsZCA9IHJvb3QuY2hpbGRyZW5baV07CiAgICAgICAgaWYgKHJlZ2lvbkluc2lkZVJlZ2lvbihjaGlsZC5yZWdpb24sIHJlZ2lvbikpIHsKICAgICAgICAgIC8vIG9vcHMuLi4gbW92ZSB0aGUgY2hpbGQgYmVuZWF0aCB1cywgYW5kIHJlbW92ZSB0aGVtIGZyb20gcm9vdAogICAgICAgICAgbm9kZS5jaGlsZHJlbi5wdXNoKGNoaWxkKTsKICAgICAgICAgIHJvb3QuY2hpbGRyZW4uc3BsaWNlKGksIDEpOwogICAgICAgICAgaS0tOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm93IHdlIGNhbiBhZGQgb3Vyc2VsdmVzCiAgICAgIHJvb3QuY2hpbGRyZW4ucHVzaChub2RlKTsKICAgIH0KCiAgICAvLyBhZGQgYWxsIHJlZ2lvbnMgdG8gdGhlIHJvb3QKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9seS5yZWdpb25zLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciByZWdpb24gPSBwb2x5LnJlZ2lvbnNbaV07CiAgICAgIGlmIChyZWdpb24ubGVuZ3RoIDwgMykKICAgICAgICAvLyByZWdpb25zIG11c3QgaGF2ZSBhdCBsZWFzdCAzIHBvaW50cyAoc2FuaXR5IGNoZWNrKQogICAgICAgIGNvbnRpbnVlOwogICAgICBhZGRDaGlsZChyb290cywgcmVnaW9uKTsKICAgIH0KCiAgICAvLyB3aXRoIG91ciBoZWlyYXJjaHksIHdlIGNhbiBkaXN0aW5ndWlzaCBiZXR3ZWVuIGV4dGVyaW9yIGJvcmRlcnMsIGFuZCBpbnRlcmlvciBob2xlcwogICAgLy8gdGhlIHJvb3Qgbm9kZXMgYXJlIGV4dGVyaW9yLCBjaGlsZHJlbiBhcmUgaW50ZXJpb3IsIGNoaWxkcmVuJ3MgY2hpbGRyZW4gYXJlIGV4dGVyaW9yLAogICAgLy8gY2hpbGRyZW4ncyBjaGlsZHJlbidzIGNoaWxkcmVuIGFyZSBpbnRlcmlvciwgZXRjCgogICAgLy8gd2hpbGUgd2UncmUgYXQgaXQsIGV4dGVyaW9ycyBhcmUgY291bnRlci1jbG9ja3dpc2UsIGFuZCBpbnRlcmlvcnMgYXJlIGNsb2Nrd2lzZQoKICAgIGZ1bmN0aW9uIGZvcmNlV2luZGluZyhyZWdpb24sIGNsb2Nrd2lzZSkgewogICAgICAvLyBmaXJzdCwgc2VlIGlmIHdlJ3JlIGNsb2Nrd2lzZSBvciBjb3VudGVyLWNsb2Nrd2lzZQogICAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TaG9lbGFjZV9mb3JtdWxhCiAgICAgIHZhciB3aW5kaW5nID0gMDsKICAgICAgdmFyIGxhc3RfeCA9IHJlZ2lvbltyZWdpb24ubGVuZ3RoIC0gMV1bMF07CiAgICAgIHZhciBsYXN0X3kgPSByZWdpb25bcmVnaW9uLmxlbmd0aCAtIDFdWzFdOwogICAgICB2YXIgY29weSA9IFtdOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lvbi5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBjdXJyX3ggPSByZWdpb25baV1bMF07CiAgICAgICAgdmFyIGN1cnJfeSA9IHJlZ2lvbltpXVsxXTsKICAgICAgICBjb3B5LnB1c2goW2N1cnJfeCwgY3Vycl95XSk7IC8vIGNyZWF0ZSBhIGNvcHkgd2hpbGUgd2UncmUgYXQgaXQKICAgICAgICB3aW5kaW5nICs9IGN1cnJfeSAqIGxhc3RfeCAtIGN1cnJfeCAqIGxhc3RfeTsKICAgICAgICBsYXN0X3ggPSBjdXJyX3g7CiAgICAgICAgbGFzdF95ID0gY3Vycl95OwogICAgICB9CiAgICAgIC8vIHRoaXMgYXNzdW1lcyBDYXJ0ZXNpYW4gY29vcmRpbmF0ZXMgKFkgaXMgcG9zaXRpdmUgZ29pbmcgdXApCiAgICAgIHZhciBpc2Nsb2Nrd2lzZSA9IHdpbmRpbmcgPCAwOwogICAgICBpZiAoaXNjbG9ja3dpc2UgIT09IGNsb2Nrd2lzZSkgY29weS5yZXZlcnNlKCk7CiAgICAgIC8vIHdoaWxlIHdlJ3JlIGhlcmUsIHRoZSBsYXN0IHBvaW50IG11c3QgYmUgdGhlIGZpcnN0IHBvaW50Li4uCiAgICAgIGNvcHkucHVzaChbY29weVswXVswXSwgY29weVswXVsxXV0pOwogICAgICByZXR1cm4gY29weTsKICAgIH0KICAgIHZhciBnZW9wb2x5cyA9IFtdOwogICAgZnVuY3Rpb24gYWRkRXh0ZXJpb3Iobm9kZSkgewogICAgICB2YXIgcG9seSA9IFtmb3JjZVdpbmRpbmcobm9kZS5yZWdpb24sIGZhbHNlKV07CiAgICAgIGdlb3BvbHlzLnB1c2gocG9seSk7CiAgICAgIC8vIGNoaWxkcmVuIG9mIGV4dGVyaW9ycyBhcmUgaW50ZXJpb3IKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSBwb2x5LnB1c2goZ2V0SW50ZXJpb3Iobm9kZS5jaGlsZHJlbltpXSkpOwogICAgfQogICAgZnVuY3Rpb24gZ2V0SW50ZXJpb3Iobm9kZSkgewogICAgICAvLyBjaGlsZHJlbiBvZiBpbnRlcmlvcnMgYXJlIGV4dGVyaW9yCiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykgYWRkRXh0ZXJpb3Iobm9kZS5jaGlsZHJlbltpXSk7CiAgICAgIC8vIHJldHVybiB0aGUgY2xvY2t3aXNlIGludGVyaW9yCiAgICAgIHJldHVybiBmb3JjZVdpbmRpbmcobm9kZS5yZWdpb24sIHRydWUpOwogICAgfQoKICAgIC8vIHJvb3Qgbm9kZXMgYXJlIGV4dGVyaW9yCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJvb3RzLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSBhZGRFeHRlcmlvcihyb290cy5jaGlsZHJlbltpXSk7CgogICAgLy8gbGFzdGx5LCBjb25zdHJ1Y3QgdGhlIGFwcHJvcnByaWF0ZSBHZW9KU09OIG9iamVjdAoKICAgIGlmIChnZW9wb2x5cy5sZW5ndGggPD0gMCkKICAgICAgLy8gZW1wdHkgR2VvSlNPTiBQb2x5Z29uCiAgICAgIHJldHVybiB7CiAgICAgICAgdHlwZTogJ1BvbHlnb24nLAogICAgICAgIGNvb3JkaW5hdGVzOiBbXQogICAgICB9OwogICAgaWYgKGdlb3BvbHlzLmxlbmd0aCA9PSAxKQogICAgICAvLyB1c2UgYSBHZW9KU09OIFBvbHlnb24KICAgICAgcmV0dXJuIHsKICAgICAgICB0eXBlOiAnUG9seWdvbicsCiAgICAgICAgY29vcmRpbmF0ZXM6IGdlb3BvbHlzWzBdCiAgICAgIH07CiAgICByZXR1cm4gewogICAgICAvLyBvdGhlcndpc2UsIHVzZSBhIEdlb0pTT04gTXVsdGlQb2x5Z29uCiAgICAgIHR5cGU6ICdNdWx0aVBvbHlnb24nLAogICAgICBjb29yZGluYXRlczogZ2VvcG9seXMKICAgIH07CiAgfQp9Owp2YXIgZ2VvanNvbiA9IEdlb0pTT04kMTsKCi8qCiAqIEBjb3B5cmlnaHQgMjAxNiBTZWFuIENvbm5lbGx5IChAdm9pZHFrKSwgaHR0cDovL3N5bnRoZXRpLmNjCiAqIEBsaWNlbnNlIE1JVAogKiBAcHJlc2VydmUgUHJvamVjdCBIb21lOiBodHRwczovL2dpdGh1Yi5jb20vdm9pZHFrL3BvbHlib29sanMKICovCnZhciBCdWlsZExvZyA9IGJ1aWxkTG9nJDE7CnZhciBFcHNpbG9uID0gZXBzaWxvbiQzOwp2YXIgSW50ZXJzZWN0ZXIgPSBpbnRlcnNlY3RlcjsKdmFyIFNlZ21lbnRDaGFpbmVyID0gc2VnbWVudENoYWluZXI7CnZhciBTZWdtZW50U2VsZWN0b3IgPSBzZWdtZW50U2VsZWN0b3I7CnZhciBHZW9KU09OID0gZ2VvanNvbjsKdmFyIGJ1aWxkTG9nID0gZmFsc2U7CnZhciBlcHNpbG9uJDIgPSBFcHNpbG9uKCk7CnZhciBQb2x5Qm9vbDsKUG9seUJvb2wgPSB7CiAgLy8gZ2V0dGVyL3NldHRlciBmb3IgYnVpbGRMb2cKICBidWlsZExvZzogZnVuY3Rpb24gKGJsKSB7CiAgICBpZiAoYmwgPT09IHRydWUpIGJ1aWxkTG9nID0gQnVpbGRMb2coKTtlbHNlIGlmIChibCA9PT0gZmFsc2UpIGJ1aWxkTG9nID0gZmFsc2U7CiAgICByZXR1cm4gYnVpbGRMb2cgPT09IGZhbHNlID8gZmFsc2UgOiBidWlsZExvZy5saXN0OwogIH0sCiAgLy8gZ2V0dGVyL3NldHRlciBmb3IgZXBzaWxvbgogIGVwc2lsb246IGZ1bmN0aW9uICh2KSB7CiAgICByZXR1cm4gZXBzaWxvbiQyLmVwc2lsb24odik7CiAgfSwKICAvLyBjb3JlIEFQSQogIHNlZ21lbnRzOiBmdW5jdGlvbiAocG9seSkgewogICAgdmFyIGkgPSBJbnRlcnNlY3Rlcih0cnVlLCBlcHNpbG9uJDIsIGJ1aWxkTG9nKTsKICAgIHBvbHkucmVnaW9ucy5mb3JFYWNoKGkuYWRkUmVnaW9uKTsKICAgIHJldHVybiB7CiAgICAgIHNlZ21lbnRzOiBpLmNhbGN1bGF0ZShwb2x5LmludmVydGVkKSwKICAgICAgaW52ZXJ0ZWQ6IHBvbHkuaW52ZXJ0ZWQKICAgIH07CiAgfSwKICBjb21iaW5lOiBmdW5jdGlvbiAoc2VnbWVudHMxLCBzZWdtZW50czIpIHsKICAgIHZhciBpMyA9IEludGVyc2VjdGVyKGZhbHNlLCBlcHNpbG9uJDIsIGJ1aWxkTG9nKTsKICAgIHJldHVybiB7CiAgICAgIGNvbWJpbmVkOiBpMy5jYWxjdWxhdGUoc2VnbWVudHMxLnNlZ21lbnRzLCBzZWdtZW50czEuaW52ZXJ0ZWQsIHNlZ21lbnRzMi5zZWdtZW50cywgc2VnbWVudHMyLmludmVydGVkKSwKICAgICAgaW52ZXJ0ZWQxOiBzZWdtZW50czEuaW52ZXJ0ZWQsCiAgICAgIGludmVydGVkMjogc2VnbWVudHMyLmludmVydGVkCiAgICB9OwogIH0sCiAgc2VsZWN0VW5pb246IGZ1bmN0aW9uIChjb21iaW5lZCkgewogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IFNlZ21lbnRTZWxlY3Rvci51bmlvbihjb21iaW5lZC5jb21iaW5lZCwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogY29tYmluZWQuaW52ZXJ0ZWQxIHx8IGNvbWJpbmVkLmludmVydGVkMgogICAgfTsKICB9LAogIHNlbGVjdEludGVyc2VjdDogZnVuY3Rpb24gKGNvbWJpbmVkKSB7CiAgICByZXR1cm4gewogICAgICBzZWdtZW50czogU2VnbWVudFNlbGVjdG9yLmludGVyc2VjdChjb21iaW5lZC5jb21iaW5lZCwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogY29tYmluZWQuaW52ZXJ0ZWQxICYmIGNvbWJpbmVkLmludmVydGVkMgogICAgfTsKICB9LAogIHNlbGVjdERpZmZlcmVuY2U6IGZ1bmN0aW9uIChjb21iaW5lZCkgewogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IFNlZ21lbnRTZWxlY3Rvci5kaWZmZXJlbmNlKGNvbWJpbmVkLmNvbWJpbmVkLCBidWlsZExvZyksCiAgICAgIGludmVydGVkOiBjb21iaW5lZC5pbnZlcnRlZDEgJiYgIWNvbWJpbmVkLmludmVydGVkMgogICAgfTsKICB9LAogIHNlbGVjdERpZmZlcmVuY2VSZXY6IGZ1bmN0aW9uIChjb21iaW5lZCkgewogICAgcmV0dXJuIHsKICAgICAgc2VnbWVudHM6IFNlZ21lbnRTZWxlY3Rvci5kaWZmZXJlbmNlUmV2KGNvbWJpbmVkLmNvbWJpbmVkLCBidWlsZExvZyksCiAgICAgIGludmVydGVkOiAhY29tYmluZWQuaW52ZXJ0ZWQxICYmIGNvbWJpbmVkLmludmVydGVkMgogICAgfTsKICB9LAogIHNlbGVjdFhvcjogZnVuY3Rpb24gKGNvbWJpbmVkKSB7CiAgICByZXR1cm4gewogICAgICBzZWdtZW50czogU2VnbWVudFNlbGVjdG9yLnhvcihjb21iaW5lZC5jb21iaW5lZCwgYnVpbGRMb2cpLAogICAgICBpbnZlcnRlZDogY29tYmluZWQuaW52ZXJ0ZWQxICE9PSBjb21iaW5lZC5pbnZlcnRlZDIKICAgIH07CiAgfSwKICBwb2x5Z29uOiBmdW5jdGlvbiAoc2VnbWVudHMpIHsKICAgIHJldHVybiB7CiAgICAgIHJlZ2lvbnM6IFNlZ21lbnRDaGFpbmVyKHNlZ21lbnRzLnNlZ21lbnRzLCBlcHNpbG9uJDIsIGJ1aWxkTG9nKSwKICAgICAgaW52ZXJ0ZWQ6IHNlZ21lbnRzLmludmVydGVkCiAgICB9OwogIH0sCiAgLy8gR2VvSlNPTiBjb252ZXJ0ZXJzCiAgcG9seWdvbkZyb21HZW9KU09OOiBmdW5jdGlvbiAoZ2VvanNvbikgewogICAgcmV0dXJuIEdlb0pTT04udG9Qb2x5Z29uKFBvbHlCb29sLCBnZW9qc29uKTsKICB9LAogIHBvbHlnb25Ub0dlb0pTT046IGZ1bmN0aW9uIChwb2x5KSB7CiAgICByZXR1cm4gR2VvSlNPTi5mcm9tUG9seWdvbihQb2x5Qm9vbCwgZXBzaWxvbiQyLCBwb2x5KTsKICB9LAogIC8vIGhlbHBlciBmdW5jdGlvbnMgZm9yIGNvbW1vbiBvcGVyYXRpb25zCiAgdW5pb246IGZ1bmN0aW9uIChwb2x5MSwgcG9seTIpIHsKICAgIHJldHVybiBvcGVyYXRlKHBvbHkxLCBwb2x5MiwgUG9seUJvb2wuc2VsZWN0VW5pb24pOwogIH0sCiAgaW50ZXJzZWN0OiBmdW5jdGlvbiAocG9seTEsIHBvbHkyKSB7CiAgICByZXR1cm4gb3BlcmF0ZShwb2x5MSwgcG9seTIsIFBvbHlCb29sLnNlbGVjdEludGVyc2VjdCk7CiAgfSwKICBkaWZmZXJlbmNlOiBmdW5jdGlvbiAocG9seTEsIHBvbHkyKSB7CiAgICByZXR1cm4gb3BlcmF0ZShwb2x5MSwgcG9seTIsIFBvbHlCb29sLnNlbGVjdERpZmZlcmVuY2UpOwogIH0sCiAgZGlmZmVyZW5jZVJldjogZnVuY3Rpb24gKHBvbHkxLCBwb2x5MikgewogICAgcmV0dXJuIG9wZXJhdGUocG9seTEsIHBvbHkyLCBQb2x5Qm9vbC5zZWxlY3REaWZmZXJlbmNlUmV2KTsKICB9LAogIHhvcjogZnVuY3Rpb24gKHBvbHkxLCBwb2x5MikgewogICAgcmV0dXJuIG9wZXJhdGUocG9seTEsIHBvbHkyLCBQb2x5Qm9vbC5zZWxlY3RYb3IpOwogIH0KfTsKZnVuY3Rpb24gb3BlcmF0ZShwb2x5MSwgcG9seTIsIHNlbGVjdG9yKSB7CiAgdmFyIHNlZzEgPSBQb2x5Qm9vbC5zZWdtZW50cyhwb2x5MSk7CiAgdmFyIHNlZzIgPSBQb2x5Qm9vbC5zZWdtZW50cyhwb2x5Mik7CiAgdmFyIGNvbWIgPSBQb2x5Qm9vbC5jb21iaW5lKHNlZzEsIHNlZzIpOwogIHZhciBzZWczID0gc2VsZWN0b3IoY29tYik7CiAgcmV0dXJuIFBvbHlCb29sLnBvbHlnb24oc2VnMyk7Cn0KaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnKSB3aW5kb3cuUG9seUJvb2wgPSBQb2x5Qm9vbDsKdmFyIHBvbHlib29sanMgPSBQb2x5Qm9vbDsKCi8qKgogKiBQZXJmb3JtcyBhIGRlZXAgY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlCiAqIGVxdWl2YWxlbnQuCiAqCiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyBjb21wYXJpbmcgYXJyYXlzLCBhcnJheSBidWZmZXJzLCBib29sZWFucywKICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLAogKiBzZXRzLCBzdHJpbmdzLCBzeW1ib2xzLCBhbmQgdHlwZWQgYXJyYXlzLiBgT2JqZWN0YCBvYmplY3RzIGFyZSBjb21wYXJlZAogKiBieSB0aGVpciBvd24sIG5vdCBpbmhlcml0ZWQsIGVudW1lcmFibGUgcHJvcGVydGllcy4gRnVuY3Rpb25zIGFuZCBET00KICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC4KICoKICogQHN0YXRpYwogKiBAbWVtYmVyT2YgXwogKiBAc2luY2UgMC4xLjAKICogQGNhdGVnb3J5IExhbmcKICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS4KICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS4KICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC4KICogQGV4YW1wbGUKICoKICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07CiAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07CiAqCiAqIF8uaXNFcXVhbChvYmplY3QsIG90aGVyKTsKICogLy8gPT4gdHJ1ZQogKgogKiBvYmplY3QgPT09IG90aGVyOwogKiAvLyA9PiBmYWxzZQogKi8KZnVuY3Rpb24gaXNFcXVhbCh2YWx1ZSwgb3RoZXIpIHsKICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTsKfQoKLyoqDQogKiDkv67lvqlQb2x5Z29u5YWn5ZCEUmluZ1N0cmluZ+eCuumWieWQiA0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ZpeENsb3NlUG9seWdvbi50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBncyDovLjlhaVQb2x5Z29u6LOH5paZ6Zmj5YiX77yM54K6W1sgW1t4MTEseTExXSxbeDEyLHkxMl0sLi4uXSwgW1t4MjEseTIxXSxbeDIyLHkyMl0sLi4uXSBdXeani+aIkOS5i+mZo+WIlw0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcmV0dXJucyB7QXJyYXl9IOWbnuWCs1BvbHlnb27pmaPliJcNCiAqIEBleGFtcGxlDQoNCiAqLwpmdW5jdGlvbiBmaXhDbG9zZVBvbHlnb24ocGdzLCBvcHQgPSB7fSkgewogIC8vY2hlY2sgcGdzCiAgaWYgKCFpc2VhcnIocGdzKSkgewogICAgdGhyb3cgbmV3IEVycm9yKGBubyBwZ3NgKTsKICB9CgogIC8vdG9Qb2x5Z29uCiAgcGdzID0gdG9Qb2x5Z29uKHBncyk7CgogIC8v5L+u5b6p5oiQ54K66ZaJ5ZCICiAgcGdzID0gbWFwKHBncywgcnMgPT4gewogICAgbGV0IGkwID0gMDsKICAgIGxldCBpMSA9IHNpemUocnMpIC0gMTsKICAgIGxldCByczAgPSByc1tpMF07CiAgICBsZXQgcnMxID0gcnNbaTFdOwogICAgaWYgKCFpc0VxdWFsKHJzMCwgcnMxKSkgewogICAgICBycy5wdXNoKHJzMCk7CiAgICB9CiAgICByZXR1cm4gcnM7CiAgfSk7CiAgcmV0dXJuIHBnczsKfQoKLyoqDQogKiDph53lsI1Qb2x5Z29u6YCy6KGM5Lqk6ZuGKGludGVyc2VjdCnomZXnkIYNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9pbnRlcnNlY3RQb2x5Z29uLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcGdzMSDovLjlhaXnrKwx5YCLUG9seWdvbuizh+aWmemZo+WIl++8jOeCulsgW1t4MTEseTExXSxbeDEyLHkxMl0sLi4uXSwgW1t4MjEseTIxXSxbeDIyLHkyMl0sLi4uXSBd5qeL5oiQ5LmL6Zmj5YiXDQogKiBAcGFyYW0ge0FycmF5fSBwZ3MyIOi8uOWFpeesrDLlgItQb2x5Z29u6LOH5paZ6Zmj5YiX77yM54K6WyBbW3gxMSx5MTFdLFt4MTIseTEyXSwuLi5dLCBbW3gyMSx5MjFdLFt4MjIseTIyXSwuLi5dIF3mp4vmiJDkuYvpmaPliJcNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuZXBzaWxvbj0wLjAwMDAwMDAwMDAwMV0g6Ly45YWlIHBvbHlib29sanMg6KiI566X5a656Kix6Kqk5beuDQogKiBAcmV0dXJucyB7QXJyYXl9IOWbnuWCs1BvbHlnb27pmaPliJcNCiAqIEBleGFtcGxlDQogKg0KICogbGV0IHBnczENCiAqIGxldCBwZ3MyDQogKiBsZXQgcg0KICoNCiAqIHBnczEgPSAnbm90IGFycmF5Jw0KICogcGdzMiA9IFtbWzIsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzIsIDRdXV0gLy9wb2x5Z29uDQogKiB0cnkgew0KICogICAgIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogfQ0KICogY2F0Y2ggKGVycikgew0KICogICAgIHIgPSBlcnIubWVzc2FnZQ0KICogfQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IG5vIHBnczENCiAqDQogKiBwZ3MxID0gW1tbMCwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMCwgNF1dXSAvL3BvbHlnb24NCiAqIHBnczIgPSAnbm90IGFycmF5Jw0KICogdHJ5IHsNCiAqICAgICByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIH0NCiAqIGNhdGNoIChlcnIpIHsNCiAqICAgICByID0gZXJyLm1lc3NhZ2UNCiAqIH0NCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiBpbnZhbGlkIHBnczINCiAqDQogKiBwZ3MxID0gW1tbMCwgMF0sIFsxLCAwXSwgWzEsIDFdLCBbMCwgMV1dXSAvL3BvbHlnb24NCiAqIHBnczIgPSBbXQ0KICogciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzAsMF0sWzEsMF0sWzEsMV0sWzAsMV0sWzAsMF1dXQ0KICoNCiAqIHBnczEgPSBbW1swLCAwXSwgWzQsIDBdLCBbNCwgNF0sIFswLCA0XV1dIC8vcG9seWdvbg0KICogcGdzMiA9IFtbWzIsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzIsIDRdXV0gLy9wb2x5Z29uDQogKiByID0gaW50ZXJzZWN0UG9seWdvbihwZ3MxLCBwZ3MyLCB7fSkNCiAqIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHIpKQ0KICogLy8gPT4gW1tbNCw0XSxbNCwwXSxbMiwwXSxbMiw0XSxbNCw0XV1dDQogKg0KICogcGdzMSA9IFtbWzAsIDBdLCBbNCwgMF0sIFs0LCA0XSwgWzAsIDRdXV0gLy9wb2x5Z29uDQogKiBwZ3MyID0gW1tbMCwgMF0sIFsyLCAwXSwgWzIsIDJdLCBbMCwgMl1dXSAvL3BvbHlnb24NCiAqIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1syLDJdLFsyLDBdLFswLDBdLFswLDJdLFsyLDJdXV0NCiAqDQogKiBwZ3MxID0gW1tbMCwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMCwgNF1dXSAvL3BvbHlnb24NCiAqIHBnczIgPSBbW1swLCAwXSwgWzIsIDJdLCBbMCwgNF1dXSAvL3BvbHlnb24NCiAqIHIgPSBpbnRlcnNlY3RQb2x5Z29uKHBnczEsIHBnczIsIHt9KQ0KICogY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocikpDQogKiAvLyA9PiBbW1syLDJdLFswLDBdLFswLDRdLFsyLDJdXV0NCiAqDQogKiBwZ3MxID0gW1tbMCwgMF0sIFs0LCAwXSwgWzQsIDRdLCBbMCwgNF1dXSAvL3BvbHlnb24NCiAqIHBnczIgPSBbW1stMSwgMF0sIFsyLCAxXSwgWy0xLCA0XV1dIC8vcG9seWdvbg0KICogciA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwge30pDQogKiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyKSkNCiAqIC8vID0+IFtbWzIsMV0sWzAsMC4zMzMzMzMzMzMzMzMzMzMzXSxbMCwzXSxbMiwxXV1dDQogKg0KICovCmZ1bmN0aW9uIGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMiwgb3B0ID0ge30pIHsKICAvL3R1cmbnmoRpbnRlcnNlY3TmupbnorrmgKfoiIfpgannlKjmgKfmr5TovIPlt64sIOW+l+S9v+eUqHBvbHlib29sanPmr5TovIPlpb0KCiAgLy9jaGVjayBwZ3MxCiAgaWYgKCFpc2VhcnIocGdzMSkpIHsKICAgIHRocm93IG5ldyBFcnJvcihgbm8gcGdzMWApOwogIH0KCiAgLy9jaGVjayBwZ3MyCiAgaWYgKGlzYXJyKHBnczIpICYmIHNpemUocGdzMikgPT09IDApIHsKICAgIHBnczEgPSBmaXhDbG9zZVBvbHlnb24ocGdzMSk7CiAgICByZXR1cm4gcGdzMTsKICB9CiAgaWYgKCFpc2FycihwZ3MyKSkgewogICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHBnczJgKTsKICB9CgogIC8vZXBzaWxvbgogIGxldCBlcHNpbG9uID0gZ2V0KG9wdCwgJ2Vwc2lsb24nLCAwLjAwMDAwMDAwMDAwMSk7CgogIC8vdG9Qb2x5Z29uCiAgcGdzMSA9IHRvUG9seWdvbihwZ3MxKTsKICBwZ3MyID0gdG9Qb2x5Z29uKHBnczIpOwogIC8vIGNvbnNvbGUubG9nKCdwZ3MxJywgcGdzMSkKICAvLyBjb25zb2xlLmxvZygncGdzMicsIHBnczIpCgogIC8vaW50ZXJzZWN0CiAgcG9seWJvb2xqcy5lcHNpbG9uKGVwc2lsb24pOwogIGxldCBpbnRzID0gcG9seWJvb2xqcy5pbnRlcnNlY3QoewogICAgcmVnaW9uczogcGdzMQogIH0sIHsKICAgIHJlZ2lvbnM6IHBnczIKICB9KTsKICAvLyBjb25zb2xlLmxvZygnaW50cycsIGludHMpCgogIC8vcGdzCiAgbGV0IHBncyA9IGdldChpbnRzLCAncmVnaW9ucycsIFtdKTsKCiAgLy9maXhDbG9zZVBvbHlnb24KICBwZ3MgPSBmaXhDbG9zZVBvbHlnb24ocGdzKTsKICByZXR1cm4gcGdzOwp9Cgpjb25zdCBlcHNpbG9uJDEgPSAxLjExMDIyMzAyNDYyNTE1NjVlLTE2Owpjb25zdCBzcGxpdHRlciA9IDEzNDIxNzcyOTsKY29uc3QgcmVzdWx0ZXJyYm91bmQgPSAoMyArIDggKiBlcHNpbG9uJDEpICogZXBzaWxvbiQxOwoKLy8gZmFzdF9leHBhbnNpb25fc3VtX3plcm9lbGltIHJvdXRpbmUgZnJvbSBvcml0aW5hbCBjb2RlCmZ1bmN0aW9uIHN1bShlbGVuLCBlLCBmbGVuLCBmLCBoKSB7CiAgbGV0IFEsIFFuZXcsIGhoLCBidmlydDsKICBsZXQgZW5vdyA9IGVbMF07CiAgbGV0IGZub3cgPSBmWzBdOwogIGxldCBlaW5kZXggPSAwOwogIGxldCBmaW5kZXggPSAwOwogIGlmIChmbm93ID4gZW5vdyA9PT0gZm5vdyA+IC1lbm93KSB7CiAgICBRID0gZW5vdzsKICAgIGVub3cgPSBlWysrZWluZGV4XTsKICB9IGVsc2UgewogICAgUSA9IGZub3c7CiAgICBmbm93ID0gZlsrK2ZpbmRleF07CiAgfQogIGxldCBoaW5kZXggPSAwOwogIGlmIChlaW5kZXggPCBlbGVuICYmIGZpbmRleCA8IGZsZW4pIHsKICAgIGlmIChmbm93ID4gZW5vdyA9PT0gZm5vdyA+IC1lbm93KSB7CiAgICAgIFFuZXcgPSBlbm93ICsgUTsKICAgICAgaGggPSBRIC0gKFFuZXcgLSBlbm93KTsKICAgICAgZW5vdyA9IGVbKytlaW5kZXhdOwogICAgfSBlbHNlIHsKICAgICAgUW5ldyA9IGZub3cgKyBROwogICAgICBoaCA9IFEgLSAoUW5ldyAtIGZub3cpOwogICAgICBmbm93ID0gZlsrK2ZpbmRleF07CiAgICB9CiAgICBRID0gUW5ldzsKICAgIGlmIChoaCAhPT0gMCkgewogICAgICBoW2hpbmRleCsrXSA9IGhoOwogICAgfQogICAgd2hpbGUgKGVpbmRleCA8IGVsZW4gJiYgZmluZGV4IDwgZmxlbikgewogICAgICBpZiAoZm5vdyA+IGVub3cgPT09IGZub3cgPiAtZW5vdykgewogICAgICAgIFFuZXcgPSBRICsgZW5vdzsKICAgICAgICBidmlydCA9IFFuZXcgLSBROwogICAgICAgIGhoID0gUSAtIChRbmV3IC0gYnZpcnQpICsgKGVub3cgLSBidmlydCk7CiAgICAgICAgZW5vdyA9IGVbKytlaW5kZXhdOwogICAgICB9IGVsc2UgewogICAgICAgIFFuZXcgPSBRICsgZm5vdzsKICAgICAgICBidmlydCA9IFFuZXcgLSBROwogICAgICAgIGhoID0gUSAtIChRbmV3IC0gYnZpcnQpICsgKGZub3cgLSBidmlydCk7CiAgICAgICAgZm5vdyA9IGZbKytmaW5kZXhdOwogICAgICB9CiAgICAgIFEgPSBRbmV3OwogICAgICBpZiAoaGggIT09IDApIHsKICAgICAgICBoW2hpbmRleCsrXSA9IGhoOwogICAgICB9CiAgICB9CiAgfQogIHdoaWxlIChlaW5kZXggPCBlbGVuKSB7CiAgICBRbmV3ID0gUSArIGVub3c7CiAgICBidmlydCA9IFFuZXcgLSBROwogICAgaGggPSBRIC0gKFFuZXcgLSBidmlydCkgKyAoZW5vdyAtIGJ2aXJ0KTsKICAgIGVub3cgPSBlWysrZWluZGV4XTsKICAgIFEgPSBRbmV3OwogICAgaWYgKGhoICE9PSAwKSB7CiAgICAgIGhbaGluZGV4KytdID0gaGg7CiAgICB9CiAgfQogIHdoaWxlIChmaW5kZXggPCBmbGVuKSB7CiAgICBRbmV3ID0gUSArIGZub3c7CiAgICBidmlydCA9IFFuZXcgLSBROwogICAgaGggPSBRIC0gKFFuZXcgLSBidmlydCkgKyAoZm5vdyAtIGJ2aXJ0KTsKICAgIGZub3cgPSBmWysrZmluZGV4XTsKICAgIFEgPSBRbmV3OwogICAgaWYgKGhoICE9PSAwKSB7CiAgICAgIGhbaGluZGV4KytdID0gaGg7CiAgICB9CiAgfQogIGlmIChRICE9PSAwIHx8IGhpbmRleCA9PT0gMCkgewogICAgaFtoaW5kZXgrK10gPSBROwogIH0KICByZXR1cm4gaGluZGV4Owp9CmZ1bmN0aW9uIGVzdGltYXRlKGVsZW4sIGUpIHsKICBsZXQgUSA9IGVbMF07CiAgZm9yIChsZXQgaSA9IDE7IGkgPCBlbGVuOyBpKyspIFEgKz0gZVtpXTsKICByZXR1cm4gUTsKfQpmdW5jdGlvbiB2ZWMobikgewogIHJldHVybiBuZXcgRmxvYXQ2NEFycmF5KG4pOwp9Cgpjb25zdCBjY3dlcnJib3VuZEEgPSAoMyArIDE2ICogZXBzaWxvbiQxKSAqIGVwc2lsb24kMTsKY29uc3QgY2N3ZXJyYm91bmRCID0gKDIgKyAxMiAqIGVwc2lsb24kMSkgKiBlcHNpbG9uJDE7CmNvbnN0IGNjd2VycmJvdW5kQyA9ICg5ICsgNjQgKiBlcHNpbG9uJDEpICogZXBzaWxvbiQxICogZXBzaWxvbiQxOwpjb25zdCBCID0gdmVjKDQpOwpjb25zdCBDMSA9IHZlYyg4KTsKY29uc3QgQzIgPSB2ZWMoMTIpOwpjb25zdCBEID0gdmVjKDE2KTsKY29uc3QgdSA9IHZlYyg0KTsKZnVuY3Rpb24gb3JpZW50MmRhZGFwdChheCwgYXksIGJ4LCBieSwgY3gsIGN5LCBkZXRzdW0pIHsKICBsZXQgYWN4dGFpbCwgYWN5dGFpbCwgYmN4dGFpbCwgYmN5dGFpbDsKICBsZXQgYnZpcnQsIGMsIGFoaSwgYWxvLCBiaGksIGJsbywgX2ksIF9qLCBfMCwgczEsIHMwLCB0MSwgdDAsIHUzOwogIGNvbnN0IGFjeCA9IGF4IC0gY3g7CiAgY29uc3QgYmN4ID0gYnggLSBjeDsKICBjb25zdCBhY3kgPSBheSAtIGN5OwogIGNvbnN0IGJjeSA9IGJ5IC0gY3k7CiAgczEgPSBhY3ggKiBiY3k7CiAgYyA9IHNwbGl0dGVyICogYWN4OwogIGFoaSA9IGMgLSAoYyAtIGFjeCk7CiAgYWxvID0gYWN4IC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeTsKICBiaGkgPSBjIC0gKGMgLSBiY3kpOwogIGJsbyA9IGJjeSAtIGJoaTsKICBzMCA9IGFsbyAqIGJsbyAtIChzMSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgdDEgPSBhY3kgKiBiY3g7CiAgYyA9IHNwbGl0dGVyICogYWN5OwogIGFoaSA9IGMgLSAoYyAtIGFjeSk7CiAgYWxvID0gYWN5IC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeDsKICBiaGkgPSBjIC0gKGMgLSBiY3gpOwogIGJsbyA9IGJjeCAtIGJoaTsKICB0MCA9IGFsbyAqIGJsbyAtICh0MSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgX2kgPSBzMCAtIHQwOwogIGJ2aXJ0ID0gczAgLSBfaTsKICBCWzBdID0gczAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MCk7CiAgX2ogPSBzMSArIF9pOwogIGJ2aXJ0ID0gX2ogLSBzMTsKICBfMCA9IHMxIC0gKF9qIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIF9pID0gXzAgLSB0MTsKICBidmlydCA9IF8wIC0gX2k7CiAgQlsxXSA9IF8wIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDEpOwogIHUzID0gX2ogKyBfaTsKICBidmlydCA9IHUzIC0gX2o7CiAgQlsyXSA9IF9qIC0gKHUzIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIEJbM10gPSB1MzsKICBsZXQgZGV0ID0gZXN0aW1hdGUoNCwgQik7CiAgbGV0IGVycmJvdW5kID0gY2N3ZXJyYm91bmRCICogZGV0c3VtOwogIGlmIChkZXQgPj0gZXJyYm91bmQgfHwgLWRldCA+PSBlcnJib3VuZCkgewogICAgcmV0dXJuIGRldDsKICB9CiAgYnZpcnQgPSBheCAtIGFjeDsKICBhY3h0YWlsID0gYXggLSAoYWN4ICsgYnZpcnQpICsgKGJ2aXJ0IC0gY3gpOwogIGJ2aXJ0ID0gYnggLSBiY3g7CiAgYmN4dGFpbCA9IGJ4IC0gKGJjeCArIGJ2aXJ0KSArIChidmlydCAtIGN4KTsKICBidmlydCA9IGF5IC0gYWN5OwogIGFjeXRhaWwgPSBheSAtIChhY3kgKyBidmlydCkgKyAoYnZpcnQgLSBjeSk7CiAgYnZpcnQgPSBieSAtIGJjeTsKICBiY3l0YWlsID0gYnkgLSAoYmN5ICsgYnZpcnQpICsgKGJ2aXJ0IC0gY3kpOwogIGlmIChhY3h0YWlsID09PSAwICYmIGFjeXRhaWwgPT09IDAgJiYgYmN4dGFpbCA9PT0gMCAmJiBiY3l0YWlsID09PSAwKSB7CiAgICByZXR1cm4gZGV0OwogIH0KICBlcnJib3VuZCA9IGNjd2VycmJvdW5kQyAqIGRldHN1bSArIHJlc3VsdGVycmJvdW5kICogTWF0aC5hYnMoZGV0KTsKICBkZXQgKz0gYWN4ICogYmN5dGFpbCArIGJjeSAqIGFjeHRhaWwgLSAoYWN5ICogYmN4dGFpbCArIGJjeCAqIGFjeXRhaWwpOwogIGlmIChkZXQgPj0gZXJyYm91bmQgfHwgLWRldCA+PSBlcnJib3VuZCkgcmV0dXJuIGRldDsKICBzMSA9IGFjeHRhaWwgKiBiY3k7CiAgYyA9IHNwbGl0dGVyICogYWN4dGFpbDsKICBhaGkgPSBjIC0gKGMgLSBhY3h0YWlsKTsKICBhbG8gPSBhY3h0YWlsIC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeTsKICBiaGkgPSBjIC0gKGMgLSBiY3kpOwogIGJsbyA9IGJjeSAtIGJoaTsKICBzMCA9IGFsbyAqIGJsbyAtIChzMSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgdDEgPSBhY3l0YWlsICogYmN4OwogIGMgPSBzcGxpdHRlciAqIGFjeXRhaWw7CiAgYWhpID0gYyAtIChjIC0gYWN5dGFpbCk7CiAgYWxvID0gYWN5dGFpbCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3g7CiAgYmhpID0gYyAtIChjIC0gYmN4KTsKICBibG8gPSBiY3ggLSBiaGk7CiAgdDAgPSBhbG8gKiBibG8gLSAodDEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIF9pID0gczAgLSB0MDsKICBidmlydCA9IHMwIC0gX2k7CiAgdVswXSA9IHMwIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDApOwogIF9qID0gczEgKyBfaTsKICBidmlydCA9IF9qIC0gczE7CiAgXzAgPSBzMSAtIChfaiAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICBfaSA9IF8wIC0gdDE7CiAgYnZpcnQgPSBfMCAtIF9pOwogIHVbMV0gPSBfMCAtIChfaSArIGJ2aXJ0KSArIChidmlydCAtIHQxKTsKICB1MyA9IF9qICsgX2k7CiAgYnZpcnQgPSB1MyAtIF9qOwogIHVbMl0gPSBfaiAtICh1MyAtIGJ2aXJ0KSArIChfaSAtIGJ2aXJ0KTsKICB1WzNdID0gdTM7CiAgY29uc3QgQzFsZW4gPSBzdW0oNCwgQiwgNCwgdSwgQzEpOwogIHMxID0gYWN4ICogYmN5dGFpbDsKICBjID0gc3BsaXR0ZXIgKiBhY3g7CiAgYWhpID0gYyAtIChjIC0gYWN4KTsKICBhbG8gPSBhY3ggLSBhaGk7CiAgYyA9IHNwbGl0dGVyICogYmN5dGFpbDsKICBiaGkgPSBjIC0gKGMgLSBiY3l0YWlsKTsKICBibG8gPSBiY3l0YWlsIC0gYmhpOwogIHMwID0gYWxvICogYmxvIC0gKHMxIC0gYWhpICogYmhpIC0gYWxvICogYmhpIC0gYWhpICogYmxvKTsKICB0MSA9IGFjeSAqIGJjeHRhaWw7CiAgYyA9IHNwbGl0dGVyICogYWN5OwogIGFoaSA9IGMgLSAoYyAtIGFjeSk7CiAgYWxvID0gYWN5IC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeHRhaWw7CiAgYmhpID0gYyAtIChjIC0gYmN4dGFpbCk7CiAgYmxvID0gYmN4dGFpbCAtIGJoaTsKICB0MCA9IGFsbyAqIGJsbyAtICh0MSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgX2kgPSBzMCAtIHQwOwogIGJ2aXJ0ID0gczAgLSBfaTsKICB1WzBdID0gczAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MCk7CiAgX2ogPSBzMSArIF9pOwogIGJ2aXJ0ID0gX2ogLSBzMTsKICBfMCA9IHMxIC0gKF9qIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIF9pID0gXzAgLSB0MTsKICBidmlydCA9IF8wIC0gX2k7CiAgdVsxXSA9IF8wIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDEpOwogIHUzID0gX2ogKyBfaTsKICBidmlydCA9IHUzIC0gX2o7CiAgdVsyXSA9IF9qIC0gKHUzIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIHVbM10gPSB1MzsKICBjb25zdCBDMmxlbiA9IHN1bShDMWxlbiwgQzEsIDQsIHUsIEMyKTsKICBzMSA9IGFjeHRhaWwgKiBiY3l0YWlsOwogIGMgPSBzcGxpdHRlciAqIGFjeHRhaWw7CiAgYWhpID0gYyAtIChjIC0gYWN4dGFpbCk7CiAgYWxvID0gYWN4dGFpbCAtIGFoaTsKICBjID0gc3BsaXR0ZXIgKiBiY3l0YWlsOwogIGJoaSA9IGMgLSAoYyAtIGJjeXRhaWwpOwogIGJsbyA9IGJjeXRhaWwgLSBiaGk7CiAgczAgPSBhbG8gKiBibG8gLSAoczEgLSBhaGkgKiBiaGkgLSBhbG8gKiBiaGkgLSBhaGkgKiBibG8pOwogIHQxID0gYWN5dGFpbCAqIGJjeHRhaWw7CiAgYyA9IHNwbGl0dGVyICogYWN5dGFpbDsKICBhaGkgPSBjIC0gKGMgLSBhY3l0YWlsKTsKICBhbG8gPSBhY3l0YWlsIC0gYWhpOwogIGMgPSBzcGxpdHRlciAqIGJjeHRhaWw7CiAgYmhpID0gYyAtIChjIC0gYmN4dGFpbCk7CiAgYmxvID0gYmN4dGFpbCAtIGJoaTsKICB0MCA9IGFsbyAqIGJsbyAtICh0MSAtIGFoaSAqIGJoaSAtIGFsbyAqIGJoaSAtIGFoaSAqIGJsbyk7CiAgX2kgPSBzMCAtIHQwOwogIGJ2aXJ0ID0gczAgLSBfaTsKICB1WzBdID0gczAgLSAoX2kgKyBidmlydCkgKyAoYnZpcnQgLSB0MCk7CiAgX2ogPSBzMSArIF9pOwogIGJ2aXJ0ID0gX2ogLSBzMTsKICBfMCA9IHMxIC0gKF9qIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIF9pID0gXzAgLSB0MTsKICBidmlydCA9IF8wIC0gX2k7CiAgdVsxXSA9IF8wIC0gKF9pICsgYnZpcnQpICsgKGJ2aXJ0IC0gdDEpOwogIHUzID0gX2ogKyBfaTsKICBidmlydCA9IHUzIC0gX2o7CiAgdVsyXSA9IF9qIC0gKHUzIC0gYnZpcnQpICsgKF9pIC0gYnZpcnQpOwogIHVbM10gPSB1MzsKICBjb25zdCBEbGVuID0gc3VtKEMybGVuLCBDMiwgNCwgdSwgRCk7CiAgcmV0dXJuIERbRGxlbiAtIDFdOwp9CmZ1bmN0aW9uIG9yaWVudDJkKGF4LCBheSwgYngsIGJ5LCBjeCwgY3kpIHsKICBjb25zdCBkZXRsZWZ0ID0gKGF5IC0gY3kpICogKGJ4IC0gY3gpOwogIGNvbnN0IGRldHJpZ2h0ID0gKGF4IC0gY3gpICogKGJ5IC0gY3kpOwogIGNvbnN0IGRldCA9IGRldGxlZnQgLSBkZXRyaWdodDsKICBpZiAoZGV0bGVmdCA9PT0gMCB8fCBkZXRyaWdodCA9PT0gMCB8fCBkZXRsZWZ0ID4gMCAhPT0gZGV0cmlnaHQgPiAwKSByZXR1cm4gZGV0OwogIGNvbnN0IGRldHN1bSA9IE1hdGguYWJzKGRldGxlZnQgKyBkZXRyaWdodCk7CiAgaWYgKE1hdGguYWJzKGRldCkgPj0gY2N3ZXJyYm91bmRBICogZGV0c3VtKSByZXR1cm4gZGV0OwogIHJldHVybiAtb3JpZW50MmRhZGFwdChheCwgYXksIGJ4LCBieSwgY3gsIGN5LCBkZXRzdW0pOwp9Cgpjb25zdCBFUFNJTE9OID0gTWF0aC5wb3coMiwgLTUyKTsKY29uc3QgRURHRV9TVEFDSyA9IG5ldyBVaW50MzJBcnJheSg1MTIpOwpjbGFzcyBEZWxhdW5hdG9yIHsKICBzdGF0aWMgZnJvbShwb2ludHMsIGdldFggPSBkZWZhdWx0R2V0WCwgZ2V0WSA9IGRlZmF1bHRHZXRZKSB7CiAgICBjb25zdCBuID0gcG9pbnRzLmxlbmd0aDsKICAgIGNvbnN0IGNvb3JkcyA9IG5ldyBGbG9hdDY0QXJyYXkobiAqIDIpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgY29uc3QgcCA9IHBvaW50c1tpXTsKICAgICAgY29vcmRzWzIgKiBpXSA9IGdldFgocCk7CiAgICAgIGNvb3Jkc1syICogaSArIDFdID0gZ2V0WShwKTsKICAgIH0KICAgIHJldHVybiBuZXcgRGVsYXVuYXRvcihjb29yZHMpOwogIH0KICBjb25zdHJ1Y3Rvcihjb29yZHMpIHsKICAgIGNvbnN0IG4gPSBjb29yZHMubGVuZ3RoID4+IDE7CiAgICBpZiAobiA+IDAgJiYgdHlwZW9mIGNvb3Jkc1swXSAhPT0gJ251bWJlcicpIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgY29vcmRzIHRvIGNvbnRhaW4gbnVtYmVycy4nKTsKICAgIHRoaXMuY29vcmRzID0gY29vcmRzOwoKICAgIC8vIGFycmF5cyB0aGF0IHdpbGwgc3RvcmUgdGhlIHRyaWFuZ3VsYXRpb24gZ3JhcGgKICAgIGNvbnN0IG1heFRyaWFuZ2xlcyA9IE1hdGgubWF4KDIgKiBuIC0gNSwgMCk7CiAgICB0aGlzLl90cmlhbmdsZXMgPSBuZXcgVWludDMyQXJyYXkobWF4VHJpYW5nbGVzICogMyk7CiAgICB0aGlzLl9oYWxmZWRnZXMgPSBuZXcgSW50MzJBcnJheShtYXhUcmlhbmdsZXMgKiAzKTsKCiAgICAvLyB0ZW1wb3JhcnkgYXJyYXlzIGZvciB0cmFja2luZyB0aGUgZWRnZXMgb2YgdGhlIGFkdmFuY2luZyBjb252ZXggaHVsbAogICAgdGhpcy5faGFzaFNpemUgPSBNYXRoLmNlaWwoTWF0aC5zcXJ0KG4pKTsKICAgIHRoaXMuX2h1bGxQcmV2ID0gbmV3IFVpbnQzMkFycmF5KG4pOyAvLyBlZGdlIHRvIHByZXYgZWRnZQogICAgdGhpcy5faHVsbE5leHQgPSBuZXcgVWludDMyQXJyYXkobik7IC8vIGVkZ2UgdG8gbmV4dCBlZGdlCiAgICB0aGlzLl9odWxsVHJpID0gbmV3IFVpbnQzMkFycmF5KG4pOyAvLyBlZGdlIHRvIGFkamFjZW50IHRyaWFuZ2xlCiAgICB0aGlzLl9odWxsSGFzaCA9IG5ldyBJbnQzMkFycmF5KHRoaXMuX2hhc2hTaXplKS5maWxsKC0xKTsgLy8gYW5ndWxhciBlZGdlIGhhc2gKCiAgICAvLyB0ZW1wb3JhcnkgYXJyYXlzIGZvciBzb3J0aW5nIHBvaW50cwogICAgdGhpcy5faWRzID0gbmV3IFVpbnQzMkFycmF5KG4pOwogICAgdGhpcy5fZGlzdHMgPSBuZXcgRmxvYXQ2NEFycmF5KG4pOwogICAgdGhpcy51cGRhdGUoKTsKICB9CiAgdXBkYXRlKCkgewogICAgY29uc3QgewogICAgICBjb29yZHMsCiAgICAgIF9odWxsUHJldjogaHVsbFByZXYsCiAgICAgIF9odWxsTmV4dDogaHVsbE5leHQsCiAgICAgIF9odWxsVHJpOiBodWxsVHJpLAogICAgICBfaHVsbEhhc2g6IGh1bGxIYXNoCiAgICB9ID0gdGhpczsKICAgIGNvbnN0IG4gPSBjb29yZHMubGVuZ3RoID4+IDE7CgogICAgLy8gcG9wdWxhdGUgYW4gYXJyYXkgb2YgcG9pbnQgaW5kaWNlczsgY2FsY3VsYXRlIGlucHV0IGRhdGEgYmJveAogICAgbGV0IG1pblggPSBJbmZpbml0eTsKICAgIGxldCBtaW5ZID0gSW5maW5pdHk7CiAgICBsZXQgbWF4WCA9IC1JbmZpbml0eTsKICAgIGxldCBtYXhZID0gLUluZmluaXR5OwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgY29uc3QgeCA9IGNvb3Jkc1syICogaV07CiAgICAgIGNvbnN0IHkgPSBjb29yZHNbMiAqIGkgKyAxXTsKICAgICAgaWYgKHggPCBtaW5YKSBtaW5YID0geDsKICAgICAgaWYgKHkgPCBtaW5ZKSBtaW5ZID0geTsKICAgICAgaWYgKHggPiBtYXhYKSBtYXhYID0geDsKICAgICAgaWYgKHkgPiBtYXhZKSBtYXhZID0geTsKICAgICAgdGhpcy5faWRzW2ldID0gaTsKICAgIH0KICAgIGNvbnN0IGN4ID0gKG1pblggKyBtYXhYKSAvIDI7CiAgICBjb25zdCBjeSA9IChtaW5ZICsgbWF4WSkgLyAyOwogICAgbGV0IG1pbkRpc3QgPSBJbmZpbml0eTsKICAgIGxldCBpMCwgaTEsIGkyOwoKICAgIC8vIHBpY2sgYSBzZWVkIHBvaW50IGNsb3NlIHRvIHRoZSBjZW50ZXIKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGNvbnN0IGQgPSBkaXN0KGN4LCBjeSwgY29vcmRzWzIgKiBpXSwgY29vcmRzWzIgKiBpICsgMV0pOwogICAgICBpZiAoZCA8IG1pbkRpc3QpIHsKICAgICAgICBpMCA9IGk7CiAgICAgICAgbWluRGlzdCA9IGQ7CiAgICAgIH0KICAgIH0KICAgIGNvbnN0IGkweCA9IGNvb3Jkc1syICogaTBdOwogICAgY29uc3QgaTB5ID0gY29vcmRzWzIgKiBpMCArIDFdOwogICAgbWluRGlzdCA9IEluZmluaXR5OwoKICAgIC8vIGZpbmQgdGhlIHBvaW50IGNsb3Nlc3QgdG8gdGhlIHNlZWQKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgIGlmIChpID09PSBpMCkgY29udGludWU7CiAgICAgIGNvbnN0IGQgPSBkaXN0KGkweCwgaTB5LCBjb29yZHNbMiAqIGldLCBjb29yZHNbMiAqIGkgKyAxXSk7CiAgICAgIGlmIChkIDwgbWluRGlzdCAmJiBkID4gMCkgewogICAgICAgIGkxID0gaTsKICAgICAgICBtaW5EaXN0ID0gZDsKICAgICAgfQogICAgfQogICAgbGV0IGkxeCA9IGNvb3Jkc1syICogaTFdOwogICAgbGV0IGkxeSA9IGNvb3Jkc1syICogaTEgKyAxXTsKICAgIGxldCBtaW5SYWRpdXMgPSBJbmZpbml0eTsKCiAgICAvLyBmaW5kIHRoZSB0aGlyZCBwb2ludCB3aGljaCBmb3JtcyB0aGUgc21hbGxlc3QgY2lyY3VtY2lyY2xlIHdpdGggdGhlIGZpcnN0IHR3bwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgaWYgKGkgPT09IGkwIHx8IGkgPT09IGkxKSBjb250aW51ZTsKICAgICAgY29uc3QgciA9IGNpcmN1bXJhZGl1cyhpMHgsIGkweSwgaTF4LCBpMXksIGNvb3Jkc1syICogaV0sIGNvb3Jkc1syICogaSArIDFdKTsKICAgICAgaWYgKHIgPCBtaW5SYWRpdXMpIHsKICAgICAgICBpMiA9IGk7CiAgICAgICAgbWluUmFkaXVzID0gcjsKICAgICAgfQogICAgfQogICAgbGV0IGkyeCA9IGNvb3Jkc1syICogaTJdOwogICAgbGV0IGkyeSA9IGNvb3Jkc1syICogaTIgKyAxXTsKICAgIGlmIChtaW5SYWRpdXMgPT09IEluZmluaXR5KSB7CiAgICAgIC8vIG9yZGVyIGNvbGxpbmVhciBwb2ludHMgYnkgZHggKG9yIGR5IGlmIGFsbCB4IGFyZSBpZGVudGljYWwpCiAgICAgIC8vIGFuZCByZXR1cm4gdGhlIGxpc3QgYXMgYSBodWxsCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgdGhpcy5fZGlzdHNbaV0gPSBjb29yZHNbMiAqIGldIC0gY29vcmRzWzBdIHx8IGNvb3Jkc1syICogaSArIDFdIC0gY29vcmRzWzFdOwogICAgICB9CiAgICAgIHF1aWNrc29ydCh0aGlzLl9pZHMsIHRoaXMuX2Rpc3RzLCAwLCBuIC0gMSk7CiAgICAgIGNvbnN0IGh1bGwgPSBuZXcgVWludDMyQXJyYXkobik7CiAgICAgIGxldCBqID0gMDsKICAgICAgZm9yIChsZXQgaSA9IDAsIGQwID0gLUluZmluaXR5OyBpIDwgbjsgaSsrKSB7CiAgICAgICAgY29uc3QgaWQgPSB0aGlzLl9pZHNbaV07CiAgICAgICAgaWYgKHRoaXMuX2Rpc3RzW2lkXSA+IGQwKSB7CiAgICAgICAgICBodWxsW2orK10gPSBpZDsKICAgICAgICAgIGQwID0gdGhpcy5fZGlzdHNbaWRdOwogICAgICAgIH0KICAgICAgfQogICAgICB0aGlzLmh1bGwgPSBodWxsLnN1YmFycmF5KDAsIGopOwogICAgICB0aGlzLnRyaWFuZ2xlcyA9IG5ldyBVaW50MzJBcnJheSgwKTsKICAgICAgdGhpcy5oYWxmZWRnZXMgPSBuZXcgVWludDMyQXJyYXkoMCk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBzd2FwIHRoZSBvcmRlciBvZiB0aGUgc2VlZCBwb2ludHMgZm9yIGNvdW50ZXItY2xvY2t3aXNlIG9yaWVudGF0aW9uCiAgICBpZiAob3JpZW50MmQoaTB4LCBpMHksIGkxeCwgaTF5LCBpMngsIGkyeSkgPCAwKSB7CiAgICAgIGNvbnN0IGkgPSBpMTsKICAgICAgY29uc3QgeCA9IGkxeDsKICAgICAgY29uc3QgeSA9IGkxeTsKICAgICAgaTEgPSBpMjsKICAgICAgaTF4ID0gaTJ4OwogICAgICBpMXkgPSBpMnk7CiAgICAgIGkyID0gaTsKICAgICAgaTJ4ID0geDsKICAgICAgaTJ5ID0geTsKICAgIH0KICAgIGNvbnN0IGNlbnRlciA9IGNpcmN1bWNlbnRlcihpMHgsIGkweSwgaTF4LCBpMXksIGkyeCwgaTJ5KTsKICAgIHRoaXMuX2N4ID0gY2VudGVyLng7CiAgICB0aGlzLl9jeSA9IGNlbnRlci55OwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgdGhpcy5fZGlzdHNbaV0gPSBkaXN0KGNvb3Jkc1syICogaV0sIGNvb3Jkc1syICogaSArIDFdLCBjZW50ZXIueCwgY2VudGVyLnkpOwogICAgfQoKICAgIC8vIHNvcnQgdGhlIHBvaW50cyBieSBkaXN0YW5jZSBmcm9tIHRoZSBzZWVkIHRyaWFuZ2xlIGNpcmN1bWNlbnRlcgogICAgcXVpY2tzb3J0KHRoaXMuX2lkcywgdGhpcy5fZGlzdHMsIDAsIG4gLSAxKTsKCiAgICAvLyBzZXQgdXAgdGhlIHNlZWQgdHJpYW5nbGUgYXMgdGhlIHN0YXJ0aW5nIGh1bGwKICAgIHRoaXMuX2h1bGxTdGFydCA9IGkwOwogICAgbGV0IGh1bGxTaXplID0gMzsKICAgIGh1bGxOZXh0W2kwXSA9IGh1bGxQcmV2W2kyXSA9IGkxOwogICAgaHVsbE5leHRbaTFdID0gaHVsbFByZXZbaTBdID0gaTI7CiAgICBodWxsTmV4dFtpMl0gPSBodWxsUHJldltpMV0gPSBpMDsKICAgIGh1bGxUcmlbaTBdID0gMDsKICAgIGh1bGxUcmlbaTFdID0gMTsKICAgIGh1bGxUcmlbaTJdID0gMjsKICAgIGh1bGxIYXNoLmZpbGwoLTEpOwogICAgaHVsbEhhc2hbdGhpcy5faGFzaEtleShpMHgsIGkweSldID0gaTA7CiAgICBodWxsSGFzaFt0aGlzLl9oYXNoS2V5KGkxeCwgaTF5KV0gPSBpMTsKICAgIGh1bGxIYXNoW3RoaXMuX2hhc2hLZXkoaTJ4LCBpMnkpXSA9IGkyOwogICAgdGhpcy50cmlhbmdsZXNMZW4gPSAwOwogICAgdGhpcy5fYWRkVHJpYW5nbGUoaTAsIGkxLCBpMiwgLTEsIC0xLCAtMSk7CiAgICBmb3IgKGxldCBrID0gMCwgeHAsIHlwOyBrIDwgdGhpcy5faWRzLmxlbmd0aDsgaysrKSB7CiAgICAgIGNvbnN0IGkgPSB0aGlzLl9pZHNba107CiAgICAgIGNvbnN0IHggPSBjb29yZHNbMiAqIGldOwogICAgICBjb25zdCB5ID0gY29vcmRzWzIgKiBpICsgMV07CgogICAgICAvLyBza2lwIG5lYXItZHVwbGljYXRlIHBvaW50cwogICAgICBpZiAoayA+IDAgJiYgTWF0aC5hYnMoeCAtIHhwKSA8PSBFUFNJTE9OICYmIE1hdGguYWJzKHkgLSB5cCkgPD0gRVBTSUxPTikgY29udGludWU7CiAgICAgIHhwID0geDsKICAgICAgeXAgPSB5OwoKICAgICAgLy8gc2tpcCBzZWVkIHRyaWFuZ2xlIHBvaW50cwogICAgICBpZiAoaSA9PT0gaTAgfHwgaSA9PT0gaTEgfHwgaSA9PT0gaTIpIGNvbnRpbnVlOwoKICAgICAgLy8gZmluZCBhIHZpc2libGUgZWRnZSBvbiB0aGUgY29udmV4IGh1bGwgdXNpbmcgZWRnZSBoYXNoCiAgICAgIGxldCBzdGFydCA9IDA7CiAgICAgIGZvciAobGV0IGogPSAwLCBrZXkgPSB0aGlzLl9oYXNoS2V5KHgsIHkpOyBqIDwgdGhpcy5faGFzaFNpemU7IGorKykgewogICAgICAgIHN0YXJ0ID0gaHVsbEhhc2hbKGtleSArIGopICUgdGhpcy5faGFzaFNpemVdOwogICAgICAgIGlmIChzdGFydCAhPT0gLTEgJiYgc3RhcnQgIT09IGh1bGxOZXh0W3N0YXJ0XSkgYnJlYWs7CiAgICAgIH0KICAgICAgc3RhcnQgPSBodWxsUHJldltzdGFydF07CiAgICAgIGxldCBlID0gc3RhcnQsCiAgICAgICAgcTsKICAgICAgd2hpbGUgKHEgPSBodWxsTmV4dFtlXSwgb3JpZW50MmQoeCwgeSwgY29vcmRzWzIgKiBlXSwgY29vcmRzWzIgKiBlICsgMV0sIGNvb3Jkc1syICogcV0sIGNvb3Jkc1syICogcSArIDFdKSA+PSAwKSB7CiAgICAgICAgZSA9IHE7CiAgICAgICAgaWYgKGUgPT09IHN0YXJ0KSB7CiAgICAgICAgICBlID0gLTE7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGUgPT09IC0xKSBjb250aW51ZTsgLy8gbGlrZWx5IGEgbmVhci1kdXBsaWNhdGUgcG9pbnQ7IHNraXAgaXQKCiAgICAgIC8vIGFkZCB0aGUgZmlyc3QgdHJpYW5nbGUgZnJvbSB0aGUgcG9pbnQKICAgICAgbGV0IHQgPSB0aGlzLl9hZGRUcmlhbmdsZShlLCBpLCBodWxsTmV4dFtlXSwgLTEsIC0xLCBodWxsVHJpW2VdKTsKCiAgICAgIC8vIHJlY3Vyc2l2ZWx5IGZsaXAgdHJpYW5nbGVzIGZyb20gdGhlIHBvaW50IHVudGlsIHRoZXkgc2F0aXNmeSB0aGUgRGVsYXVuYXkgY29uZGl0aW9uCiAgICAgIGh1bGxUcmlbaV0gPSB0aGlzLl9sZWdhbGl6ZSh0ICsgMik7CiAgICAgIGh1bGxUcmlbZV0gPSB0OyAvLyBrZWVwIHRyYWNrIG9mIGJvdW5kYXJ5IHRyaWFuZ2xlcyBvbiB0aGUgaHVsbAogICAgICBodWxsU2l6ZSsrOwoKICAgICAgLy8gd2FsayBmb3J3YXJkIHRocm91Z2ggdGhlIGh1bGwsIGFkZGluZyBtb3JlIHRyaWFuZ2xlcyBhbmQgZmxpcHBpbmcgcmVjdXJzaXZlbHkKICAgICAgbGV0IG4gPSBodWxsTmV4dFtlXTsKICAgICAgd2hpbGUgKHEgPSBodWxsTmV4dFtuXSwgb3JpZW50MmQoeCwgeSwgY29vcmRzWzIgKiBuXSwgY29vcmRzWzIgKiBuICsgMV0sIGNvb3Jkc1syICogcV0sIGNvb3Jkc1syICogcSArIDFdKSA8IDApIHsKICAgICAgICB0ID0gdGhpcy5fYWRkVHJpYW5nbGUobiwgaSwgcSwgaHVsbFRyaVtpXSwgLTEsIGh1bGxUcmlbbl0pOwogICAgICAgIGh1bGxUcmlbaV0gPSB0aGlzLl9sZWdhbGl6ZSh0ICsgMik7CiAgICAgICAgaHVsbE5leHRbbl0gPSBuOyAvLyBtYXJrIGFzIHJlbW92ZWQKICAgICAgICBodWxsU2l6ZS0tOwogICAgICAgIG4gPSBxOwogICAgICB9CgogICAgICAvLyB3YWxrIGJhY2t3YXJkIGZyb20gdGhlIG90aGVyIHNpZGUsIGFkZGluZyBtb3JlIHRyaWFuZ2xlcyBhbmQgZmxpcHBpbmcKICAgICAgaWYgKGUgPT09IHN0YXJ0KSB7CiAgICAgICAgd2hpbGUgKHEgPSBodWxsUHJldltlXSwgb3JpZW50MmQoeCwgeSwgY29vcmRzWzIgKiBxXSwgY29vcmRzWzIgKiBxICsgMV0sIGNvb3Jkc1syICogZV0sIGNvb3Jkc1syICogZSArIDFdKSA8IDApIHsKICAgICAgICAgIHQgPSB0aGlzLl9hZGRUcmlhbmdsZShxLCBpLCBlLCAtMSwgaHVsbFRyaVtlXSwgaHVsbFRyaVtxXSk7CiAgICAgICAgICB0aGlzLl9sZWdhbGl6ZSh0ICsgMik7CiAgICAgICAgICBodWxsVHJpW3FdID0gdDsKICAgICAgICAgIGh1bGxOZXh0W2VdID0gZTsgLy8gbWFyayBhcyByZW1vdmVkCiAgICAgICAgICBodWxsU2l6ZS0tOwogICAgICAgICAgZSA9IHE7CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyB1cGRhdGUgdGhlIGh1bGwgaW5kaWNlcwogICAgICB0aGlzLl9odWxsU3RhcnQgPSBodWxsUHJldltpXSA9IGU7CiAgICAgIGh1bGxOZXh0W2VdID0gaHVsbFByZXZbbl0gPSBpOwogICAgICBodWxsTmV4dFtpXSA9IG47CgogICAgICAvLyBzYXZlIHRoZSB0d28gbmV3IGVkZ2VzIGluIHRoZSBoYXNoIHRhYmxlCiAgICAgIGh1bGxIYXNoW3RoaXMuX2hhc2hLZXkoeCwgeSldID0gaTsKICAgICAgaHVsbEhhc2hbdGhpcy5faGFzaEtleShjb29yZHNbMiAqIGVdLCBjb29yZHNbMiAqIGUgKyAxXSldID0gZTsKICAgIH0KICAgIHRoaXMuaHVsbCA9IG5ldyBVaW50MzJBcnJheShodWxsU2l6ZSk7CiAgICBmb3IgKGxldCBpID0gMCwgZSA9IHRoaXMuX2h1bGxTdGFydDsgaSA8IGh1bGxTaXplOyBpKyspIHsKICAgICAgdGhpcy5odWxsW2ldID0gZTsKICAgICAgZSA9IGh1bGxOZXh0W2VdOwogICAgfQoKICAgIC8vIHRyaW0gdHlwZWQgdHJpYW5nbGUgbWVzaCBhcnJheXMKICAgIHRoaXMudHJpYW5nbGVzID0gdGhpcy5fdHJpYW5nbGVzLnN1YmFycmF5KDAsIHRoaXMudHJpYW5nbGVzTGVuKTsKICAgIHRoaXMuaGFsZmVkZ2VzID0gdGhpcy5faGFsZmVkZ2VzLnN1YmFycmF5KDAsIHRoaXMudHJpYW5nbGVzTGVuKTsKICB9CiAgX2hhc2hLZXkoeCwgeSkgewogICAgcmV0dXJuIE1hdGguZmxvb3IocHNldWRvQW5nbGUoeCAtIHRoaXMuX2N4LCB5IC0gdGhpcy5fY3kpICogdGhpcy5faGFzaFNpemUpICUgdGhpcy5faGFzaFNpemU7CiAgfQogIF9sZWdhbGl6ZShhKSB7CiAgICBjb25zdCB7CiAgICAgIF90cmlhbmdsZXM6IHRyaWFuZ2xlcywKICAgICAgX2hhbGZlZGdlczogaGFsZmVkZ2VzLAogICAgICBjb29yZHMKICAgIH0gPSB0aGlzOwogICAgbGV0IGkgPSAwOwogICAgbGV0IGFyID0gMDsKCiAgICAvLyByZWN1cnNpb24gZWxpbWluYXRlZCB3aXRoIGEgZml4ZWQtc2l6ZSBzdGFjawogICAgd2hpbGUgKHRydWUpIHsKICAgICAgY29uc3QgYiA9IGhhbGZlZGdlc1thXTsKCiAgICAgIC8qIGlmIHRoZSBwYWlyIG9mIHRyaWFuZ2xlcyBkb2Vzbid0IHNhdGlzZnkgdGhlIERlbGF1bmF5IGNvbmRpdGlvbgogICAgICAgKiAocDEgaXMgaW5zaWRlIHRoZSBjaXJjdW1jaXJjbGUgb2YgW3AwLCBwbCwgcHJdKSwgZmxpcCB0aGVtLAogICAgICAgKiB0aGVuIGRvIHRoZSBzYW1lIGNoZWNrL2ZsaXAgcmVjdXJzaXZlbHkgZm9yIHRoZSBuZXcgcGFpciBvZiB0cmlhbmdsZXMKICAgICAgICoKICAgICAgICogICAgICAgICAgIHBsICAgICAgICAgICAgICAgICAgICBwbAogICAgICAgKiAgICAgICAgICAvfHxcICAgICAgICAgICAgICAgICAgLyAgXAogICAgICAgKiAgICAgICBhbC8gfHwgXGJsICAgICAgICAgICAgYWwvICAgIFxhCiAgICAgICAqICAgICAgICAvICB8fCAgXCAgICAgICAgICAgICAgLyAgICAgIFwKICAgICAgICogICAgICAgLyAgYXx8YiAgXCAgICBmbGlwICAgIC9fX19hcl9fX1wKICAgICAgICogICAgIHAwXCAgIHx8ICAgL3AxICAgPT4gICBwMFwtLS1ibC0tLS9wMQogICAgICAgKiAgICAgICAgXCAgfHwgIC8gICAgICAgICAgICAgIFwgICAgICAvCiAgICAgICAqICAgICAgIGFyXCB8fCAvYnIgICAgICAgICAgICAgYlwgICAgL2JyCiAgICAgICAqICAgICAgICAgIFx8fC8gICAgICAgICAgICAgICAgICBcICAvCiAgICAgICAqICAgICAgICAgICBwciAgICAgICAgICAgICAgICAgICAgcHIKICAgICAgICovCiAgICAgIGNvbnN0IGEwID0gYSAtIGEgJSAzOwogICAgICBhciA9IGEwICsgKGEgKyAyKSAlIDM7CiAgICAgIGlmIChiID09PSAtMSkgewogICAgICAgIC8vIGNvbnZleCBodWxsIGVkZ2UKICAgICAgICBpZiAoaSA9PT0gMCkgYnJlYWs7CiAgICAgICAgYSA9IEVER0VfU1RBQ0tbLS1pXTsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBjb25zdCBiMCA9IGIgLSBiICUgMzsKICAgICAgY29uc3QgYWwgPSBhMCArIChhICsgMSkgJSAzOwogICAgICBjb25zdCBibCA9IGIwICsgKGIgKyAyKSAlIDM7CiAgICAgIGNvbnN0IHAwID0gdHJpYW5nbGVzW2FyXTsKICAgICAgY29uc3QgcHIgPSB0cmlhbmdsZXNbYV07CiAgICAgIGNvbnN0IHBsID0gdHJpYW5nbGVzW2FsXTsKICAgICAgY29uc3QgcDEgPSB0cmlhbmdsZXNbYmxdOwogICAgICBjb25zdCBpbGxlZ2FsID0gaW5DaXJjbGUoY29vcmRzWzIgKiBwMF0sIGNvb3Jkc1syICogcDAgKyAxXSwgY29vcmRzWzIgKiBwcl0sIGNvb3Jkc1syICogcHIgKyAxXSwgY29vcmRzWzIgKiBwbF0sIGNvb3Jkc1syICogcGwgKyAxXSwgY29vcmRzWzIgKiBwMV0sIGNvb3Jkc1syICogcDEgKyAxXSk7CiAgICAgIGlmIChpbGxlZ2FsKSB7CiAgICAgICAgdHJpYW5nbGVzW2FdID0gcDE7CiAgICAgICAgdHJpYW5nbGVzW2JdID0gcDA7CiAgICAgICAgY29uc3QgaGJsID0gaGFsZmVkZ2VzW2JsXTsKCiAgICAgICAgLy8gZWRnZSBzd2FwcGVkIG9uIHRoZSBvdGhlciBzaWRlIG9mIHRoZSBodWxsIChyYXJlKTsgZml4IHRoZSBoYWxmZWRnZSByZWZlcmVuY2UKICAgICAgICBpZiAoaGJsID09PSAtMSkgewogICAgICAgICAgbGV0IGUgPSB0aGlzLl9odWxsU3RhcnQ7CiAgICAgICAgICBkbyB7CiAgICAgICAgICAgIGlmICh0aGlzLl9odWxsVHJpW2VdID09PSBibCkgewogICAgICAgICAgICAgIHRoaXMuX2h1bGxUcmlbZV0gPSBhOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGUgPSB0aGlzLl9odWxsUHJldltlXTsKICAgICAgICAgIH0gd2hpbGUgKGUgIT09IHRoaXMuX2h1bGxTdGFydCk7CiAgICAgICAgfQogICAgICAgIHRoaXMuX2xpbmsoYSwgaGJsKTsKICAgICAgICB0aGlzLl9saW5rKGIsIGhhbGZlZGdlc1thcl0pOwogICAgICAgIHRoaXMuX2xpbmsoYXIsIGJsKTsKICAgICAgICBjb25zdCBiciA9IGIwICsgKGIgKyAxKSAlIDM7CgogICAgICAgIC8vIGRvbid0IHdvcnJ5IGFib3V0IGhpdHRpbmcgdGhlIGNhcDogaXQgY2FuIG9ubHkgaGFwcGVuIG9uIGV4dHJlbWVseSBkZWdlbmVyYXRlIGlucHV0CiAgICAgICAgaWYgKGkgPCBFREdFX1NUQUNLLmxlbmd0aCkgewogICAgICAgICAgRURHRV9TVEFDS1tpKytdID0gYnI7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmIChpID09PSAwKSBicmVhazsKICAgICAgICBhID0gRURHRV9TVEFDS1stLWldOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gYXI7CiAgfQogIF9saW5rKGEsIGIpIHsKICAgIHRoaXMuX2hhbGZlZGdlc1thXSA9IGI7CiAgICBpZiAoYiAhPT0gLTEpIHRoaXMuX2hhbGZlZGdlc1tiXSA9IGE7CiAgfQoKICAvLyBhZGQgYSBuZXcgdHJpYW5nbGUgZ2l2ZW4gdmVydGV4IGluZGljZXMgYW5kIGFkamFjZW50IGhhbGYtZWRnZSBpZHMKICBfYWRkVHJpYW5nbGUoaTAsIGkxLCBpMiwgYSwgYiwgYykgewogICAgY29uc3QgdCA9IHRoaXMudHJpYW5nbGVzTGVuOwogICAgdGhpcy5fdHJpYW5nbGVzW3RdID0gaTA7CiAgICB0aGlzLl90cmlhbmdsZXNbdCArIDFdID0gaTE7CiAgICB0aGlzLl90cmlhbmdsZXNbdCArIDJdID0gaTI7CiAgICB0aGlzLl9saW5rKHQsIGEpOwogICAgdGhpcy5fbGluayh0ICsgMSwgYik7CiAgICB0aGlzLl9saW5rKHQgKyAyLCBjKTsKICAgIHRoaXMudHJpYW5nbGVzTGVuICs9IDM7CiAgICByZXR1cm4gdDsKICB9Cn0KCi8vIG1vbm90b25pY2FsbHkgaW5jcmVhc2VzIHdpdGggcmVhbCBhbmdsZSwgYnV0IGRvZXNuJ3QgbmVlZCBleHBlbnNpdmUgdHJpZ29ub21ldHJ5CmZ1bmN0aW9uIHBzZXVkb0FuZ2xlKGR4LCBkeSkgewogIGNvbnN0IHAgPSBkeCAvIChNYXRoLmFicyhkeCkgKyBNYXRoLmFicyhkeSkpOwogIHJldHVybiAoZHkgPiAwID8gMyAtIHAgOiAxICsgcCkgLyA0OyAvLyBbMC4uMV0KfQoKZnVuY3Rpb24gZGlzdChheCwgYXksIGJ4LCBieSkgewogIGNvbnN0IGR4ID0gYXggLSBieDsKICBjb25zdCBkeSA9IGF5IC0gYnk7CiAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5Owp9CmZ1bmN0aW9uIGluQ2lyY2xlKGF4LCBheSwgYngsIGJ5LCBjeCwgY3ksIHB4LCBweSkgewogIGNvbnN0IGR4ID0gYXggLSBweDsKICBjb25zdCBkeSA9IGF5IC0gcHk7CiAgY29uc3QgZXggPSBieCAtIHB4OwogIGNvbnN0IGV5ID0gYnkgLSBweTsKICBjb25zdCBmeCA9IGN4IC0gcHg7CiAgY29uc3QgZnkgPSBjeSAtIHB5OwogIGNvbnN0IGFwID0gZHggKiBkeCArIGR5ICogZHk7CiAgY29uc3QgYnAgPSBleCAqIGV4ICsgZXkgKiBleTsKICBjb25zdCBjcCA9IGZ4ICogZnggKyBmeSAqIGZ5OwogIHJldHVybiBkeCAqIChleSAqIGNwIC0gYnAgKiBmeSkgLSBkeSAqIChleCAqIGNwIC0gYnAgKiBmeCkgKyBhcCAqIChleCAqIGZ5IC0gZXkgKiBmeCkgPCAwOwp9CmZ1bmN0aW9uIGNpcmN1bXJhZGl1cyhheCwgYXksIGJ4LCBieSwgY3gsIGN5KSB7CiAgY29uc3QgZHggPSBieCAtIGF4OwogIGNvbnN0IGR5ID0gYnkgLSBheTsKICBjb25zdCBleCA9IGN4IC0gYXg7CiAgY29uc3QgZXkgPSBjeSAtIGF5OwogIGNvbnN0IGJsID0gZHggKiBkeCArIGR5ICogZHk7CiAgY29uc3QgY2wgPSBleCAqIGV4ICsgZXkgKiBleTsKICBjb25zdCBkID0gMC41IC8gKGR4ICogZXkgLSBkeSAqIGV4KTsKICBjb25zdCB4ID0gKGV5ICogYmwgLSBkeSAqIGNsKSAqIGQ7CiAgY29uc3QgeSA9IChkeCAqIGNsIC0gZXggKiBibCkgKiBkOwogIHJldHVybiB4ICogeCArIHkgKiB5Owp9CmZ1bmN0aW9uIGNpcmN1bWNlbnRlcihheCwgYXksIGJ4LCBieSwgY3gsIGN5KSB7CiAgY29uc3QgZHggPSBieCAtIGF4OwogIGNvbnN0IGR5ID0gYnkgLSBheTsKICBjb25zdCBleCA9IGN4IC0gYXg7CiAgY29uc3QgZXkgPSBjeSAtIGF5OwogIGNvbnN0IGJsID0gZHggKiBkeCArIGR5ICogZHk7CiAgY29uc3QgY2wgPSBleCAqIGV4ICsgZXkgKiBleTsKICBjb25zdCBkID0gMC41IC8gKGR4ICogZXkgLSBkeSAqIGV4KTsKICBjb25zdCB4ID0gYXggKyAoZXkgKiBibCAtIGR5ICogY2wpICogZDsKICBjb25zdCB5ID0gYXkgKyAoZHggKiBjbCAtIGV4ICogYmwpICogZDsKICByZXR1cm4gewogICAgeCwKICAgIHkKICB9Owp9CmZ1bmN0aW9uIHF1aWNrc29ydChpZHMsIGRpc3RzLCBsZWZ0LCByaWdodCkgewogIGlmIChyaWdodCAtIGxlZnQgPD0gMjApIHsKICAgIGZvciAobGV0IGkgPSBsZWZ0ICsgMTsgaSA8PSByaWdodDsgaSsrKSB7CiAgICAgIGNvbnN0IHRlbXAgPSBpZHNbaV07CiAgICAgIGNvbnN0IHRlbXBEaXN0ID0gZGlzdHNbdGVtcF07CiAgICAgIGxldCBqID0gaSAtIDE7CiAgICAgIHdoaWxlIChqID49IGxlZnQgJiYgZGlzdHNbaWRzW2pdXSA+IHRlbXBEaXN0KSBpZHNbaiArIDFdID0gaWRzW2otLV07CiAgICAgIGlkc1tqICsgMV0gPSB0ZW1wOwogICAgfQogIH0gZWxzZSB7CiAgICBjb25zdCBtZWRpYW4gPSBsZWZ0ICsgcmlnaHQgPj4gMTsKICAgIGxldCBpID0gbGVmdCArIDE7CiAgICBsZXQgaiA9IHJpZ2h0OwogICAgc3dhcChpZHMsIG1lZGlhbiwgaSk7CiAgICBpZiAoZGlzdHNbaWRzW2xlZnRdXSA+IGRpc3RzW2lkc1tyaWdodF1dKSBzd2FwKGlkcywgbGVmdCwgcmlnaHQpOwogICAgaWYgKGRpc3RzW2lkc1tpXV0gPiBkaXN0c1tpZHNbcmlnaHRdXSkgc3dhcChpZHMsIGksIHJpZ2h0KTsKICAgIGlmIChkaXN0c1tpZHNbbGVmdF1dID4gZGlzdHNbaWRzW2ldXSkgc3dhcChpZHMsIGxlZnQsIGkpOwogICAgY29uc3QgdGVtcCA9IGlkc1tpXTsKICAgIGNvbnN0IHRlbXBEaXN0ID0gZGlzdHNbdGVtcF07CiAgICB3aGlsZSAodHJ1ZSkgewogICAgICBkbyBpKys7IHdoaWxlIChkaXN0c1tpZHNbaV1dIDwgdGVtcERpc3QpOwogICAgICBkbyBqLS07IHdoaWxlIChkaXN0c1tpZHNbal1dID4gdGVtcERpc3QpOwogICAgICBpZiAoaiA8IGkpIGJyZWFrOwogICAgICBzd2FwKGlkcywgaSwgaik7CiAgICB9CiAgICBpZHNbbGVmdCArIDFdID0gaWRzW2pdOwogICAgaWRzW2pdID0gdGVtcDsKICAgIGlmIChyaWdodCAtIGkgKyAxID49IGogLSBsZWZ0KSB7CiAgICAgIHF1aWNrc29ydChpZHMsIGRpc3RzLCBpLCByaWdodCk7CiAgICAgIHF1aWNrc29ydChpZHMsIGRpc3RzLCBsZWZ0LCBqIC0gMSk7CiAgICB9IGVsc2UgewogICAgICBxdWlja3NvcnQoaWRzLCBkaXN0cywgbGVmdCwgaiAtIDEpOwogICAgICBxdWlja3NvcnQoaWRzLCBkaXN0cywgaSwgcmlnaHQpOwogICAgfQogIH0KfQpmdW5jdGlvbiBzd2FwKGFyciwgaSwgaikgewogIGNvbnN0IHRtcCA9IGFycltpXTsKICBhcnJbaV0gPSBhcnJbal07CiAgYXJyW2pdID0gdG1wOwp9CmZ1bmN0aW9uIGRlZmF1bHRHZXRYKHApIHsKICByZXR1cm4gcFswXTsKfQpmdW5jdGlvbiBkZWZhdWx0R2V0WShwKSB7CiAgcmV0dXJuIHBbMV07Cn0KCmNvbnN0IGVwc2lsb24gPSAxZS02OwpjbGFzcyBQYXRoIHsKICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMuX3gwID0gdGhpcy5feTAgPQogICAgLy8gc3RhcnQgb2YgY3VycmVudCBzdWJwYXRoCiAgICB0aGlzLl94MSA9IHRoaXMuX3kxID0gbnVsbDsgLy8gZW5kIG9mIGN1cnJlbnQgc3VicGF0aAogICAgdGhpcy5fID0gIiI7CiAgfQogIG1vdmVUbyh4LCB5KSB7CiAgICB0aGlzLl8gKz0gYE0ke3RoaXMuX3gwID0gdGhpcy5feDEgPSAreH0sJHt0aGlzLl95MCA9IHRoaXMuX3kxID0gK3l9YDsKICB9CiAgY2xvc2VQYXRoKCkgewogICAgaWYgKHRoaXMuX3gxICE9PSBudWxsKSB7CiAgICAgIHRoaXMuX3gxID0gdGhpcy5feDAsIHRoaXMuX3kxID0gdGhpcy5feTA7CiAgICAgIHRoaXMuXyArPSAiWiI7CiAgICB9CiAgfQogIGxpbmVUbyh4LCB5KSB7CiAgICB0aGlzLl8gKz0gYEwke3RoaXMuX3gxID0gK3h9LCR7dGhpcy5feTEgPSAreX1gOwogIH0KICBhcmMoeCwgeSwgcikgewogICAgeCA9ICt4LCB5ID0gK3ksIHIgPSArcjsKICAgIGNvbnN0IHgwID0geCArIHI7CiAgICBjb25zdCB5MCA9IHk7CiAgICBpZiAociA8IDApIHRocm93IG5ldyBFcnJvcigibmVnYXRpdmUgcmFkaXVzIik7CiAgICBpZiAodGhpcy5feDEgPT09IG51bGwpIHRoaXMuXyArPSBgTSR7eDB9LCR7eTB9YDtlbHNlIGlmIChNYXRoLmFicyh0aGlzLl94MSAtIHgwKSA+IGVwc2lsb24gfHwgTWF0aC5hYnModGhpcy5feTEgLSB5MCkgPiBlcHNpbG9uKSB0aGlzLl8gKz0gIkwiICsgeDAgKyAiLCIgKyB5MDsKICAgIGlmICghcikgcmV0dXJuOwogICAgdGhpcy5fICs9IGBBJHtyfSwke3J9LDAsMSwxLCR7eCAtIHJ9LCR7eX1BJHtyfSwke3J9LDAsMSwxLCR7dGhpcy5feDEgPSB4MH0sJHt0aGlzLl95MSA9IHkwfWA7CiAgfQogIHJlY3QoeCwgeSwgdywgaCkgewogICAgdGhpcy5fICs9IGBNJHt0aGlzLl94MCA9IHRoaXMuX3gxID0gK3h9LCR7dGhpcy5feTAgPSB0aGlzLl95MSA9ICt5fWgkeyt3fXYkeytofWgkey13fVpgOwogIH0KICB2YWx1ZSgpIHsKICAgIHJldHVybiB0aGlzLl8gfHwgbnVsbDsKICB9Cn0KCmNsYXNzIFBvbHlnb24gewogIGNvbnN0cnVjdG9yKCkgewogICAgdGhpcy5fID0gW107CiAgfQogIG1vdmVUbyh4LCB5KSB7CiAgICB0aGlzLl8ucHVzaChbeCwgeV0pOwogIH0KICBjbG9zZVBhdGgoKSB7CiAgICB0aGlzLl8ucHVzaCh0aGlzLl9bMF0uc2xpY2UoKSk7CiAgfQogIGxpbmVUbyh4LCB5KSB7CiAgICB0aGlzLl8ucHVzaChbeCwgeV0pOwogIH0KICB2YWx1ZSgpIHsKICAgIHJldHVybiB0aGlzLl8ubGVuZ3RoID8gdGhpcy5fIDogbnVsbDsKICB9Cn0KCmNsYXNzIFZvcm9ub2kgewogIGNvbnN0cnVjdG9yKGRlbGF1bmF5LCBbeG1pbiwgeW1pbiwgeG1heCwgeW1heF0gPSBbMCwgMCwgOTYwLCA1MDBdKSB7CiAgICBpZiAoISgoeG1heCA9ICt4bWF4KSA+PSAoeG1pbiA9ICt4bWluKSkgfHwgISgoeW1heCA9ICt5bWF4KSA+PSAoeW1pbiA9ICt5bWluKSkpIHRocm93IG5ldyBFcnJvcigiaW52YWxpZCBib3VuZHMiKTsKICAgIHRoaXMuZGVsYXVuYXkgPSBkZWxhdW5heTsKICAgIHRoaXMuX2NpcmN1bWNlbnRlcnMgPSBuZXcgRmxvYXQ2NEFycmF5KGRlbGF1bmF5LnBvaW50cy5sZW5ndGggKiAyKTsKICAgIHRoaXMudmVjdG9ycyA9IG5ldyBGbG9hdDY0QXJyYXkoZGVsYXVuYXkucG9pbnRzLmxlbmd0aCAqIDIpOwogICAgdGhpcy54bWF4ID0geG1heCwgdGhpcy54bWluID0geG1pbjsKICAgIHRoaXMueW1heCA9IHltYXgsIHRoaXMueW1pbiA9IHltaW47CiAgICB0aGlzLl9pbml0KCk7CiAgfQogIHVwZGF0ZSgpIHsKICAgIHRoaXMuZGVsYXVuYXkudXBkYXRlKCk7CiAgICB0aGlzLl9pbml0KCk7CiAgICByZXR1cm4gdGhpczsKICB9CiAgX2luaXQoKSB7CiAgICBjb25zdCB7CiAgICAgIGRlbGF1bmF5OiB7CiAgICAgICAgcG9pbnRzLAogICAgICAgIGh1bGwsCiAgICAgICAgdHJpYW5nbGVzCiAgICAgIH0sCiAgICAgIHZlY3RvcnMKICAgIH0gPSB0aGlzOwogICAgbGV0IGJ4LCBieTsgLy8gbGF6aWx5IGNvbXB1dGVkIGJhcnljZW50ZXIgb2YgdGhlIGh1bGwKCiAgICAvLyBDb21wdXRlIGNpcmN1bWNlbnRlcnMuCiAgICBjb25zdCBjaXJjdW1jZW50ZXJzID0gdGhpcy5jaXJjdW1jZW50ZXJzID0gdGhpcy5fY2lyY3VtY2VudGVycy5zdWJhcnJheSgwLCB0cmlhbmdsZXMubGVuZ3RoIC8gMyAqIDIpOwogICAgZm9yIChsZXQgaSA9IDAsIGogPSAwLCBuID0gdHJpYW5nbGVzLmxlbmd0aCwgeCwgeTsgaSA8IG47IGkgKz0gMywgaiArPSAyKSB7CiAgICAgIGNvbnN0IHQxID0gdHJpYW5nbGVzW2ldICogMjsKICAgICAgY29uc3QgdDIgPSB0cmlhbmdsZXNbaSArIDFdICogMjsKICAgICAgY29uc3QgdDMgPSB0cmlhbmdsZXNbaSArIDJdICogMjsKICAgICAgY29uc3QgeDEgPSBwb2ludHNbdDFdOwogICAgICBjb25zdCB5MSA9IHBvaW50c1t0MSArIDFdOwogICAgICBjb25zdCB4MiA9IHBvaW50c1t0Ml07CiAgICAgIGNvbnN0IHkyID0gcG9pbnRzW3QyICsgMV07CiAgICAgIGNvbnN0IHgzID0gcG9pbnRzW3QzXTsKICAgICAgY29uc3QgeTMgPSBwb2ludHNbdDMgKyAxXTsKICAgICAgY29uc3QgZHggPSB4MiAtIHgxOwogICAgICBjb25zdCBkeSA9IHkyIC0geTE7CiAgICAgIGNvbnN0IGV4ID0geDMgLSB4MTsKICAgICAgY29uc3QgZXkgPSB5MyAtIHkxOwogICAgICBjb25zdCBhYiA9IChkeCAqIGV5IC0gZHkgKiBleCkgKiAyOwogICAgICBpZiAoTWF0aC5hYnMoYWIpIDwgMWUtOSkgewogICAgICAgIC8vIEZvciBhIGRlZ2VuZXJhdGUgdHJpYW5nbGUsIHRoZSBjaXJjdW1jZW50ZXIgaXMgYXQgdGhlIGluZmluaXR5LCBpbiBhCiAgICAgICAgLy8gZGlyZWN0aW9uIG9ydGhvZ29uYWwgdG8gdGhlIGhhbGZlZGdlIGFuZCBhd2F5IGZyb20gdGhlIOKAnGNlbnRlcuKAnSBvZgogICAgICAgIC8vIHRoZSBkaWFncmFtIDxieCwgYnk+LCBkZWZpbmVkIGFzIHRoZSBodWxs4oCZcyBiYXJ5Y2VudGVyLgogICAgICAgIGlmIChieCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICBieCA9IGJ5ID0gMDsKICAgICAgICAgIGZvciAoY29uc3QgaSBvZiBodWxsKSBieCArPSBwb2ludHNbaSAqIDJdLCBieSArPSBwb2ludHNbaSAqIDIgKyAxXTsKICAgICAgICAgIGJ4IC89IGh1bGwubGVuZ3RoLCBieSAvPSBodWxsLmxlbmd0aDsKICAgICAgICB9CiAgICAgICAgY29uc3QgYSA9IDFlOSAqIE1hdGguc2lnbigoYnggLSB4MSkgKiBleSAtIChieSAtIHkxKSAqIGV4KTsKICAgICAgICB4ID0gKHgxICsgeDMpIC8gMiAtIGEgKiBleTsKICAgICAgICB5ID0gKHkxICsgeTMpIC8gMiArIGEgKiBleDsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBkID0gMSAvIGFiOwogICAgICAgIGNvbnN0IGJsID0gZHggKiBkeCArIGR5ICogZHk7CiAgICAgICAgY29uc3QgY2wgPSBleCAqIGV4ICsgZXkgKiBleTsKICAgICAgICB4ID0geDEgKyAoZXkgKiBibCAtIGR5ICogY2wpICogZDsKICAgICAgICB5ID0geTEgKyAoZHggKiBjbCAtIGV4ICogYmwpICogZDsKICAgICAgfQogICAgICBjaXJjdW1jZW50ZXJzW2pdID0geDsKICAgICAgY2lyY3VtY2VudGVyc1tqICsgMV0gPSB5OwogICAgfQoKICAgIC8vIENvbXB1dGUgZXh0ZXJpb3IgY2VsbCByYXlzLgogICAgbGV0IGggPSBodWxsW2h1bGwubGVuZ3RoIC0gMV07CiAgICBsZXQgcDAsCiAgICAgIHAxID0gaCAqIDQ7CiAgICBsZXQgeDAsCiAgICAgIHgxID0gcG9pbnRzWzIgKiBoXTsKICAgIGxldCB5MCwKICAgICAgeTEgPSBwb2ludHNbMiAqIGggKyAxXTsKICAgIHZlY3RvcnMuZmlsbCgwKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaHVsbC5sZW5ndGg7ICsraSkgewogICAgICBoID0gaHVsbFtpXTsKICAgICAgcDAgPSBwMSwgeDAgPSB4MSwgeTAgPSB5MTsKICAgICAgcDEgPSBoICogNCwgeDEgPSBwb2ludHNbMiAqIGhdLCB5MSA9IHBvaW50c1syICogaCArIDFdOwogICAgICB2ZWN0b3JzW3AwICsgMl0gPSB2ZWN0b3JzW3AxXSA9IHkwIC0geTE7CiAgICAgIHZlY3RvcnNbcDAgKyAzXSA9IHZlY3RvcnNbcDEgKyAxXSA9IHgxIC0geDA7CiAgICB9CiAgfQogIHJlbmRlcihjb250ZXh0KSB7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IHsKICAgICAgZGVsYXVuYXk6IHsKICAgICAgICBoYWxmZWRnZXMsCiAgICAgICAgaW5lZGdlcywKICAgICAgICBodWxsCiAgICAgIH0sCiAgICAgIGNpcmN1bWNlbnRlcnMsCiAgICAgIHZlY3RvcnMKICAgIH0gPSB0aGlzOwogICAgaWYgKGh1bGwubGVuZ3RoIDw9IDEpIHJldHVybiBudWxsOwogICAgZm9yIChsZXQgaSA9IDAsIG4gPSBoYWxmZWRnZXMubGVuZ3RoOyBpIDwgbjsgKytpKSB7CiAgICAgIGNvbnN0IGogPSBoYWxmZWRnZXNbaV07CiAgICAgIGlmIChqIDwgaSkgY29udGludWU7CiAgICAgIGNvbnN0IHRpID0gTWF0aC5mbG9vcihpIC8gMykgKiAyOwogICAgICBjb25zdCB0aiA9IE1hdGguZmxvb3IoaiAvIDMpICogMjsKICAgICAgY29uc3QgeGkgPSBjaXJjdW1jZW50ZXJzW3RpXTsKICAgICAgY29uc3QgeWkgPSBjaXJjdW1jZW50ZXJzW3RpICsgMV07CiAgICAgIGNvbnN0IHhqID0gY2lyY3VtY2VudGVyc1t0al07CiAgICAgIGNvbnN0IHlqID0gY2lyY3VtY2VudGVyc1t0aiArIDFdOwogICAgICB0aGlzLl9yZW5kZXJTZWdtZW50KHhpLCB5aSwgeGosIHlqLCBjb250ZXh0KTsKICAgIH0KICAgIGxldCBoMCwKICAgICAgaDEgPSBodWxsW2h1bGwubGVuZ3RoIC0gMV07CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bGwubGVuZ3RoOyArK2kpIHsKICAgICAgaDAgPSBoMSwgaDEgPSBodWxsW2ldOwogICAgICBjb25zdCB0ID0gTWF0aC5mbG9vcihpbmVkZ2VzW2gxXSAvIDMpICogMjsKICAgICAgY29uc3QgeCA9IGNpcmN1bWNlbnRlcnNbdF07CiAgICAgIGNvbnN0IHkgPSBjaXJjdW1jZW50ZXJzW3QgKyAxXTsKICAgICAgY29uc3QgdiA9IGgwICogNDsKICAgICAgY29uc3QgcCA9IHRoaXMuX3Byb2plY3QoeCwgeSwgdmVjdG9yc1t2ICsgMl0sIHZlY3RvcnNbdiArIDNdKTsKICAgICAgaWYgKHApIHRoaXMuX3JlbmRlclNlZ21lbnQoeCwgeSwgcFswXSwgcFsxXSwgY29udGV4dCk7CiAgICB9CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICByZW5kZXJCb3VuZHMoY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb250ZXh0LnJlY3QodGhpcy54bWluLCB0aGlzLnltaW4sIHRoaXMueG1heCAtIHRoaXMueG1pbiwgdGhpcy55bWF4IC0gdGhpcy55bWluKTsKICAgIHJldHVybiBidWZmZXIgJiYgYnVmZmVyLnZhbHVlKCk7CiAgfQogIHJlbmRlckNlbGwoaSwgY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCBwb2ludHMgPSB0aGlzLl9jbGlwKGkpOwogICAgaWYgKHBvaW50cyA9PT0gbnVsbCB8fCAhcG9pbnRzLmxlbmd0aCkgcmV0dXJuOwogICAgY29udGV4dC5tb3ZlVG8ocG9pbnRzWzBdLCBwb2ludHNbMV0pOwogICAgbGV0IG4gPSBwb2ludHMubGVuZ3RoOwogICAgd2hpbGUgKHBvaW50c1swXSA9PT0gcG9pbnRzW24gLSAyXSAmJiBwb2ludHNbMV0gPT09IHBvaW50c1tuIC0gMV0gJiYgbiA+IDEpIG4gLT0gMjsKICAgIGZvciAobGV0IGkgPSAyOyBpIDwgbjsgaSArPSAyKSB7CiAgICAgIGlmIChwb2ludHNbaV0gIT09IHBvaW50c1tpIC0gMl0gfHwgcG9pbnRzW2kgKyAxXSAhPT0gcG9pbnRzW2kgLSAxXSkgY29udGV4dC5saW5lVG8ocG9pbnRzW2ldLCBwb2ludHNbaSArIDFdKTsKICAgIH0KICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICAqY2VsbFBvbHlnb25zKCkgewogICAgY29uc3QgewogICAgICBkZWxhdW5heTogewogICAgICAgIHBvaW50cwogICAgICB9CiAgICB9ID0gdGhpczsKICAgIGZvciAobGV0IGkgPSAwLCBuID0gcG9pbnRzLmxlbmd0aCAvIDI7IGkgPCBuOyArK2kpIHsKICAgICAgY29uc3QgY2VsbCA9IHRoaXMuY2VsbFBvbHlnb24oaSk7CiAgICAgIGlmIChjZWxsKSBjZWxsLmluZGV4ID0gaSwgeWllbGQgY2VsbDsKICAgIH0KICB9CiAgY2VsbFBvbHlnb24oaSkgewogICAgY29uc3QgcG9seWdvbiA9IG5ldyBQb2x5Z29uKCk7CiAgICB0aGlzLnJlbmRlckNlbGwoaSwgcG9seWdvbik7CiAgICByZXR1cm4gcG9seWdvbi52YWx1ZSgpOwogIH0KICBfcmVuZGVyU2VnbWVudCh4MCwgeTAsIHgxLCB5MSwgY29udGV4dCkgewogICAgbGV0IFM7CiAgICBjb25zdCBjMCA9IHRoaXMuX3JlZ2lvbmNvZGUoeDAsIHkwKTsKICAgIGNvbnN0IGMxID0gdGhpcy5fcmVnaW9uY29kZSh4MSwgeTEpOwogICAgaWYgKGMwID09PSAwICYmIGMxID09PSAwKSB7CiAgICAgIGNvbnRleHQubW92ZVRvKHgwLCB5MCk7CiAgICAgIGNvbnRleHQubGluZVRvKHgxLCB5MSk7CiAgICB9IGVsc2UgaWYgKFMgPSB0aGlzLl9jbGlwU2VnbWVudCh4MCwgeTAsIHgxLCB5MSwgYzAsIGMxKSkgewogICAgICBjb250ZXh0Lm1vdmVUbyhTWzBdLCBTWzFdKTsKICAgICAgY29udGV4dC5saW5lVG8oU1syXSwgU1szXSk7CiAgICB9CiAgfQogIGNvbnRhaW5zKGksIHgsIHkpIHsKICAgIGlmICgoeCA9ICt4LCB4ICE9PSB4KSB8fCAoeSA9ICt5LCB5ICE9PSB5KSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRoaXMuZGVsYXVuYXkuX3N0ZXAoaSwgeCwgeSkgPT09IGk7CiAgfQogICpuZWlnaGJvcnMoaSkgewogICAgY29uc3QgY2kgPSB0aGlzLl9jbGlwKGkpOwogICAgaWYgKGNpKSBmb3IgKGNvbnN0IGogb2YgdGhpcy5kZWxhdW5heS5uZWlnaGJvcnMoaSkpIHsKICAgICAgY29uc3QgY2ogPSB0aGlzLl9jbGlwKGopOwogICAgICAvLyBmaW5kIHRoZSBjb21tb24gZWRnZQogICAgICBpZiAoY2opIGxvb3A6IGZvciAobGV0IGFpID0gMCwgbGkgPSBjaS5sZW5ndGg7IGFpIDwgbGk7IGFpICs9IDIpIHsKICAgICAgICBmb3IgKGxldCBhaiA9IDAsIGxqID0gY2oubGVuZ3RoOyBhaiA8IGxqOyBhaiArPSAyKSB7CiAgICAgICAgICBpZiAoY2lbYWldID09PSBjalthal0gJiYgY2lbYWkgKyAxXSA9PT0gY2pbYWogKyAxXSAmJiBjaVsoYWkgKyAyKSAlIGxpXSA9PT0gY2pbKGFqICsgbGogLSAyKSAlIGxqXSAmJiBjaVsoYWkgKyAzKSAlIGxpXSA9PT0gY2pbKGFqICsgbGogLSAxKSAlIGxqXSkgewogICAgICAgICAgICB5aWVsZCBqOwogICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICBfY2VsbChpKSB7CiAgICBjb25zdCB7CiAgICAgIGNpcmN1bWNlbnRlcnMsCiAgICAgIGRlbGF1bmF5OiB7CiAgICAgICAgaW5lZGdlcywKICAgICAgICBoYWxmZWRnZXMsCiAgICAgICAgdHJpYW5nbGVzCiAgICAgIH0KICAgIH0gPSB0aGlzOwogICAgY29uc3QgZTAgPSBpbmVkZ2VzW2ldOwogICAgaWYgKGUwID09PSAtMSkgcmV0dXJuIG51bGw7IC8vIGNvaW5jaWRlbnQgcG9pbnQKICAgIGNvbnN0IHBvaW50cyA9IFtdOwogICAgbGV0IGUgPSBlMDsKICAgIGRvIHsKICAgICAgY29uc3QgdCA9IE1hdGguZmxvb3IoZSAvIDMpOwogICAgICBwb2ludHMucHVzaChjaXJjdW1jZW50ZXJzW3QgKiAyXSwgY2lyY3VtY2VudGVyc1t0ICogMiArIDFdKTsKICAgICAgZSA9IGUgJSAzID09PSAyID8gZSAtIDIgOiBlICsgMTsKICAgICAgaWYgKHRyaWFuZ2xlc1tlXSAhPT0gaSkgYnJlYWs7IC8vIGJhZCB0cmlhbmd1bGF0aW9uCiAgICAgIGUgPSBoYWxmZWRnZXNbZV07CiAgICB9IHdoaWxlIChlICE9PSBlMCAmJiBlICE9PSAtMSk7CiAgICByZXR1cm4gcG9pbnRzOwogIH0KICBfY2xpcChpKSB7CiAgICAvLyBkZWdlbmVyYXRlIGNhc2UgKDEgdmFsaWQgcG9pbnQ6IHJldHVybiB0aGUgYm94KQogICAgaWYgKGkgPT09IDAgJiYgdGhpcy5kZWxhdW5heS5odWxsLmxlbmd0aCA9PT0gMSkgewogICAgICByZXR1cm4gW3RoaXMueG1heCwgdGhpcy55bWluLCB0aGlzLnhtYXgsIHRoaXMueW1heCwgdGhpcy54bWluLCB0aGlzLnltYXgsIHRoaXMueG1pbiwgdGhpcy55bWluXTsKICAgIH0KICAgIGNvbnN0IHBvaW50cyA9IHRoaXMuX2NlbGwoaSk7CiAgICBpZiAocG9pbnRzID09PSBudWxsKSByZXR1cm4gbnVsbDsKICAgIGNvbnN0IHsKICAgICAgdmVjdG9yczogVgogICAgfSA9IHRoaXM7CiAgICBjb25zdCB2ID0gaSAqIDQ7CiAgICByZXR1cm4gdGhpcy5fc2ltcGxpZnkoVlt2XSB8fCBWW3YgKyAxXSA/IHRoaXMuX2NsaXBJbmZpbml0ZShpLCBwb2ludHMsIFZbdl0sIFZbdiArIDFdLCBWW3YgKyAyXSwgVlt2ICsgM10pIDogdGhpcy5fY2xpcEZpbml0ZShpLCBwb2ludHMpKTsKICB9CiAgX2NsaXBGaW5pdGUoaSwgcG9pbnRzKSB7CiAgICBjb25zdCBuID0gcG9pbnRzLmxlbmd0aDsKICAgIGxldCBQID0gbnVsbDsKICAgIGxldCB4MCwKICAgICAgeTAsCiAgICAgIHgxID0gcG9pbnRzW24gLSAyXSwKICAgICAgeTEgPSBwb2ludHNbbiAtIDFdOwogICAgbGV0IGMwLAogICAgICBjMSA9IHRoaXMuX3JlZ2lvbmNvZGUoeDEsIHkxKTsKICAgIGxldCBlMCwKICAgICAgZTEgPSAwOwogICAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqICs9IDIpIHsKICAgICAgeDAgPSB4MSwgeTAgPSB5MSwgeDEgPSBwb2ludHNbal0sIHkxID0gcG9pbnRzW2ogKyAxXTsKICAgICAgYzAgPSBjMSwgYzEgPSB0aGlzLl9yZWdpb25jb2RlKHgxLCB5MSk7CiAgICAgIGlmIChjMCA9PT0gMCAmJiBjMSA9PT0gMCkgewogICAgICAgIGUwID0gZTEsIGUxID0gMDsKICAgICAgICBpZiAoUCkgUC5wdXNoKHgxLCB5MSk7ZWxzZSBQID0gW3gxLCB5MV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbGV0IFMsIHN4MCwgc3kwLCBzeDEsIHN5MTsKICAgICAgICBpZiAoYzAgPT09IDApIHsKICAgICAgICAgIGlmICgoUyA9IHRoaXMuX2NsaXBTZWdtZW50KHgwLCB5MCwgeDEsIHkxLCBjMCwgYzEpKSA9PT0gbnVsbCkgY29udGludWU7CiAgICAgICAgICBbc3gwLCBzeTAsIHN4MSwgc3kxXSA9IFM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICgoUyA9IHRoaXMuX2NsaXBTZWdtZW50KHgxLCB5MSwgeDAsIHkwLCBjMSwgYzApKSA9PT0gbnVsbCkgY29udGludWU7CiAgICAgICAgICBbc3gxLCBzeTEsIHN4MCwgc3kwXSA9IFM7CiAgICAgICAgICBlMCA9IGUxLCBlMSA9IHRoaXMuX2VkZ2Vjb2RlKHN4MCwgc3kwKTsKICAgICAgICAgIGlmIChlMCAmJiBlMSkgdGhpcy5fZWRnZShpLCBlMCwgZTEsIFAsIFAubGVuZ3RoKTsKICAgICAgICAgIGlmIChQKSBQLnB1c2goc3gwLCBzeTApO2Vsc2UgUCA9IFtzeDAsIHN5MF07CiAgICAgICAgfQogICAgICAgIGUwID0gZTEsIGUxID0gdGhpcy5fZWRnZWNvZGUoc3gxLCBzeTEpOwogICAgICAgIGlmIChlMCAmJiBlMSkgdGhpcy5fZWRnZShpLCBlMCwgZTEsIFAsIFAubGVuZ3RoKTsKICAgICAgICBpZiAoUCkgUC5wdXNoKHN4MSwgc3kxKTtlbHNlIFAgPSBbc3gxLCBzeTFdOwogICAgICB9CiAgICB9CiAgICBpZiAoUCkgewogICAgICBlMCA9IGUxLCBlMSA9IHRoaXMuX2VkZ2Vjb2RlKFBbMF0sIFBbMV0pOwogICAgICBpZiAoZTAgJiYgZTEpIHRoaXMuX2VkZ2UoaSwgZTAsIGUxLCBQLCBQLmxlbmd0aCk7CiAgICB9IGVsc2UgaWYgKHRoaXMuY29udGFpbnMoaSwgKHRoaXMueG1pbiArIHRoaXMueG1heCkgLyAyLCAodGhpcy55bWluICsgdGhpcy55bWF4KSAvIDIpKSB7CiAgICAgIHJldHVybiBbdGhpcy54bWF4LCB0aGlzLnltaW4sIHRoaXMueG1heCwgdGhpcy55bWF4LCB0aGlzLnhtaW4sIHRoaXMueW1heCwgdGhpcy54bWluLCB0aGlzLnltaW5dOwogICAgfQogICAgcmV0dXJuIFA7CiAgfQogIF9jbGlwU2VnbWVudCh4MCwgeTAsIHgxLCB5MSwgYzAsIGMxKSB7CiAgICAvLyBmb3IgbW9yZSByb2J1c3RuZXNzLCBhbHdheXMgY29uc2lkZXIgdGhlIHNlZ21lbnQgaW4gdGhlIHNhbWUgb3JkZXIKICAgIGNvbnN0IGZsaXAgPSBjMCA8IGMxOwogICAgaWYgKGZsaXApIFt4MCwgeTAsIHgxLCB5MSwgYzAsIGMxXSA9IFt4MSwgeTEsIHgwLCB5MCwgYzEsIGMwXTsKICAgIHdoaWxlICh0cnVlKSB7CiAgICAgIGlmIChjMCA9PT0gMCAmJiBjMSA9PT0gMCkgcmV0dXJuIGZsaXAgPyBbeDEsIHkxLCB4MCwgeTBdIDogW3gwLCB5MCwgeDEsIHkxXTsKICAgICAgaWYgKGMwICYgYzEpIHJldHVybiBudWxsOwogICAgICBsZXQgeCwKICAgICAgICB5LAogICAgICAgIGMgPSBjMCB8fCBjMTsKICAgICAgaWYgKGMgJiAwYjEwMDApIHggPSB4MCArICh4MSAtIHgwKSAqICh0aGlzLnltYXggLSB5MCkgLyAoeTEgLSB5MCksIHkgPSB0aGlzLnltYXg7ZWxzZSBpZiAoYyAmIDBiMDEwMCkgeCA9IHgwICsgKHgxIC0geDApICogKHRoaXMueW1pbiAtIHkwKSAvICh5MSAtIHkwKSwgeSA9IHRoaXMueW1pbjtlbHNlIGlmIChjICYgMGIwMDEwKSB5ID0geTAgKyAoeTEgLSB5MCkgKiAodGhpcy54bWF4IC0geDApIC8gKHgxIC0geDApLCB4ID0gdGhpcy54bWF4O2Vsc2UgeSA9IHkwICsgKHkxIC0geTApICogKHRoaXMueG1pbiAtIHgwKSAvICh4MSAtIHgwKSwgeCA9IHRoaXMueG1pbjsKICAgICAgaWYgKGMwKSB4MCA9IHgsIHkwID0geSwgYzAgPSB0aGlzLl9yZWdpb25jb2RlKHgwLCB5MCk7ZWxzZSB4MSA9IHgsIHkxID0geSwgYzEgPSB0aGlzLl9yZWdpb25jb2RlKHgxLCB5MSk7CiAgICB9CiAgfQogIF9jbGlwSW5maW5pdGUoaSwgcG9pbnRzLCB2eDAsIHZ5MCwgdnhuLCB2eW4pIHsKICAgIGxldCBQID0gQXJyYXkuZnJvbShwb2ludHMpLAogICAgICBwOwogICAgaWYgKHAgPSB0aGlzLl9wcm9qZWN0KFBbMF0sIFBbMV0sIHZ4MCwgdnkwKSkgUC51bnNoaWZ0KHBbMF0sIHBbMV0pOwogICAgaWYgKHAgPSB0aGlzLl9wcm9qZWN0KFBbUC5sZW5ndGggLSAyXSwgUFtQLmxlbmd0aCAtIDFdLCB2eG4sIHZ5bikpIFAucHVzaChwWzBdLCBwWzFdKTsKICAgIGlmIChQID0gdGhpcy5fY2xpcEZpbml0ZShpLCBQKSkgewogICAgICBmb3IgKGxldCBqID0gMCwgbiA9IFAubGVuZ3RoLCBjMCwgYzEgPSB0aGlzLl9lZGdlY29kZShQW24gLSAyXSwgUFtuIC0gMV0pOyBqIDwgbjsgaiArPSAyKSB7CiAgICAgICAgYzAgPSBjMSwgYzEgPSB0aGlzLl9lZGdlY29kZShQW2pdLCBQW2ogKyAxXSk7CiAgICAgICAgaWYgKGMwICYmIGMxKSBqID0gdGhpcy5fZWRnZShpLCBjMCwgYzEsIFAsIGopLCBuID0gUC5sZW5ndGg7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAodGhpcy5jb250YWlucyhpLCAodGhpcy54bWluICsgdGhpcy54bWF4KSAvIDIsICh0aGlzLnltaW4gKyB0aGlzLnltYXgpIC8gMikpIHsKICAgICAgUCA9IFt0aGlzLnhtaW4sIHRoaXMueW1pbiwgdGhpcy54bWF4LCB0aGlzLnltaW4sIHRoaXMueG1heCwgdGhpcy55bWF4LCB0aGlzLnhtaW4sIHRoaXMueW1heF07CiAgICB9CiAgICByZXR1cm4gUDsKICB9CiAgX2VkZ2UoaSwgZTAsIGUxLCBQLCBqKSB7CiAgICB3aGlsZSAoZTAgIT09IGUxKSB7CiAgICAgIGxldCB4LCB5OwogICAgICBzd2l0Y2ggKGUwKSB7CiAgICAgICAgY2FzZSAwYjAxMDE6CiAgICAgICAgICBlMCA9IDBiMDEwMDsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIC8vIHRvcC1sZWZ0CiAgICAgICAgY2FzZSAwYjAxMDA6CiAgICAgICAgICBlMCA9IDBiMDExMCwgeCA9IHRoaXMueG1heCwgeSA9IHRoaXMueW1pbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIHRvcAogICAgICAgIGNhc2UgMGIwMTEwOgogICAgICAgICAgZTAgPSAwYjAwMTA7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICAvLyB0b3AtcmlnaHQKICAgICAgICBjYXNlIDBiMDAxMDoKICAgICAgICAgIGUwID0gMGIxMDEwLCB4ID0gdGhpcy54bWF4LCB5ID0gdGhpcy55bWF4OwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gcmlnaHQKICAgICAgICBjYXNlIDBiMTAxMDoKICAgICAgICAgIGUwID0gMGIxMDAwOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgLy8gYm90dG9tLXJpZ2h0CiAgICAgICAgY2FzZSAwYjEwMDA6CiAgICAgICAgICBlMCA9IDBiMTAwMSwgeCA9IHRoaXMueG1pbiwgeSA9IHRoaXMueW1heDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIGJvdHRvbQogICAgICAgIGNhc2UgMGIxMDAxOgogICAgICAgICAgZTAgPSAwYjAwMDE7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICAvLyBib3R0b20tbGVmdAogICAgICAgIGNhc2UgMGIwMDAxOgogICAgICAgICAgZTAgPSAwYjAxMDEsIHggPSB0aGlzLnhtaW4sIHkgPSB0aGlzLnltaW47CiAgICAgICAgICBicmVhazsKICAgICAgICAvLyBsZWZ0CiAgICAgIH0KICAgICAgLy8gTm90ZTogdGhpcyBpbXBsaWNpdGx5IGNoZWNrcyBmb3Igb3V0IG9mIGJvdW5kczogaWYgUFtqXSBvciBQW2orMV0gYXJlCiAgICAgIC8vIHVuZGVmaW5lZCwgdGhlIGNvbmRpdGlvbmFsIHN0YXRlbWVudCB3aWxsIGJlIGV4ZWN1dGVkLgogICAgICBpZiAoKFBbal0gIT09IHggfHwgUFtqICsgMV0gIT09IHkpICYmIHRoaXMuY29udGFpbnMoaSwgeCwgeSkpIHsKICAgICAgICBQLnNwbGljZShqLCAwLCB4LCB5KSwgaiArPSAyOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gajsKICB9CiAgX3Byb2plY3QoeDAsIHkwLCB2eCwgdnkpIHsKICAgIGxldCB0ID0gSW5maW5pdHksCiAgICAgIGMsCiAgICAgIHgsCiAgICAgIHk7CiAgICBpZiAodnkgPCAwKSB7CiAgICAgIC8vIHRvcAogICAgICBpZiAoeTAgPD0gdGhpcy55bWluKSByZXR1cm4gbnVsbDsKICAgICAgaWYgKChjID0gKHRoaXMueW1pbiAtIHkwKSAvIHZ5KSA8IHQpIHkgPSB0aGlzLnltaW4sIHggPSB4MCArICh0ID0gYykgKiB2eDsKICAgIH0gZWxzZSBpZiAodnkgPiAwKSB7CiAgICAgIC8vIGJvdHRvbQogICAgICBpZiAoeTAgPj0gdGhpcy55bWF4KSByZXR1cm4gbnVsbDsKICAgICAgaWYgKChjID0gKHRoaXMueW1heCAtIHkwKSAvIHZ5KSA8IHQpIHkgPSB0aGlzLnltYXgsIHggPSB4MCArICh0ID0gYykgKiB2eDsKICAgIH0KICAgIGlmICh2eCA+IDApIHsKICAgICAgLy8gcmlnaHQKICAgICAgaWYgKHgwID49IHRoaXMueG1heCkgcmV0dXJuIG51bGw7CiAgICAgIGlmICgoYyA9ICh0aGlzLnhtYXggLSB4MCkgLyB2eCkgPCB0KSB4ID0gdGhpcy54bWF4LCB5ID0geTAgKyAodCA9IGMpICogdnk7CiAgICB9IGVsc2UgaWYgKHZ4IDwgMCkgewogICAgICAvLyBsZWZ0CiAgICAgIGlmICh4MCA8PSB0aGlzLnhtaW4pIHJldHVybiBudWxsOwogICAgICBpZiAoKGMgPSAodGhpcy54bWluIC0geDApIC8gdngpIDwgdCkgeCA9IHRoaXMueG1pbiwgeSA9IHkwICsgKHQgPSBjKSAqIHZ5OwogICAgfQogICAgcmV0dXJuIFt4LCB5XTsKICB9CiAgX2VkZ2Vjb2RlKHgsIHkpIHsKICAgIHJldHVybiAoeCA9PT0gdGhpcy54bWluID8gMGIwMDAxIDogeCA9PT0gdGhpcy54bWF4ID8gMGIwMDEwIDogMGIwMDAwKSB8ICh5ID09PSB0aGlzLnltaW4gPyAwYjAxMDAgOiB5ID09PSB0aGlzLnltYXggPyAwYjEwMDAgOiAwYjAwMDApOwogIH0KICBfcmVnaW9uY29kZSh4LCB5KSB7CiAgICByZXR1cm4gKHggPCB0aGlzLnhtaW4gPyAwYjAwMDEgOiB4ID4gdGhpcy54bWF4ID8gMGIwMDEwIDogMGIwMDAwKSB8ICh5IDwgdGhpcy55bWluID8gMGIwMTAwIDogeSA+IHRoaXMueW1heCA/IDBiMTAwMCA6IDBiMDAwMCk7CiAgfQogIF9zaW1wbGlmeShQKSB7CiAgICBpZiAoUCAmJiBQLmxlbmd0aCA+IDQpIHsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBQLmxlbmd0aDsgaSArPSAyKSB7CiAgICAgICAgY29uc3QgaiA9IChpICsgMikgJSBQLmxlbmd0aCwKICAgICAgICAgIGsgPSAoaSArIDQpICUgUC5sZW5ndGg7CiAgICAgICAgaWYgKFBbaV0gPT09IFBbal0gJiYgUFtqXSA9PT0gUFtrXSB8fCBQW2kgKyAxXSA9PT0gUFtqICsgMV0gJiYgUFtqICsgMV0gPT09IFBbayArIDFdKSB7CiAgICAgICAgICBQLnNwbGljZShqLCAyKSwgaSAtPSAyOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoIVAubGVuZ3RoKSBQID0gbnVsbDsKICAgIH0KICAgIHJldHVybiBQOwogIH0KfQoKY29uc3QgdGF1ID0gMiAqIE1hdGguUEksCiAgcG93ID0gTWF0aC5wb3c7CmZ1bmN0aW9uIHBvaW50WChwKSB7CiAgcmV0dXJuIHBbMF07Cn0KZnVuY3Rpb24gcG9pbnRZKHApIHsKICByZXR1cm4gcFsxXTsKfQoKLy8gQSB0cmlhbmd1bGF0aW9uIGlzIGNvbGxpbmVhciBpZiBhbGwgaXRzIHRyaWFuZ2xlcyBoYXZlIGEgbm9uLW51bGwgYXJlYQpmdW5jdGlvbiBjb2xsaW5lYXIoZCkgewogIGNvbnN0IHsKICAgIHRyaWFuZ2xlcywKICAgIGNvb3JkcwogIH0gPSBkOwogIGZvciAobGV0IGkgPSAwOyBpIDwgdHJpYW5nbGVzLmxlbmd0aDsgaSArPSAzKSB7CiAgICBjb25zdCBhID0gMiAqIHRyaWFuZ2xlc1tpXSwKICAgICAgYiA9IDIgKiB0cmlhbmdsZXNbaSArIDFdLAogICAgICBjID0gMiAqIHRyaWFuZ2xlc1tpICsgMl0sCiAgICAgIGNyb3NzID0gKGNvb3Jkc1tjXSAtIGNvb3Jkc1thXSkgKiAoY29vcmRzW2IgKyAxXSAtIGNvb3Jkc1thICsgMV0pIC0gKGNvb3Jkc1tiXSAtIGNvb3Jkc1thXSkgKiAoY29vcmRzW2MgKyAxXSAtIGNvb3Jkc1thICsgMV0pOwogICAgaWYgKGNyb3NzID4gMWUtMTApIHJldHVybiBmYWxzZTsKICB9CiAgcmV0dXJuIHRydWU7Cn0KZnVuY3Rpb24gaml0dGVyKHgsIHksIHIpIHsKICByZXR1cm4gW3ggKyBNYXRoLnNpbih4ICsgeSkgKiByLCB5ICsgTWF0aC5jb3MoeCAtIHkpICogcl07Cn0KY2xhc3MgRGVsYXVuYXkgewogIHN0YXRpYyBmcm9tKHBvaW50cywgZnggPSBwb2ludFgsIGZ5ID0gcG9pbnRZLCB0aGF0KSB7CiAgICByZXR1cm4gbmV3IERlbGF1bmF5KCJsZW5ndGgiIGluIHBvaW50cyA/IGZsYXRBcnJheShwb2ludHMsIGZ4LCBmeSwgdGhhdCkgOiBGbG9hdDY0QXJyYXkuZnJvbShmbGF0SXRlcmFibGUocG9pbnRzLCBmeCwgZnksIHRoYXQpKSk7CiAgfQogIGNvbnN0cnVjdG9yKHBvaW50cykgewogICAgdGhpcy5fZGVsYXVuYXRvciA9IG5ldyBEZWxhdW5hdG9yKHBvaW50cyk7CiAgICB0aGlzLmluZWRnZXMgPSBuZXcgSW50MzJBcnJheShwb2ludHMubGVuZ3RoIC8gMik7CiAgICB0aGlzLl9odWxsSW5kZXggPSBuZXcgSW50MzJBcnJheShwb2ludHMubGVuZ3RoIC8gMik7CiAgICB0aGlzLnBvaW50cyA9IHRoaXMuX2RlbGF1bmF0b3IuY29vcmRzOwogICAgdGhpcy5faW5pdCgpOwogIH0KICB1cGRhdGUoKSB7CiAgICB0aGlzLl9kZWxhdW5hdG9yLnVwZGF0ZSgpOwogICAgdGhpcy5faW5pdCgpOwogICAgcmV0dXJuIHRoaXM7CiAgfQogIF9pbml0KCkgewogICAgY29uc3QgZCA9IHRoaXMuX2RlbGF1bmF0b3IsCiAgICAgIHBvaW50cyA9IHRoaXMucG9pbnRzOwoKICAgIC8vIGNoZWNrIGZvciBjb2xsaW5lYXIKICAgIGlmIChkLmh1bGwgJiYgZC5odWxsLmxlbmd0aCA+IDIgJiYgY29sbGluZWFyKGQpKSB7CiAgICAgIHRoaXMuY29sbGluZWFyID0gSW50MzJBcnJheS5mcm9tKHsKICAgICAgICBsZW5ndGg6IHBvaW50cy5sZW5ndGggLyAyCiAgICAgIH0sIChfLCBpKSA9PiBpKS5zb3J0KChpLCBqKSA9PiBwb2ludHNbMiAqIGldIC0gcG9pbnRzWzIgKiBqXSB8fCBwb2ludHNbMiAqIGkgKyAxXSAtIHBvaW50c1syICogaiArIDFdKTsgLy8gZm9yIGV4YWN0IG5laWdoYm9ycwogICAgICBjb25zdCBlID0gdGhpcy5jb2xsaW5lYXJbMF0sCiAgICAgICAgZiA9IHRoaXMuY29sbGluZWFyW3RoaXMuY29sbGluZWFyLmxlbmd0aCAtIDFdLAogICAgICAgIGJvdW5kcyA9IFtwb2ludHNbMiAqIGVdLCBwb2ludHNbMiAqIGUgKyAxXSwgcG9pbnRzWzIgKiBmXSwgcG9pbnRzWzIgKiBmICsgMV1dLAogICAgICAgIHIgPSAxZS04ICogTWF0aC5oeXBvdChib3VuZHNbM10gLSBib3VuZHNbMV0sIGJvdW5kc1syXSAtIGJvdW5kc1swXSk7CiAgICAgIGZvciAobGV0IGkgPSAwLCBuID0gcG9pbnRzLmxlbmd0aCAvIDI7IGkgPCBuOyArK2kpIHsKICAgICAgICBjb25zdCBwID0gaml0dGVyKHBvaW50c1syICogaV0sIHBvaW50c1syICogaSArIDFdLCByKTsKICAgICAgICBwb2ludHNbMiAqIGldID0gcFswXTsKICAgICAgICBwb2ludHNbMiAqIGkgKyAxXSA9IHBbMV07CiAgICAgIH0KICAgICAgdGhpcy5fZGVsYXVuYXRvciA9IG5ldyBEZWxhdW5hdG9yKHBvaW50cyk7CiAgICB9IGVsc2UgewogICAgICBkZWxldGUgdGhpcy5jb2xsaW5lYXI7CiAgICB9CiAgICBjb25zdCBoYWxmZWRnZXMgPSB0aGlzLmhhbGZlZGdlcyA9IHRoaXMuX2RlbGF1bmF0b3IuaGFsZmVkZ2VzOwogICAgY29uc3QgaHVsbCA9IHRoaXMuaHVsbCA9IHRoaXMuX2RlbGF1bmF0b3IuaHVsbDsKICAgIGNvbnN0IHRyaWFuZ2xlcyA9IHRoaXMudHJpYW5nbGVzID0gdGhpcy5fZGVsYXVuYXRvci50cmlhbmdsZXM7CiAgICBjb25zdCBpbmVkZ2VzID0gdGhpcy5pbmVkZ2VzLmZpbGwoLTEpOwogICAgY29uc3QgaHVsbEluZGV4ID0gdGhpcy5faHVsbEluZGV4LmZpbGwoLTEpOwoKICAgIC8vIENvbXB1dGUgYW4gaW5kZXggZnJvbSBlYWNoIHBvaW50IHRvIGFuIChhcmJpdHJhcnkpIGluY29taW5nIGhhbGZlZGdlCiAgICAvLyBVc2VkIHRvIGdpdmUgdGhlIGZpcnN0IG5laWdoYm9yIG9mIGVhY2ggcG9pbnQ7IGZvciB0aGlzIHJlYXNvbiwKICAgIC8vIG9uIHRoZSBodWxsIHdlIGdpdmUgcHJpb3JpdHkgdG8gZXh0ZXJpb3IgaGFsZmVkZ2VzCiAgICBmb3IgKGxldCBlID0gMCwgbiA9IGhhbGZlZGdlcy5sZW5ndGg7IGUgPCBuOyArK2UpIHsKICAgICAgY29uc3QgcCA9IHRyaWFuZ2xlc1tlICUgMyA9PT0gMiA/IGUgLSAyIDogZSArIDFdOwogICAgICBpZiAoaGFsZmVkZ2VzW2VdID09PSAtMSB8fCBpbmVkZ2VzW3BdID09PSAtMSkgaW5lZGdlc1twXSA9IGU7CiAgICB9CiAgICBmb3IgKGxldCBpID0gMCwgbiA9IGh1bGwubGVuZ3RoOyBpIDwgbjsgKytpKSB7CiAgICAgIGh1bGxJbmRleFtodWxsW2ldXSA9IGk7CiAgICB9CgogICAgLy8gZGVnZW5lcmF0ZSBjYXNlOiAxIG9yIDIgKGRpc3RpbmN0KSBwb2ludHMKICAgIGlmIChodWxsLmxlbmd0aCA8PSAyICYmIGh1bGwubGVuZ3RoID4gMCkgewogICAgICB0aGlzLnRyaWFuZ2xlcyA9IG5ldyBJbnQzMkFycmF5KDMpLmZpbGwoLTEpOwogICAgICB0aGlzLmhhbGZlZGdlcyA9IG5ldyBJbnQzMkFycmF5KDMpLmZpbGwoLTEpOwogICAgICB0aGlzLnRyaWFuZ2xlc1swXSA9IGh1bGxbMF07CiAgICAgIGluZWRnZXNbaHVsbFswXV0gPSAxOwogICAgICBpZiAoaHVsbC5sZW5ndGggPT09IDIpIHsKICAgICAgICBpbmVkZ2VzW2h1bGxbMV1dID0gMDsKICAgICAgICB0aGlzLnRyaWFuZ2xlc1sxXSA9IGh1bGxbMV07CiAgICAgICAgdGhpcy50cmlhbmdsZXNbMl0gPSBodWxsWzFdOwogICAgICB9CiAgICB9CiAgfQogIHZvcm9ub2koYm91bmRzKSB7CiAgICByZXR1cm4gbmV3IFZvcm9ub2kodGhpcywgYm91bmRzKTsKICB9CiAgKm5laWdoYm9ycyhpKSB7CiAgICBjb25zdCB7CiAgICAgIGluZWRnZXMsCiAgICAgIGh1bGwsCiAgICAgIF9odWxsSW5kZXgsCiAgICAgIGhhbGZlZGdlcywKICAgICAgdHJpYW5nbGVzLAogICAgICBjb2xsaW5lYXIKICAgIH0gPSB0aGlzOwoKICAgIC8vIGRlZ2VuZXJhdGUgY2FzZSB3aXRoIHNldmVyYWwgY29sbGluZWFyIHBvaW50cwogICAgaWYgKGNvbGxpbmVhcikgewogICAgICBjb25zdCBsID0gY29sbGluZWFyLmluZGV4T2YoaSk7CiAgICAgIGlmIChsID4gMCkgeWllbGQgY29sbGluZWFyW2wgLSAxXTsKICAgICAgaWYgKGwgPCBjb2xsaW5lYXIubGVuZ3RoIC0gMSkgeWllbGQgY29sbGluZWFyW2wgKyAxXTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgZTAgPSBpbmVkZ2VzW2ldOwogICAgaWYgKGUwID09PSAtMSkgcmV0dXJuOyAvLyBjb2luY2lkZW50IHBvaW50CiAgICBsZXQgZSA9IGUwLAogICAgICBwMCA9IC0xOwogICAgZG8gewogICAgICB5aWVsZCBwMCA9IHRyaWFuZ2xlc1tlXTsKICAgICAgZSA9IGUgJSAzID09PSAyID8gZSAtIDIgOiBlICsgMTsKICAgICAgaWYgKHRyaWFuZ2xlc1tlXSAhPT0gaSkgcmV0dXJuOyAvLyBiYWQgdHJpYW5ndWxhdGlvbgogICAgICBlID0gaGFsZmVkZ2VzW2VdOwogICAgICBpZiAoZSA9PT0gLTEpIHsKICAgICAgICBjb25zdCBwID0gaHVsbFsoX2h1bGxJbmRleFtpXSArIDEpICUgaHVsbC5sZW5ndGhdOwogICAgICAgIGlmIChwICE9PSBwMCkgeWllbGQgcDsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgIH0gd2hpbGUgKGUgIT09IGUwKTsKICB9CiAgZmluZCh4LCB5LCBpID0gMCkgewogICAgaWYgKCh4ID0gK3gsIHggIT09IHgpIHx8ICh5ID0gK3ksIHkgIT09IHkpKSByZXR1cm4gLTE7CiAgICBjb25zdCBpMCA9IGk7CiAgICBsZXQgYzsKICAgIHdoaWxlICgoYyA9IHRoaXMuX3N0ZXAoaSwgeCwgeSkpID49IDAgJiYgYyAhPT0gaSAmJiBjICE9PSBpMCkgaSA9IGM7CiAgICByZXR1cm4gYzsKICB9CiAgX3N0ZXAoaSwgeCwgeSkgewogICAgY29uc3QgewogICAgICBpbmVkZ2VzLAogICAgICBodWxsLAogICAgICBfaHVsbEluZGV4LAogICAgICBoYWxmZWRnZXMsCiAgICAgIHRyaWFuZ2xlcywKICAgICAgcG9pbnRzCiAgICB9ID0gdGhpczsKICAgIGlmIChpbmVkZ2VzW2ldID09PSAtMSB8fCAhcG9pbnRzLmxlbmd0aCkgcmV0dXJuIChpICsgMSkgJSAocG9pbnRzLmxlbmd0aCA+PiAxKTsKICAgIGxldCBjID0gaTsKICAgIGxldCBkYyA9IHBvdyh4IC0gcG9pbnRzW2kgKiAyXSwgMikgKyBwb3coeSAtIHBvaW50c1tpICogMiArIDFdLCAyKTsKICAgIGNvbnN0IGUwID0gaW5lZGdlc1tpXTsKICAgIGxldCBlID0gZTA7CiAgICBkbyB7CiAgICAgIGxldCB0ID0gdHJpYW5nbGVzW2VdOwogICAgICBjb25zdCBkdCA9IHBvdyh4IC0gcG9pbnRzW3QgKiAyXSwgMikgKyBwb3coeSAtIHBvaW50c1t0ICogMiArIDFdLCAyKTsKICAgICAgaWYgKGR0IDwgZGMpIGRjID0gZHQsIGMgPSB0OwogICAgICBlID0gZSAlIDMgPT09IDIgPyBlIC0gMiA6IGUgKyAxOwogICAgICBpZiAodHJpYW5nbGVzW2VdICE9PSBpKSBicmVhazsgLy8gYmFkIHRyaWFuZ3VsYXRpb24KICAgICAgZSA9IGhhbGZlZGdlc1tlXTsKICAgICAgaWYgKGUgPT09IC0xKSB7CiAgICAgICAgZSA9IGh1bGxbKF9odWxsSW5kZXhbaV0gKyAxKSAlIGh1bGwubGVuZ3RoXTsKICAgICAgICBpZiAoZSAhPT0gdCkgewogICAgICAgICAgaWYgKHBvdyh4IC0gcG9pbnRzW2UgKiAyXSwgMikgKyBwb3coeSAtIHBvaW50c1tlICogMiArIDFdLCAyKSA8IGRjKSByZXR1cm4gZTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0gd2hpbGUgKGUgIT09IGUwKTsKICAgIHJldHVybiBjOwogIH0KICByZW5kZXIoY29udGV4dCkgewogICAgY29uc3QgYnVmZmVyID0gY29udGV4dCA9PSBudWxsID8gY29udGV4dCA9IG5ldyBQYXRoKCkgOiB1bmRlZmluZWQ7CiAgICBjb25zdCB7CiAgICAgIHBvaW50cywKICAgICAgaGFsZmVkZ2VzLAogICAgICB0cmlhbmdsZXMKICAgIH0gPSB0aGlzOwogICAgZm9yIChsZXQgaSA9IDAsIG4gPSBoYWxmZWRnZXMubGVuZ3RoOyBpIDwgbjsgKytpKSB7CiAgICAgIGNvbnN0IGogPSBoYWxmZWRnZXNbaV07CiAgICAgIGlmIChqIDwgaSkgY29udGludWU7CiAgICAgIGNvbnN0IHRpID0gdHJpYW5nbGVzW2ldICogMjsKICAgICAgY29uc3QgdGogPSB0cmlhbmdsZXNbal0gKiAyOwogICAgICBjb250ZXh0Lm1vdmVUbyhwb2ludHNbdGldLCBwb2ludHNbdGkgKyAxXSk7CiAgICAgIGNvbnRleHQubGluZVRvKHBvaW50c1t0al0sIHBvaW50c1t0aiArIDFdKTsKICAgIH0KICAgIHRoaXMucmVuZGVySHVsbChjb250ZXh0KTsKICAgIHJldHVybiBidWZmZXIgJiYgYnVmZmVyLnZhbHVlKCk7CiAgfQogIHJlbmRlclBvaW50cyhjb250ZXh0LCByKSB7CiAgICBpZiAociA9PT0gdW5kZWZpbmVkICYmICghY29udGV4dCB8fCB0eXBlb2YgY29udGV4dC5tb3ZlVG8gIT09ICJmdW5jdGlvbiIpKSByID0gY29udGV4dCwgY29udGV4dCA9IG51bGw7CiAgICByID0gciA9PSB1bmRlZmluZWQgPyAyIDogK3I7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IHsKICAgICAgcG9pbnRzCiAgICB9ID0gdGhpczsKICAgIGZvciAobGV0IGkgPSAwLCBuID0gcG9pbnRzLmxlbmd0aDsgaSA8IG47IGkgKz0gMikgewogICAgICBjb25zdCB4ID0gcG9pbnRzW2ldLAogICAgICAgIHkgPSBwb2ludHNbaSArIDFdOwogICAgICBjb250ZXh0Lm1vdmVUbyh4ICsgciwgeSk7CiAgICAgIGNvbnRleHQuYXJjKHgsIHksIHIsIDAsIHRhdSk7CiAgICB9CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICByZW5kZXJIdWxsKGNvbnRleHQpIHsKICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQgPT0gbnVsbCA/IGNvbnRleHQgPSBuZXcgUGF0aCgpIDogdW5kZWZpbmVkOwogICAgY29uc3QgewogICAgICBodWxsLAogICAgICBwb2ludHMKICAgIH0gPSB0aGlzOwogICAgY29uc3QgaCA9IGh1bGxbMF0gKiAyLAogICAgICBuID0gaHVsbC5sZW5ndGg7CiAgICBjb250ZXh0Lm1vdmVUbyhwb2ludHNbaF0sIHBvaW50c1toICsgMV0pOwogICAgZm9yIChsZXQgaSA9IDE7IGkgPCBuOyArK2kpIHsKICAgICAgY29uc3QgaCA9IDIgKiBodWxsW2ldOwogICAgICBjb250ZXh0LmxpbmVUbyhwb2ludHNbaF0sIHBvaW50c1toICsgMV0pOwogICAgfQogICAgY29udGV4dC5jbG9zZVBhdGgoKTsKICAgIHJldHVybiBidWZmZXIgJiYgYnVmZmVyLnZhbHVlKCk7CiAgfQogIGh1bGxQb2x5Z29uKCkgewogICAgY29uc3QgcG9seWdvbiA9IG5ldyBQb2x5Z29uKCk7CiAgICB0aGlzLnJlbmRlckh1bGwocG9seWdvbik7CiAgICByZXR1cm4gcG9seWdvbi52YWx1ZSgpOwogIH0KICByZW5kZXJUcmlhbmdsZShpLCBjb250ZXh0KSB7CiAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0ID09IG51bGwgPyBjb250ZXh0ID0gbmV3IFBhdGgoKSA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IHsKICAgICAgcG9pbnRzLAogICAgICB0cmlhbmdsZXMKICAgIH0gPSB0aGlzOwogICAgY29uc3QgdDAgPSB0cmlhbmdsZXNbaSAqPSAzXSAqIDI7CiAgICBjb25zdCB0MSA9IHRyaWFuZ2xlc1tpICsgMV0gKiAyOwogICAgY29uc3QgdDIgPSB0cmlhbmdsZXNbaSArIDJdICogMjsKICAgIGNvbnRleHQubW92ZVRvKHBvaW50c1t0MF0sIHBvaW50c1t0MCArIDFdKTsKICAgIGNvbnRleHQubGluZVRvKHBvaW50c1t0MV0sIHBvaW50c1t0MSArIDFdKTsKICAgIGNvbnRleHQubGluZVRvKHBvaW50c1t0Ml0sIHBvaW50c1t0MiArIDFdKTsKICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7CiAgICByZXR1cm4gYnVmZmVyICYmIGJ1ZmZlci52YWx1ZSgpOwogIH0KICAqdHJpYW5nbGVQb2x5Z29ucygpIHsKICAgIGNvbnN0IHsKICAgICAgdHJpYW5nbGVzCiAgICB9ID0gdGhpczsKICAgIGZvciAobGV0IGkgPSAwLCBuID0gdHJpYW5nbGVzLmxlbmd0aCAvIDM7IGkgPCBuOyArK2kpIHsKICAgICAgeWllbGQgdGhpcy50cmlhbmdsZVBvbHlnb24oaSk7CiAgICB9CiAgfQogIHRyaWFuZ2xlUG9seWdvbihpKSB7CiAgICBjb25zdCBwb2x5Z29uID0gbmV3IFBvbHlnb24oKTsKICAgIHRoaXMucmVuZGVyVHJpYW5nbGUoaSwgcG9seWdvbik7CiAgICByZXR1cm4gcG9seWdvbi52YWx1ZSgpOwogIH0KfQpmdW5jdGlvbiBmbGF0QXJyYXkocG9pbnRzLCBmeCwgZnksIHRoYXQpIHsKICBjb25zdCBuID0gcG9pbnRzLmxlbmd0aDsKICBjb25zdCBhcnJheSA9IG5ldyBGbG9hdDY0QXJyYXkobiAqIDIpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICBjb25zdCBwID0gcG9pbnRzW2ldOwogICAgYXJyYXlbaSAqIDJdID0gZnguY2FsbCh0aGF0LCBwLCBpLCBwb2ludHMpOwogICAgYXJyYXlbaSAqIDIgKyAxXSA9IGZ5LmNhbGwodGhhdCwgcCwgaSwgcG9pbnRzKTsKICB9CiAgcmV0dXJuIGFycmF5Owp9CmZ1bmN0aW9uKiBmbGF0SXRlcmFibGUocG9pbnRzLCBmeCwgZnksIHRoYXQpIHsKICBsZXQgaSA9IDA7CiAgZm9yIChjb25zdCBwIG9mIHBvaW50cykgewogICAgeWllbGQgZnguY2FsbCh0aGF0LCBwLCBpLCBwb2ludHMpOwogICAgeWllbGQgZnkuY2FsbCh0aGF0LCBwLCBpLCBwb2ludHMpOwogICAgKytpOwogIH0KfQoKLyoqDQogKiDoh6rnhLbphLDpu57lhafmj5Lms5UoTmF0dXJhbCBOZWlnaGJvciBJbnRlcnBvbGF0aW9uKeWFp+aPkum7nuaVuOWAvA0KICoNCiAqIEEgRmFzdCBhbmQgQWNjdXJhdGUgQWxnb3JpdGhtIGZvciBOYXR1cmFsIE5laWdoYm9yIEludGVycG9sYXRpb24NCiAqIGh0dHBzOi8vZ3dsdWNhc3RyaWcuZ2l0aHViLmlvL1RpbmZvdXJEb2NzL05hdHVyYWxOZWlnaGJvclRpbmZvdXJBbGdvcml0aG0vaW5kZXguaHRtbA0KICoNCiAqIEFuIEludHJvZHVjdGlvbiB0byBOYXR1cmFsIE5laWdoYm9yIEludGVycG9sYXRpb24NCiAqIGh0dHBzOi8vZ3dsdWNhc3RyaWcuZ2l0aHViLmlvL1RpbmZvdXJEb2NzL05hdHVyYWxOZWlnaGJvckludHJvL2luZGV4Lmh0bWwNCiAqDQogKiBbd2lraV1OYXR1cmFsIG5laWdoYm9yIGludGVycG9sYXRpb24NCiAqIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL05hdHVyYWxfbmVpZ2hib3JfaW50ZXJwb2xhdGlvbg0KICoNCiAqIE5hdHVyYWwgbmVpZ2hib3IgaW50ZXJwb2xhdGlvbg0KICogaHR0cHM6Ly9vYnNlcnZhYmxlaHEuY29tL0BrYXJsZXJzcy9uYXR1cmFsLW5laWdoYm9yLWludGVycG9sYXRpb24NCiAqDQogKiBkMy1kZWxhdW5heQ0KICogaHR0cHM6Ly9naXRodWIuY29tL2QzL2QzLWRlbGF1bmF5DQogKg0KICogb25saW5lIHRlc3QNCiAqIGh0dHBzOi8vY2FydG9ncmFwaHktcGxheWdyb3VuZC5naXRsYWIuaW8vcGxheWdyb3VuZHMvdHJpYW5ndWxhdGlvbi1kZWxhdW5heS12b3Jvbm9pLWRpYWdyYW0vDQogKg0KICogVW5pdCBUZXN0OiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3ctZ2lzL2Jsb2IvbWFzdGVyL3Rlc3QvaW50ZXJwMk5hdHVyYWxOZWlnaGJvci50ZXN0Lm1qcyBHaXRodWJ9DQogKiBAbWVtYmVyT2Ygdy1naXMNCiAqIEBwYXJhbSB7QXJyYXl9IHBzU3JjIOi8uOWFpeS6jOe2reW6p+aomeWKoOingOa4rOaVuOaTmum7numZo+WIl++8jOeCult7eDp4MSx5OnkxLHo6ejF9LHt4OngyLHk6eTIsejp6Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIlw0KICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHBzVGFyIOi8uOWFpeS6jOe2reW6p+aomem7numZo+WIl+aIlum7nueJqeS7tu+8jOeCult7eDp4MSx5OnkxfSx7eDp4Mix5OnkyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiX77yM5oiWe3g6eDEseTp5MX3pu57nianku7YNCiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0PXt9XSDovLjlhaXoqK3lrprnianku7bvvIzpoJDoqK17fQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WD0neCddIOi8uOWFpem7nueJqeS7tuS5i3jmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neCcNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVk9J3knXSDovLjlhaXpu57nianku7bkuYt55qyE5L2N5a2X5Liy77yM54K65bqn5qiZ77yM6aCQ6KitJ3knDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlaPSd6J10g6Ly45YWl6bue54mp5Lu25LmLeuashOS9jeWtl+S4su+8jOeCuuingOa4rOWAvO+8jOmgkOiorSd6Jw0KICogQHBhcmFtIHtOdW1iZXJ9IFtvcHQuc2NhbGU9MV0g6Ly45YWl5q2j6KaP5YyW56+E5ZyN5pW45YC877yM5Zug6JmV55CG5aSa6YKK5b2i5pmC5pyJ5pW45YC85a656Kix6Kqk5beu77yM5pWF6aCI6YCa6YGO57iu5pS+5YC85Z+f5L6G5rib5bCR5ZWP6aGM77yM6aCQ6KitMeaYr+ato+imj+WMljDoh7Mx5LmL6ZaT77yM5L2/55Soc2NhbGVYWeWJh+aYr+ato+imj+WMlueCujDoh7NzY2FsZVhZ5LmL6ZaT77yM6aCQ6KitMQ0KICogQHJldHVybnMge0FycmF5fE9iamVjdH0g5Zue5YKz6bue54mp5Lu26Zmj5YiX5oiW6bue54mp5Lu277yM6Iul55m855Sf6Yyv6Kqk5YmH5Zue5YKz6Yyv6Kqk6KiK5oGv54mp5Lu2DQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHANCiAqIGxldCByDQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAxMjQzLA0KICogICAgIHk6IDEyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDEyNDMsIHk6IDEyMDcsIHo6IG51bGwgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogbnVsbCwgeTogMjAxLCB6OiAxMjIgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIGxldCBmdW5JbnRlcnBGcmFnbWVudCA9IChtc2cpID0+IHsNCiAqICAgICAvLyBjb25zb2xlLmxvZygnZnVuSW50ZXJwRnJhZ21lbnQnLCBtc2cpDQogKiAgICAgcmV0dXJuIG1zZy52IC8v6aCQ6Kit5Zue5YKzbXNnLnYsIOS4ieinkuW9ouS4ieinkum7nuWQhOm7nnbngrpyQSp6LCDmlYXkuInpu57kuYtyQeWQiOeCujEsIOaMh+WumuWFp+aPkuWAvHrngrrkuInop5Lpu5525LmL57i95ZKMKHYxLHYyLHYzKQ0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHAsIHsgZnVuSW50ZXJwRnJhZ21lbnQgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiBudWxsLCB5OiAyMDEsIHo6IDEyMiB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAxMjQzLA0KICogICAgIHk6IDEyMDcsDQogKiB9DQogKiBsZXQgZnVuSW50ZXJwRnJhZ21lbnROb1VzZSA9IChtc2cpID0+IHsNCiAqICAgICAvLyBjb25zb2xlLmxvZygnZnVuSW50ZXJwRnJhZ21lbnROb1VzZScsIG1zZykNCiAqICAgICByZXR1cm4gbXNnLnYgLy/poJDoqK3lm57lgrNtc2cudiwg5q2k6JmV5Zug5YWn5o+S6bue5pa85Y6f5aeL6bue5omA5b2i5oiQ5pyA5bCP5Ye45aSa6YKK5b2i5LmL5aSWLCDmlYXnhKHms5Xlhafmj5IsIOS6puS4jeacg+WRvOWPq2Z1bkludGVycEZyYWdtZW50DQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCwgeyBmdW5JbnRlcnBGcmFnbWVudDogZnVuSW50ZXJwRnJhZ21lbnROb1VzZSB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMTI0MywgeTogMTIwNywgejogbnVsbCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiBudWxsLCB5OiAyMDEsIHo6IDEyMiB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogbGV0IGZ1bkludGVycEZyYWdtZW50cyA9IChtc2cpID0+IHsNCiAqICAgICAvLyBjb25zb2xlLmxvZygnZnVuSW50ZXJwRnJhZ21lbnRzJywgbXNnKQ0KICogICAgIC8vIGxldCB2ID0gcHNbMF0udiArIHBzWzFdLnYgKyBwc1syXS52DQogKiAgICAgcmV0dXJuIG1zZy52IC8v6aCQ6Kit5Zue5YKzbXNnLnYsIOS4ieinkuW9ouS4ieinkum7nueCum1zZy5wcywg5ZCE6buedueCunJBKnosIOaVheS4iem7nuS5i3JB5ZCI54K6MSwg5oyH5a6a5YWn5o+S5YC8eueCuuS4ieinkum7nnbkuYvnuL3lkowodjEsdjIsdjMpDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCwgeyBmdW5JbnRlcnBGcmFnbWVudHMgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjgzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjgzLCB5OiAyMDcsIHo6IDExNC40MzA0MDQyMTk1MTkwOCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMTE2MCwNCiAqICAgICB5OiAzODAsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDExNjAsIHk6IDM4MCwgejogbnVsbCB9DQogKg0KICogcHMgPSBbeyBhOiAyNDMsIGI6IDIwNiwgYzogOTUgfSwgeyBhOiAyMzMsIGI6IDIyNSwgYzogMTQ2IH0sIHsgYTogMjEsIGI6IDMyNSwgYzogMjIgfSwgeyBhOiA5NTMsIGI6IDI4LCBjOiAyMjMgfSwgeyBhOiAxMDkyLCBiOiAyOTAsIGM6IDM5IH0sIHsgYTogNzQ0LCBiOiAyMDAsIGM6IDE5MSB9LCB7IGE6IDE3NCwgYjogMywgYzogMjIgfSwgeyBhOiA1MzcsIGI6IDM2OCwgYzogMjQ5IH0sIHsgYTogMTE1MSwgYjogMzcxLCBjOiA4NiB9LCB7IGE6IDgxNCwgYjogMjUyLCBjOiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgYTogMjQzLA0KICogICAgIGI6IDIwNywNCiAqIH0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwLCB7IGtleVg6ICdhJywga2V5WTogJ2InLCBrZXlaOiAnYycgfSkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IGE6IDI0MywgYjogMjA3LCBjOiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSBbDQogKiAgICAgew0KICogICAgICAgICB4OiAyNDMsDQogKiAgICAgICAgIHk6IDIwNywNCiAqICAgICB9LA0KICogICAgIHsNCiAqICAgICAgICAgeDogMjgzLA0KICogICAgICAgICB5OiAyMDcsDQogKiAgICAgfSwNCiAqIF0NCiAqIHIgPSBpbnRlcnAyTmF0dXJhbE5laWdoYm9yKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IFsNCiAqIC8vICAgeyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4MTMgfSwNCiAqIC8vICAgeyB4OiAyODMsIHk6IDIwNywgejogMTE0LjQzMDQwNDIxOTUxOTA4IH0NCiAqIC8vIF0NCiAqDQogKiBwcyA9IFt7IHg6IDAuMDAwMjQzLCB5OiAwLjAwMDIwNiwgejogOTUgfSwgeyB4OiAwLjAwMDIzMywgeTogMC4wMDAyMjUsIHo6IDE0NiB9LCB7IHg6IDAuMDAwMDIxLCB5OiAwLjAwMDMyNSwgejogMjIgfSwgeyB4OiAwLjAwMDk1MywgeTogMC4wMDAwMjgsIHo6IDIyMyB9LCB7IHg6IDAuMDAxMDkyLCB5OiAwLjAwMDI5LCB6OiAzOSB9LCB7IHg6IDAuMDAwNzQ0LCB5OiAwLjAwMDIwMCwgejogMTkxIH0sIHsgeDogMC4wMDAxNzQsIHk6IDAuMDAwMDAzLCB6OiAyMiB9LCB7IHg6IDAuMDAwNTM3LCB5OiAwLjAwMDM2OCwgejogMjQ5IH0sIHsgeDogMC4wMDExNTEsIHk6IDAuMDAwMzcxLCB6OiA4NiB9LCB7IHg6IDAuMDAwODE0LCB5OiAwLjAwMDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDAuMDAwMjQzLA0KICogICAgIHk6IDAuMDAwMjA3LA0KICogfQ0KICogciA9IGludGVycDJOYXR1cmFsTmVpZ2hib3IocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAwLjAwMDI0MywgeTogMC4wMDAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2NzggfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwcywgcCwgeyBzY2FsZTogMTAwMCB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODU1IH0NCiAqDQogKi8KZnVuY3Rpb24gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwc1NyYywgcHNUYXIsIG9wdCA9IHt9KSB7CiAgLy9jaGVjayBwc1NyYwogIGlmICghaXNlYXJyKHBzU3JjKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNTcmMgaXMgbm90IGFuIGVmZmVjdGl2ZSBhcnJheScKICAgIH07CiAgfQoKICAvL2NoZWNrIHBzVGFyCiAgaWYgKCFpc2VvYmoocHNUYXIpICYmICFpc2VhcnIocHNUYXIpKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1RhciBpcyBub3QgYW4gZWZmZWN0aXZlIG9iamVjdCBvciBhcnJheScKICAgIH07CiAgfQoKICAvL2lzT25lCiAgbGV0IGlzT25lID0gaXNlb2JqKHBzVGFyKTsKICBpZiAoaXNPbmUpIHsKICAgIHBzVGFyID0gW3BzVGFyXTsKICB9CgogIC8va2V5WAogIGxldCBrZXlYID0gZ2V0KG9wdCwgJ2tleVgnKTsKICBpZiAoIWlzZXN0cihrZXlYKSkgewogICAga2V5WCA9ICd4JzsKICB9CgogIC8va2V5WQogIGxldCBrZXlZID0gZ2V0KG9wdCwgJ2tleVknKTsKICBpZiAoIWlzZXN0cihrZXlZKSkgewogICAga2V5WSA9ICd5JzsKICB9CgogIC8va2V5WgogIGxldCBrZXlaID0gZ2V0KG9wdCwgJ2tleVonKTsKICBpZiAoIWlzZXN0cihrZXlaKSkgewogICAga2V5WiA9ICd6JzsKICB9CgogIC8vc2NhbGUKICBsZXQgc2NhbGUgPSBnZXQob3B0LCAnc2NhbGUnKTsKICBpZiAoIWlzbnVtKHNjYWxlKSkgewogICAgc2NhbGUgPSAxOwogIH0KICBzY2FsZSA9IGNkYmwoc2NhbGUpOwoKICAvL2Z1bkludGVycEZyYWdtZW50CiAgbGV0IGZ1bkludGVycEZyYWdtZW50ID0gZ2V0KG9wdCwgJ2Z1bkludGVycEZyYWdtZW50Jyk7CiAgbGV0IHVzZUZ1bkludGVycEZyYWdtZW50ID0gaXNmdW4oZnVuSW50ZXJwRnJhZ21lbnQpOwoKICAvL2Z1bkludGVycEZyYWdtZW50cwogIGxldCBmdW5JbnRlcnBGcmFnbWVudHMgPSBnZXQob3B0LCAnZnVuSW50ZXJwRnJhZ21lbnRzJyk7CiAgbGV0IHVzZUZ1bkludGVycEZyYWdtZW50cyA9IGlzZnVuKGZ1bkludGVycEZyYWdtZW50cyk7CgogIC8va2V5SW5kCiAgbGV0IGtleUluZCA9ICdpbmQnOwoKICAvL3B0c1hZWnRvQXJyCiAgcHNTcmMgPSBwdHNYWVp0b0Fycihwc1NyYywgewogICAga2V5WCwKICAgIGtleVksCiAgICBrZXlaLAogICAga2V5SW5kCiAgfSk7CgogIC8vY2hlY2sgcHNTcmMKICBpZiAoc2l6ZShwc1NyYykgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzU3JjIGhhcyBubyBlZmZlY3RpdmUgZGF0YScKICAgIH07CiAgfQogIC8vIGNvbnNvbGUubG9nKCdwdHNYWVp0b0FyciBwc1NyYycsIHBzU3JjKQoKICAvL3B0c1hZdG9BcnIKICBwc1RhciA9IHB0c1hZdG9BcnIocHNUYXIsIHsKICAgIGtleVgsCiAgICBrZXlZLAogICAga2V5SW5kCiAgfSk7CgogIC8vY2hlY2sgcHNUYXIKICBpZiAoc2l6ZShwc1RhcikgPT09IDApIHsKICAgIHJldHVybiB7CiAgICAgIGVycjogJ3BzVGFyIGhhcyBubyBlZmZlY3RpdmUgZGF0YScKICAgIH07CiAgfQogIC8vIGNvbnNvbGUubG9nKCdwdHNYWXRvQXJyIHBzVGFyJywgcHNUYXIpCgogIC8vaW50ZXJwMk5vcm1hbGl6ZQogIGxldCBpdG5tID0gaW50ZXJwMk5vcm1hbGl6ZShwc1NyYywgewogICAga2V5SW5kLAogICAgc2NhbGUKICB9KTsKICAvLyBjb25zb2xlLmxvZygnaXRubS5zdCcsIGl0bm0uc3QpCiAgLy8gY29uc29sZS5sb2coJ2l0bm0ucHNNaW5NYXgnLCBpdG5tLnBzTWluTWF4KQogIHBzU3JjID0gaXRubS5wczsgLy/opIflr6vmraPopo/ljJbmlbjmk5oKICBsZXQgbnYgPSBpdG5tLm52OwogIGxldCBpbnYgPSBpdG5tLmludjsKICAvLyBjb25zb2xlLmxvZygnaW50ZXJwMk5vcm1hbGl6ZSBwc1NyYycsIHBzU3JjKQoKICAvL3BzU3JjSXRyCiAgbGV0IHBzU3JjSXRyID0gWy4uLnBzU3JjXTsKCiAgLy9wc1NyY09yaQogIGxldCBwc1NyY09yaSA9IFsuLi5wc1NyY107CgogIC8va3BLbm93bgogIGxldCBrcEtub3duID0ge307CiAgZm9yRWFjaChwc1NyYywgdiA9PiB7CiAgICBsZXQgayA9IGAke3YueH0tJHt2Lnl9YDsgLy94LHnlt7LntpPooqvmraPopo/ljJYKICAgIGtwS25vd25ba10gPSB2Lno7IC8veCx5LHrlt7LntpPooqvmraPopo/ljJYKICB9KTsKCiAgLy9pbnREbnkKICBsZXQgaW50RG55ID0gRGVsYXVuYXkuZnJvbShwc1NyY09yaSwgZCA9PiBkLngsIGQgPT4gZC55KTsgLy94LHnlt7LntpPooqvmraPopo/ljJYKCiAgLy8gLy9ocGcsIOWOn+Wni+aVuOaTmuW9ouaIkOacgOWkluahhumCiueVjAogIC8vIGxldCBocGcgPSBpbnREbnkuaHVsbFBvbHlnb24oKQogIC8vIC8vIGNvbnNvbGUubG9nKCdpbnREbnkuaHVsbFBvbHlnb24nLCBocGcpCgogIC8vdmJveAogIGxldCB2Ym94ID0gWzAsIDAsIHNjYWxlLCBzY2FsZV07CgogIC8vaW5pVm9yCiAgbGV0IGluaVZvciA9IGludERueS52b3Jvbm9pKHZib3gpOwogIC8vIGNvbnNvbGUubG9nKCdpbmlWb3InLCBpbmlWb3IpCgogIC8vYWRkUG9pbnRDb3JlCiAgbGV0IGFkZFBvaW50Q29yZSA9IChkYXRhLCB4LCB5LCBpbmRUYXIpID0+IHsKICAgIC8vcHNTcmNUZW1wCiAgICBsZXQgcHNTcmNUZW1wID0gWy4uLnBzU3JjXTsKCiAgICAvL25ld0l0ZW0KICAgIGxldCBuZXdJdGVtID0gewogICAgICB4LAogICAgICB5LAogICAgICB6OiAwCiAgICB9OyAvL3gseSx65bey57aT6KKr5q2j6KaP5YyWCgogICAgLy9wdXNoCiAgICBwc1NyY1RlbXAucHVzaChuZXdJdGVtKTsKICAgIGRhdGEucHVzaChuZXdJdGVtKTsKCiAgICAvL3Bvc3RWb3IKICAgIGxldCBwb3N0Vm9yID0gRGVsYXVuYXkuZnJvbShwc1NyY1RlbXAsIGQgPT4gZC54LCBkID0+IGQueSkudm9yb25vaSh2Ym94KTsgLy94LHnlt7LntpPooqvmraPopo/ljJYKICAgIC8vIGNvbnNvbGUubG9nKCdwb3N0Vm9yJywgcG9zdFZvcikKCiAgICAvL25ld0lkeAogICAgbGV0IG5ld0lkeCA9IHBzU3JjVGVtcC5sZW5ndGggLSAxOwogICAgLy8gY29uc29sZS5sb2coJ25ld0lkeCcsIG5ld0lkeCkKCiAgICAvL3Bnc1F1ZXJ5CiAgICBsZXQgcGdzUXVlcnkgPSBwb3N0Vm9yLmNlbGxQb2x5Z29uKG5ld0lkeCk7CiAgICAvLyBjb25zb2xlLmxvZygncGdzUXVlcnknLCBwZ3NRdWVyeSkKCiAgICAvL2FyZWFRdWVyeQogICAgbGV0IGFyZWFRdWVyeSA9IGdldEFyZWFQb2x5Z29uKHBnc1F1ZXJ5KTsKICAgIC8vIGNvbnNvbGUubG9nKCdhcmVhUXVlcnknLCBhcmVhUXVlcnkpCgogICAgLy9uZXdQb2ludFZhbAogICAgbGV0IG5ld1BvaW50VmFsID0gbnVsbDsKICAgIHsKICAgICAgLy9uZWlnaGJvckluZGljZXMKICAgICAgbGV0IG5laWdoYm9ySW5kaWNlcyA9IFtdOwogICAgICAvLyBmb3IgKGxldCBpIG9mIHBvc3RWb3IuZGVsYXVuYXkubmVpZ2hib3JzKG5ld0lkeCkpIHsgLy/lm6Dngrpwb3N0Vm9yLmRlbGF1bmF5Lm5laWdoYm9yc+aYr2dlbmVyYXRvciwg6ICD5oWu6KaB5pSv5o+0aWUxMeW+l+S9v+eUqHdoaWxl6IiHbmV4dOiugOWPlgogICAgICAvLyAgICAgbmVpZ2hib3JJbmRpY2VzLnB1c2goaSkKICAgICAgLy8gfQogICAgICBsZXQgc3EgPSBwb3N0Vm9yLmRlbGF1bmF5Lm5laWdoYm9ycyhuZXdJZHgpOwogICAgICAvLyBjb25zb2xlLmxvZyhgc3FgLCBzcSkKICAgICAgbGV0IG5leHQgPSBzcS5uZXh0KCk7CiAgICAgIHdoaWxlICghbmV4dC5kb25lKSB7CiAgICAgICAgbGV0IHYgPSBuZXh0LnZhbHVlOwogICAgICAgIG5laWdoYm9ySW5kaWNlcy5wdXNoKHYpOwogICAgICAgIG5leHQgPSBzcS5uZXh0KCk7CiAgICAgIH0KICAgICAgLy8gY29uc29sZS5sb2coJ25laWdoYm9ySW5kaWNlcycsIG5laWdoYm9ySW5kaWNlcykKCiAgICAgIC8vc3ViVmFsdWVzCiAgICAgIGxldCBzdWJWYWx1ZXMgPSBtYXAobmVpZ2hib3JJbmRpY2VzLCBpZHggPT4gewogICAgICAgIC8vIGNvbnNvbGUubG9nKCdpZHgnLCBpZHgpCgogICAgICAgIC8vcGdzMSwgcGdzMgogICAgICAgIGxldCBwZ3MxID0gW3Bnc1F1ZXJ5XTsKICAgICAgICBsZXQgcGdzMiA9IFtpbmlWb3IuY2VsbFBvbHlnb24oaWR4KV07CiAgICAgICAgLy8gY29uc29sZS5sb2coJ3BnczEnLCBwZ3MxLCAncGdzMicsIHBnczIpCgogICAgICAgIC8vaW50ZXJzZWN0CiAgICAgICAgbGV0IHBnc0ludHMgPSBbXTsKICAgICAgICB0cnkgewogICAgICAgICAgcGdzSW50cyA9IGludGVyc2VjdFBvbHlnb24ocGdzMSwgcGdzMik7CiAgICAgICAgICAvLyBjb25zb2xlLmxvZygncGdzSW50cycsIHBnc0ludHMpCiAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAvL2NvbnNvbGUubG9nKCdwZ3MxJywgcGdzMSkKICAgICAgICAgIC8vY29uc29sZS5sb2coJ3BnczInLCBwZ3MyKQogICAgICAgICAgLy9jb25zb2xlLmxvZyhlcnIpCiAgICAgICAgfQoKICAgICAgICAvL2FyZWFJbnRzCiAgICAgICAgbGV0IGFyZWFJbnRzID0gMDsKICAgICAgICBpZiAoc2l6ZShwZ3NJbnRzKSA9PT0gMSkgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYXJlYUludHMgPSBnZXRBcmVhUG9seWdvbihwZ3NJbnRzWzBdKTsKICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnZ2V0QXJlYVBvbHlnb24nLGQzLmdldEFyZWFQb2x5Z29uKGlzLnJlZ2lvbnNbMF0pLGdldEFyZWFQb2x5Z29uKGlzLnJlZ2lvbnNbMF0pKQogICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdwZ3NJbnRzJywgcGdzSW50cyk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB7CiAgICAgICAgICBpYTogYXJlYUludHMsCiAgICAgICAgICBpZHgKICAgICAgICB9OwogICAgICB9KTsKICAgICAgLy8gY29uc29sZS5sb2coJ3N1YlZhbHVlcycsIHN1YlZhbHVlcykKCiAgICAgIC8vY2hlY2sKICAgICAgewogICAgICAgIC8vbgogICAgICAgIGxldCBuID0gc2l6ZShzdWJWYWx1ZXMpOwoKICAgICAgICAvL2lhcwogICAgICAgIGxldCBpYXMgPSBtYXAoc3ViVmFsdWVzLCAnaWEnKTsKCiAgICAgICAgLy9yCiAgICAgICAgbGV0IHIgPSBzdW0kMShpYXMpOwoKICAgICAgICAvL2NoZWNrCiAgICAgICAgaWYgKHIgIT09IGFyZWFRdWVyeSkgewogICAgICAgICAgLy8gY29uc29sZS5sb2coYGlh57i95ZKM5pyJ5pmC5pyD5LiN562J5pa8YXJlYVF1ZXJ5YCkKICAgICAgICAgIC8vaWHnuL3lkozmnInmmYLmnIPkuI3nrYnmlrxhcmVhUXVlcnkKCiAgICAgICAgICBpZiAoYXJlYVF1ZXJ5ID4gMCAmJiByID4gMCkgewogICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhg6IulaWHnuL3lkozoiIdhcmVhUXVlcnnpg70+MCwg5YmH6Kq/5pW05ZCEaWHkvb/lhbbnuL3lkoznuK7mlL7oh7NhcmVhUXVlcnlgKQogICAgICAgICAgICAvL+iLpWlh57i95ZKM6IiHYXJlYVF1ZXJ56YO9PjAsIOWJh+iqv+aVtOWQhGlh5L2/5YW257i95ZKM57iu5pS+6IezYXJlYVF1ZXJ5CiAgICAgICAgICAgIGxldCBzID0gYXJlYVF1ZXJ5IC8gcjsKICAgICAgICAgICAgc3ViVmFsdWVzID0gbWFwKHN1YlZhbHVlcywgc3YgPT4gewogICAgICAgICAgICAgIHN2LmlhICo9IHM7CiAgICAgICAgICAgICAgcmV0dXJuIHN2OwogICAgICAgICAgICB9KTsKICAgICAgICAgIH0gZWxzZSBpZiAoYXJlYVF1ZXJ5ID09PSAwICYmIHIgPiAwKSB7CiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGDoi6VhcmVhUXVlcnnngrow5LiUaWHnuL3lkow+MCwg5YmH5L2/55SoaWHnuL3lkozngrphcmVhUXVlcnlgKQogICAgICAgICAgICAvL+iLpWFyZWFRdWVyeeeCujDkuJRpYee4veWSjD4wLCDliYfkvb/nlKhpYee4veWSjOeCumFyZWFRdWVyeQogICAgICAgICAgICBhcmVhUXVlcnkgPSByOwogICAgICAgICAgfSBlbHNlIGlmIChhcmVhUXVlcnkgPiAwICYmIHIgPT09IDApIHsKICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYOiLpWFyZWFRdWVyeT4w5LiUaWHnuL3lkow9MCwg5YmH5YGH6Kit5ZCEaWHngrrlubPliIZhcmVhUXVlcnlgKQogICAgICAgICAgICAvL+iLpWFyZWFRdWVyeT4w5LiUaWHnuL3lkow9MCwg5YmH5YGH6Kit5ZCEaWHngrrlubPliIZhcmVhUXVlcnkKICAgICAgICAgICAgbGV0IHMgPSBhcmVhUXVlcnkgLyBuOwogICAgICAgICAgICBzdWJWYWx1ZXMgPSBtYXAoc3ViVmFsdWVzLCBzdiA9PiB7CiAgICAgICAgICAgICAgc3YuaWEgPSBzOwogICAgICAgICAgICAgIHJldHVybiBzdjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjb25zb2xlLmxvZygnYXJlYVF1ZXJ5JywgYXJlYVF1ZXJ5KTsKICAgICAgICAgICAgY29uc29sZS5sb2coJ3N1bShpYXMpJywgcik7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXJlYVF1ZXJ5IT09c3VtKGlhcykgJiYgKGFyZWFRdWVyeTwwIG9yIHN1bShpYXMpPDApJyk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChhcmVhUXVlcnkgPT09IDApIHsKICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGDoi6VhcmVhUXVlcnk9MOS4lGlh57i95ZKMPTAsIOWJh+WBh+iorWFyZWFRdWVyeeeCujEsIOiAjOWQhGlh54K65bmz5YiGMWApCiAgICAgICAgICAvL+iLpWFyZWFRdWVyeT1pYee4veWSjD0wLCDliYflgYfoqK1hcmVhUXVlcnnngroxLCDogIzlkIRpYeeCuuW5s+WIhjEKICAgICAgICAgIGFyZWFRdWVyeSA9IDE7CiAgICAgICAgICBsZXQgcyA9IDEgLyBuOwogICAgICAgICAgc3ViVmFsdWVzID0gbWFwKHN1YlZhbHVlcywgc3YgPT4gewogICAgICAgICAgICBzdi5pYSA9IHM7CiAgICAgICAgICAgIHJldHVybiBzdjsKICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAoYXJlYVF1ZXJ5IDwgMCkgewogICAgICAgICAgLy8gY29uc29sZS5sb2coYOiLpWFyZWFRdWVyeT1pYee4veWSjDwwLCDliYfloLHpjK9gKQogICAgICAgICAgLy/oi6VhcmVhUXVlcnk9aWHnuL3lkow8MCwg5YmH5aCx6YyvCiAgICAgICAgICBjb25zb2xlLmxvZygnYXJlYVF1ZXJ5JywgYXJlYVF1ZXJ5KTsKICAgICAgICAgIGNvbnNvbGUubG9nKCdzdW0oaWFzKScsIHIpOwogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcmVhUXVlcnk8MCAmJiBzdW0oaWFzKTwwJyk7CiAgICAgICAgfQogICAgICB9CgogICAgICAvL25ld1BvaW50VmFscwogICAgICBsZXQgbmV3UG9pbnRWYWxzID0gW107CiAgICAgIGZvckVhY2goc3ViVmFsdWVzLCBvID0+IHsKICAgICAgICAvL3JBLCB6LCB2CiAgICAgICAgbGV0IHJBID0gby5pYSAvIGFyZWFRdWVyeTsKICAgICAgICBsZXQgeiA9IGRhdGFbby5pZHhdLno7IC8veCx5LHrlt7LntpPooqvmraPopo/ljJYKICAgICAgICBsZXQgdiA9IHJBICogejsKICAgICAgICAvLyBjb25zb2xlLmxvZygnc3ViVmFsdWUnLCAnckEnLCByQSwgJ28uaWR4Jywgby5pZHgsICd6JywgeiwgJ3YnLCB2KQoKICAgICAgICAvL3VzZUZ1bkludGVycEZyYWdtZW50CiAgICAgICAgaWYgKHVzZUZ1bkludGVycEZyYWdtZW50KSB7CiAgICAgICAgICB2ID0gZnVuSW50ZXJwRnJhZ21lbnQoewogICAgICAgICAgICB2LAogICAgICAgICAgICBhcmVhOiBvLmlhLAogICAgICAgICAgICBhcmVhVG90YWw6IGFyZWFRdWVyeSwKICAgICAgICAgICAgYXJlYVJhdGlvOiByQSwKICAgICAgICAgICAgeiwKICAgICAgICAgICAgaW5kU3JjOiBvLmlkeCwKICAgICAgICAgICAgaW5kVGFyCiAgICAgICAgICAgIC8vIGRhdGEsCiAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8vcAogICAgICAgIGxldCBwID0gewogICAgICAgICAgdiwKICAgICAgICAgIGFyZWE6IG8uaWEsCiAgICAgICAgICBhcmVhVG90YWw6IGFyZWFRdWVyeSwKICAgICAgICAgIGFyZWFSYXRpbzogckEsCiAgICAgICAgICB6LAogICAgICAgICAgaW5kU3JjOiBvLmlkeCwKICAgICAgICAgIGluZFRhcgogICAgICAgIH07CgogICAgICAgIC8vcHVzaAogICAgICAgIG5ld1BvaW50VmFscy5wdXNoKHApOwogICAgICB9KTsKCiAgICAgIC8vbmV3UG9pbnRWYWwKICAgICAgbGV0IHZ0ID0gc3VtJDEobWFwKG5ld1BvaW50VmFscywgJ3YnKSk7CiAgICAgIGlmICh1c2VGdW5JbnRlcnBGcmFnbWVudHMpIHsKICAgICAgICB2dCA9IGZ1bkludGVycEZyYWdtZW50cyh7CiAgICAgICAgICBwczogbmV3UG9pbnRWYWxzLAogICAgICAgICAgdjogdnQsCiAgICAgICAgICBpbmRUYXIsCiAgICAgICAgICBmdW5JbnY6IHZ2ID0+IHsKICAgICAgICAgICAgcmV0dXJuIGludih2diwgMik7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgbmV3UG9pbnRWYWwgPSB2dDsKCiAgICAgIC8vIGlmIChpc05hTihuZXdQb2ludFZhbCkpIHsKICAgICAgLy8gICAgIGNvbnNvbGUubG9nKCdpc05hTihuZXdQb2ludFZhbCknLCBzdWJWYWx1ZXMsICdhcmVhUXVlcnknLCBhcmVhUXVlcnkpCiAgICAgIC8vIH0KICAgICAgLy8gY29uc29sZS5sb2coYGFyZWFRdWVyeVske2FyZWFRdWVyeX1dID4gMGAsICduZXdQb2ludFZhbCcsIG5ld1BvaW50VmFsKQogICAgfQoKICAgIC8vdXBkYXRlIG5ld1BvaW50VmFsCiAgICBkYXRhW2RhdGEubGVuZ3RoIC0gMV0ueiA9IG5ld1BvaW50VmFsOyAvL3gseSx65bey57aT6KKr5q2j6KaP5YyWCgogICAgcmV0dXJuIG5ld1BvaW50VmFsOwogIH07CgogIC8vYWRkUG9pbnQKICBsZXQgYWRkUG9pbnQgPSAoZGF0YSwgeCwgeSwgaW5kVGFyKSA9PiB7CiAgICAvL3IKICAgIGxldCByOwogICAgdHJ5IHsKICAgICAgciA9IGFkZFBvaW50Q29yZShkYXRhLCB4LCB5LCBpbmRUYXIpOwogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIGNvbnNvbGUubG9nKGVycik7CiAgICAgIHIgPSBudWxsOwogICAgICBkYXRhLnBvcCgpOwogICAgfQogICAgcmV0dXJuIHI7CiAgfTsKCiAgLy9nZXROegogIGxldCBnZXROeiA9IChueCwgbnksIGluZFRhcikgPT4gewogICAgLy9jaGVjawogICAgbGV0IGsgPSBgJHtueH0tJHtueX1gOyAvL3gseeW3sue2k+iiq+ato+imj+WMlgogICAgaWYgKGhhc2tleShrcEtub3duLCBrKSkgewogICAgICByZXR1cm4ga3BLbm93bltrXTsKICAgIH0KCiAgICAvL2NoZWNrCiAgICBpZiAobnggPCB2Ym94WzBdIHx8IG54ID4gdmJveFsyXSB8fCBueSA8IHZib3hbMV0gfHwgbnkgPiB2Ym94WzNdKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vcHJlZGljdAogICAgbGV0IG56ID0gYWRkUG9pbnQocHNTcmNJdHIsIG54LCBueSwgaW5kVGFyKTsKCiAgICAvL3NhdmUKICAgIGtwS25vd25ba10gPSBuejsKICAgIHJldHVybiBuejsKICB9OwoKICAvL2l0dgogIGxldCBpdHYgPSAocCwgaW5kVGFyKSA9PiB7CiAgICAvL3gsIG54CiAgICBsZXQgeCA9IHAueDsKICAgIGxldCBueCA9IG52KHgsICd4Jyk7CiAgICBpZiAoIWlzTnVtYmVyKG54KSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgbnhbJHtueH1dYCk7IC8veCx56aCQ5pyf6YO95piv5pyJ5YC8CiAgICB9CgogICAgLy95LCBueQogICAgbGV0IHkgPSBwLnk7CiAgICBsZXQgbnkgPSBudih5LCAneScpOwogICAgaWYgKCFpc051bWJlcihueSkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG55WyR7bnl9XWApOyAvL3gseemgkOacn+mDveaYr+acieWAvAogICAgfQoKICAgIC8vbnosIHoKICAgIGxldCBueiA9IGdldE56KG54LCBueSwgaW5kVGFyKTsKICAgIGxldCB6ID0gaW52KG56LCAneicpOwogICAgaWYgKCFpc051bWJlcih6KSkgewogICAgICB6ID0gbnVsbDsgLy966aCI5pSv5o+05Y+v6IO954Sh5rOV5YWn5o+SCiAgICB9CgogICAgLy8gY29uc29sZS5sb2coJ3gnLCB4LCAneScsIHksICd6JywgeikKICAgIC8vIGNvbnNvbGUubG9nKCdueCcsIG54LCAnbnknLCBueSwgJ256JywgbnopCgogICAgLy9yCiAgICBsZXQgciA9IHsKICAgICAgW2tleVhdOiB4LAogICAgICBba2V5WV06IHksCiAgICAgIFtrZXlaXTogegogICAgfTsKICAgIHJldHVybiByOwogIH07CgogIC8vcgogIGxldCByOwogIGlmIChpc09uZSkgewogICAgbGV0IHAgPSBwc1RhclswXTsKICAgIHIgPSBpdHYocCwgMCk7CiAgfSBlbHNlIHsKICAgIHIgPSBbXTsKICAgIGZvckVhY2gocHNUYXIsIChwLCBpbmRUYXIpID0+IHsKICAgICAgci5wdXNoKGl0dihwLCBpbmRUYXIpKTsKICAgIH0pOwogIH0KICByZXR1cm4gcjsKfQoKLy9mb3JrIGZyb206IGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9vZW80Yi9rcmlnaW5nLmpzL21hc3Rlci9rcmlnaW5nLmpzCgovL+epuumWk+e1seioiOWIhuaekOS5i+iuiueVsOaVuOeahOeQhuirluaooeWeizogaHR0cHM6Ly93d3cuc3VwZXJnZW90ZWsuY29tL3R3L21hbnVhbHMvU1NBL3RvcGljMzIuaHRtCi8v5Zyo56m66ZaT5YiG5p6Q55qE5YGH6Kit5LmL5LiL77yM55u46YSw5oSI6L+R55qE5YWp6bue77yM5Zyo55u45Ly85oiW5piv55u46Zec56iL5bqm5LiK5oeJ5pyJ6LyD5by355qE6Zec5L+C44CC5Y+N5LmL77yM6Iul5YWp6bue55qE6Led6Zui5ouJ5aSn77yM5YmH5YW26ZaT55qE55u46Zec56iL5bqm5oeJ5Lmf5pyD5bCx5q2k6ZmN5L2O44CCCi8v6ICM5Y2K6K6K55Ww5ZyW77yIU2VtaXZhcmlvZ3JhbXPvvInoiIflhbHorormlbjvvIhDb3ZhcmlhbmNl77yJ55CG6KuW55qE55m85bGV77yM5Z2H5piv55So6YeP5ris6Led6Zui55qE5LqS55u46Zec56iL5bqm77yM5Y2z5piv5bCH5q2k6KeA5b+16YCP6YGO5pa556iL5byP55qE6L2J5o+b5bCH5YW26YeP5YyW44CCCgovLyAvLyBFeHRlbmQgdGhlIEFycmF5IGNsYXNzCi8vIEFycmF5LnByb3RvdHlwZS5tYXggPSBmdW5jdGlvbigpIHsKLy8gICAgIHJldHVybiBNYXRoLm1heC5hcHBseShudWxsLCB0aGlzKQovLyB9Ci8vIEFycmF5LnByb3RvdHlwZS5taW4gPSBmdW5jdGlvbigpIHsKLy8gICAgIHJldHVybiBNYXRoLm1pbi5hcHBseShudWxsLCB0aGlzKQovLyB9Ci8vIEFycmF5LnByb3RvdHlwZS5tZWFuID0gZnVuY3Rpb24oKSB7Ci8vICAgICBsZXQgaSwgc3VtCi8vICAgICBmb3IgKGkgPSAwLCBzdW0gPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykgewovLyAgICAgICAgIHN1bSArPSB0aGlzW2ldCi8vICAgICB9Ci8vICAgICByZXR1cm4gc3VtIC8gdGhpcy5sZW5ndGgKLy8gfQovLyBBcnJheS5wcm90b3R5cGUucGlwID0gZnVuY3Rpb24oeCwgeSkgewovLyAgICAgbGV0IGk7IGxldCBqOyBsZXQgYyA9IGZhbHNlCi8vICAgICBmb3IgKGkgPSAwLCBqID0gdGhpcy5sZW5ndGggLSAxOyBpIDwgdGhpcy5sZW5ndGg7IGogPSBpKyspIHsKLy8gICAgICAgICBpZiAoKCh0aGlzW2ldWzFdID4geSkgIT09ICh0aGlzW2pdWzFdID4geSkpICYmCi8vICAgICAgKHggPCAodGhpc1tqXVswXSAtIHRoaXNbaV1bMF0pICogKHkgLSB0aGlzW2ldWzFdKSAvICh0aGlzW2pdWzFdIC0gdGhpc1tpXVsxXSkgKyB0aGlzW2ldWzBdKSkgewovLyAgICAgIGMgPSAhYwovLyAgICAgICAgIH0KLy8gICAgIH0KLy8gICAgIHJldHVybiBjCi8vIH0KCmxldCBrcmlnaW5nID0ge307CgovLyBsZXQgcGlwID0gZnVuY3Rpb24oYXJyLCB4LCB5KSB7Ci8vICAgICBsZXQgaQovLyAgICAgbGV0IGoKLy8gICAgIGxldCBjID0gZmFsc2UKLy8gICAgIGZvciAoaSA9IDAsIGogPSBhcnIubGVuZ3RoIC0gMTsgaSA8IGFyci5sZW5ndGg7IGogPSBpKyspIHsKLy8gICAgICAgICBpZiAoKChhcnJbaV1bMV0gPiB5KSAhPT0gKGFycltqXVsxXSA+IHkpKSAmJgovLyAgICAgICAgICAoeCA8IChhcnJbal1bMF0gLSBhcnJbaV1bMF0pICogKHkgLSBhcnJbaV1bMV0pIC8gKGFycltqXVsxXSAtIGFycltpXVsxXSkgKyBhcnJbaV1bMF0pKSB7Ci8vICAgICAgICAgICAgIGMgPSAhYwovLyAgICAgICAgIH0KLy8gICAgIH0KLy8gICAgIHJldHVybiBjCi8vIH0KCmxldCBjcmVhdGVBcnJheVdpdGhWYWx1ZXMgPSBmdW5jdGlvbiAodmFsdWUsIG4pIHsKICBsZXQgYXJyYXkgPSBbXTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgYXJyYXkucHVzaCh2YWx1ZSk7CiAgfQogIHJldHVybiBhcnJheTsKfTsKCi8vIE1hdHJpeCBhbGdlYnJhCmxldCBrcmlnaW5nX21hdHJpeF9kaWFnID0gZnVuY3Rpb24gKGMsIG4pIHsKICBsZXQgWiA9IGNyZWF0ZUFycmF5V2l0aFZhbHVlcygwLCBuICogbik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIFpbaSAqIG4gKyBpXSA9IGM7CiAgcmV0dXJuIFo7Cn07CmxldCBrcmlnaW5nX21hdHJpeF90cmFuc3Bvc2UgPSBmdW5jdGlvbiAoWCwgbiwgbSkgewogIGxldCBpOwogIGxldCBqOwogIGxldCBaID0gQXJyYXkobSAqIG4pOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBtOyBqKyspIHsKICAgICAgWltqICogbiArIGldID0gWFtpICogbSArIGpdOwogICAgfQogIH0KICByZXR1cm4gWjsKfTsKCi8vIGxldCBrcmlnaW5nX21hdHJpeF9zY2FsZSA9IGZ1bmN0aW9uKFgsIGMsIG4sIG0pIHsKLy8gICAgIGxldCBpLCBqCi8vICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7Ci8vICAgICAgICAgZm9yIChqID0gMDsgaiA8IG07IGorKykgewovLyAgICAgICAgICAgICBYW2kgKiBtICsgal0gKj0gYwovLyAgICAgICAgIH0KLy8gICAgIH0KLy8gfQoKbGV0IGtyaWdpbmdfbWF0cml4X2FkZCA9IGZ1bmN0aW9uIChYLCBZLCBuLCBtKSB7CiAgbGV0IGk7CiAgbGV0IGo7CiAgbGV0IFogPSBBcnJheShuICogbSk7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IG07IGorKykgewogICAgICBaW2kgKiBtICsgal0gPSBYW2kgKiBtICsgal0gKyBZW2kgKiBtICsgal07CiAgICB9CiAgfQogIHJldHVybiBaOwp9OwoKLy8gTmFpdmUgbWF0cml4IG11bHRpcGxpY2F0aW9uCmxldCBrcmlnaW5nX21hdHJpeF9tdWx0aXBseSA9IGZ1bmN0aW9uIChYLCBZLCBuLCBtLCBwKSB7CiAgbGV0IGk7CiAgbGV0IGo7CiAgbGV0IGs7CiAgbGV0IFogPSBBcnJheShuICogcCk7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IHA7IGorKykgewogICAgICBaW2kgKiBwICsgal0gPSAwOwogICAgICBmb3IgKGsgPSAwOyBrIDwgbTsgaysrKSB7CiAgICAgICAgWltpICogcCArIGpdICs9IFhbaSAqIG0gKyBrXSAqIFlbayAqIHAgKyBqXTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gWjsKfTsKCi8vIENob2xlc2t5IGRlY29tcG9zaXRpb24KbGV0IGtyaWdpbmdfbWF0cml4X2Nob2wgPSBmdW5jdGlvbiAoWCwgbikgewogIGxldCBpOwogIGxldCBqOwogIGxldCBrOwogIGxldCBwID0gQXJyYXkobik7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgcFtpXSA9IFhbaSAqIG4gKyBpXTsKICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBmb3IgKGogPSAwOyBqIDwgaTsgaisrKSB7CiAgICAgIHBbaV0gLT0gWFtpICogbiArIGpdICogWFtpICogbiArIGpdOwogICAgfQogICAgaWYgKHBbaV0gPD0gMCkgcmV0dXJuIGZhbHNlOwogICAgcFtpXSA9IE1hdGguc3FydChwW2ldKTsKICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7CiAgICAgIGZvciAoayA9IDA7IGsgPCBpOyBrKyspIHsKICAgICAgICBYW2ogKiBuICsgaV0gLT0gWFtqICogbiArIGtdICogWFtpICogbiArIGtdOwogICAgICB9CiAgICAgIFhbaiAqIG4gKyBpXSAvPSBwW2ldOwogICAgfQogIH0KICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSBYW2kgKiBuICsgaV0gPSBwW2ldOwogIHJldHVybiB0cnVlOwp9OwoKLy8gSW52ZXJzaW9uIG9mIGNob2xlc2t5IGRlY29tcG9zaXRpb24KbGV0IGtyaWdpbmdfbWF0cml4X2Nob2wyaW52ID0gZnVuY3Rpb24gKFgsIG4pIHsKICBsZXQgaTsKICBsZXQgajsKICBsZXQgazsKICBsZXQgc3VtOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIFhbaSAqIG4gKyBpXSA9IDEgLyBYW2kgKiBuICsgaV07CiAgICBmb3IgKGogPSBpICsgMTsgaiA8IG47IGorKykgewogICAgICBzdW0gPSAwOwogICAgICBmb3IgKGsgPSBpOyBrIDwgajsgaysrKSB7CiAgICAgICAgc3VtIC09IFhbaiAqIG4gKyBrXSAqIFhbayAqIG4gKyBpXTsKICAgICAgfQogICAgICBYW2ogKiBuICsgaV0gPSBzdW0gLyBYW2ogKiBuICsgal07CiAgICB9CiAgfQogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7CiAgICAgIFhbaSAqIG4gKyBqXSA9IDA7CiAgICB9CiAgfQogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIFhbaSAqIG4gKyBpXSAqPSBYW2kgKiBuICsgaV07CiAgICBmb3IgKGsgPSBpICsgMTsgayA8IG47IGsrKykgewogICAgICBYW2kgKiBuICsgaV0gKz0gWFtrICogbiArIGldICogWFtrICogbiArIGldOwogICAgfQogICAgZm9yIChqID0gaSArIDE7IGogPCBuOyBqKyspIHsKICAgICAgZm9yIChrID0gajsgayA8IG47IGsrKykgewogICAgICAgIFhbaSAqIG4gKyBqXSArPSBYW2sgKiBuICsgaV0gKiBYW2sgKiBuICsgal07CiAgICAgIH0KICAgIH0KICB9CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IGk7IGorKykgewogICAgICBYW2kgKiBuICsgal0gPSBYW2ogKiBuICsgaV07CiAgICB9CiAgfQp9OwoKLy8gSW52ZXJzaW9uIHZpYSBnYXVzcy1qb3JkYW4gZWxpbWluYXRpb24KbGV0IGtyaWdpbmdfbWF0cml4X3NvbHZlID0gZnVuY3Rpb24gKFgsIG4pIHsKICBsZXQgbSA9IG47CiAgbGV0IGIgPSBBcnJheShuICogbik7CiAgbGV0IGluZHhjID0gQXJyYXkobik7CiAgbGV0IGluZHhyID0gQXJyYXkobik7CiAgbGV0IGlwaXYgPSBBcnJheShuKTsKICBsZXQgaTsKICBsZXQgaWNvbDsKICBsZXQgaXJvdzsKICBsZXQgajsKICBsZXQgazsKICBsZXQgbDsKICBsZXQgbGw7CiAgbGV0IGJpZywgZHVtLCBwaXZpbnYsIHRlbXA7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IG47IGorKykgewogICAgICBpZiAoaSA9PT0gaikgYltpICogbiArIGpdID0gMTtlbHNlIGJbaSAqIG4gKyBqXSA9IDA7CiAgICB9CiAgfQogIGZvciAoaiA9IDA7IGogPCBuOyBqKyspIGlwaXZbal0gPSAwOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGJpZyA9IDA7CiAgICBmb3IgKGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgIGlmIChpcGl2W2pdICE9PSAxKSB7CiAgICAgICAgZm9yIChrID0gMDsgayA8IG47IGsrKykgewogICAgICAgICAgaWYgKGlwaXZba10gPT09IDApIHsKICAgICAgICAgICAgaWYgKE1hdGguYWJzKFhbaiAqIG4gKyBrXSkgPj0gYmlnKSB7CiAgICAgICAgICAgICAgYmlnID0gTWF0aC5hYnMoWFtqICogbiArIGtdKTsKICAgICAgICAgICAgICBpcm93ID0gajsKICAgICAgICAgICAgICBpY29sID0gazsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogICAgKytpcGl2W2ljb2xdOwogICAgaWYgKGlyb3cgIT09IGljb2wpIHsKICAgICAgZm9yIChsID0gMDsgbCA8IG47IGwrKykgewogICAgICAgIHRlbXAgPSBYW2lyb3cgKiBuICsgbF07CiAgICAgICAgWFtpcm93ICogbiArIGxdID0gWFtpY29sICogbiArIGxdOwogICAgICAgIFhbaWNvbCAqIG4gKyBsXSA9IHRlbXA7CiAgICAgIH0KICAgICAgZm9yIChsID0gMDsgbCA8IG07IGwrKykgewogICAgICAgIHRlbXAgPSBiW2lyb3cgKiBuICsgbF07CiAgICAgICAgYltpcm93ICogbiArIGxdID0gYltpY29sICogbiArIGxdOwogICAgICAgIGJbaWNvbCAqIG4gKyBsXSA9IHRlbXA7CiAgICAgIH0KICAgIH0KICAgIGluZHhyW2ldID0gaXJvdzsKICAgIGluZHhjW2ldID0gaWNvbDsKICAgIGlmIChYW2ljb2wgKiBuICsgaWNvbF0gPT09IDApIHJldHVybiBmYWxzZTsgLy8gU2luZ3VsYXIKCiAgICBwaXZpbnYgPSAxIC8gWFtpY29sICogbiArIGljb2xdOwogICAgWFtpY29sICogbiArIGljb2xdID0gMTsKICAgIGZvciAobCA9IDA7IGwgPCBuOyBsKyspIFhbaWNvbCAqIG4gKyBsXSAqPSBwaXZpbnY7CiAgICBmb3IgKGwgPSAwOyBsIDwgbTsgbCsrKSBiW2ljb2wgKiBuICsgbF0gKj0gcGl2aW52OwogICAgZm9yIChsbCA9IDA7IGxsIDwgbjsgbGwrKykgewogICAgICBpZiAobGwgIT09IGljb2wpIHsKICAgICAgICBkdW0gPSBYW2xsICogbiArIGljb2xdOwogICAgICAgIFhbbGwgKiBuICsgaWNvbF0gPSAwOwogICAgICAgIGZvciAobCA9IDA7IGwgPCBuOyBsKyspIFhbbGwgKiBuICsgbF0gLT0gWFtpY29sICogbiArIGxdICogZHVtOwogICAgICAgIGZvciAobCA9IDA7IGwgPCBtOyBsKyspIGJbbGwgKiBuICsgbF0gLT0gYltpY29sICogbiArIGxdICogZHVtOwogICAgICB9CiAgICB9CiAgfQogIGZvciAobCA9IG4gLSAxOyBsID49IDA7IGwtLSkgewogICAgaWYgKGluZHhyW2xdICE9PSBpbmR4Y1tsXSkgewogICAgICBmb3IgKGsgPSAwOyBrIDwgbjsgaysrKSB7CiAgICAgICAgdGVtcCA9IFhbayAqIG4gKyBpbmR4cltsXV07CiAgICAgICAgWFtrICogbiArIGluZHhyW2xdXSA9IFhbayAqIG4gKyBpbmR4Y1tsXV07CiAgICAgICAgWFtrICogbiArIGluZHhjW2xdXSA9IHRlbXA7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn07CgovLyBWYXJpb2dyYW0gbW9kZWxzCmxldCBrcmlnaW5nX3ZhcmlvZ3JhbV9nYXVzc2lhbiA9IGZ1bmN0aW9uIChoLCBudWdnZXQsIHJhbmdlLCBzaWxsLCBBKSB7CiAgcmV0dXJuIG51Z2dldCArIChzaWxsIC0gbnVnZ2V0KSAvIHJhbmdlICogKDEuMCAtIE1hdGguZXhwKC0oMS4wIC8gQSkgKiBNYXRoLnBvdyhoIC8gcmFuZ2UsIDIpKSk7Cn07CmxldCBrcmlnaW5nX3ZhcmlvZ3JhbV9leHBvbmVudGlhbCA9IGZ1bmN0aW9uIChoLCBudWdnZXQsIHJhbmdlLCBzaWxsLCBBKSB7CiAgcmV0dXJuIG51Z2dldCArIChzaWxsIC0gbnVnZ2V0KSAvIHJhbmdlICogKDEuMCAtIE1hdGguZXhwKC0oMS4wIC8gQSkgKiAoaCAvIHJhbmdlKSkpOwp9OwpsZXQga3JpZ2luZ192YXJpb2dyYW1fc3BoZXJpY2FsID0gZnVuY3Rpb24gKGgsIG51Z2dldCwgcmFuZ2UsIHNpbGwsIEEpIHsKICBpZiAoaCA+IHJhbmdlKSByZXR1cm4gbnVnZ2V0ICsgKHNpbGwgLSBudWdnZXQpIC8gcmFuZ2U7CiAgcmV0dXJuIG51Z2dldCArIChzaWxsIC0gbnVnZ2V0KSAvIHJhbmdlICogKDEuNSAqIChoIC8gcmFuZ2UpIC0gMC41ICogTWF0aC5wb3coaCAvIHJhbmdlLCAzKSk7Cn07CgovLyBUcmFpbiB1c2luZyBnYXVzc2lhbiBwcm9jZXNzZXMgd2l0aCBiYXllc2lhbiBwcmlvcnMKa3JpZ2luZy50cmFpbiA9IGZ1bmN0aW9uICh0LCB4LCB5LCBtb2RlbCwgc2lnbWEyLCBhbHBoYSkgewogIGxldCB2YXJpb2dyYW0gPSB7CiAgICB0LAogICAgeCwKICAgIHksCiAgICBudWdnZXQ6IDAuMCwKICAgIHJhbmdlOiAwLjAsCiAgICBzaWxsOiAwLjAsCiAgICBBOiAxIC8gMywKICAgIG46IDAKICB9OwogIHN3aXRjaCAobW9kZWwpIHsKICAgIGNhc2UgJ2dhdXNzaWFuJzoKICAgICAgdmFyaW9ncmFtLm1vZGVsID0ga3JpZ2luZ192YXJpb2dyYW1fZ2F1c3NpYW47CiAgICAgIGJyZWFrOwogICAgY2FzZSAnZXhwb25lbnRpYWwnOgogICAgICB2YXJpb2dyYW0ubW9kZWwgPSBrcmlnaW5nX3ZhcmlvZ3JhbV9leHBvbmVudGlhbDsKICAgICAgYnJlYWs7CiAgICBjYXNlICdzcGhlcmljYWwnOgogICAgICB2YXJpb2dyYW0ubW9kZWwgPSBrcmlnaW5nX3ZhcmlvZ3JhbV9zcGhlcmljYWw7CiAgICAgIGJyZWFrOwogIH0KCiAgLy8gTGFnIGRpc3RhbmNlL3NlbWl2YXJpYW5jZQogIGxldCBpOwogIGxldCBqOwogIGxldCBrOwogIGxldCBsOwogIGxldCBuID0gdC5sZW5ndGg7CiAgbGV0IGRpc3RhbmNlID0gQXJyYXkoKG4gKiBuIC0gbikgLyAyKTsKICBmb3IgKGkgPSAwLCBrID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IGk7IGorKywgaysrKSB7CiAgICAgIGRpc3RhbmNlW2tdID0gQXJyYXkoMik7CiAgICAgIGRpc3RhbmNlW2tdWzBdID0gTWF0aC5wb3coTWF0aC5wb3coeFtpXSAtIHhbal0sIDIpICsgTWF0aC5wb3coeVtpXSAtIHlbal0sIDIpLCAwLjUpOwogICAgICBkaXN0YW5jZVtrXVsxXSA9IE1hdGguYWJzKHRbaV0gLSB0W2pdKTsKICAgIH0KICB9CiAgZGlzdGFuY2Uuc29ydChmdW5jdGlvbiAoYSwgYikgewogICAgcmV0dXJuIGFbMF0gLSBiWzBdOwogIH0pOwogIHZhcmlvZ3JhbS5yYW5nZSA9IGRpc3RhbmNlWyhuICogbiAtIG4pIC8gMiAtIDFdWzBdOwoKICAvLyBCaW4gbGFnIGRpc3RhbmNlCiAgbGV0IGxhZ3MgPSAobiAqIG4gLSBuKSAvIDIgPiAzMCA/IDMwIDogKG4gKiBuIC0gbikgLyAyOwogIC8vIGNvbnNvbGUubG9nKCdsYWdzJywgbGFncykKICBsZXQgdG9sZXJhbmNlID0gdmFyaW9ncmFtLnJhbmdlIC8gbGFnczsKICBsZXQgbGFnID0gY3JlYXRlQXJyYXlXaXRoVmFsdWVzKDAsIGxhZ3MpOwogIGxldCBzZW1pID0gY3JlYXRlQXJyYXlXaXRoVmFsdWVzKDAsIGxhZ3MpOwogIGlmIChsYWdzIDwgMzApIHsKICAgIGZvciAobCA9IDA7IGwgPCBsYWdzOyBsKyspIHsKICAgICAgbGFnW2xdID0gZGlzdGFuY2VbbF1bMF07CiAgICAgIHNlbWlbbF0gPSBkaXN0YW5jZVtsXVsxXTsKICAgIH0KICB9IGVsc2UgewogICAgZm9yIChpID0gMCwgaiA9IDAsIGsgPSAwLCBsID0gMDsgaSA8IGxhZ3MgJiYgaiA8IChuICogbiAtIG4pIC8gMjsgaSsrLCBrID0gMCkgewogICAgICB3aGlsZSAoZGlzdGFuY2Vbal1bMF0gPD0gKGkgKyAxKSAqIHRvbGVyYW5jZSkgewogICAgICAgIGxhZ1tsXSArPSBkaXN0YW5jZVtqXVswXTsKICAgICAgICBzZW1pW2xdICs9IGRpc3RhbmNlW2pdWzFdOwogICAgICAgIGorKzsKICAgICAgICBrKys7CiAgICAgICAgaWYgKGogPj0gKG4gKiBuIC0gbikgLyAyKSBicmVhazsKICAgICAgfQogICAgICBpZiAoayA+IDApIHsKICAgICAgICBsYWdbbF0gLz0gazsKICAgICAgICBzZW1pW2xdIC89IGs7CiAgICAgICAgbCsrOwogICAgICAgIC8vIGNvbnNvbGUubG9nKCdsKysnLCBsKQogICAgICB9CiAgICB9CgogICAgaWYgKGwgPCAyKSByZXR1cm4gdmFyaW9ncmFtOyAvLyBFcnJvcjogTm90IGVub3VnaCBwb2ludHMKICB9CgogIC8vc2F2ZQogIGxldCBiYXJzID0gW107CiAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykgewogICAgbGV0IHMwID0gbGFnW2ldOwogICAgbGV0IHMxID0gc2VtaVtpXTsKICAgIGJhcnMucHVzaChbczAsIHMxXSk7CiAgfQogIGxldCBzdnBkID0gewogICAgZGF0YTogZGlzdGFuY2UsCiAgICBiYXJzCiAgfTsKICB2YXJpb2dyYW0uc3ZwZCA9IHN2cGQ7CgogIC8vIEZlYXR1cmUgdHJhbnNmb3JtYXRpb24KICBuID0gbDsKICB2YXJpb2dyYW0ucmFuZ2UgPSBsYWdbbiAtIDFdIC0gbGFnWzBdOwogIGxldCBYID0gY3JlYXRlQXJyYXlXaXRoVmFsdWVzKDEsIDIgKiBuKTsKICBsZXQgWSA9IEFycmF5KG4pOwogIGxldCBBID0gdmFyaW9ncmFtLkE7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgc3dpdGNoIChtb2RlbCkgewogICAgICBjYXNlICdnYXVzc2lhbic6CiAgICAgICAgWFtpICogMiArIDFdID0gMS4wIC0gTWF0aC5leHAoLSgxLjAgLyBBKSAqIE1hdGgucG93KGxhZ1tpXSAvIHZhcmlvZ3JhbS5yYW5nZSwgMikpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdleHBvbmVudGlhbCc6CiAgICAgICAgWFtpICogMiArIDFdID0gMS4wIC0gTWF0aC5leHAoLSgxLjAgLyBBKSAqIGxhZ1tpXSAvIHZhcmlvZ3JhbS5yYW5nZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ3NwaGVyaWNhbCc6CiAgICAgICAgWFtpICogMiArIDFdID0gMS41ICogKGxhZ1tpXSAvIHZhcmlvZ3JhbS5yYW5nZSkgLSAwLjUgKiBNYXRoLnBvdyhsYWdbaV0gLyB2YXJpb2dyYW0ucmFuZ2UsIDMpOwogICAgICAgIGJyZWFrOwogICAgfQogICAgWVtpXSA9IHNlbWlbaV07CiAgfQoKICAvLyBMZWFzdCBzcXVhcmVzCiAgbGV0IFh0ID0ga3JpZ2luZ19tYXRyaXhfdHJhbnNwb3NlKFgsIG4sIDIpOwogIGxldCBaID0ga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoWHQsIFgsIDIsIG4sIDIpOwogIFogPSBrcmlnaW5nX21hdHJpeF9hZGQoWiwga3JpZ2luZ19tYXRyaXhfZGlhZygxIC8gYWxwaGEsIDIpLCAyLCAyKTsKICBsZXQgY2xvbmVaID0gWi5zbGljZSgwKTsKICBpZiAoa3JpZ2luZ19tYXRyaXhfY2hvbChaLCAyKSkgewogICAga3JpZ2luZ19tYXRyaXhfY2hvbDJpbnYoWiwgMik7CiAgfSBlbHNlIHsKICAgIGtyaWdpbmdfbWF0cml4X3NvbHZlKGNsb25lWiwgMik7CiAgICBaID0gY2xvbmVaOwogIH0KICBsZXQgVyA9IGtyaWdpbmdfbWF0cml4X211bHRpcGx5KGtyaWdpbmdfbWF0cml4X211bHRpcGx5KFosIFh0LCAyLCAyLCBuKSwgWSwgMiwgbiwgMSk7CgogIC8vIFZhcmlvZ3JhbSBwYXJhbWV0ZXJzCiAgdmFyaW9ncmFtLm51Z2dldCA9IFdbMF07CiAgdmFyaW9ncmFtLnNpbGwgPSBXWzFdICogdmFyaW9ncmFtLnJhbmdlICsgdmFyaW9ncmFtLm51Z2dldDsKICB2YXJpb2dyYW0ubiA9IHgubGVuZ3RoOwoKICAvLyBHcmFtIG1hdHJpeCB3aXRoIHByaW9yCiAgbiA9IHgubGVuZ3RoOwogIGxldCBLID0gQXJyYXkobiAqIG4pOwogIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGZvciAoaiA9IDA7IGogPCBpOyBqKyspIHsKICAgICAgS1tpICogbiArIGpdID0gdmFyaW9ncmFtLm1vZGVsKE1hdGgucG93KE1hdGgucG93KHhbaV0gLSB4W2pdLCAyKSArIE1hdGgucG93KHlbaV0gLSB5W2pdLCAyKSwgMC41KSwgdmFyaW9ncmFtLm51Z2dldCwgdmFyaW9ncmFtLnJhbmdlLCB2YXJpb2dyYW0uc2lsbCwgdmFyaW9ncmFtLkEpOwogICAgICBLW2ogKiBuICsgaV0gPSBLW2kgKiBuICsgal07CiAgICB9CiAgICBLW2kgKiBuICsgaV0gPSB2YXJpb2dyYW0ubW9kZWwoMCwgdmFyaW9ncmFtLm51Z2dldCwgdmFyaW9ncmFtLnJhbmdlLCB2YXJpb2dyYW0uc2lsbCwgdmFyaW9ncmFtLkEpOwogIH0KCiAgLy8gSW52ZXJzZSBwZW5hbGl6ZWQgR3JhbSBtYXRyaXggcHJvamVjdGVkIHRvIHRhcmdldCB2ZWN0b3IKICBsZXQgQyA9IGtyaWdpbmdfbWF0cml4X2FkZChLLCBrcmlnaW5nX21hdHJpeF9kaWFnKHNpZ21hMiwgbiksIG4sIG4pOwogIGxldCBjbG9uZUMgPSBDLnNsaWNlKDApOwogIGlmIChrcmlnaW5nX21hdHJpeF9jaG9sKEMsIG4pKSB7CiAgICBrcmlnaW5nX21hdHJpeF9jaG9sMmludihDLCBuKTsKICB9IGVsc2UgewogICAga3JpZ2luZ19tYXRyaXhfc29sdmUoY2xvbmVDLCBuKTsKICAgIEMgPSBjbG9uZUM7CiAgfQoKICAvLyBDb3B5IHVucHJvamVjdGVkIGludmVydGVkIG1hdHJpeCBhcyBLCiAgbGV0IF9LID0gQy5zbGljZSgwKTsKICBsZXQgX00gPSBrcmlnaW5nX21hdHJpeF9tdWx0aXBseShDLCB0LCBuLCBuLCAxKTsKICB2YXJpb2dyYW0uSyA9IF9LOwogIHZhcmlvZ3JhbS5NID0gX007CiAgcmV0dXJuIHZhcmlvZ3JhbTsKfTsKCi8vIE1vZGVsIHByZWRpY3Rpb24Ka3JpZ2luZy5wcmVkaWN0ID0gZnVuY3Rpb24gKHgsIHksIHZhcmlvZ3JhbSkgewogIGxldCBpOwogIGxldCBrID0gQXJyYXkodmFyaW9ncmFtLm4pOwogIGZvciAoaSA9IDA7IGkgPCB2YXJpb2dyYW0ubjsgaSsrKSB7CiAgICBrW2ldID0gdmFyaW9ncmFtLm1vZGVsKE1hdGgucG93KE1hdGgucG93KHggLSB2YXJpb2dyYW0ueFtpXSwgMikgKyBNYXRoLnBvdyh5IC0gdmFyaW9ncmFtLnlbaV0sIDIpLCAwLjUpLCB2YXJpb2dyYW0ubnVnZ2V0LCB2YXJpb2dyYW0ucmFuZ2UsIHZhcmlvZ3JhbS5zaWxsLCB2YXJpb2dyYW0uQSk7CiAgfQogIHJldHVybiBrcmlnaW5nX21hdHJpeF9tdWx0aXBseShrLCB2YXJpb2dyYW0uTSwgMSwgdmFyaW9ncmFtLm4sIDEpWzBdOwp9OwprcmlnaW5nLnZhcmlhbmNlID0gZnVuY3Rpb24gKHgsIHksIHZhcmlvZ3JhbSkgewogIGxldCBpOwogIGxldCBrID0gQXJyYXkodmFyaW9ncmFtLm4pOwogIGZvciAoaSA9IDA7IGkgPCB2YXJpb2dyYW0ubjsgaSsrKSB7CiAgICBrW2ldID0gdmFyaW9ncmFtLm1vZGVsKE1hdGgucG93KE1hdGgucG93KHggLSB2YXJpb2dyYW0ueFtpXSwgMikgKyBNYXRoLnBvdyh5IC0gdmFyaW9ncmFtLnlbaV0sIDIpLCAwLjUpLCB2YXJpb2dyYW0ubnVnZ2V0LCB2YXJpb2dyYW0ucmFuZ2UsIHZhcmlvZ3JhbS5zaWxsLCB2YXJpb2dyYW0uQSk7CiAgfQogIHJldHVybiB2YXJpb2dyYW0ubW9kZWwoMCwgdmFyaW9ncmFtLm51Z2dldCwgdmFyaW9ncmFtLnJhbmdlLCB2YXJpb2dyYW0uc2lsbCwgdmFyaW9ncmFtLkEpICsga3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoa3JpZ2luZ19tYXRyaXhfbXVsdGlwbHkoaywgdmFyaW9ncmFtLkssIDEsIHZhcmlvZ3JhbS5uLCB2YXJpb2dyYW0ubiksIGssIDEsIHZhcmlvZ3JhbS5uLCAxKVswXTsKfTsKCi8vISBMaW5lYXIgYWxnZWJyYSBwcmltaXRpdmVzIChwdXJlIEpTLCB6ZXJvIGRlcGVuZGVuY2llcykKLy8hCi8vISBQb3J0IG9mIGBmcmllZHJpY2ggMC42LjBgOgovLyEgICAtIGBzcmMvYWxnZWJyYS9tb2QucnNgICAgICAgICAgICAgICAoY292YXJpYW5jZS1tYXRyaXggaGVscGVycykKLy8hICAgLSBgc3JjL2FsZ2VicmEvZXh0ZW5kYWJsZV9tYXRyaXgucnNgIChFTWF0cml4IC8gRVZlY3RvciDihpIgRXh0ZW5kYWJsZU1hdHJpeCAvIEV4dGVuZGFibGVWZWN0b3IpCi8vISAgIC0gdGhlIHNsaWNlIG9mIGBuYWxnZWJyYWAgdGhhdCBmcmllZHJpY2ggYWN0dWFsbHkgdXNlcwovLyEgICAgIChtYXRyaXggLyB2ZWN0b3Igb3BzLCBDaG9sZXNreSBkZWNvbXBvc2l0aW9uLCB0cmlhbmd1bGFyIHNvbHZlcywKLy8hICAgICAgQ2hvbGVza3kgc29sdmUgLyBpbnZlcnNlLCBsZWFzdC1zcXVhcmVzKS4KLy8hCi8vISBEYXRhIHJlcHJlc2VudGF0aW9uIChzZWUgUE9SVF9TUEVDIMKnMik6Ci8vISAgIC0gdmVjdG9yID0gbnVtYmVyW10KLy8hICAgLSBtYXRyaXggPSBudW1iZXJbXVtdIChyb3ctbWFqb3I7IG1hdHJpeFtyXVtjXSA9IHJvdyByLCBjb2wgYykKLy8hCi8vISBBbGwgbWF0cml4IG1hdGggaGVyZSBpcyByb3ctbWFqb3I7IHdlIGRvIE5PVCBlbXVsYXRlIG5hbGdlYnJhJ3MKLy8hIGNvbHVtbi1tYWpvciBtZW1vcnkgbGF5b3V0LCBvbmx5IGl0cyBtYXRoZW1hdGljYWwgc2VtYW50aWNzLgoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCQVNJQyBWRUNUT1IgT1BFUkFUSU9OUyAoaW5wdXQ6IG51bWJlcltdKQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogRG90IHByb2R1Y3QgzqMgYeG1osK3YuG1oi4KICogQHBhcmFtIHtudW1iZXJbXX0gYQogKiBAcGFyYW0ge251bWJlcltdfSBiCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBkb3QoYSwgYikgewogIGxldCBzID0gMDsKICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHMgKz0gYVtpXSAqIGJbaV07CiAgcmV0dXJuIHM7Cn0KCi8qKgogKiBFbGVtZW50LXdpc2Ugc3VidHJhY3Rpb24gYSDiiJIgYi4KICogQHBhcmFtIHtudW1iZXJbXX0gYQogKiBAcGFyYW0ge251bWJlcltdfSBiCiAqIEByZXR1cm5zIHtudW1iZXJbXX0KICovCmZ1bmN0aW9uIHN1YlZlYyhhLCBiKSB7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KGEubGVuZ3RoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIG91dFtpXSA9IGFbaV0gLSBiW2ldOwogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBFdWNsaWRlYW4gbm9ybSBzcXJ0KM6jIGHhtaLCsikuCiAqIEBwYXJhbSB7bnVtYmVyW119IGEKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIG5vcm0oYSkgewogIHJldHVybiBNYXRoLnNxcnQobm9ybVNxdWFyZWQoYSkpOwp9CgovKioKICogU3F1YXJlZCBFdWNsaWRlYW4gbm9ybSDOoyBh4bWiwrIuCiAqIEBwYXJhbSB7bnVtYmVyW119IGEKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIG5vcm1TcXVhcmVkKGEpIHsKICBsZXQgcyA9IDA7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSBzICs9IGFbaV0gKiBhW2ldOwogIHJldHVybiBzOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE1BVFJJWCAvIE1BVFJJWC1WRUNUT1IgT1BFUkFUSU9OUyAobWF0cml4ID0gbnVtYmVyW11bXSwgb25lIHJvdyBwZXIgcm93KQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogTWF0cml4IHByb2R1Y3QgQShtw5drKSDCtyBCKGvDl24pIOKGkiAobcOXbikuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcGFyYW0ge251bWJlcltdW119IEIKICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiBtYXRNdWwoQSwgQikgewogIGNvbnN0IG0gPSBBLmxlbmd0aDsKICBjb25zdCBrID0gQVswXS5sZW5ndGg7CiAgY29uc3QgbiA9IEJbMF0ubGVuZ3RoOwogIGNvbnN0IG91dCA9IG5ldyBBcnJheShtKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG07IGkrKykgewogICAgY29uc3QgQWkgPSBBW2ldOwogICAgY29uc3Qgcm93ID0gbmV3IEFycmF5KG4pLmZpbGwoMCk7CiAgICBmb3IgKGxldCBwID0gMDsgcCA8IGs7IHArKykgewogICAgICBjb25zdCBhID0gQWlbcF07CiAgICAgIGNvbnN0IEJwID0gQltwXTsKICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBuOyBqKyspIHJvd1tqXSArPSBhICogQnBbal07CiAgICB9CiAgICBvdXRbaV0gPSByb3c7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBNYXRyaXgtdmVjdG9yIHByb2R1Y3QgQShtw5duKSDCtyB4KG4pIOKGkiBudW1iZXJbXShtKS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEBwYXJhbSB7bnVtYmVyW119IHgKICogQHJldHVybnMge251bWJlcltdfQogKi8KZnVuY3Rpb24gbWF0VmVjKEEsIHgpIHsKICBjb25zdCBtID0gQS5sZW5ndGg7CiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KG0pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICBjb25zdCBBaSA9IEFbaV07CiAgICBsZXQgcyA9IDA7CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IEFpLmxlbmd0aDsgaisrKSBzICs9IEFpW2pdICogeFtqXTsKICAgIG91dFtpXSA9IHM7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBUcmFuc3Bvc2Ugb2YgQS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gdHJhbnNwb3NlKEEpIHsKICBjb25zdCBtID0gQS5sZW5ndGg7CiAgY29uc3QgbiA9IEFbMF0ubGVuZ3RoOwogIGNvbnN0IG91dCA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykgewogICAgY29uc3QgY29sID0gbmV3IEFycmF5KG0pOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIGNvbFtpXSA9IEFbaV1bal07CiAgICBvdXRbal0gPSBjb2w7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBFbGVtZW50LXdpc2UgbWF0cml4IHN1YnRyYWN0aW9uIEEg4oiSIEIuCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gQQogKiBAcGFyYW0ge251bWJlcltdW119IEIKICogQHJldHVybnMge251bWJlcltdW119CiAqLwpmdW5jdGlvbiBtYXRTdWIoQSwgQikgewogIGNvbnN0IG0gPSBBLmxlbmd0aDsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobSk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIHsKICAgIGNvbnN0IG4gPSBBW2ldLmxlbmd0aDsKICAgIGNvbnN0IHJvdyA9IG5ldyBBcnJheShuKTsKICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSByb3dbal0gPSBBW2ldW2pdIC0gQltpXVtqXTsKICAgIG91dFtpXSA9IHJvdzsKICB9CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIG7Dl24gaWRlbnRpdHkgbWF0cml4LgogKiBAcGFyYW0ge251bWJlcn0gbgogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIGlkZW50aXR5KG4pIHsKICBjb25zdCBvdXQgPSBuZXcgQXJyYXkobik7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgIGNvbnN0IHJvdyA9IG5ldyBBcnJheShuKS5maWxsKDApOwogICAgcm93W2ldID0gMTsKICAgIG91dFtpXSA9IHJvdzsKICB9CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIG3Dl24gemVybyBtYXRyaXguCiAqIEBwYXJhbSB7bnVtYmVyfSBtCiAqIEBwYXJhbSB7bnVtYmVyfSBuCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gemVyb3MobSwgbikgewogIGNvbnN0IG91dCA9IG5ldyBBcnJheShtKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG07IGkrKykgb3V0W2ldID0gbmV3IEFycmF5KG4pLmZpbGwoMCk7CiAgcmV0dXJuIG91dDsKfQoKLyoqCiAqIFRyYWNlIM6jIEHhtaLhtaIgKGFsc28gdXNlZCBhcyBnZW5lcmljIGRpYWdvbmFsIHN1bSwgZS5nLiB0cmFjZShB4oG7wrkpKS4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiB0cmFjZShBKSB7CiAgY29uc3QgbiA9IE1hdGgubWluKEEubGVuZ3RoLCBBWzBdLmxlbmd0aCk7CiAgbGV0IHMgPSAwOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBzICs9IEFbaV1baV07CiAgcmV0dXJuIHM7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gQ0hPTEVTS1kgREVDT01QT1NJVElPTiAmIFRSSUFOR1VMQVIgU09MVkVTCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBDaG9sZXNreSBkZWNvbXBvc2l0aW9uIG9mIGEgc3ltbWV0cmljIHBvc2l0aXZlLWRlZmluaXRlIG1hdHJpeCBBKG7Dl24pLAogKiByZXR1cm5pbmcgdGhlIGxvd2VyLXRyaWFuZ3VsYXIgZmFjdG9yIEwgc3VjaCB0aGF0IEEgPSBMwrdM4bWALgogKgogKiBGYWlsdXJlIChub24tcG9zaXRpdmUtZGVmaW5pdGUpIGJlaGF2aW91cjoKICogICAtIGBlcHNpbG9uID09PSBudWxsYCDihpIgdGhyb3cgRXJyb3IgKG1hdGNoZXMgUnVzdCBgLmV4cGVjdCgpYCBwYW5pYykuCiAqICAgLSBgZXBzaWxvbmAgYSBmaW5pdGUgcG9zaXRpdmUgbnVtYmVyIOKGkiBtaW1pYyBuYWxnZWJyYQogKiAgICAgYENob2xlc2t5OjpuZXdfd2l0aF9zdWJzdGl0dXRlYDogd2hlbmV2ZXIgYSBkaWFnb25hbCBwaXZvdCBk4rG8IOKJpCAwLAogKiAgICAgc3Vic3RpdHV0ZSBgZXBzaWxvbmAgZm9yIHRoYXQgcGl2b3QgYW5kIGtlZXAgZ29pbmcuIElmIGV2ZW4gdGhlCiAqICAgICBzdWJzdGl0dXRlIGZhaWxzIHRvIGtlZXAgdGhpbmdzIHJlYWwgKGNhbm5vdCBoYXBwZW4gZm9yIGVwc2lsb24gPiAwKSwKICogICAgIHRocm93LgogKgogKiBSZWFkcyBvbmx5IHRoZSBsb3dlciB0cmlhbmdsZSBvZiBBICh0aGUgdXBwZXIgdHJpYW5nbGUgaXMgaWdub3JlZCksIG1hdGNoaW5nCiAqIG5hbGdlYnJhJ3MgYmVoYXZpb3VyIG9mIHVzaW5nIG9ubHkgdGhlIGxvd2VyLXRyaWFuZ3VsYXIgcGFydC4KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAqIEBwYXJhbSB7bnVtYmVyfG51bGx9IFtlcHNpbG9uPW51bGxdCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfSBsb3dlci10cmlhbmd1bGFyIEwKICovCmZ1bmN0aW9uIGNob2xlc2t5KEEsIGVwc2lsb24gPSBudWxsKSB7CiAgY29uc3QgbiA9IEEubGVuZ3RoOwogIC8vIEwgc3RhcnRzIGFzIGEgemVybyBtYXRyaXg7IHdlIGZpbGwgdGhlIGxvd2VyIHRyaWFuZ2xlIGNvbHVtbiBieSBjb2x1bW4sCiAgLy8gbWlycm9yaW5nIG5hbGdlYnJhJ3MgaW4tcGxhY2UgYWxnb3JpdGhtIChsb3dlci10cmlhbmd1bGFyLCBjb2x1bW4tbWFqb3IpLgogIGNvbnN0IEwgPSB6ZXJvcyhuLCBuKTsKICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykgewogICAgLy8gRGlhZ29uYWwgcGl2b3Q6IEFbal1bal0g4oiSIM6jX3trPGp9IExbal1ba13CsgogICAgbGV0IGRpYWcgPSBBW2pdW2pdOwogICAgZm9yIChsZXQgayA9IDA7IGsgPCBqOyBrKyspIGRpYWcgLT0gTFtqXVtrXSAqIExbal1ba107CiAgICBpZiAoZXBzaWxvbiA9PT0gbnVsbCkgewogICAgICBpZiAoIShkaWFnID4gMCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkNob2xlc2t5IGRlY29tcG9zaXRpb24gZmFpbGVkLCBjb25zaWRlciBzZXR0aW5nIGBjaG9sZXNreV9lcHNpbG9uYCB2aWEgYEdhdXNzaWFuUHJvY2Vzc0J1aWxkZXJgIik7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoIShkaWFnID4gMCkpIHsKICAgICAgLy8gbmV3X3dpdGhfc3Vic3RpdHV0ZTogcmVwbGFjZSB0aGUgbm9uLXBvc2l0aXZlIHBpdm90IHdpdGggZXBzaWxvbi4KICAgICAgZGlhZyA9IGVwc2lsb247CiAgICB9CiAgICBjb25zdCBsamogPSBNYXRoLnNxcnQoZGlhZyk7CiAgICBMW2pdW2pdID0gbGpqOwoKICAgIC8vIEJlbG93LWRpYWdvbmFsIGVudHJpZXMgb2YgY29sdW1uIGo6CiAgICAvLyAgIExbaV1bal0gPSAoQVtpXVtqXSDiiJIgzqNfe2s8an0gTFtpXVtrXcK3TFtqXVtrXSkgLyBMW2pdW2pdCiAgICBmb3IgKGxldCBpID0gaiArIDE7IGkgPCBuOyBpKyspIHsKICAgICAgbGV0IHMgPSBBW2ldW2pdOwogICAgICBmb3IgKGxldCBrID0gMDsgayA8IGo7IGsrKykgcyAtPSBMW2ldW2tdICogTFtqXVtrXTsKICAgICAgTFtpXVtqXSA9IHMgLyBsamo7CiAgICB9CiAgfQogIHJldHVybiBMOwp9CgovKioKICogU29sdmUgTMK3WCA9IEIgd2hlcmUgTCBpcyBsb3dlci10cmlhbmd1bGFyIChmb3J3YXJkIHN1YnN0aXR1dGlvbikuCiAqIEIgbWF5IGJlIGEgdmVjdG9yIChudW1iZXJbXSkg4oaSIHNvbHZlcyBvbmUgUkhTLCBvciBhIG1hdHJpeCAobnVtYmVyW11bXSkKICog4oaSIHNvbHZlcyBjb2x1bW4gYnkgY29sdW1uIChlYWNoIGNvbHVtbiBpcyBvbmUgUkhTKSwgcmV0dXJuaW5nIHRoZSBzYW1lIHNoYXBlLgogKiBNYXRjaGVzIG5hbGdlYnJhIGBzb2x2ZV9sb3dlcl90cmlhbmd1bGFyYC4KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBMIGxvd2VyLXRyaWFuZ3VsYXIKICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBCCiAqIEByZXR1cm5zIHtudW1iZXJbXXxudW1iZXJbXVtdfQogKi8KZnVuY3Rpb24gc29sdmVMb3dlclRyaShMLCBCKSB7CiAgaWYgKEFycmF5LmlzQXJyYXkoQlswXSkpIHsKICAgIC8vIEIgaXMgYSBtYXRyaXg6IHNvbHZlIGVhY2ggY29sdW1uLgogICAgY29uc3QgbiA9IEwubGVuZ3RoOwogICAgY29uc3QgbmNvbHMgPSBCWzBdLmxlbmd0aDsKICAgIGNvbnN0IFggPSB6ZXJvcyhuLCBuY29scyk7CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG5jb2xzOyBjKyspIHsKICAgICAgY29uc3QgY29sID0gbmV3IEFycmF5KG4pOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgY29sW2ldID0gQltpXVtjXTsKICAgICAgY29uc3Qgc29sID0gc29sdmVMb3dlclRyaVZlYyhMLCBjb2wpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgWFtpXVtjXSA9IHNvbFtpXTsKICAgIH0KICAgIHJldHVybiBYOwogIH0KICByZXR1cm4gc29sdmVMb3dlclRyaVZlYyhMLCBCKTsKfQoKLyoqCiAqIEZvcndhcmQgc3Vic3RpdHV0aW9uIGZvciBhIHNpbmdsZSBSSFMgdmVjdG9yOiBzb2x2ZSBMwrd4ID0gYi4KICogQHBhcmFtIHtudW1iZXJbXVtdfSBMIGxvd2VyLXRyaWFuZ3VsYXIKICogQHBhcmFtIHtudW1iZXJbXX0gYgogKiBAcmV0dXJucyB7bnVtYmVyW119CiAqLwpmdW5jdGlvbiBzb2x2ZUxvd2VyVHJpVmVjKEwsIGIpIHsKICBjb25zdCBuID0gTC5sZW5ndGg7CiAgY29uc3QgeCA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgewogICAgbGV0IHMgPSBiW2ldOwogICAgY29uc3QgTGkgPSBMW2ldOwogICAgZm9yIChsZXQgayA9IDA7IGsgPCBpOyBrKyspIHMgLT0gTGlba10gKiB4W2tdOwogICAgeFtpXSA9IHMgLyBMaVtpXTsKICB9CiAgcmV0dXJuIHg7Cn0KCi8qKgogKiBTb2x2ZSBVwrdYID0gQiB3aGVyZSBVIGlzIHVwcGVyLXRyaWFuZ3VsYXIgKGJhY2sgc3Vic3RpdHV0aW9uKS4KICogSW4gZnJpZWRyaWNoIHRoZSB1cHBlci10cmlhbmd1bGFyIHN5c3RlbSBpcyBVID0gTOG1gC4KICogQiBtYXkgYmUgbnVtYmVyW10gb3IgbnVtYmVyW11bXSAoY29sdW1uLXdpc2UpLCByZXR1cm5pbmcgdGhlIHNhbWUgc2hhcGUuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gVSB1cHBlci10cmlhbmd1bGFyCiAqIEBwYXJhbSB7bnVtYmVyW118bnVtYmVyW11bXX0gQgogKiBAcmV0dXJucyB7bnVtYmVyW118bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHNvbHZlVXBwZXJUcmkoVSwgQikgewogIGlmIChBcnJheS5pc0FycmF5KEJbMF0pKSB7CiAgICBjb25zdCBuID0gVS5sZW5ndGg7CiAgICBjb25zdCBuY29scyA9IEJbMF0ubGVuZ3RoOwogICAgY29uc3QgWCA9IHplcm9zKG4sIG5jb2xzKTsKICAgIGZvciAobGV0IGMgPSAwOyBjIDwgbmNvbHM7IGMrKykgewogICAgICBjb25zdCBjb2wgPSBuZXcgQXJyYXkobik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBjb2xbaV0gPSBCW2ldW2NdOwogICAgICBjb25zdCBzb2wgPSBzb2x2ZVVwcGVyVHJpVmVjKFUsIGNvbCk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBYW2ldW2NdID0gc29sW2ldOwogICAgfQogICAgcmV0dXJuIFg7CiAgfQogIHJldHVybiBzb2x2ZVVwcGVyVHJpVmVjKFUsIEIpOwp9CgovKioKICogQmFjayBzdWJzdGl0dXRpb24gZm9yIGEgc2luZ2xlIFJIUyB2ZWN0b3I6IHNvbHZlIFXCt3ggPSBiLgogKiBAcGFyYW0ge251bWJlcltdW119IFUgdXBwZXItdHJpYW5ndWxhcgogKiBAcGFyYW0ge251bWJlcltdfSBiCiAqIEByZXR1cm5zIHtudW1iZXJbXX0KICovCmZ1bmN0aW9uIHNvbHZlVXBwZXJUcmlWZWMoVSwgYikgewogIGNvbnN0IG4gPSBVLmxlbmd0aDsKICBjb25zdCB4ID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IGkgPSBuIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgIGxldCBzID0gYltpXTsKICAgIGNvbnN0IFVpID0gVVtpXTsKICAgIGZvciAobGV0IGsgPSBpICsgMTsgayA8IG47IGsrKykgcyAtPSBVaVtrXSAqIHhba107CiAgICB4W2ldID0gcyAvIFVpW2ldOwogIH0KICByZXR1cm4geDsKfQoKLyoqCiAqIFNvbHZlIEHCt1ggPSBCIGdpdmVuIHRoZSBsb3dlci10cmlhbmd1bGFyIENob2xlc2t5IGZhY3RvciBMIChBID0gTMK3TOG1gCk6CiAqIGZpcnN0IHNvbHZlIEzCt1kgPSBCIChmb3J3YXJkKSwgdGhlbiBM4bWAwrdYID0gWSAoYmFjaykuCiAqIE1hdGNoZXMgbmFsZ2VicmEgYENob2xlc2t5Ojpzb2x2ZWAuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gTCBsb3dlci10cmlhbmd1bGFyIGZhY3RvcgogKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IEIKICogQHJldHVybnMge251bWJlcltdfG51bWJlcltdW119CiAqLwpmdW5jdGlvbiBjaG9sZXNreVNvbHZlKEwsIEIpIHsKICBjb25zdCB5ID0gc29sdmVMb3dlclRyaShMLCBCKTsKICBjb25zdCBMdCA9IHRyYW5zcG9zZShMKTsKICByZXR1cm4gc29sdmVVcHBlclRyaShMdCwgeSk7Cn0KCi8qKgogKiBDb21wdXRlIEHigbvCuSA9IChMwrdM4bWAKeKBu8K5IGZyb20gdGhlIGxvd2VyLXRyaWFuZ3VsYXIgQ2hvbGVza3kgZmFjdG9yIEwsCiAqIGJ5IHNvbHZpbmcgQcK3WCA9IEkuIE1hdGNoZXMgbmFsZ2VicmEgYENob2xlc2t5OjppbnZlcnNlYC4KICoKICogQHBhcmFtIHtudW1iZXJbXVtdfSBMIGxvd2VyLXRyaWFuZ3VsYXIgZmFjdG9yCiAqIEByZXR1cm5zIHtudW1iZXJbXVtdfSBB4oG7wrkKICovCmZ1bmN0aW9uIGNob2xlc2t5SW52ZXJzZShMKSB7CiAgY29uc3QgbiA9IEwubGVuZ3RoOwogIHJldHVybiBjaG9sZXNreVNvbHZlKEwsIGlkZW50aXR5KG4pKTsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBFWFRFTkRBQkxFIE1BVFJJWCAvIFZFQ1RPUiAgKEVNYXRyaXggLyBFVmVjdG9yKQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQSBtYXRyaXggdGhhdCBjYW4gZ3JvdyBieSBhcHBlbmRpbmcgcm93cy4KICoKICogSlMgcG9ydCBub3RlOiB3ZSBzaW1wbHkgYHB1c2hgIHJvd3MuIFRoZSBSdXN0IHZlcnNpb24gcHJlLWFsbG9jYXRlcyB3aXRoIGEKICogMS41w5cgY2FwYWNpdHktZG91Ymxpbmcgc3RyYXRlZ3kgcHVyZWx5IGZvciBtZW1vcnkgZWZmaWNpZW5jeTsgdGhhdCBoYXMgbm8KICogZWZmZWN0IG9uIHRoZSBudW1lcmljYWwgcmVzdWx0LCBzbyB3ZSBvbWl0IGl0IChQT1JUX1NQRUMgwqcyLjMpLgogKi8KY2xhc3MgRXh0ZW5kYWJsZU1hdHJpeCB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBkYXRhCiAgICovCiAgY29uc3RydWN0b3IoZGF0YSkgewogICAgLyoqIEB0eXBlIHtudW1iZXJbXVtdfSAqLwogICAgdGhpcy5kYXRhID0gZGF0YTsKICB9CgogIC8qKiBOdW1iZXIgb2Ygcm93cy4gQHJldHVybnMge251bWJlcn0gKi8KICBnZXQgbnJvd3MoKSB7CiAgICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aDsKICB9CgogIC8qKiBOdW1iZXIgb2YgY29sdW1ucy4gQHJldHVybnMge251bWJlcn0gKi8KICBnZXQgbmNvbHMoKSB7CiAgICByZXR1cm4gdGhpcy5kYXRhLmxlbmd0aCA9PT0gMCA/IDAgOiB0aGlzLmRhdGFbMF0ubGVuZ3RoOwogIH0KCiAgLyoqCiAgICogQ3VycmVudCBkYXRhIGFzIG51bWJlcltdW10gKGludGVybmFsIHJlZmVyZW5jZTsgY2FsbGVyIG11c3QgdHJlYXQgYXMgcmVhZC1vbmx5KS4KICAgKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICAgKi8KICBhc01hdHJpeCgpIHsKICAgIHJldHVybiB0aGlzLmRhdGE7CiAgfQoKICAvKioKICAgKiBBcHBlbmQgcm93cyBhdCB0aGUgYm90dG9tIChpbiBwbGFjZSkuCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSByb3dzCiAgICovCiAgYWRkUm93cyhyb3dzKSB7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd3MubGVuZ3RoOyBpKyspIHRoaXMuZGF0YS5wdXNoKHJvd3NbaV0pOwogIH0KfQoKLyoqCiAqIEEgdmVjdG9yIHRoYXQgY2FuIGdyb3cgYnkgYXBwZW5kaW5nIGVudHJpZXMuCiAqLwpjbGFzcyBFeHRlbmRhYmxlVmVjdG9yIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdfSBkYXRhCiAgICovCiAgY29uc3RydWN0b3IoZGF0YSkgewogICAgLyoqIEB0eXBlIHtudW1iZXJbXX0gKi8KICAgIHRoaXMuZGF0YSA9IGRhdGE7CiAgfQoKICAvKiogTnVtYmVyIG9mIHJvd3MgKGVudHJpZXMpLiBAcmV0dXJucyB7bnVtYmVyfSAqLwogIGdldCBucm93cygpIHsKICAgIHJldHVybiB0aGlzLmRhdGEubGVuZ3RoOwogIH0KCiAgLyoqCiAgICogQ3VycmVudCBkYXRhIGFzIG51bWJlcltdIChpbnRlcm5hbCByZWZlcmVuY2U7IGNhbGxlciBtdXN0IHRyZWF0IGFzIHJlYWQtb25seSkuCiAgICogQHJldHVybnMge251bWJlcltdfQogICAqLwogIGFzVmVjdG9yKCkgewogICAgcmV0dXJuIHRoaXMuZGF0YTsKICB9CgogIC8qKgogICAqIEFwcGVuZCBlbnRyaWVzIChpbiBwbGFjZSkuCiAgICogQHBhcmFtIHtudW1iZXJbXX0gcm93cwogICAqLwogIGFkZFJvd3Mocm93cykgewogICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB0aGlzLmRhdGEucHVzaChyb3dzW2ldKTsKICB9CgogIC8qKgogICAqIE92ZXJ3cml0ZSB0aGUgd2hvbGUgY29udGVudDsgbGVuZ3RoIG11c3QgZXF1YWwgdGhlIGN1cnJlbnQgbGVuZ3RoCiAgICogKG1hdGNoZXMgUnVzdCBgYXNzZXJ0X2VxIWApLgogICAqIEBwYXJhbSB7bnVtYmVyW119IHJvd3MKICAgKi8KICBhc3NpZ24ocm93cykgewogICAgaWYgKHJvd3MubGVuZ3RoICE9PSB0aGlzLmRhdGEubGVuZ3RoKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgRXh0ZW5kYWJsZVZlY3Rvci5hc3NpZ246IGxlbmd0aCBtaXNtYXRjaCAoZ290ICR7cm93cy5sZW5ndGh9LCBleHBlY3RlZCAke3RoaXMuZGF0YS5sZW5ndGh9KWApOwogICAgfQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB0aGlzLmRhdGFbaV0gPSByb3dzW2ldOwogIH0KfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDSE9MRVNLWSBERUNPTVBPU0lUSU9OIENMQVNTIChpbmNyZW1lbnRhbCBPKG7CsikgdXBkYXRlKQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQSBzdG9yZWQgQ2hvbGVza3kgZGVjb21wb3NpdGlvbiBvZiBhIHN5bW1ldHJpYyBwb3NpdGl2ZS1kZWZpbml0ZSBtYXRyaXgsCiAqIHN1cHBvcnRpbmcgaW5jcmVtZW50YWwgTyhuwrIpIGdyb3d0aCB2aWEgYGluc2VydENvbHVtbmAgKHVzZWQgYnkKICogR2F1c3NpYW5Qcm9jZXNzLmFkZFNhbXBsZXMpLiBNaXJyb3JzIG5hbGdlYnJhJ3MgYENob2xlc2t5YCBvYmplY3QgdGhhdAogKiBmcmllZHJpY2gga2VlcHMgaW5zaWRlIHRoZSBHUC4KICovCmNsYXNzIENob2xlc2t5RGVjb21wb3NpdGlvbiB7CiAgLyoqCiAgICogQnVpbGQgZnJvbSBhIHN5bW1ldHJpYyBwb3NpdGl2ZS1kZWZpbml0ZSBtYXRyaXguCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBBCiAgICogQHBhcmFtIHtudW1iZXJ8bnVsbH0gW2Vwc2lsb249bnVsbF0gbnVsbCDihpIgdGhyb3cgb24gZmFpbHVyZTsgcG9zaXRpdmUg4oaSIHN1YnN0aXR1dGUgbW9kZS4KICAgKi8KICBjb25zdHJ1Y3RvcihBLCBlcHNpbG9uID0gbnVsbCkgewogICAgLyoqIEB0eXBlIHtudW1iZXJbXVtdfSBsb3dlci10cmlhbmd1bGFyIGZhY3RvciBMIChBID0gTMK3TOG1gCkgKi8KICAgIHRoaXMuX0wgPSBjaG9sZXNreShBLCBlcHNpbG9uKTsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfG51bGx9ICovCiAgICB0aGlzLl9lcHNpbG9uID0gZXBzaWxvbjsKICB9CgogIC8qKgogICAqIExvd2VyLXRyaWFuZ3VsYXIgZmFjdG9yIEwuCiAgICogQHJldHVybnMge251bWJlcltdW119CiAgICovCiAgbCgpIHsKICAgIHJldHVybiB0aGlzLl9MOwogIH0KCiAgLyoqCiAgICogU29sdmUgQcK3WCA9IEIgKEI6IG51bWJlcltdIHwgbnVtYmVyW11bXSksIHNhbWUgc2hhcGUgb3V0LgogICAqIEVxdWl2YWxlbnQgdG8gY2hvbGVza3lTb2x2ZSh0aGlzLmwoKSwgQikuCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBCCiAgICogQHJldHVybnMge251bWJlcltdfG51bWJlcltdW119CiAgICovCiAgc29sdmUoQikgewogICAgcmV0dXJuIGNob2xlc2t5U29sdmUodGhpcy5fTCwgQik7CiAgfQoKICAvKioKICAgKiBTb2x2ZSBMwrdYID0gQiAoZm9yd2FyZCBzdWJzdGl0dXRpb24gb25seSkuCiAgICogRXF1aXZhbGVudCB0byBzb2x2ZUxvd2VyVHJpKHRoaXMubCgpLCBCKS4KICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IEIKICAgKiBAcmV0dXJucyB7bnVtYmVyW118bnVtYmVyW11bXX0KICAgKi8KICBzb2x2ZUxvd2VyKEIpIHsKICAgIHJldHVybiBzb2x2ZUxvd2VyVHJpKHRoaXMuX0wsIEIpOwogIH0KCiAgLyoqCiAgICogSW52ZXJzZSBB4oG7wrkuCiAgICogQHJldHVybnMge251bWJlcltdW119CiAgICovCiAgaW52ZXJzZSgpIHsKICAgIHJldHVybiBjaG9sZXNreUludmVyc2UodGhpcy5fTCk7CiAgfQoKICAvKioKICAgKiBJbnNlcnQgYSByb3cvY29sdW1uIGF0IHBvc2l0aW9uIGBjb2xJbmRleGAsIHlpZWxkaW5nIHRoZQogICAqIChuKzEpw5cobisxKSBkZWNvbXBvc2l0aW9uLiBJbiBmcmllZHJpY2ggYGNvbEluZGV4YCBpcyBhbHdheXMgdGhlIG9sZAogICAqIGRpbWVuc2lvbiAoaS5lLiBhcHBlbmRlZCBhdCB0aGUgZW5kKSwgc28gdGhpcyBpbXBsZW1lbnRzIHRoZSBzdGFuZGFyZAogICAqICJib3JkZXJpbmciIHVwZGF0ZToKICAgKgogICAqICAgTCcgPSBbIEwgICAgICAwICAgXSAgICAgIHdpdGggICBMIMK3IGwyMSA9IHZbMC4ubl0gICAobG93ZXItdHJpIHNvbHZlKQogICAqICAgICAgICBbIGwyMeG1gCAgIGwyMiBdICAgICAgICAgICAgIGwyMiA9IHNxcnQodltuXSDiiJIgbDIxwrdsMjEpCiAgICoKICAgKiB3aGVyZSBgdmAgPSBgbmV3Q29sdW1uYCAobGVuZ3RoIG4rMSk6IHZbMC4ubl0gYXJlIGNvdmFyaWFuY2VzIHdpdGggdGhlCiAgICogZXhpc3Rpbmcgcm93cyBhbmQgdltuXSBpcyB0aGUgbmV3IHBvaW50J3Mgc2VsZi1jb3ZhcmlhbmNlIChhbHJlYWR5CiAgICogaW5jbHVkaW5nIG5vaXNlwrIpLgogICAqCiAgICogSWYgbDIywrIg4omkIDAgYW5kIGFuIGVwc2lsb24gd2FzIGNvbmZpZ3VyZWQsIHN1YnN0aXR1dGUgZXBzaWxvbiBmb3IgdGhlCiAgICogcGl2b3QgKG1hdGNoZXMgdGhlIHN1YnN0aXR1dGUgYmVoYXZpb3VyIG9mIHRoZSBiYXRjaCBDaG9sZXNreSkuCiAgICoKICAgKiBVcGRhdGVzIHRoaXMgb2JqZWN0IGluIHBsYWNlIGFuZCByZXR1cm5zIGB0aGlzYC4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyfSBjb2xJbmRleCAgbXVzdCBlcXVhbCB0aGUgY3VycmVudCBkaW1lbnNpb24gKGVuZCBpbnNlcnRpb24pCiAgICogQHBhcmFtIHtudW1iZXJbXX0gbmV3Q29sdW1uIGxlbmd0aCBjb2xJbmRleCsxCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgaW5zZXJ0Q29sdW1uKGNvbEluZGV4LCBuZXdDb2x1bW4pIHsKICAgIGNvbnN0IG4gPSB0aGlzLl9MLmxlbmd0aDsgLy8gb2xkIGRpbWVuc2lvbgogICAgLy8gZnJpZWRyaWNoIG9ubHkgZXZlciBpbnNlcnRzIGF0IHRoZSBlbmQuCiAgICBpZiAoY29sSW5kZXggIT09IG4pIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaG9sZXNreURlY29tcG9zaXRpb24uaW5zZXJ0Q29sdW1uOiBvbmx5IGVuZCBpbnNlcnRpb24gc3VwcG9ydGVkIChjb2xJbmRleD0ke2NvbEluZGV4fSwgZGltPSR7bn0pYCk7CiAgICB9CiAgICBjb25zdCBMID0gdGhpcy5fTDsKCiAgICAvLyBTb2x2ZSBMIMK3IGwyMSA9IHZbMC4ubl0gIChmb3J3YXJkIHN1YnN0aXR1dGlvbikuCiAgICBjb25zdCB2ID0gbmV3Q29sdW1uOwogICAgY29uc3QgbDIxID0gbmV3IEFycmF5KG4pOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgbGV0IHMgPSB2W2ldOwogICAgICBjb25zdCBMaSA9IExbaV07CiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaTsgaysrKSBzIC09IExpW2tdICogbDIxW2tdOwogICAgICBsMjFbaV0gPSBzIC8gTGlbaV07CiAgICB9CgogICAgLy8gbDIyID0gc3FydCh2W25dIOKIkiBsMjHCt2wyMSkKICAgIGxldCBwaXZvdCA9IHZbbl07CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgcGl2b3QgLT0gbDIxW2ldICogbDIxW2ldOwogICAgaWYgKHRoaXMuX2Vwc2lsb24gPT09IG51bGwpIHsKICAgICAgaWYgKCEocGl2b3QgPiAwKSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiQ2hvbGVza3kgZGVjb21wb3NpdGlvbiBmYWlsZWQsIGNvbnNpZGVyIHNldHRpbmcgYGNob2xlc2t5X2Vwc2lsb25gIHZpYSBgR2F1c3NpYW5Qcm9jZXNzQnVpbGRlcmAiKTsKICAgICAgfQogICAgfSBlbHNlIGlmICghKHBpdm90ID4gMCkpIHsKICAgICAgcGl2b3QgPSB0aGlzLl9lcHNpbG9uOwogICAgfQogICAgY29uc3QgbDIyID0gTWF0aC5zcXJ0KHBpdm90KTsKCiAgICAvLyBCdWlsZCB0aGUgKG4rMSnDlyhuKzEpIGxvd2VyLXRyaWFuZ3VsYXIgZmFjdG9yLgogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIExbaV0ucHVzaCgwKTsgLy8gcGFkIGV4aXN0aW5nIHJvd3Mgd2l0aCBhIDAgaW4gdGhlIG5ldyBjb2x1bW4KICAgIGNvbnN0IGxhc3RSb3cgPSBuZXcgQXJyYXkobiArIDEpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIGxhc3RSb3dbaV0gPSBsMjFbaV07CiAgICBsYXN0Um93W25dID0gbDIyOwogICAgTC5wdXNoKGxhc3RSb3cpOwogICAgcmV0dXJuIHRoaXM7CiAgfQp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIENPVkFSSUFOQ0UtTUFUUklYIEhFTFBFUlMgIChhbGdlYnJhL21vZC5ycyBmcmVlIGZ1bmN0aW9ucykKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIENvdmFyaWFuY2UgbWF0cml4IGJldHdlZW4gcm93cyBvZiBtMSBhbmQgcm93cyBvZiBtMiB1c2luZyBga2VybmVsYC4KICogb3V0W3JdW2NdID0ga2VybmVsLmtlcm5lbChtMVtyXSwgbTJbY10pLiBTaGFwZSAobTEubGVuZ3RoIMOXIG0yLmxlbmd0aCkuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gbTEKICogQHBhcmFtIHtudW1iZXJbXVtdfSBtMgogKiBAcGFyYW0ge3trZXJuZWw6ICh4MTpudW1iZXJbXSwgeDI6bnVtYmVyW10pID0+IG51bWJlcn19IGtlcm5lbAogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIG1ha2VDb3ZhcmlhbmNlTWF0cml4KG0xLCBtMiwga2VybmVsKSB7CiAgY29uc3QgciA9IG0xLmxlbmd0aDsKICBjb25zdCBjID0gbTIubGVuZ3RoOwogIGNvbnN0IG91dCA9IG5ldyBBcnJheShyKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHI7IGkrKykgewogICAgY29uc3Qgcm93ID0gbmV3IEFycmF5KGMpOwogICAgY29uc3QgeGkgPSBtMVtpXTsKICAgIGZvciAobGV0IGogPSAwOyBqIDwgYzsgaisrKSByb3dbal0gPSBrZXJuZWwua2VybmVsKHhpLCBtMltqXSk7CiAgICBvdXRbaV0gPSByb3c7CiAgfQogIHJldHVybiBvdXQ7Cn0KCi8qKgogKiBDb3ZhcmlhbmNlIG1hdHJpeCBvZiBgaW5wdXRzYCB3aXRoIGRpYWdvbmFsIG5vaXNlwrIsIHJldHVybmVkIGFzIGl0cwogKiBDaG9sZXNreURlY29tcG9zaXRpb24uCiAqCiAqICAgY292W2ldW2pdID0ga2VybmVsLmtlcm5lbChpbnB1dHNbaV0sIGlucHV0c1tqXSkKICogICBjb3ZbaV1baV0gKz0gZGlhZ29uYWxOb2lzZcKyICAgKG5vdGU6IHRoZSBTUVVBUkUgb2YgdGhlIG5vaXNlKQogKgogKiBgZXBzaWxvbmAgaXMgZm9yd2FyZGVkIHRvIHRoZSBDaG9sZXNreSAobnVsbCDihpIgdGhyb3cgb24gZmFpbHVyZTsKICogcG9zaXRpdmUg4oaSIHN1YnN0aXR1dGUgbW9kZSkuCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzCiAqIEBwYXJhbSB7e2tlcm5lbDogKHgxOm51bWJlcltdLCB4MjpudW1iZXJbXSkgPT4gbnVtYmVyfX0ga2VybmVsCiAqIEBwYXJhbSB7bnVtYmVyfSBkaWFnb25hbE5vaXNlIHRoZSBub2lzZSBTVEFOREFSRCBERVZJQVRJT04KICogQHBhcmFtIHtudW1iZXJ8bnVsbH0gW2Vwc2lsb249bnVsbF0KICogQHJldHVybnMge0Nob2xlc2t5RGVjb21wb3NpdGlvbn0KICovCmZ1bmN0aW9uIG1ha2VDaG9sZXNreUNvdk1hdHJpeChpbnB1dHMsIGtlcm5lbCwgZGlhZ29uYWxOb2lzZSwgZXBzaWxvbiA9IG51bGwpIHsKICBjb25zdCBuID0gaW5wdXRzLmxlbmd0aDsKICBjb25zdCBub2lzZVNxID0gZGlhZ29uYWxOb2lzZSAqIGRpYWdvbmFsTm9pc2U7CiAgY29uc3QgY292ID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBjb25zdCByb3cgPSBuZXcgQXJyYXkobik7CiAgICBjb25zdCB4aSA9IGlucHV0c1tpXTsKICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSByb3dbal0gPSBrZXJuZWwua2VybmVsKHhpLCBpbnB1dHNbal0pOwogICAgcm93W2ldICs9IG5vaXNlU3E7CiAgICBjb3ZbaV0gPSByb3c7CiAgfQogIHJldHVybiBuZXcgQ2hvbGVza3lEZWNvbXBvc2l0aW9uKGNvdiwgZXBzaWxvbik7Cn0KCi8qKgogKiBJbmNyZW1lbnRhbGx5IGFkZCB0aGUgbGFzdCBgbmJOZXdJbnB1dHNgIHJvd3Mgb2YgYGFsbElucHV0c2AgdG8gYW4gZXhpc3RpbmcKICogQ2hvbGVza3kgZGVjb21wb3NpdGlvbiAoaW4gcGxhY2UpLCBvbmUgcm93IGF0IGEgdGltZS4gRm9yIGVhY2ggbmV3IHJvdzoKICogICAtIGNvbXB1dGUgdGhlIG5ldyBjb2x1bW4gKGNvdmFyaWFuY2VzIHdpdGggYWxsIHJvd3MgdXAgdG8gYW5kIGluY2x1ZGluZwogKiAgICAgaXRzZWxmLCBsZW5ndGggY29sX2luZGV4KzEpLAogKiAgIC0gYWRkIG5vaXNlwrIgdG8gdGhlIGZpbmFsIChzZWxmKSBlbnRyeSwKICogICAtIGNhbGwgYGNob2xlc2t5Lmluc2VydENvbHVtbihjb2xfaW5kZXgsIGNvbHVtbilgLgogKgogKiBAcGFyYW0ge0Nob2xlc2t5RGVjb21wb3NpdGlvbn0gY2hvbGVza3kgdXBkYXRlZCBpbiBwbGFjZQogKiBAcGFyYW0ge251bWJlcltdW119IGFsbElucHV0cyBmdWxsIGlucHV0IG1hdHJpeCAob2xkIHJvd3MgdGhlbiBuZXcgcm93cykKICogQHBhcmFtIHtudW1iZXJ9IG5iTmV3SW5wdXRzIG51bWJlciBvZiB0cmFpbGluZyByb3dzIHRvIGFkZAogKiBAcGFyYW0ge3trZXJuZWw6ICh4MTpudW1iZXJbXSwgeDI6bnVtYmVyW10pID0+IG51bWJlcn19IGtlcm5lbAogKiBAcGFyYW0ge251bWJlcn0gZGlhZ29uYWxOb2lzZSB0aGUgbm9pc2UgU1RBTkRBUkQgREVWSUFUSU9OCiAqLwpmdW5jdGlvbiBhZGRSb3dzQ2hvbGVza3lDb3ZNYXRyaXgoY2hvbGVza3ksIGFsbElucHV0cywgbmJOZXdJbnB1dHMsIGtlcm5lbCwgZGlhZ29uYWxOb2lzZSkgewogIGNvbnN0IHRvdGFsID0gYWxsSW5wdXRzLmxlbmd0aDsKICBjb25zdCBuYk9sZCA9IHRvdGFsIC0gbmJOZXdJbnB1dHM7CiAgY29uc3Qgbm9pc2VTcSA9IGRpYWdvbmFsTm9pc2UgKiBkaWFnb25hbE5vaXNlOwogIGZvciAobGV0IHJvd0luZGV4ID0gMDsgcm93SW5kZXggPCBuYk5ld0lucHV0czsgcm93SW5kZXgrKykgewogICAgY29uc3QgY29sSW5kZXggPSBuYk9sZCArIHJvd0luZGV4OwogICAgY29uc3Qgcm93ID0gYWxsSW5wdXRzW2NvbEluZGV4XTsKICAgIGNvbnN0IGNvbHVtblNpemUgPSBjb2xJbmRleCArIDE7CiAgICBjb25zdCBuZXdDb2x1bW4gPSBuZXcgQXJyYXkoY29sdW1uU2l6ZSk7CiAgICBmb3IgKGxldCB0cmFpbmluZ1Jvd0luZGV4ID0gMDsgdHJhaW5pbmdSb3dJbmRleCA8IGNvbHVtblNpemU7IHRyYWluaW5nUm93SW5kZXgrKykgewogICAgICBuZXdDb2x1bW5bdHJhaW5pbmdSb3dJbmRleF0gPSBrZXJuZWwua2VybmVsKGFsbElucHV0c1t0cmFpbmluZ1Jvd0luZGV4XSwgcm93KTsKICAgIH0KICAgIG5ld0NvbHVtbltjb2xJbmRleF0gKz0gbm9pc2VTcTsKICAgIGNob2xlc2t5Lmluc2VydENvbHVtbihjb2xJbmRleCwgbmV3Q29sdW1uKTsKICB9Cn0KCi8qKgogKiBGb3IgZWFjaCBrZXJuZWwgaHlwZXItcGFyYW1ldGVyLCBidWlsZCB0aGUgKHN5bW1ldHJpYykgZ3JhZGllbnQgbWF0cml4CiAqIOKIgksv4oiCcGFyYW0uIFJldHVybnMgbnVtYmVyW11bXVtdIG9mIGxlbmd0aCBrZXJuZWwubmJQYXJhbWV0ZXJzKCkuCiAqCiAqICAgbWF0c1twXVtyXVtjXSA9IG1hdHNbcF1bY11bcl0gPSBrZXJuZWwuZ3JhZGllbnQoaW5wdXRzW3JdLCBpbnB1dHNbY10pW3BdCiAqCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzCiAqIEBwYXJhbSB7e25iUGFyYW1ldGVyczogKCkgPT4gbnVtYmVyLCBncmFkaWVudDogKHgxOm51bWJlcltdLCB4MjpudW1iZXJbXSkgPT4gbnVtYmVyW119fSBrZXJuZWwKICogQHJldHVybnMge251bWJlcltdW11bXX0KICovCmZ1bmN0aW9uIG1ha2VHcmFkaWVudENvdmFyaWFuY2VNYXRyaWNlcyhpbnB1dHMsIGtlcm5lbCkgewogIGNvbnN0IG4gPSBpbnB1dHMubGVuZ3RoOwogIGNvbnN0IG5iUGFyYW1zID0ga2VybmVsLm5iUGFyYW1ldGVycygpOwogIGNvbnN0IG1hdHMgPSBuZXcgQXJyYXkobmJQYXJhbXMpOwogIGZvciAobGV0IHAgPSAwOyBwIDwgbmJQYXJhbXM7IHArKykgbWF0c1twXSA9IHplcm9zKG4sIG4pOwogIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSB7CiAgICBjb25zdCB4ciA9IGlucHV0c1tyXTsKICAgIC8vIFN5bW1ldHJpYzogZmlsbCAocixjKSBhbmQgKGMscikgdG9nZXRoZXIgZm9yIGMg4omlIHIuCiAgICBmb3IgKGxldCBjID0gcjsgYyA8IG47IGMrKykgewogICAgICBjb25zdCBncmFkID0ga2VybmVsLmdyYWRpZW50KHhyLCBpbnB1dHNbY10pOwogICAgICBmb3IgKGxldCBwID0gMDsgcCA8IG5iUGFyYW1zOyBwKyspIHsKICAgICAgICBtYXRzW3BdW3JdW2NdID0gZ3JhZFtwXTsKICAgICAgICBtYXRzW3BdW2NdW3JdID0gZ3JhZFtwXTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gbWF0czsKfQoKLy8hICMgS2VybmVscwoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBGSVQgSEVVUklTVElDUyAoZnJlZSBmdW5jdGlvbnMsIGV4cG9ydGVkIGZvciBrZXJuZWxzICYgdGVzdHMpCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBSb3VnaCBiYW5kd2lkdGggZXN0aW1hdGU6IG1lYW4gRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gZGlzdGluY3Qgc2FtcGxlcy4KICogICDOo197aTxqfSDigJZ44bWiIOKIkiB44rG84oCWIC8gKG4obuKIkjEpLzIpCiAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBmaXRCYW5kd2lkdGhNZWFuKGlucHV0cykgewogIGxldCBzdW1EaXN0YW5jZXMgPSAwOwogIGNvbnN0IG5iU2FtcGxlcyA9IGlucHV0cy5sZW5ndGg7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYlNhbXBsZXM7IGkrKykgewogICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgbmJTYW1wbGVzOyBqKyspIHsKICAgICAgc3VtRGlzdGFuY2VzICs9IG5vcm0oc3ViVmVjKGlucHV0c1tpXSwgaW5wdXRzW2pdKSk7CiAgICB9CiAgfQogIC8vIEludGVnZXIgYXJpdGhtZXRpYyBtYXRjaGVzIFJ1c3QgYChuKm4gLSBuKSAvIDJgLgogIGNvbnN0IG5iRGlzdGFuY2VzID0gKG5iU2FtcGxlcyAqIG5iU2FtcGxlcyAtIG5iU2FtcGxlcykgLyAyOwogIHJldHVybiBzdW1EaXN0YW5jZXMgLyBuYkRpc3RhbmNlczsKfQoKLyoqCiAqIEJlc3QtZ3Vlc3MgYW1wbGl0dWRlID0gdmFyaWFuY2Ugb2YgdGhlIG91dHB1dHMuCiAqCiAqIE1hdGNoZXMgbmFsZ2VicmEgYHZhcmlhbmNlKClgOiDOoyh54bWiIOKIkiBtZWFuKcKyIC8gTiAoZGl2aWRlcyBieSBOLCB0aGUgc2FtcGxlCiAqIGNvdW50IOKAlCBOT1QgTuKIkjEpLiBDb25maXJtZWQgZnJvbSBuYWxnZWJyYSAwLjM0LjIgc3RhdGlzdGljcy5ycyAoUE9SVF9TUEVDIMKnNC4xKS4KICoKICogQHBhcmFtIHtudW1iZXJbXX0gb3V0cHV0cwogKiBAcmV0dXJucyB7bnVtYmVyfQogKi8KZnVuY3Rpb24gZml0QW1wbGl0dWRlVmFyKG91dHB1dHMpIHsKICBjb25zdCBuID0gb3V0cHV0cy5sZW5ndGg7CiAgbGV0IG1lYW4gPSAwOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBtZWFuICs9IG91dHB1dHNbaV07CiAgbWVhbiAvPSBuOwogIGxldCBhY2MgPSAwOwogIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBjb25zdCBkID0gb3V0cHV0c1tpXSAtIG1lYW47CiAgICBhY2MgKz0gZCAqIGQ7CiAgfQogIHJldHVybiBhY2MgLyBuOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKICogU3F1YXJlZCBleHBvbmVudGlhbCAoYS5rLmEuIEdhdXNzaWFuKSBrZXJuZWw6CiAqICAgayh4LHkpID0gQcK3ZXhwKOKIkuKAlnjiiJJ54oCWwrIgLyAoMsK3bHPCsikpLCAgQSA9IHxhbXBsfC4KICogUGFyYW1ldGVyczogW2xzLCBhbXBsXSAoZGVmYXVsdHMgbHMgPSAxLCBhbXBsID0gMSkuIG5iUGFyYW1ldGVycyA9IDIuIFNjYWxhYmxlLgogKi8KY2xhc3MgU3F1YXJlZEV4cCB7CiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJ9IFtscz0xXQogICAqIEBwYXJhbSB7bnVtYmVyfSBbYW1wbD0xXQogICAqLwogIGNvbnN0cnVjdG9yKGxzID0gMSwgYW1wbCA9IDEpIHsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSBsZW5ndGggc2NhbGUgKi8KICAgIHRoaXMubHMgPSBsczsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSBhbXBsaXR1ZGUgKi8KICAgIHRoaXMuYW1wbCA9IGFtcGw7CiAgfQogIG5iUGFyYW1ldGVycygpIHsKICAgIHJldHVybiAyOwogIH0KICBpc1NjYWxhYmxlKCkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MQogICAqIEBwYXJhbSB7bnVtYmVyW119IHgyCiAgICogQHJldHVybnMge251bWJlcn0KICAgKi8KICBrZXJuZWwoeDEsIHgyKSB7CiAgICAvLyBTYW5pdGl6ZSBwYXJhbWV0ZXJzLgogICAgY29uc3QgYW1wbCA9IE1hdGguYWJzKHRoaXMuYW1wbCk7CiAgICBjb25zdCBkaXN0YW5jZVNxdWFyZWQgPSBub3JtU3F1YXJlZChzdWJWZWMoeDEsIHgyKSk7CiAgICBjb25zdCB4ID0gLWRpc3RhbmNlU3F1YXJlZCAvICgyICogdGhpcy5scyAqIHRoaXMubHMpOwogICAgcmV0dXJuIGFtcGwgKiBNYXRoLmV4cCh4KTsKICB9CgogIC8qKgogICAqIGdyYWRpZW50ID0gW2dyYWRfbHMsIGdyYWRfYW1wbF0gd2l0aCBkwrIgPSDigJZ44oiSeeKAlsKyLCBBID0gfGFtcGx8LAogICAqICAgZSA9IGV4cCjiiJJkwrIvKDLCt2xzwrIpKToKICAgKiAgIGdyYWRfbHMgICA9IChkwrIgwrcgQSDCtyBlKSAvIGxzwrMKICAgKiAgIGdyYWRfYW1wbCA9IHNpZ24oYW1wbCkgwrcgZQogICAqIEBwYXJhbSB7bnVtYmVyW119IHgxCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDIKICAgKiBAcmV0dXJucyB7bnVtYmVyW119CiAgICovCiAgZ3JhZGllbnQoeDEsIHgyKSB7CiAgICBjb25zdCBhbXBsID0gTWF0aC5hYnModGhpcy5hbXBsKTsKICAgIGNvbnN0IGRpc3RhbmNlU3F1YXJlZCA9IG5vcm1TcXVhcmVkKHN1YlZlYyh4MSwgeDIpKTsKICAgIGNvbnN0IGV4cG9uZW50aWFsID0gTWF0aC5leHAoLWRpc3RhbmNlU3F1YXJlZCAvICgyICogdGhpcy5scyAqIHRoaXMubHMpKTsKICAgIGNvbnN0IGdyYWRMcyA9IGRpc3RhbmNlU3F1YXJlZCAqIGFtcGwgKiBleHBvbmVudGlhbCAvIE1hdGgucG93KHRoaXMubHMsIDMpOwogICAgY29uc3QgZ3JhZEFtcGwgPSBNYXRoLnNpZ24odGhpcy5hbXBsKSAqIGV4cG9uZW50aWFsOwogICAgcmV0dXJuIFtncmFkTHMsIGdyYWRBbXBsXTsKICB9CgogIC8qKiBAcGFyYW0ge251bWJlcn0gc2NhbGUgKi8KICByZXNjYWxlKHNjYWxlKSB7CiAgICB0aGlzLmFtcGwgKj0gc2NhbGU7CiAgfQogIGdldFBhcmFtZXRlcnMoKSB7CiAgICByZXR1cm4gW3RoaXMubHMsIHRoaXMuYW1wbF07CiAgfQoKICAvKiogQHBhcmFtIHtudW1iZXJbXX0gcGFyYW1ldGVycyAqLwogIHNldFBhcmFtZXRlcnMocGFyYW1ldGVycykgewogICAgdGhpcy5scyA9IHBhcmFtZXRlcnNbMF07CiAgICB0aGlzLmFtcGwgPSBwYXJhbWV0ZXJzWzFdOwogIH0KCiAgLyoqCiAgICogaGV1cmlzdGljOiBscyA9IG1lYW4gaW50ZXItc2FtcGxlIGRpc3RhbmNlLCBhbXBsID0gb3V0cHV0IHZhcmlhbmNlLgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJbXX0gb3V0cHV0cwogICAqLwogIGhldXJpc3RpY0ZpdChpbnB1dHMsIG91dHB1dHMpIHsKICAgIHRoaXMubHMgPSBmaXRCYW5kd2lkdGhNZWFuKGlucHV0cyk7CiAgICB0aGlzLmFtcGwgPSBmaXRBbXBsaXR1ZGVWYXIob3V0cHV0cyk7CiAgfQp9CgovKiogR2F1c3NpYW4ga2VybmVsIOKAlCBhbGlhcyBvZiBTcXVhcmVkRXhwIChSdXN0IGBwdWIgdHlwZSBHYXVzc2lhbiA9IFNxdWFyZWRFeHBgKS4gKi8KY29uc3QgR2F1c3NpYW4gPSBTcXVhcmVkRXhwOwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIEV4cG9uZW50aWFsIGtlcm5lbDoKICogICBrKHgseSkgPSBBwrdleHAo4oiS4oCWeOKIknnigJYgLyAoMsK3bHPCsikpLCAgQSA9IHxhbXBsfC4KICogTk9URSB0aGUgZGVub21pbmF0b3IgaXMgMsK3bHPCsiAoTk9UIGxzKSwgZmFpdGhmdWwgdG8gUnVzdC4KICogUGFyYW1ldGVyczogW2xzLCBhbXBsXSAoZGVmYXVsdHMgbHMgPSAxLCBhbXBsID0gMSkuIG5iUGFyYW1ldGVycyA9IDIuIFNjYWxhYmxlLgogKi8KY2xhc3MgRXhwb25lbnRpYWwgewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyfSBbbHM9MV0KICAgKiBAcGFyYW0ge251bWJlcn0gW2FtcGw9MV0KICAgKi8KICBjb25zdHJ1Y3RvcihscyA9IDEsIGFtcGwgPSAxKSB7CiAgICAvKiogQHR5cGUge251bWJlcn0gbGVuZ3RoIHNjYWxlICovCiAgICB0aGlzLmxzID0gbHM7CiAgICAvKiogQHR5cGUge251bWJlcn0gYW1wbGl0dWRlICovCiAgICB0aGlzLmFtcGwgPSBhbXBsOwogIH0KICBuYlBhcmFtZXRlcnMoKSB7CiAgICByZXR1cm4gMjsKICB9CiAgaXNTY2FsYWJsZSgpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXX0geDEKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MgogICAqIEByZXR1cm5zIHtudW1iZXJ9CiAgICovCiAga2VybmVsKHgxLCB4MikgewogICAgY29uc3QgYW1wbCA9IE1hdGguYWJzKHRoaXMuYW1wbCk7CiAgICBjb25zdCBkaXN0YW5jZSA9IG5vcm0oc3ViVmVjKHgxLCB4MikpOwogICAgY29uc3QgeCA9IC1kaXN0YW5jZSAvICgyICogdGhpcy5scyAqIHRoaXMubHMpOwogICAgcmV0dXJuIGFtcGwgKiBNYXRoLmV4cCh4KTsKICB9CgogIC8qKgogICAqIGdyYWRpZW50ID0gW2dyYWRfbHMsIGdyYWRfYW1wbF0gd2l0aCBkID0g4oCWeOKIknnigJYsIEEgPSB8YW1wbHwsCiAgICogICBlID0gZXhwKOKIkmQvKDLCt2xzwrIpKToKICAgKiAgIGdyYWRfbHMgICA9IChkIMK3IEEgwrcgZSkgLyBsc8KzCiAgICogICBncmFkX2FtcGwgPSBzaWduKGFtcGwpIMK3IGUKICAgKiBAcGFyYW0ge251bWJlcltdfSB4MQogICAqIEBwYXJhbSB7bnVtYmVyW119IHgyCiAgICogQHJldHVybnMge251bWJlcltdfQogICAqLwogIGdyYWRpZW50KHgxLCB4MikgewogICAgY29uc3QgYW1wbCA9IE1hdGguYWJzKHRoaXMuYW1wbCk7CiAgICBjb25zdCBkaXN0YW5jZSA9IG5vcm0oc3ViVmVjKHgxLCB4MikpOwogICAgY29uc3QgZXhwb25lbnRpYWwgPSBNYXRoLmV4cCgtZGlzdGFuY2UgLyAoMiAqIHRoaXMubHMgKiB0aGlzLmxzKSk7CiAgICBjb25zdCBncmFkTHMgPSBkaXN0YW5jZSAqIGFtcGwgKiBleHBvbmVudGlhbCAvIE1hdGgucG93KHRoaXMubHMsIDMpOwogICAgY29uc3QgZ3JhZEFtcGwgPSBNYXRoLnNpZ24odGhpcy5hbXBsKSAqIGV4cG9uZW50aWFsOwogICAgcmV0dXJuIFtncmFkTHMsIGdyYWRBbXBsXTsKICB9CgogIC8qKiBAcGFyYW0ge251bWJlcn0gc2NhbGUgKi8KICByZXNjYWxlKHNjYWxlKSB7CiAgICB0aGlzLmFtcGwgKj0gc2NhbGU7CiAgfQogIGdldFBhcmFtZXRlcnMoKSB7CiAgICByZXR1cm4gW3RoaXMubHMsIHRoaXMuYW1wbF07CiAgfQoKICAvKiogQHBhcmFtIHtudW1iZXJbXX0gcGFyYW1ldGVycyAqLwogIHNldFBhcmFtZXRlcnMocGFyYW1ldGVycykgewogICAgdGhpcy5scyA9IHBhcmFtZXRlcnNbMF07CiAgICB0aGlzLmFtcGwgPSBwYXJhbWV0ZXJzWzFdOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcltdfSBvdXRwdXRzCiAgICovCiAgaGV1cmlzdGljRml0KGlucHV0cywgb3V0cHV0cykgewogICAgdGhpcy5scyA9IGZpdEJhbmR3aWR0aE1lYW4oaW5wdXRzKTsKICAgIHRoaXMuYW1wbCA9IGZpdEFtcGxpdHVkZVZhcihvdXRwdXRzKTsKICB9Cn0KCi8qKgogKiBQcmlvciBtb2RlbHMgZm9yIEdhdXNzaWFuIFByb2Nlc3MgUmVncmVzc2lvbi4KICoKICogUG9ydCBvZiBgZnJpZWRyaWNoIDAuNi4wIHNyYy9wYXJhbWV0ZXJzL3ByaW9yLnJzYC4KICoKICogV2hlbiBhc2tlZCB0byBwcmVkaWN0IGEgdmFsdWUgZm9yIGFuIGlucHV0IHRoYXQgaXMgdG9vIGRpc3NpbWlsYXIgdG8ga25vd24KICogaW5wdXRzLCB0aGUgbW9kZWwgcmV0dXJucyB0aGUgcHJpb3IuIFRoZSBHUCBpcyBmaXR0ZWQgb24gdGhlICpyZXNpZHVhbCogb2YKICogdGhlIHByaW9yLCBzbyBhIGdvb2QgcHJpb3IgY2FuIHNpZ25pZmljYW50bHkgaW1wcm92ZSBwcmVjaXNpb24uCiAqCiAqIERhdGEgcmVwcmVzZW50YXRpb24gKHNlZSBQT1JUX1NQRUMgwqcyKToKICogICAtIGlucHV0cyAgOiBudW1iZXJbXVtdIChyb3ctbWFqb3I7IG9uZSBzYW1wbGUgcGVyIHJvdykKICogICAtIG91dHB1dHMgOiBudW1iZXJbXQogKgogKiBEZXBlbmRlbmNpZXM6IGFsZ2VicmEubWpzIChkb3QsIGxzdHNxU29sdmUpCiAqLwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIENvbnN0YW50UHJpb3IKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKICogVGhlIENvbnN0YW50IHByaW9yLgogKgogKiBSZXR1cm5zIGEgc2luZ2xlIGNvbnN0YW50IHZhbHVlIGZvciBldmVyeSBpbnB1dCBwb2ludDogZih4KSA9IGMuCiAqIENhbiBiZSBmaXR0ZWQgdG8gdGhlIG1lYW4gb2YgdGhlIHRyYWluaW5nIG91dHB1dHMuCiAqLwpjbGFzcyBDb25zdGFudFByaW9yIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcn0gYyB0aGUgY29uc3RhbnQgcHJpb3IgdmFsdWUKICAgKi8KICBjb25zdHJ1Y3RvcihjKSB7CiAgICAvKiogQHR5cGUge251bWJlcn0gKi8KICAgIHRoaXMuYyA9IGM7CiAgfQoKICAvKioKICAgKiBDcmVhdGVzIHRoZSBkZWZhdWx0IENvbnN0YW50UHJpb3Igd2l0aCBjID0gMC4KICAgKiBNYXRjaGVzIFJ1c3QgYENvbnN0YW50UHJpb3I6OmRlZmF1bHQoX2lucHV0X2RpbWVuc2lvbikg4oaSIFNlbGY6Om5ldygwZjY0KWAuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcn0gX2lucHV0RGltZW5zaW9uIGlnbm9yZWQKICAgKiBAcmV0dXJucyB7Q29uc3RhbnRQcmlvcn0KICAgKi8KICBzdGF0aWMgZGVmYXVsdChfaW5wdXREaW1lbnNpb24pIHsKICAgIHJldHVybiBuZXcgQ29uc3RhbnRQcmlvcigwKTsKICB9CgogIC8qKgogICAqIFJldHVybnMgYSBjb25zdGFudCB2ZWN0b3Igb2YgbGVuZ3RoIGBpbnB1dHMubGVuZ3RoYCwgZWFjaCBlbnRyeSA9IHRoaXMuYy4KICAgKiBNYXRjaGVzIFJ1c3QgYHByaW9yKGlucHV0KSDihpIgRFZlY3Rvcjo6ZnJvbV9lbGVtZW50KGlucHV0Lm5yb3dzKCksIHNlbGYuYylgLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBpbnB1dHMgb25lIHNhbXBsZSBwZXIgcm93CiAgICogQHJldHVybnMge251bWJlcltdfSBjb25zdGFudCBhcnJheSwgbGVuZ3RoID0gaW5wdXRzLmxlbmd0aAogICAqLwogIHByaW9yKGlucHV0cykgewogICAgcmV0dXJuIG5ldyBBcnJheShpbnB1dHMubGVuZ3RoKS5maWxsKHRoaXMuYyk7CiAgfQoKICAvKioKICAgKiBGaXRzIHRoZSBwcmlvciB0byB0aGUgYXJpdGhtZXRpYyBtZWFuIG9mIGBvdXRwdXRzYC4KICAgKiBNYXRjaGVzIFJ1c3QgYGZpdChfLCB0cmFpbmluZ19vdXRwdXRzKSB7IHNlbGYuYyA9IHRyYWluaW5nX291dHB1dHMubWVhbigpIH1gLgogICAqIG5hbGdlYnJhJ3MgYG1lYW4oKWAgZGl2aWRlcyBieSBOIChlbGVtZW50IGNvdW50KSwgbWF0Y2hpbmcgSlMgYXJpdGhtZXRpYyBtZWFuLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXVtdfSBfaW5wdXRzIGlnbm9yZWQKICAgKiBAcGFyYW0ge251bWJlcltdfSBvdXRwdXRzIHRyYWluaW5nIG91dHB1dCB2YWx1ZXMKICAgKi8KICBmaXQoX2lucHV0cywgb3V0cHV0cykgewogICAgY29uc3QgbiA9IG91dHB1dHMubGVuZ3RoOwogICAgbGV0IHN1bSA9IDA7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgc3VtICs9IG91dHB1dHNbaV07CiAgICB0aGlzLmMgPSBzdW0gLyBuOwogIH0KfQoKLyoqCiAqIGNvbnZlcnNpb24ubWpzIOKAlCBJbnB1dCBmbGV4aWJpbGl0eSBmb3IgdGhlIEpTIHBvcnQgb2YgZnJpZWRyaWNoIDAuNi4wLgogKgogKiBQb3J0IG9mIGBzcmMvY29udmVyc2lvbi9tb2QucnNgLgogKgogKiBSdXN0J3MgYElucHV0YCB0cmFpdCB1c2VzIHRoZSB0eXBlIHN5c3RlbSB0byBkaXN0aW5ndWlzaDoKICogICAtIGBWZWM8ZjY0PmAgICAgICAgKHNpbmdsZSBtdWx0aWRpbWVuc2lvbmFsIHBvaW50KSDihpIgb3V0cHV0IGBmNjRgCiAqICAgLSBgVmVjPFZlYzxmNjQ+PmAgKG11bHRpcGxlIHBvaW50cykgICAgICAgICAgICAgICDihpIgb3V0cHV0IGBWZWM8ZjY0PmAKICogICAtIGBETWF0cml4PGY2ND5gICAobmFsZ2VicmEgbWF0cml4KSAgICAgICAgICAgICAgIOKGkiBvdXRwdXQgYERWZWN0b3I8ZjY0PmAKICoKICogSlMgaGFzIG5vIHBhcmFtZXRyaWMgdHlwZXMsIHNvIHdlIHVzZSAqKnJ1bnRpbWUgZGV0ZWN0aW9uKiogb24gdGhlIGZpcnN0CiAqIGVsZW1lbnQgb2YgdGhlIGlucHV0IGFycmF5OgogKiAgIC0gYG51bWJlcltdYCAgIHdoZXJlIGB0eXBlb2YgaW5wdXRbMF0gPT09ICdudW1iZXInYCDihpIgc2luZ2xlIHBvaW50CiAqICAgLSBgbnVtYmVyW11bXWAgd2hlcmUgYEFycmF5LmlzQXJyYXkoaW5wdXRbMF0pYCAgICAgIOKGkiBtdWx0aXBsZSBwb2ludHMKICoKICogVGhlICJpc1NpbmdsZSIgZmxhZyBpcyBwcm9wYWdhdGVkIGludG8gR1AgcmVzdWx0cyBzbyB0aGF0OgogKiAgIC0gc2luZ2xlLXBvaW50IGlucHV0cyAg4oaSIHNjYWxhciBvdXRwdXRzICAoYG51bWJlcmApCiAqICAgLSBtdWx0aS1wb2ludCBpbnB1dHMgICDihpIgdmVjdG9yIG91dHB1dHMgIChgbnVtYmVyW11gKQogKgogKiBUaGlzIG1hdGNoZXMgdGhlIGBPdXRWZWN0b3IgPSBmNjRgIHZzIGBPdXRWZWN0b3IgPSBWZWM8ZjY0PmAgZGlzdGluY3Rpb24KICogb2YgdGhlIFJ1c3QgdHJhaXQgaW1wbHMuCiAqCiAqIFBPUlRfU1BFQyDCpzkgKGNvbnZlcnNpb24ubWpzKSwgwqcxMiBpdGVtIDEwIChjb2x1bW4tbWFqb3IgdnMgcm93LW1ham9yKS4KICoKICogTm8gaW50ZXJuYWwgZGVwZW5kZW5jaWVzIChjb252ZXJzaW9uLm1qcyBoYXMgbm8gaW1wb3J0cyBwZXIgUE9SVF9TUEVDIMKnMQogKiBkZXBlbmRlbmN5IGdyYXBoKS4KICovCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gaXNTaW5nbGUKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKICogRGV0ZWN0IHdoZXRoZXIgYGlucHV0YCByZXByZXNlbnRzIGEgKipzaW5nbGUqKiBtdWx0aWRpbWVuc2lvbmFsIHBvaW50LgogKgogKiBSdWxlcyAobWlycm9ycyBSdXN0IHRyYWl0IGRpc3BhdGNoKToKICogICAtIGBudW1iZXJbXWAgICAoYWxsIGVsZW1lbnRzIGFyZSBudW1iZXJzKSAg4oaSIHRydWUgICAoc2luZ2xlIHBvaW50LCBsaWtlIGBWZWM8ZjY0PmApCiAqICAgLSBgbnVtYmVyW11bXWAgKGZpcnN0IGVsZW1lbnQgaXMgYW4gYXJyYXkpICDihpIgZmFsc2UgIChtdWx0aXBsZSBwb2ludHMsIGxpa2UgYFZlYzxWZWM8ZjY0Pj5gKQogKgogKiBBbiBlbXB0eSBhcnJheSBpcyB0cmVhdGVkIGFzIG11bHRpLXBvaW50IChmYWxzeSBzaW5nbGUsIG1hdGNoZXMKICogdGhlIGBhc3NlcnRfbmUhKG5iX3Jvd3MsIDApYCBndWFyZCBpbiB0aGUgUnVzdCBgVmVjPFZlYzxmNjQ+PmAgaW1wbCDigJQKICogZW1wdHkgaW5wdXRzIGFyZSByZWplY3RlZCB1cHN0cmVhbSBhbnl3YXkpLgogKgogKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0CiAqIEByZXR1cm5zIHtib29sZWFufQogKi8KZnVuY3Rpb24gaXNTaW5nbGUoaW5wdXQpIHsKICBpZiAoIUFycmF5LmlzQXJyYXkoaW5wdXQpIHx8IGlucHV0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlOwogIHJldHVybiB0eXBlb2YgaW5wdXRbMF0gPT09ICdudW1iZXInOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gdG9NYXRyaXgKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKICogTm9ybWFsaXNlIGFueSByZWNvZ25pc2VkIGlucHV0IGZvcm0gdG8gYG51bWJlcltdW11gIChvbmUgcm93IHBlciBzYW1wbGUpLgogKgogKiB8IEpTIGlucHV0ICAgICAgICAgICAgICB8IFJ1c3QgYW5hbG9ndWUgICAgICAgICB8IFJlc3VsdCAgICAgICAgICAgICAgIHwKICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CiAqIHwgYFthLCBiLCBjXWAgICAgICAgICAgIHwgYFZlYzxmNjQ+YCAgICAgICAgICAgIHwgYFtbYSwgYiwgY11dYCAoMcOXZCkgIHwKICogfCBgW1thLGJdLFtjLGRdLOKApl1gICAgICB8IGBWZWM8VmVjPGY2ND4+YCAgICAgICB8IHVuY2hhbmdlZCAgICAgICAgICAgIHwKICoKICogTWF0Y2hlcyBgSW5wdXQ6OnRvX2RtYXRyaXhgIChib3RoIGltcGxzKToKICogICAtIGBWZWM8ZjY0PmAg4oaSIGBETWF0cml4Ojpmcm9tX3Jvd19zbGljZSgxLCBtLmxlbigpLCBtKWAg4oCUIHdyYXBzIGluIDEgcm93LgogKiAgIC0gYFZlYzxWZWM8ZjY0Pj5gIOKGkiBgRE1hdHJpeDo6ZnJvbV9mbihuYl9yb3dzLCBuYl9jb2xzLCB8cixjfCBtW3JdW2NdKWAg4oCUIGRpcmVjdC4KICoKICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dAogKiBAcmV0dXJucyB7bnVtYmVyW11bXX0KICovCmZ1bmN0aW9uIHRvTWF0cml4KGlucHV0KSB7CiAgaWYgKGlzU2luZ2xlKGlucHV0KSkgewogICAgLy8gU2luZ2xlIHBvaW50OiB3cmFwIGludG8gYSAxLXJvdyBtYXRyaXguCiAgICByZXR1cm4gW2lucHV0LnNsaWNlKCldOwogIH0KICAvLyBNdWx0aXBsZSBwb2ludHM6IHJldHVybiBhIHNoYWxsb3cgY29weSBvZiB0aGUgb3V0ZXIgYXJyYXkgc28gY2FsbGVycwogIC8vIGNhbm5vdCBhY2NpZGVudGFsbHkgbXV0YXRlIHRoZSBvcmlnaW5hbCwgd2hpbGUga2VlcGluZyBpbm5lciByb3cgcmVmcy4KICByZXR1cm4gaW5wdXQuc2xpY2UoKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIHRvVmVjdG9yCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIE5vcm1hbGlzZSBhIHRyYWluaW5nLW91dHB1dCB2YWx1ZSB0byBgbnVtYmVyW11gLgogKgogKiB8IEpTIG91dHB1dCAgIHwgUnVzdCBhbmFsb2d1ZSAgfCBSZXN1bHQgICB8CiAqIHwtLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLXwKICogfCBgbnVtYmVyYCAgICB8IGBmNjRgICAgICAgICAgIHwgYFt2XWAgICAgfAogKiB8IGBudW1iZXJbXWAgIHwgYFZlYzxmNjQ+YCAgICAgfCB1bmNoYW5nZWR8CiAqCiAqIE1hdGNoZXMgYElucHV0Ojp0b19kdmVjdG9yYDoKICogICAtIGBWZWM8ZjY0PmAgaW1wbDogYERWZWN0b3I6OmZyb21fZWxlbWVudCgxLCAqdilgIOKAlCB3cmFwcyBzY2FsYXIgaW4gMS1lbGVtZW50IHZlY3Rvci4KICogICAtIGBWZWM8VmVjPGY2ND4+YCBpbXBsOiBgRFZlY3Rvcjo6ZnJvbV9jb2x1bW5fc2xpY2UodilgIOKAlCBkaXJlY3Qgc2xpY2UuCiAqCiAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSBvdXRwdXQKICogQHJldHVybnMge251bWJlcltdfQogKi8KZnVuY3Rpb24gdG9WZWN0b3Iob3V0cHV0KSB7CiAgaWYgKHR5cGVvZiBvdXRwdXQgPT09ICdudW1iZXInKSB7CiAgICByZXR1cm4gW291dHB1dF07CiAgfQogIHJldHVybiBvdXRwdXQuc2xpY2UoKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIGZyb21WZWN0b3IKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKICogQ29udmVydCBhbiBpbnRlcm5hbCByZXN1bHQgdmVjdG9yIGJhY2sgdG8gdGhlIHVzZXItZmFjaW5nIG91dHB1dCB0eXBlLgogKgogKiB8IGBzaW5nbGVgIHwgUmVzdWx0ICAgICAgICAgIHwgUnVzdCBhbmFsb2d1ZSAoYGZyb21fZHZlY3RvcmApICAgICAgICAgfAogKiB8LS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAogKiB8IGB0cnVlYCAgIHwgYHZbMF1gIChudW1iZXIpIHwgYFZlYzxmNjQ+YCBpbXBsOiBgYXNzZXJ0X2VxIShucm93cywxKTsgdlswXWAgfAogKiB8IGBmYWxzZWAgIHwgYHYuc2xpY2UoKWAgICAgIHwgYFZlYzxWZWM8ZjY0Pj5gIGltcGw6IGB2Lml0ZXIoKS5jbG9uZWQoKS5jb2xsZWN0KClgIHwKICoKICogTm90ZTogYHByZWRpY3RDb3ZhcmlhbmNlYCAqKmFsd2F5cyoqIHJldHVybnMgYG51bWJlcltdW11gIGFuZCBtdXN0IE5PVCBjYWxsCiAqIHRoaXMgZnVuY3Rpb24gKFBPUlRfU1BFQyDCpzksIMKnNi43KS4KICoKICogQHBhcmFtIHtudW1iZXJbXX0gdiAgICAgIGludGVybmFsIHJlc3VsdCB2ZWN0b3IKICogQHBhcmFtIHtib29sZWFufSAgc2luZ2xlIHRydWUgaWYgdGhlIG9yaWdpbmFsIGlucHV0IHdhcyBhIHNpbmdsZSBwb2ludAogKiBAcmV0dXJucyB7bnVtYmVyfG51bWJlcltdfQogKi8KZnVuY3Rpb24gZnJvbVZlY3Rvcih2LCBzaW5nbGUpIHsKICBpZiAoc2luZ2xlKSB7CiAgICAvLyBNaXJyb3JzOiBhc3NlcnRfZXEhKHYubnJvd3MoKSwgMSk7IHZbMF0KICAgIHJldHVybiB2WzBdOwogIH0KICByZXR1cm4gdi5zbGljZSgpOwp9CgovKioKICogTXVsdGl2YXJpYXRlIE5vcm1hbCBEaXN0cmlidXRpb24gc2FtcGxlci4KICoKICogUG9ydCBvZiBgZnJpZWRyaWNoIDAuNi4wYCBgc3JjL2dhdXNzaWFuX3Byb2Nlc3MvbXVsdGl2YXJpYXRlX25vcm1hbC5yc2AuCiAqCiAqIEV4cG9ydHM6CiAqICAgLSBgbXVsYmVycnkzMihzZWVkKWAgICAgIOKAkyBzZWVkYWJsZSBQUk5HIChQT1JUX1NQRUMgwqczKQogKiAgIC0gYHN0YW5kYXJkTm9ybWFsKHJuZylgICDigJMgQm94LU11bGxlciBOKDAsMSkgc2FtcGxlciAoUE9SVF9TUEVDIMKnMykKICogICAtIGBNdWx0aXZhcmlhdGVOb3JtYWxgICAg4oCTIGNsYXNzIHByb2R1Y2VkIGJ5IGBHYXVzc2lhblByb2Nlc3Muc2FtcGxlQXRgCiAqCiAqIFplcm8gZXh0ZXJuYWwgbnBtIGRlcGVuZGVuY2llcy4gUFJORyBjaG9pY2UgKG11bGJlcnJ5MzIgKyBCb3gtTXVsbGVyKSBpcwogKiBOT1QgYml0LWZvci1iaXQgaWRlbnRpY2FsIHRvIFJ1c3QncyByYW5kIC8gcmFuZF9kaXN0ciwgYnV0IGlzIHN0YXRpc3RpY2FsbHkKICogY29ycmVjdCBhbmQgcmVwcm9kdWNpYmxlIGdpdmVuIGEgc2VlZCAoUE9SVF9TUEVDIMKnMTIuNikuCiAqCiAqIERhdGEgcmVwcmVzZW50YXRpb24gKFBPUlRfU1BFQyDCpzIpOgogKiAgIHZlY3RvciA9IG51bWJlcltdCiAqICAgbWF0cml4ID0gbnVtYmVyW11bXSAocm93LW1ham9yKQogKi8KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gTk9STUFMIFNBTVBMRVIg4oCTIEJveC1NdWxsZXIgKFBPUlRfU1BFQyDCpzMsIGV4YWN0IGltcGxlbWVudGF0aW9uIHNwZWNpZmllZCkKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIERyYXcgb25lIHN0YW5kYXJkLW5vcm1hbCBzYW1wbGUgTigwLDEpIHVzaW5nIHRoZSBCb3gtTXVsbGVyIHRyYW5zZm9ybS4KICoKICogQ29uc3VtZXMgdHdvIHVuaWZvcm0gZHJhd3MgZnJvbSBgcm5nYDsgcmV0cmllcyBpZiB0aGUgZmlyc3QgZHJhdyBpcyBleGFjdGx5CiAqIDAgKHRvIGF2b2lkIGxvZygwKSDihpIgLUluZmluaXR5KS4KICoKICogTm90ZTogdGhpcyB1c2VzIG9ubHkgdGhlIGNvc2luZSBicmFuY2ggb2YgQm94LU11bGxlciAodGhlIHNpbmUgYnJhbmNoIGlzCiAqIGRpc2NhcmRlZCksIG1hdGNoaW5nIHRoZSBQT1JUX1NQRUMgwqczIGNhbm9uaWNhbCBpbXBsZW1lbnRhdGlvbi4gU3RhdGlzdGljYWwKICogY29ycmVjdG5lc3MgaXMgbWFpbnRhaW5lZDsgdGhlIHNpbmUgYnJhbmNoIHdvdWxkIGdpdmUgZXF1YWxseSB2YWxpZCBzYW1wbGVzCiAqIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAqCiAqIEBwYXJhbSB7KCkgPT4gbnVtYmVyfSBybmcgIHVuaWZvcm0gWzAsIDEpIGdlbmVyYXRvciAoZS5nLiBmcm9tIG11bGJlcnJ5MzIpCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBzdGFuZGFyZE5vcm1hbChybmcpIHsKICBsZXQgdTEgPSAwLAogICAgdTIgPSAwOwogIHdoaWxlICh1MSA9PT0gMCkgdTEgPSBybmcoKTsgLy8gYXZvaWQgbG9nKDApCiAgdTIgPSBybmcoKTsKICByZXR1cm4gTWF0aC5zcXJ0KC0yICogTWF0aC5sb2codTEpKSAqIE1hdGguY29zKDIgKiBNYXRoLlBJICogdTIpOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE11bHRpdmFyaWF0ZU5vcm1hbCBDTEFTUwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogTXVsdGl2YXJpYXRlIE5vcm1hbCBEaXN0cmlidXRpb24gTihtZWFuLCDOoykuCiAqCiAqIFByb2R1Y2VkIGJ5IGBHYXVzc2lhblByb2Nlc3Muc2FtcGxlQXQoaW5wdXRzKWAuIFN0b3JlcyB0aGUgQ2hvbGVza3kgZmFjdG9yCiAqIEwgb2YgdGhlIHBvc3RlcmlvciBjb3ZhcmlhbmNlIM6jICh3aGVyZSDOoyA9IEzCt0zhtYApLiBTYW1wbGluZyB1c2VzOgogKgogKiAgIHogfiBOKDAsIEkpICAoZHJhdyBlYWNoIGNvbXBvbmVudCB2aWEgQm94LU11bGxlcikKICogICB4ID0gbWVhbiArIEzCt3ogIOKGkiAgeCB+IE4obWVhbiwgzqMpCiAqCiAqIFRoZSBgaXNTaW5nbGVgIGZsYWcgbWlycm9ycyB0aGUgUnVzdCBgUGhhbnRvbURhdGE8VD5gIG1lY2hhbmlzbTogd2hlbiB0aGUKICogR1Agd2FzIHF1ZXJpZWQgYXQgYSBzaW5nbGUgcG9pbnQgKGBUID0gVmVjPGY2ND5gKSB0aGUgb3V0cHV0IG9mIGBtZWFuKClgIGFuZAogKiBgc2FtcGxlKClgIGlzIGEgYG51bWJlcmA7IHdoZW4gcXVlcmllZCBhdCBtdWx0aXBsZSBwb2ludHMgaXQgaXMgYSBgbnVtYmVyW11gLgogKgogKiBQb3J0IG5vdGVzOgogKiAgIC0gUnVzdCBzdG9yZXMgYGNob2xlc2t5X2NvdmFyaWFuY2VgIChhbHJlYWR5IHRoZSBsb3dlci10cmlhbmd1bGFyIGZhY3RvciBMCiAqICAgICBmcm9tIGBuYWxnZWJyYTo6Q2hvbGVza3k6OnVucGFjaygpYCkuIEpTIGxpa2V3aXNlIHN0b3JlcyBvbmx5IEwgYWZ0ZXIKICogICAgIGRlY29tcG9zaW5nIHRoZSBjb3ZhcmlhbmNlIGluIHRoZSBjb25zdHJ1Y3Rvci4KICogICAtIENob2xlc2t5IGZhaWx1cmUg4oaSIHRocm93IChtYXRjaGVzIFJ1c3QgYC5leHBlY3QoIi4uLiIpYCkuCiAqLwpjbGFzcyBNdWx0aXZhcmlhdGVOb3JtYWwgewogIC8qKgogICAqIEBwYXJhbSB7bnVtYmVyW119ICAgbWVhbiAgICAgICAgcG9zdGVyaW9yIG1lYW4gdmVjdG9yIChsZW5ndGggbikKICAgKiBAcGFyYW0ge251bWJlcltdW119IGNvdmFyaWFuY2UgIHBvc3RlcmlvciBjb3ZhcmlhbmNlIG1hdHJpeCAobsOXbiksIHN5bW1ldHJpYyBwb3NpdGl2ZS1kZWZpbml0ZQogICAqIEBwYXJhbSB7Ym9vbGVhbn0gICAgaXNTaW5nbGUgICAgdHJ1ZSB3aGVuIHRoZSBHUCBpbnB1dCB3YXMgYSBzaW5nbGUgcG9pbnQgKG51bWJlcltdKTsKICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlIHdoZW4gbXVsdGlwbGUgcG9pbnRzIChudW1iZXJbXVtdKQogICAqLwogIGNvbnN0cnVjdG9yKG1lYW4sIGNvdmFyaWFuY2UsIGlzU2luZ2xlKSB7CiAgICAvKiogQHR5cGUge251bWJlcltdfSAqLwogICAgdGhpcy5fbWVhbiA9IG1lYW47CiAgICAvKioKICAgICAqIExvd2VyLXRyaWFuZ3VsYXIgQ2hvbGVza3kgZmFjdG9yIEwgb2YgdGhlIGNvdmFyaWFuY2UgKM6jID0gTMK3TOG1gCkuCiAgICAgKiBAdHlwZSB7bnVtYmVyW11bXX0KICAgICAqLwogICAgdGhpcy5fTCA9IGNob2xlc2t5KGNvdmFyaWFuY2UsIG51bGwpOyAvLyBudWxsIOKGkiB0aHJvdyBvbiBmYWlsdXJlIChtYXRjaGVzIFJ1c3QgLmV4cGVjdCkKICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi8KICAgIHRoaXMuX2lzU2luZ2xlID0gaXNTaW5nbGU7CiAgfQoKICAvKioKICAgKiBQb3N0ZXJpb3IgbWVhbi4KICAgKgogICAqIFJldHVybnMgYSBgbnVtYmVyYCB3aGVuIGBpc1NpbmdsZWAgaXMgdHJ1ZSAoc2luZ2xlLXBvaW50IHF1ZXJ5KSwKICAgKiBvciBhIGBudW1iZXJbXWAgd2hlbiBmYWxzZSAobXVsdGktcG9pbnQgcXVlcnkpLgogICAqCiAgICogQHJldHVybnMge251bWJlciB8IG51bWJlcltdfQogICAqLwogIG1lYW4oKSB7CiAgICByZXR1cm4gZnJvbVZlY3Rvcih0aGlzLl9tZWFuLCB0aGlzLl9pc1NpbmdsZSk7CiAgfQoKICAvKioKICAgKiBEcmF3IG9uZSBzYW1wbGUgZnJvbSBOKG1lYW4sIM6jKS4KICAgKgogICAqIEFsZ29yaXRobSAoUE9SVF9TUEVDIMKnOCk6CiAgICogICAxLiB6ID0gW3N0YW5kYXJkTm9ybWFsKHJuZyksIOKApl0gIChvbmUgTigwLDEpIHBlciBkaW1lbnNpb24pCiAgICogICAyLiBzYW1wbGVWZWMgPSBtZWFuICsgTMK3egogICAqICAgMy4gcmV0dXJuIGZyb21WZWN0b3Ioc2FtcGxlVmVjLCBpc1NpbmdsZSkKICAgKgogICAqIGBybmdgIG11c3QgYmUgYSBgKCkgPT4gbnVtYmVyIOKIiCBbMCwgMSlgIGZ1bmN0aW9uLCBlLmcuIHRoZSBjbG9zdXJlCiAgICogcmV0dXJuZWQgYnkgYG11bGJlcnJ5MzIoc2VlZClgLiBUaGUgb3V0cHV0IHR5cGUgbWlycm9ycyBgbWVhbigpYC4KICAgKgogICAqIE51bWVyaWMgbm90ZTogdGhlIFBSTkcgYW5kIEJveC1NdWxsZXIgaW1wbGVtZW50YXRpb24gZGlmZmVyIGZyb20gUnVzdCdzCiAgICogYHJhbmRgL2ByYW5kX2Rpc3RyYCwgc28gc2FtcGxlIHZhbHVlcyB3aWxsIG5vdCBtYXRjaCBSdXN0IGJpdC1mb3ItYml0LgogICAqIFN0YXRpc3RpY2FsIGNvcnJlY3RuZXNzIGFuZCByZXByb2R1Y2liaWxpdHkgZ2l2ZW4gYSBzZWVkIGFyZSBndWFyYW50ZWVkLgogICAqCiAgICogQHBhcmFtIHsoKSA9PiBudW1iZXJ9IHJuZwogICAqIEByZXR1cm5zIHtudW1iZXIgfCBudW1iZXJbXX0KICAgKi8KICBzYW1wbGUocm5nKSB7CiAgICBjb25zdCBuID0gdGhpcy5fbWVhbi5sZW5ndGg7CiAgICAvLyBTdGVwIDE6IGRyYXcgeiB+IE4oMCwgSSkKICAgIGNvbnN0IHogPSBuZXcgQXJyYXkobik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgeltpXSA9IHN0YW5kYXJkTm9ybWFsKHJuZyk7CiAgICAvLyBTdGVwIDI6IHNhbXBsZVZlYyA9IG1lYW4gKyBMwrd6CiAgICBjb25zdCBMeiA9IG1hdFZlYyh0aGlzLl9MLCB6KTsKICAgIGNvbnN0IHNhbXBsZVZlYyA9IG5ldyBBcnJheShuKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSBzYW1wbGVWZWNbaV0gPSB0aGlzLl9tZWFuW2ldICsgTHpbaV07CiAgICAvLyBTdGVwIDM6IGNvbnZlcnQgdG8gc2NhbGFyIG9yIHZlY3RvciBkZXBlbmRpbmcgb24gcXVlcnkgdHlwZQogICAgcmV0dXJuIGZyb21WZWN0b3Ioc2FtcGxlVmVjLCB0aGlzLl9pc1NpbmdsZSk7CiAgfQp9CgovLyEgUGFyYW1ldGVyIG9wdGltaXphdGlvbiAoQURBTSBncmFkaWVudCBhc2NlbnQgb24gdGhlIG1hcmdpbmFsIGxvZy1saWtlbGlob29kKS4KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gTk9OLVNDQUxBQkxFIEtFUk5FTAovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogQ29tcHV0ZXMgdGhlIGdyYWRpZW50IG9mIHRoZSBtYXJnaW5hbCBsaWtlbGlob29kIGZvciB0aGUgY3VycmVudCB2YWx1ZSBvZgogKiBlYWNoIHBhcmFtZXRlci4gVGhlIHByb2R1Y2VkIHZlY3RvciBjb250YWlucyB0aGUgZ3JhZGllbnQgcGVyIGtlcm5lbAogKiBwYXJhbWV0ZXIgZm9sbG93ZWQgYnkgdGhlIGdyYWRpZW50IGZvciB0aGUgbm9pc2UgcGFyYW1ldGVyLgogKgogKiBQZXItcGFyYW1ldGVyIGZvcm11bGEgKGBvcHRpbWl6ZXIucnM6MjRgKToKICogICDCvSAoIGFscGhh4bWAIMK3IGRwIMK3IGFscGhhIOKIkiB0cmFjZShL4oG7wrkgwrcgZHApICkKICogd2hlcmUKICogICBLICAgICA9IGNvdih0cmFpbiwgdHJhaW4pCiAqICAgYWxwaGEgPSBL4oG7wrkgwrcgb3V0cHV0CiAqICAgZHAgICAgPSDiiIJLL+KIgnBhcmFtZXRlcgogKgogKiBOb2lzZSBncmFkaWVudCAoYGdyYWRpZW50KEssIG5vaXNlKSA9IDLCt25vaXNlwrdJZGApOgogKiAgIG5vaXNlIMK3ICggYWxwaGHCt2FscGhhIOKIkiB0cmFjZShL4oG7wrkpICkKICoKICogQHBhcmFtIHtvYmplY3R9IGdwIEdhdXNzaWFuUHJvY2VzcyAoc2VlIG1vZHVsZSBub3RlKQogKiBAcmV0dXJucyB7bnVtYmVyW119IGxlbmd0aCA9IGtlcm5lbC5uYlBhcmFtZXRlcnMoKSArIDEgKGxhc3QgZW50cnkgPSBub2lzZSkKICovCmZ1bmN0aW9uIGdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKGdwKSB7CiAgLy8gTmVlZGVkIGZvciB0aGUgcGVyLXBhcmFtZXRlciBncmFkaWVudCBjb21wdXRhdGlvbi4KICBjb25zdCBjb3ZJbnYgPSBncC5jb3ZtYXRDaG9sZXNreS5pbnZlcnNlKCk7IC8vIEvigbvCuQogIGNvbnN0IG91dHB1dCA9IGdwLnRyYWluaW5nT3V0cHV0cy5hc1ZlY3RvcigpOwoKICAvLyBhbHBoYSA9IEvigbvCuSDCtyBvdXRwdXQgIChtYXRWZWM7IGNvdkludiBpcyBzeW1tZXRyaWMpLgogIGNvbnN0IG4gPSBvdXRwdXQubGVuZ3RoOwogIGNvbnN0IGFscGhhID0gbmV3IEFycmF5KG4pOwogIGZvciAobGV0IHIgPSAwOyByIDwgbjsgcisrKSB7CiAgICBsZXQgcyA9IDA7CiAgICBjb25zdCByb3cgPSBjb3ZJbnZbcl07CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG47IGMrKykgcyArPSByb3dbY10gKiBvdXRwdXRbY107CiAgICBhbHBoYVtyXSA9IHM7CiAgfQogIGNvbnN0IGlucHV0cyA9IGdwLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CiAgY29uc3QgcmVzdWx0cyA9IFtdOwoKICAvLyBMb29wIG92ZXIgdGhlIGdyYWRpZW50IG1hdHJpeCBmb3IgZWFjaCBwYXJhbWV0ZXIuCiAgZm9yIChjb25zdCBjb3ZHcmFkaWVudCBvZiBtYWtlR3JhZGllbnRDb3ZhcmlhbmNlTWF0cmljZXMoaW5wdXRzLCBncC5rZXJuZWwpKSB7CiAgICAvLyBkYXRhX2ZpdCA9IM6jX2MgYWxwaGFbY10gwrcgKGFscGhhIMK3IGNvbF9jKSAgPSAgYWxwaGHhtYAgwrcgY292R3JhZGllbnQgwrcgYWxwaGEKICAgIC8vIGNvdkdyYWRpZW50IGlzIHN5bW1ldHJpYywgc28gaXRzIGNvbHVtbiBjIGVxdWFscyBpdHMgcm93IGMuCiAgICBsZXQgZGF0YUZpdCA9IDA7CiAgICBmb3IgKGxldCBjID0gMDsgYyA8IG47IGMrKykgewogICAgICAvLyBhbHBoYSDCtyAoY29sdW1uIGMgb2YgY292R3JhZGllbnQpCiAgICAgIGxldCBhY29sID0gMDsKICAgICAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIGFjb2wgKz0gYWxwaGFbcl0gKiBjb3ZHcmFkaWVudFtyXVtjXTsKICAgICAgZGF0YUZpdCArPSBhY29sICogYWxwaGFbY107CiAgICB9CgogICAgLy8gY29tcGxleGl0eV9wZW5hbHR5ID0gzqNfciAocm93IHIgb2YgY292SW52KSDCtyAoY29sdW1uIHIgb2YgY292R3JhZGllbnQpCiAgICAvLyAgICAgICAgICAgICAgICAgICAgPSB0cmFjZShjb3ZJbnYgwrcgY292R3JhZGllbnQpCiAgICBsZXQgY29tcGxleGl0eVBlbmFsdHkgPSAwOwogICAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIHsKICAgICAgY29uc3QgY1JvdyA9IGNvdkludltyXTsKICAgICAgbGV0IHRyID0gMDsKICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBuOyBrKyspIHRyICs9IGNSb3dba10gKiBjb3ZHcmFkaWVudFtrXVtyXTsKICAgICAgY29tcGxleGl0eVBlbmFsdHkgKz0gdHI7CiAgICB9CiAgICByZXN1bHRzLnB1c2goKGRhdGFGaXQgLSBjb21wbGV4aXR5UGVuYWx0eSkgLyAyKTsKICB9CgogIC8vIE5vaXNlIHBhcmFtZXRlcjogZ3JhZGllbnQoSywgbm9pc2UpID0gMsK3bm9pc2XCt0lkLgogIGNvbnN0IGRhdGFGaXQgPSBkb3QoYWxwaGEsIGFscGhhKTsKICBjb25zdCBjb21wbGV4aXR5UGVuYWx0eSA9IHRyYWNlKGNvdkludik7IC8vIHRyYWNlKEvigbvCuSkKICBjb25zdCBub2lzZUdyYWRpZW50ID0gZ3Aubm9pc2UgKiAoZGF0YUZpdCAtIGNvbXBsZXhpdHlQZW5hbHR5KTsKICByZXN1bHRzLnB1c2gobm9pc2VHcmFkaWVudCk7CiAgcmV0dXJuIHJlc3VsdHM7Cn0KCi8qKgogKiBGaXQgcGFyYW1ldGVycyB1c2luZyB0aGUgQURBTSBncmFkaWVudC1hc2NlbnQgYWxnb3JpdGhtLgogKgogKiBSdW5zIGZvciBhdCBtb3N0IGBtYXhJdGVyYCBpdGVyYXRpb25zLiBTdG9wcyBlYXJseSBpZiBldmVyeSBjb21wb25lbnQgb2YgdGhlCiAqIHVwZGF0ZSBzdGVwIGBkZWx0YWAgaXMg4omkIGBjb252ZXJnZW5jZUZyYWN0aW9uYCBpbiBtYWduaXR1ZGUgKG5vIHNpZ25pZmljYW50CiAqIHByb2dyZXNzKSwgb3IgaWYgdGhlIHJ1bnRpbWUgZXhjZWVkcyBgbWF4VGltZWAgKG1pbGxpc2Vjb25kcykuCiAqCiAqIFRoZSBgbm9pc2VgIHBhcmFtZXRlciBpcyBmaXR0ZWQgaW4gbG9nLXNjYWxlLCBzaW5jZSBpdHMgbWFnbml0dWRlIG1hdHRlcnMKICogbW9yZSB0aGFuIGl0cyBwcmVjaXNlIHZhbHVlLgogKgogKiBBREFNIGNvbnN0YW50cyAoYG9wdGltaXplci5yczo3OWApOiBiZXRhMT0wLjksIGJldGEyPTAuOTk5LCBlcHNpbG9uPTFlLTgsCiAqIGxlYXJuaW5nUmF0ZT0wLjEuCiAqCiAqIEBwYXJhbSB7b2JqZWN0fSBncAogKiBAcGFyYW0ge251bWJlcn0gbWF4SXRlcgogKiBAcGFyYW0ge251bWJlcn0gY29udmVyZ2VuY2VGcmFjdGlvbgogKiBAcGFyYW0ge251bWJlcn0gbWF4VGltZSBtaWxsaXNlY29uZHMKICovCmZ1bmN0aW9uIG9wdGltaXplUGFyYW1ldGVycyhncCwgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSkgewogIGNvbnN0IGJldGExID0gMC45OwogIGNvbnN0IGJldGEyID0gMC45OTk7CiAgY29uc3QgZXBzaWxvbiA9IDFlLTg7CiAgY29uc3QgbGVhcm5pbmdSYXRlID0gMC4xOwoKICAvLyBJbml0aWFsIHBhcmFtZXRlcnM6IGtlcm5lbCBwYXJhbXMgd2l0aCBhbnkgMCByZXBsYWNlZCBieSBlcHNpbG9uIChhIDAKICAvLyBwYXJhbWV0ZXIgd291bGQgYmxvY2sgdGhlIG11bHRpcGxpY2F0aXZlIEFEQU0gdXBkYXRlKSwgdGhlbiBub2lzZSBpbgogIC8vIGxvZy1zcGFjZS4KICBjb25zdCBwYXJhbWV0ZXJzID0gZ3Aua2VybmVsLmdldFBhcmFtZXRlcnMoKS5tYXAocCA9PiBwID09PSAwID8gZXBzaWxvbiA6IHApOwogIHBhcmFtZXRlcnMucHVzaChNYXRoLmxvZyhncC5ub2lzZSkpOyAvLyBub2lzZSBpbiBsb2ctc3BhY2UKCiAgY29uc3QgbWVhbkdyYWQgPSBuZXcgQXJyYXkocGFyYW1ldGVycy5sZW5ndGgpLmZpbGwoMCk7CiAgY29uc3QgdmFyR3JhZCA9IG5ldyBBcnJheShwYXJhbWV0ZXJzLmxlbmd0aCkuZmlsbCgwKTsKICBjb25zdCB0aW1lU3RhcnQgPSBEYXRlLm5vdygpOwogIGZvciAobGV0IGkgPSAxOyBpIDw9IG1heEl0ZXI7IGkrKykgewogICAgY29uc3QgZ3JhZGllbnRzID0gZ3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QoZ3ApOwogICAgLy8gQ29ycmVjdCB0aGUgbm9pc2UgZ3JhZGllbnQgZm9yIGxvZy1zcGFjZS4KICAgIGdyYWRpZW50c1tncmFkaWVudHMubGVuZ3RoIC0gMV0gKj0gZ3Aubm9pc2U7CiAgICBsZXQgaGFkU2lnbmlmaWNhbnRQcm9ncmVzcyA9IGZhbHNlOwogICAgZm9yIChsZXQgcCA9IDA7IHAgPCBwYXJhbWV0ZXJzLmxlbmd0aDsgcCsrKSB7CiAgICAgIG1lYW5HcmFkW3BdID0gYmV0YTEgKiBtZWFuR3JhZFtwXSArICgxIC0gYmV0YTEpICogZ3JhZGllbnRzW3BdOwogICAgICB2YXJHcmFkW3BdID0gYmV0YTIgKiB2YXJHcmFkW3BdICsgKDEgLSBiZXRhMikgKiBncmFkaWVudHNbcF0gKiBncmFkaWVudHNbcF07CiAgICAgIGNvbnN0IGJpYXNDb3JyZWN0ZWRNZWFuID0gbWVhbkdyYWRbcF0gLyAoMSAtIE1hdGgucG93KGJldGExLCBpKSk7CiAgICAgIGNvbnN0IGJpYXNDb3JyZWN0ZWRWYXJpYW5jZSA9IHZhckdyYWRbcF0gLyAoMSAtIE1hdGgucG93KGJldGEyLCBpKSk7CiAgICAgIGNvbnN0IGRlbHRhID0gbGVhcm5pbmdSYXRlICogYmlhc0NvcnJlY3RlZE1lYW4gLyAoTWF0aC5zcXJ0KGJpYXNDb3JyZWN0ZWRWYXJpYW5jZSkgKyBlcHNpbG9uKTsKICAgICAgaWYgKE1hdGguYWJzKGRlbHRhKSA+IGNvbnZlcmdlbmNlRnJhY3Rpb24pIGhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgPSB0cnVlOwogICAgICBwYXJhbWV0ZXJzW3BdICo9IDEgKyBkZWx0YTsKICAgIH0KCiAgICAvLyBTZXQga2VybmVsIHBhcmFtZXRlcnMgKHRoZSBrZXJuZWwgcmVhZHMgb25seSBpdHMgb3duIGxlYWRpbmcgcHJlZml4CiAgICAvLyBvZiBgcGFyYW1ldGVyc2A7IHRoZSB0cmFpbGluZyBub2lzZSBsb2ctdmFsdWUgaXMgaWdub3JlZCBieSBpdCkuCiAgICBncC5rZXJuZWwuc2V0UGFyYW1ldGVycyhwYXJhbWV0ZXJzKTsKICAgIC8vIEdldCB0aGUgbm9pc2Ugb3V0IG9mIGxvZy1zcGFjZSBiZWZvcmUgc2V0dGluZyBpdC4KICAgIGdwLm5vaXNlID0gTWF0aC5leHAocGFyYW1ldGVyc1twYXJhbWV0ZXJzLmxlbmd0aCAtIDFdKTsKCiAgICAvLyBSZWZpdCB0aGUgbW9kZWwgKHJlYnVpbGQgdGhlIENob2xlc2t5IGZhY3RvciBvZiB0aGUgY292YXJpYW5jZSBtYXRyaXgpLgogICAgZ3AuY292bWF0Q2hvbGVza3kgPSBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoZ3AudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKSwgZ3Aua2VybmVsLCBncC5ub2lzZSwgZ3AuY2hvbGVza3lFcHNpbG9uKTsKICAgIGlmICghaGFkU2lnbmlmaWNhbnRQcm9ncmVzcyB8fCBEYXRlLm5vdygpIC0gdGltZVN0YXJ0ID4gbWF4VGltZSkgewogICAgICBicmVhazsKICAgIH0KICB9Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gU0NBTEFCTEUgS0VSTkVMCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBSZXR1cm5zIGBbc2NhbGUsIGdyYWRpZW50c11gOiB0aGUgb3B0aW1hbCBzY2FsZSBmb3IgdGhlIGtlcm5lbCtub2lzZSAodXNlZCB0bwogKiBvcHRpbWl6ZSB0aGUgbm9pc2UpIHBsdXMgdGhlIGdyYWRpZW50IHBlciBrZXJuZWwgcGFyYW1ldGVyIChOT1QgaW5jbHVkaW5nIHRoZQogKiBub2lzZSBncmFkaWVudCkuCiAqCiAqIFBlci1wYXJhbWV0ZXIgZm9ybXVsYSAoYG9wdGltaXplci5yczoxNTBgKToKICogICDCvSAoIGFscGhh4bWAIMK3IGRwIMK3IGFscGhhIC8gc2NhbGUg4oiSIHRyYWNlKEvigbvCuSDCtyBkcCkgKQogKiAgIHNjYWxlID0gb3V0cHV04bWAIMK3IEvigbvCuSDCtyBvdXRwdXQgLyBuCiAqIE5PVEU6IHRoZSBkYXRhLWZpdCB0ZXJtIGlzIGRpdmlkZWQgYnkgYHNjYWxlYCwgdW5saWtlIHRoZSB1bnNjYWxlZCBncmFkaWVudC4KICoKICogQHBhcmFtIHtvYmplY3R9IGdwCiAqIEByZXR1cm5zIHtbbnVtYmVyLCBudW1iZXJbXV19IFtzY2FsZSwgcmVzdWx0c10gKHJlc3VsdHMgbGVuZ3RoID0gbmJQYXJhbWV0ZXJzKQogKi8KZnVuY3Rpb24gc2NhbGVkR3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QoZ3ApIHsKICBjb25zdCBjb3ZJbnYgPSBncC5jb3ZtYXRDaG9sZXNreS5pbnZlcnNlKCk7IC8vIEvigbvCuQogIGNvbnN0IG91dHB1dCA9IGdwLnRyYWluaW5nT3V0cHV0cy5hc1ZlY3RvcigpOwogIGNvbnN0IG4gPSBvdXRwdXQubGVuZ3RoOwoKICAvLyBhbHBoYSA9IEvigbvCuSDCtyBvdXRwdXQKICBjb25zdCBhbHBoYSA9IG5ldyBBcnJheShuKTsKICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgewogICAgbGV0IHMgPSAwOwogICAgY29uc3Qgcm93ID0gY292SW52W3JdOwogICAgZm9yIChsZXQgYyA9IDA7IGMgPCBuOyBjKyspIHMgKz0gcm93W2NdICogb3V0cHV0W2NdOwogICAgYWxwaGFbcl0gPSBzOwogIH0KCiAgLy8gU2NhbGluZyBmb3IgdGhlIGtlcm5lbDogb3V0cHV04bWAIMK3IEvigbvCuSDCtyBvdXRwdXQgLyBuID0gb3V0cHV0wrdhbHBoYSAvIG4uCiAgY29uc3Qgc2NhbGUgPSBkb3Qob3V0cHV0LCBhbHBoYSkgLyBuOwogIGNvbnN0IGlucHV0cyA9IGdwLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CiAgY29uc3QgcmVzdWx0cyA9IFtdOwogIGZvciAoY29uc3QgY292R3JhZGllbnQgb2YgbWFrZUdyYWRpZW50Q292YXJpYW5jZU1hdHJpY2VzKGlucHV0cywgZ3Aua2VybmVsKSkgewogICAgLy8gZGF0YV9maXQgPSAoYWxwaGHhtYAgwrcgY292R3JhZGllbnQgwrcgYWxwaGEpIC8gc2NhbGUKICAgIGxldCBkYXRhRml0ID0gMDsKICAgIGZvciAobGV0IGMgPSAwOyBjIDwgbjsgYysrKSB7CiAgICAgIGxldCBhY29sID0gMDsKICAgICAgZm9yIChsZXQgciA9IDA7IHIgPCBuOyByKyspIGFjb2wgKz0gYWxwaGFbcl0gKiBjb3ZHcmFkaWVudFtyXVtjXTsKICAgICAgZGF0YUZpdCArPSBhY29sICogYWxwaGFbY107CiAgICB9CiAgICBkYXRhRml0IC89IHNjYWxlOwoKICAgIC8vIGNvbXBsZXhpdHlfcGVuYWx0eSA9IHRyYWNlKGNvdkludiDCtyBjb3ZHcmFkaWVudCkKICAgIGxldCBjb21wbGV4aXR5UGVuYWx0eSA9IDA7CiAgICBmb3IgKGxldCByID0gMDsgciA8IG47IHIrKykgewogICAgICBjb25zdCBjUm93ID0gY292SW52W3JdOwogICAgICBsZXQgdHIgPSAwOwogICAgICBmb3IgKGxldCBrID0gMDsgayA8IG47IGsrKykgdHIgKz0gY1Jvd1trXSAqIGNvdkdyYWRpZW50W2tdW3JdOwogICAgICBjb21wbGV4aXR5UGVuYWx0eSArPSB0cjsKICAgIH0KICAgIHJlc3VsdHMucHVzaCgoZGF0YUZpdCAtIGNvbXBsZXhpdHlQZW5hbHR5KSAvIDIpOwogIH0KCiAgLy8gTk9URTogZmFpdGhmdWwgdG8gUnVzdCBzb3VyY2Ug4oCUIHRoZSBub2lzZSBncmFkaWVudCBpcyBpbnRlbnRpb25hbGx5IE5PVAogIC8vIHB1c2hlZCBoZXJlIChpdCBpcyBjb21tZW50ZWQgb3V0IGluIG9wdGltaXplci5yczoxODgtMTkxKTsgdGhlIG5vaXNlIGlzCiAgLy8gaW5zdGVhZCBmaXR0ZWQgdmlhIGBrZXJuZWwucmVzY2FsZShzY2FsZSlgICsgYGdwLm5vaXNlICo9IHNjYWxlYC4KCiAgcmV0dXJuIFtzY2FsZSwgcmVzdWx0c107Cn0KCi8qKgogKiBGaXQgcGFyYW1ldGVycyB1c2luZyBBREFNIGdyYWRpZW50IGFzY2VudDsgYWRkaXRpb25hbGx5LCBhdCBlYWNoIHN0ZXAgdGhlCiAqIGtlcm5lbCBhbmQgbm9pc2UgYXJlIHJlc2NhbGVkIGJ5IHRoZSBvcHRpbWFsIG1hZ25pdHVkZSBgc2NhbGVgLgogKgogKiBSdW5zIGZvciBhdCBtb3N0IGBtYXhJdGVyYCBpdGVyYXRpb25zLiBTdG9wcyBlYXJseSBvbiBubyBzaWduaWZpY2FudCBwcm9ncmVzcwogKiAoYWxsIGBkZWx0YWAg4omkIGBjb252ZXJnZW5jZUZyYWN0aW9uYCkgb3IgaWYgdGhlIHJ1bnRpbWUgZXhjZWVkcyBgbWF4VGltZWAKICogKG1pbGxpc2Vjb25kcykuCiAqCiAqIEFEQU0gY29uc3RhbnRzIGlkZW50aWNhbCB0byB7QGxpbmsgb3B0aW1pemVQYXJhbWV0ZXJzfS4KICoKICogQHBhcmFtIHtvYmplY3R9IGdwCiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhJdGVyCiAqIEBwYXJhbSB7bnVtYmVyfSBjb252ZXJnZW5jZUZyYWN0aW9uCiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhUaW1lIG1pbGxpc2Vjb25kcwogKi8KZnVuY3Rpb24gc2NhbGVkT3B0aW1pemVQYXJhbWV0ZXJzKGdwLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKSB7CiAgY29uc3QgYmV0YTEgPSAwLjk7CiAgY29uc3QgYmV0YTIgPSAwLjk5OTsKICBjb25zdCBlcHNpbG9uID0gMWUtODsKICBjb25zdCBsZWFybmluZ1JhdGUgPSAwLjE7CgogIC8vIEluaXRpYWwgcGFyYW1ldGVyczoga2VybmVsIHBhcmFtcyB3aXRoIDAgcmVwbGFjZWQgYnkgZXBzaWxvbi4KICAvLyAoTm8gbm9pc2UgcHVzaGVkOiB0aGUgbm9pc2UgaXMgZml0dGVkIGJ5IHJlc2NhbGluZywgbm90IGJ5IGdyYWRpZW50LikKICBsZXQgcGFyYW1ldGVycyA9IGdwLmtlcm5lbC5nZXRQYXJhbWV0ZXJzKCkubWFwKHAgPT4gcCA9PT0gMCA/IGVwc2lsb24gOiBwKTsKICBjb25zdCBtZWFuR3JhZCA9IG5ldyBBcnJheShwYXJhbWV0ZXJzLmxlbmd0aCkuZmlsbCgwKTsKICBjb25zdCB2YXJHcmFkID0gbmV3IEFycmF5KHBhcmFtZXRlcnMubGVuZ3RoKS5maWxsKDApOwogIGNvbnN0IHRpbWVTdGFydCA9IERhdGUubm93KCk7CiAgZm9yIChsZXQgaSA9IDE7IGkgPD0gbWF4SXRlcjsgaSsrKSB7CiAgICBjb25zdCBbc2NhbGUsIGdyYWRpZW50c10gPSBzY2FsZWRHcmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZChncCk7CiAgICBsZXQgaGFkU2lnbmlmaWNhbnRQcm9ncmVzcyA9IGZhbHNlOwogICAgZm9yIChsZXQgcCA9IDA7IHAgPCBwYXJhbWV0ZXJzLmxlbmd0aDsgcCsrKSB7CiAgICAgIG1lYW5HcmFkW3BdID0gYmV0YTEgKiBtZWFuR3JhZFtwXSArICgxIC0gYmV0YTEpICogZ3JhZGllbnRzW3BdOwogICAgICB2YXJHcmFkW3BdID0gYmV0YTIgKiB2YXJHcmFkW3BdICsgKDEgLSBiZXRhMikgKiBncmFkaWVudHNbcF0gKiBncmFkaWVudHNbcF07CiAgICAgIGNvbnN0IGJpYXNDb3JyZWN0ZWRNZWFuID0gbWVhbkdyYWRbcF0gLyAoMSAtIE1hdGgucG93KGJldGExLCBpKSk7CiAgICAgIGNvbnN0IGJpYXNDb3JyZWN0ZWRWYXJpYW5jZSA9IHZhckdyYWRbcF0gLyAoMSAtIE1hdGgucG93KGJldGEyLCBpKSk7CiAgICAgIGNvbnN0IGRlbHRhID0gbGVhcm5pbmdSYXRlICogYmlhc0NvcnJlY3RlZE1lYW4gLyAoTWF0aC5zcXJ0KGJpYXNDb3JyZWN0ZWRWYXJpYW5jZSkgKyBlcHNpbG9uKTsKICAgICAgaWYgKE1hdGguYWJzKGRlbHRhKSA+IGNvbnZlcmdlbmNlRnJhY3Rpb24pIGhhZFNpZ25pZmljYW50UHJvZ3Jlc3MgPSB0cnVlOwogICAgICBwYXJhbWV0ZXJzW3BdICo9IDEgKyBkZWx0YTsKICAgIH0KCiAgICAvLyBTZXQgcGFyYW1ldGVycywgdGhlbiByZXNjYWxlIHRoZSBrZXJuZWwgYW5kIG5vaXNlIGJ5IHRoZSBvcHRpbWFsIHNjYWxlLgogICAgZ3Aua2VybmVsLnNldFBhcmFtZXRlcnMocGFyYW1ldGVycyk7CiAgICBncC5rZXJuZWwucmVzY2FsZShzY2FsZSk7CiAgICBncC5ub2lzZSAqPSBzY2FsZTsKICAgIC8vIEdldCBwYXJhbWV0ZXJzIGJhY2sgYXMgdGhleSBoYXZlIGJlZW4gcmVzY2FsZWQgKHJlc2NhbGUgY2hhbmdlcyB0aGUKICAgIC8vIGFtcGxpdHVkZSwgc28gdGhlIGxvY2FsIGBwYXJhbWV0ZXJzYCBtdXN0IGJlIHJlZnJlc2hlZCBmcm9tIHRoZSBrZXJuZWwpLgogICAgcGFyYW1ldGVycyA9IGdwLmtlcm5lbC5nZXRQYXJhbWV0ZXJzKCk7CgogICAgLy8gUmVmaXQgdGhlIG1vZGVsLgogICAgZ3AuY292bWF0Q2hvbGVza3kgPSBtYWtlQ2hvbGVza3lDb3ZNYXRyaXgoZ3AudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKSwgZ3Aua2VybmVsLCBncC5ub2lzZSwgZ3AuY2hvbGVza3lFcHNpbG9uKTsKICAgIGlmICghaGFkU2lnbmlmaWNhbnRQcm9ncmVzcyB8fCBEYXRlLm5vdygpIC0gdGltZVN0YXJ0ID4gbWF4VGltZSkgewogICAgICBicmVhazsKICAgIH0KICB9Cn0KCi8vISBHYXVzc2lhbiBwcm9jZXNzLgoKLyoqIERlZmF1bHQgbWF4aW11bSBmaXR0aW5nIHRpbWU6IG9uZSBob3VyLCBleHByZXNzZWQgaW4gbWlsbGlzZWNvbmRzIChSdXN0IHVzZXMgY2hyb25vOjpEdXJhdGlvbjo6c2Vjb25kcygzNjAwKSkuICovCmNvbnN0IERFRkFVTFRfTUFYX1RJTUVfTVMgPSAzNjAwICogMTAwMDsKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gR2F1c3NpYW5Qcm9jZXNzCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBBIEdhdXNzaWFuIHByb2Nlc3MgdGhhdCBjYW4gYmUgdXNlZCB0byBtYWtlIHByZWRpY3Rpb25zIGJhc2VkIG9uIGl0cyB0cmFpbmluZwogKiBkYXRhLgogKgogKiBJbnRlcm5hbCBzdGF0ZSAobWlycm9ycyB0aGUgUnVzdCBgR2F1c3NpYW5Qcm9jZXNzYCBzdHJ1Y3QsIGBtb2QucnM6NTlgKToKICogICAtIGBwcmlvcmAgICAgICAgICAgIFByaW9yIGluc3RhbmNlLgogKiAgIC0gYGtlcm5lbGAgICAgICAgICAgS2VybmVsIGluc3RhbmNlLgogKiAgIC0gYG5vaXNlYCAgICAgICAgICAgbnVtYmVyIOKAlCBub2lzZSBTVEFOREFSRCBERVZJQVRJT04gKG5vdCB2YXJpYW5jZSkuCiAqICAgLSBgY2hvbGVza3lFcHNpbG9uYCBudW1iZXIgfCBudWxsIOKAlCBzdWJzdGl0dXRlIHBpdm90IGZvciBDaG9sZXNreSAob3IgbnVsbCkuCiAqICAgLSBgdHJhaW5pbmdJbnB1dHNgICBFeHRlbmRhYmxlTWF0cml4LgogKiAgIC0gYHRyYWluaW5nT3V0cHV0c2AgRXh0ZW5kYWJsZVZlY3RvciDigJQgc3RvcmVzIGBvdXRwdXRzIOKIkiBwcmlvcihpbnB1dHMpYCAodGhlIHJlc2lkdWFsISkuCiAqICAgLSBgY292bWF0Q2hvbGVza3lgICBDaG9sZXNreURlY29tcG9zaXRpb24gb2YgSyA9IGtlcm5lbChYLFgpICsgbm9pc2XCssK3SS4KICovCmNsYXNzIEdhdXNzaWFuUHJvY2VzcyB7CiAgLyoqCiAgICogUmF3IGNvbnN0cnVjdG9yIChgbW9kLnJzOjE0MmApLiBQcmVmZXIge0BsaW5rIEdhdXNzaWFuUHJvY2Vzcy5kZWZhdWx0fSBvcgogICAqIHtAbGluayBHYXVzc2lhblByb2Nlc3MuYnVpbGRlcn0uCiAgICoKICAgKiBAcGFyYW0ge29iamVjdH0gICAgICAgcHJpb3IgICAgICAgICAgICBQcmlvciBpbnN0YW5jZS4KICAgKiBAcGFyYW0ge29iamVjdH0gICAgICAga2VybmVsICAgICAgICAgICBLZXJuZWwgaW5zdGFuY2UuCiAgICogQHBhcmFtIHtudW1iZXJ9ICAgICAgIG5vaXNlICAgICAgICAgICAgbm9pc2Ugc3RhbmRhcmQgZGV2aWF0aW9uICjiiaUgMCkuCiAgICogQHBhcmFtIHtudW1iZXJ8bnVsbH0gIGNob2xlc2t5RXBzaWxvbiAgc3Vic3RpdHV0ZSBwaXZvdCAob3IgbnVsbCB0byB0aHJvdyBvbiBmYWlsdXJlKS4KICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IHRyYWluaW5nSW5wdXRzICByYXcgaW5wdXRzLgogICAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSAgICAgdHJhaW5pbmdPdXRwdXRzIHJhdyBvdXRwdXRzIChOT1QgeWV0IHJlc2lkdWFsaXNlZCkuCiAgICovCiAgY29uc3RydWN0b3IocHJpb3IsIGtlcm5lbCwgbm9pc2UsIGNob2xlc2t5RXBzaWxvbiwgdHJhaW5pbmdJbnB1dHMsIHRyYWluaW5nT3V0cHV0cykgewogICAgaWYgKCEobm9pc2UgPj0gMCkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgbm9pc2UgcGFyYW1ldGVyIHNob3VsZCBiZSBub24tbmVnYXRpdmUgYnV0IHdlIHRyaWVkIHRvIHNldCBpdCB0byAke25vaXNlfWApOwogICAgfQoKICAgIC8vIE5vcm1hbGlzZSBpbnB1dHMvb3V0cHV0cyBpbnRvIG1hdHJpeCAvIHZlY3RvciBmb3JtIChtYXRjaGVzIFQ6OmludG9fZG1hdHJpeCAvIGludG9fZHZlY3RvcikuCiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeCh0cmFpbmluZ0lucHV0cyk7CiAgICBjb25zdCBvdXRwdXRzVmVjdG9yID0gdG9WZWN0b3IodHJhaW5pbmdPdXRwdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXgubGVuZ3RoICE9PSBvdXRwdXRzVmVjdG9yLmxlbmd0aCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYHRyYWluaW5nX2lucHV0cy5ucm93cygpICgke2lucHV0c01hdHJpeC5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfb3V0cHV0cy5ucm93cygpICgke291dHB1dHNWZWN0b3IubGVuZ3RofSlgKTsKICAgIH0KCiAgICAvKiogQHR5cGUge29iamVjdH0gKi8KICAgIHRoaXMucHJpb3IgPSBwcmlvcjsKICAgIC8qKiBAdHlwZSB7b2JqZWN0fSAqLwogICAgdGhpcy5rZXJuZWwgPSBrZXJuZWw7CiAgICAvKiogQHR5cGUge251bWJlcn0gbm9pc2Ugc3RhbmRhcmQgZGV2aWF0aW9uICovCiAgICB0aGlzLm5vaXNlID0gbm9pc2U7CiAgICAvKiogQHR5cGUge251bWJlcnxudWxsfSAqLwogICAgdGhpcy5jaG9sZXNreUVwc2lsb24gPSBjaG9sZXNreUVwc2lsb247CgogICAgLy8gRXh0ZW5kYWJsZSB0cmFpbmluZyBkYXRhLiB0cmFpbmluZ091dHB1dHMgaG9sZHMgdGhlIFBSSU9SIFJFU0lEVUFMLgogICAgLyoqIEB0eXBlIHtFeHRlbmRhYmxlTWF0cml4fSAqLwogICAgdGhpcy50cmFpbmluZ0lucHV0cyA9IG5ldyBFeHRlbmRhYmxlTWF0cml4KGlucHV0c01hdHJpeCk7CiAgICBjb25zdCBwcmlvclZhbHVlcyA9IHByaW9yLnByaW9yKGlucHV0c01hdHJpeCk7CiAgICBjb25zdCByZXNpZHVhbCA9IG5ldyBBcnJheShvdXRwdXRzVmVjdG9yLmxlbmd0aCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dHNWZWN0b3IubGVuZ3RoOyBpKyspIHsKICAgICAgcmVzaWR1YWxbaV0gPSBvdXRwdXRzVmVjdG9yW2ldIC0gcHJpb3JWYWx1ZXNbaV07CiAgICB9CiAgICAvKiogQHR5cGUge0V4dGVuZGFibGVWZWN0b3J9ICovCiAgICB0aGlzLnRyYWluaW5nT3V0cHV0cyA9IG5ldyBFeHRlbmRhYmxlVmVjdG9yKHJlc2lkdWFsKTsKCiAgICAvLyBDaG9sZXNreSBvZiB0aGUgY292YXJpYW5jZSBtYXRyaXggSyA9IGtlcm5lbChYLFgpICsgbm9pc2XCssK3SS4KICAgIC8qKiBAdHlwZSB7aW1wb3J0KCcuL2FsZ2VicmEubWpzJykuQ2hvbGVza3lEZWNvbXBvc2l0aW9ufSAqLwogICAgdGhpcy5jb3ZtYXRDaG9sZXNreSA9IG1ha2VDaG9sZXNreUNvdk1hdHJpeChpbnB1dHNNYXRyaXgsIGtlcm5lbCwgbm9pc2UsIGNob2xlc2t5RXBzaWxvbik7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gU1RBVElDIENPTlNUUlVDVE9SUwogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogUmV0dXJucyBhIEdhdXNzaWFuIHByb2Nlc3Mgd2l0aCBhIEdhdXNzaWFuIGtlcm5lbCBhbmQgYSBjb25zdGFudCBwcmlvciwKICAgKiBib3RoIGZpdHRlZCB0byB0aGUgZGF0YSAoYG1vZC5yczo5NmApLgogICAqCiAgICogRXF1aXZhbGVudCB0byBgYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpLmZpdF9rZXJuZWwoKS5maXRfcHJpb3IoKS50cmFpbigpYC4KICAgKgogICAqIE5vdGU6IGBkZWZhdWx0YCBpcyBhIHZhbGlkIHN0YXRpYy1tZXRob2QgbmFtZSBpbiBKUyBjbGFzc2VzOyBzZWUKICAgKiB7QGxpbmsgR2F1c3NpYW5Qcm9jZXNzLmZyb21EYXRhfSBmb3IgYSBzYWZlIGFsaWFzLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIG91dHB1dHMKICAgKiBAcmV0dXJucyB7R2F1c3NpYW5Qcm9jZXNzfQogICAqLwogIHN0YXRpYyBkZWZhdWx0KGlucHV0cywgb3V0cHV0cykgewogICAgcmV0dXJuIEdhdXNzaWFuUHJvY2Vzcy5idWlsZGVyKGlucHV0cywgb3V0cHV0cykuZml0S2VybmVsKCkuZml0UHJpb3IoKS50cmFpbigpOwogIH0KCiAgLyoqCiAgICogU2FmZSBhbGlhcyBvZiB7QGxpbmsgR2F1c3NpYW5Qcm9jZXNzLmRlZmF1bHR9IChpbiBjYXNlIGEgdG9vbGNoYWluIGRpc2xpa2VzCiAgICogdGhlIGBkZWZhdWx0YCBtZXRob2QgbmFtZSkuIElkZW50aWNhbCBiZWhhdmlvdXIuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSAgICAgb3V0cHV0cwogICAqIEByZXR1cm5zIHtHYXVzc2lhblByb2Nlc3N9CiAgICovCiAgc3RhdGljIGZyb21EYXRhKGlucHV0cywgb3V0cHV0cykgewogICAgcmV0dXJuIEdhdXNzaWFuUHJvY2Vzcy5kZWZhdWx0KGlucHV0cywgb3V0cHV0cyk7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIGEgYnVpbGRlciB0byBkZWZpbmUgc3BlY2lmaWMgcGFyYW1ldGVycyBvZiB0aGUgR2F1c3NpYW4gcHJvY2VzcwogICAqIChgbW9kLnJzOjEyOWApLiBEZWZhdWx0cyB0byBhIEdhdXNzaWFuIGtlcm5lbCArIGNvbnN0YW50IHByaW9yLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIG91dHB1dHMKICAgKiBAcmV0dXJucyB7R2F1c3NpYW5Qcm9jZXNzQnVpbGRlcn0KICAgKi8KICBzdGF0aWMgYnVpbGRlcihpbnB1dHMsIG91dHB1dHMpIHsKICAgIHJldHVybiBuZXcgR2F1c3NpYW5Qcm9jZXNzQnVpbGRlcihpbnB1dHMsIG91dHB1dHMpOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIEFERCBTQU1QTEVTCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBBZGRzIG5ldyBzYW1wbGVzIHRvIHRoZSBtb2RlbCAoYG1vZC5yczoxNzNgKS4KICAgKgogICAqIFVwZGF0ZXMgdGhlIG1vZGVsIGluIE8obsKyKSAoZmFzdGVyIHRoYW4gcmV0cmFpbmluZyBmcm9tIHNjcmF0Y2gpIGJ1dCBkb2VzCiAgICogTk9UIHJlZml0IHRoZSBwYXJhbWV0ZXJzLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gICAgIG91dHB1dHMKICAgKi8KICBhZGRfc2FtcGxlcyhpbnB1dHMsIG91dHB1dHMpIHsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KGlucHV0cyk7CiAgICBjb25zdCBvdXRwdXRzVmVjdG9yID0gdG9WZWN0b3Iob3V0cHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4Lmxlbmd0aCAhPT0gb3V0cHV0c1ZlY3Rvci5sZW5ndGgpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubnJvd3MoKSAoJHtpbnB1dHNNYXRyaXgubGVuZ3RofSkgIT09IG91dHB1dHMubnJvd3MoKSAoJHtvdXRwdXRzVmVjdG9yLmxlbmd0aH0pYCk7CiAgICB9CiAgICBpZiAoaW5wdXRzTWF0cml4WzBdLmxlbmd0aCAhPT0gdGhpcy50cmFpbmluZ0lucHV0cy5uY29scykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5uY29scygpICgke2lucHV0c01hdHJpeFswXS5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfaW5wdXRzLm5jb2xzKCkgKCR7dGhpcy50cmFpbmluZ0lucHV0cy5uY29sc30pYCk7CiAgICB9CgogICAgLy8gUmVzaWR1YWxpc2UgdGhlIG5ldyBvdXRwdXRzIGFnYWluc3QgdGhlIGN1cnJlbnQgcHJpb3IuCiAgICBjb25zdCBwcmlvclZhbHVlcyA9IHRoaXMucHJpb3IucHJpb3IoaW5wdXRzTWF0cml4KTsKICAgIGNvbnN0IHJlc2lkdWFsID0gbmV3IEFycmF5KG91dHB1dHNWZWN0b3IubGVuZ3RoKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0c1ZlY3Rvci5sZW5ndGg7IGkrKykgewogICAgICByZXNpZHVhbFtpXSA9IG91dHB1dHNWZWN0b3JbaV0gLSBwcmlvclZhbHVlc1tpXTsKICAgIH0KCiAgICAvLyBHcm93IHRoZSB0cmFpbmluZyBkYXRhLgogICAgdGhpcy50cmFpbmluZ0lucHV0cy5hZGRSb3dzKGlucHV0c01hdHJpeCk7CiAgICB0aGlzLnRyYWluaW5nT3V0cHV0cy5hZGRSb3dzKHJlc2lkdWFsKTsKCiAgICAvLyBJbmNyZW1lbnRhbGx5IGV4dGVuZCB0aGUgQ2hvbGVza3kgZGVjb21wb3NpdGlvbiB3aXRoIHRoZSBuZXcgcm93cy4KICAgIGNvbnN0IG5iTmV3SW5wdXRzID0gaW5wdXRzTWF0cml4Lmxlbmd0aDsKICAgIGFkZFJvd3NDaG9sZXNreUNvdk1hdHJpeCh0aGlzLmNvdm1hdENob2xlc2t5LCB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCksIG5iTmV3SW5wdXRzLCB0aGlzLmtlcm5lbCwgdGhpcy5ub2lzZSk7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gTElLRUxJSE9PRAogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogTG9nIGxpa2VsaWhvb2Qgb2YgdGhlIGN1cnJlbnQgbW9kZWwgZ2l2ZW4gdGhlIHRyYWluaW5nIGRhdGEgKGBtb2QucnM6MTk2YCkuCiAgICoKICAgKiBGb3JtdWxhOgogICAqICAg4oiSwr0gKCBvdXRwdXThtYDCt0vigbvCucK3b3V0cHV0ICsgzqNfciBsbnxrZXJuZWwoeOG1oyx44bWjKSArIG5vaXNlwrJ8ICsgbsK3bG4oMs+AKSApCiAgICoKICAgKiB3aGVyZSBgb3V0cHV0YCBpcyB0aGUgcHJpb3IgcmVzaWR1YWwuCiAgICoKICAgKiBAcmV0dXJucyB7bnVtYmVyfQogICAqLwogIGxpa2VsaWhvb2QoKSB7CiAgICBjb25zdCBvdXRwdXQgPSB0aGlzLnRyYWluaW5nT3V0cHV0cy5hc1ZlY3RvcigpOyAvLyByZXNpZHVhbAogICAgY29uc3QgTCA9IHRoaXMuY292bWF0Q2hvbGVza3kubCgpOwoKICAgIC8vIHRyYW5zcG9zZShvbCnCt29sID0gb3V0cHV04bWAwrdL4oG7wrnCt291dHB1dCwgd2hlcmUgTMK3b2wgPSBvdXRwdXQuCiAgICBjb25zdCBvbCA9IHNvbHZlTG93ZXJUcmkoTCwgb3V0cHV0KTsKICAgIGNvbnN0IGRhdGFGaXQgPSBub3JtU3F1YXJlZChvbCk7CgogICAgLy8gQ29tcGxleGl0eSBwZW5hbHR5OiDOoyBsbnwgc2VsZi1jb3ZhcmlhbmNlICsgbm9pc2XCsiB8LgogICAgY29uc3QgaW5wdXRzID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwogICAgY29uc3Qgbm9pc2VTcSA9IHRoaXMubm9pc2UgKiB0aGlzLm5vaXNlOwogICAgbGV0IGNvbXBsZXhpdHlQZW5hbHR5ID0gMDsKICAgIGZvciAobGV0IHIgPSAwOyByIDwgaW5wdXRzLmxlbmd0aDsgcisrKSB7CiAgICAgIGNvbnN0IHNlbGZDb3YgPSB0aGlzLmtlcm5lbC5rZXJuZWwoaW5wdXRzW3JdLCBpbnB1dHNbcl0pICsgbm9pc2VTcTsKICAgICAgY29tcGxleGl0eVBlbmFsdHkgKz0gTWF0aC5sb2coTWF0aC5hYnMoc2VsZkNvdikpOwogICAgfQogICAgY29uc3QgbiA9IGlucHV0cy5sZW5ndGg7CiAgICBjb25zdCBub3JtYWxpemF0aW9uQ29uc3RhbnQgPSBuICogTWF0aC5sb2coMiAqIE1hdGguUEkpOwogICAgcmV0dXJuIC0oZGF0YUZpdCArIGNvbXBsZXhpdHlQZW5hbHR5ICsgbm9ybWFsaXphdGlvbkNvbnN0YW50KSAvIDI7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gUFJFRElDVAogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogUHJlZGljdHMgdGhlIG1lYW4gb2YgdGhlIEdhdXNzaWFuIHByb2Nlc3MgZm9yIGVhY2ggcm93IG9mIGBpbnB1dHNgCiAgICogKGBtb2QucnM6MjI2YCkuCiAgICoKICAgKiBGb3JtdWxhOiBgcHJpb3IgKyBjb3YoaW5wdXQsdHJhaW4pwrdL4oG7wrnCt291dHB1dGAuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEByZXR1cm5zIHtudW1iZXJ8bnVtYmVyW119IG51bWJlciBmb3IgYSBzaW5nbGUtcG9pbnQgaW5wdXQsIG51bWJlcltdIG90aGVyd2lzZS4KICAgKi8KICBwcmVkaWN0KGlucHV0cykgewogICAgY29uc3Qgc2luZ2xlID0gaXNTaW5nbGUoaW5wdXRzKTsKICAgIGNvbnN0IGlucHV0c01hdHJpeCA9IHRvTWF0cml4KGlucHV0cyk7CiAgICBpZiAoaW5wdXRzTWF0cml4WzBdLmxlbmd0aCAhPT0gdGhpcy50cmFpbmluZ0lucHV0cy5uY29scykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0cy5uY29scygpICgke2lucHV0c01hdHJpeFswXS5sZW5ndGh9KSAhPT0gdHJhaW5pbmdfaW5wdXRzLm5jb2xzKCkgKCR7dGhpcy50cmFpbmluZ0lucHV0cy5uY29sc30pYCk7CiAgICB9CiAgICBjb25zdCB0cmFpbk1hdHJpeCA9IHRoaXMudHJhaW5pbmdJbnB1dHMuYXNNYXRyaXgoKTsKCiAgICAvLyB3ZWlnaHRzIChuVHJhaW4gw5cgbklucHV0KSA9IEvigbvCuSDCtyBjb3YodHJhaW4sIGlucHV0cykuCiAgICBsZXQgd2VpZ2h0cyA9IG1ha2VDb3ZhcmlhbmNlTWF0cml4KHRyYWluTWF0cml4LCBpbnB1dHNNYXRyaXgsIHRoaXMua2VybmVsKTsKICAgIHdlaWdodHMgPSB0aGlzLmNvdm1hdENob2xlc2t5LnNvbHZlKHdlaWdodHMpOwogICAgY29uc3QgbWVhbiA9IHRoaXMuX21lYW5Gcm9tV2VpZ2h0cyh3ZWlnaHRzLCBpbnB1dHNNYXRyaXgpOwogICAgcmV0dXJuIGZyb21WZWN0b3IobWVhbiwgc2luZ2xlKTsKICB9CgogIC8qKgogICAqIFByZWRpY3RzIHRoZSB2YXJpYW5jZSBvZiB0aGUgR2F1c3NpYW4gcHJvY2VzcyBmb3IgZWFjaCByb3cgb2YgYGlucHV0c2AKICAgKiAoYG1vZC5yczoyNDhgKS4KICAgKgogICAqIEZvcm11bGEgKGRpYWdvbmFsIG9mKToKICAgKiAgIGNvdihpbnB1dCxpbnB1dCkg4oiSIGNvdihpbnB1dCx0cmFpbinCt0vigbvCucK3Y292KHRyYWluLGlucHV0KQogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcmV0dXJucyB7bnVtYmVyfG51bWJlcltdfQogICAqLwogIHByZWRpY3RfdmFyaWFuY2UoaW5wdXRzKSB7CiAgICBjb25zdCBzaW5nbGUgPSBpc1NpbmdsZShpbnB1dHMpOwogICAgY29uc3QgaW5wdXRzTWF0cml4ID0gdG9NYXRyaXgoaW5wdXRzKTsKICAgIGlmIChpbnB1dHNNYXRyaXhbMF0ubGVuZ3RoICE9PSB0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRzLm5jb2xzKCkgKCR7aW5wdXRzTWF0cml4WzBdLmxlbmd0aH0pICE9PSB0cmFpbmluZ19pbnB1dHMubmNvbHMoKSAoJHt0aGlzLnRyYWluaW5nSW5wdXRzLm5jb2xzfSlgKTsKICAgIH0KICAgIGNvbnN0IHRyYWluTWF0cml4ID0gdGhpcy50cmFpbmluZ0lucHV0cy5hc01hdHJpeCgpOwoKICAgIC8vIGNvdl90cmFpbl9pbnB1dHMgKG5UcmFpbiDDlyBuSW5wdXQpLgogICAgY29uc3QgY292VHJhaW5JbnB1dHMgPSBtYWtlQ292YXJpYW5jZU1hdHJpeCh0cmFpbk1hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CgogICAgLy8ga2wgPSBM4oG7wrkgwrcgY292X3RyYWluX2lucHV0cyAgKHNvbHZlIEzCt2tsID0gY292X3RyYWluX2lucHV0cykuCiAgICBjb25zdCBrbCA9IHNvbHZlTG93ZXJUcmkodGhpcy5jb3ZtYXRDaG9sZXNreS5sKCksIGNvdlRyYWluSW5wdXRzKTsKCiAgICAvLyB2YXJpYW5jZVtpXSA9IGtlcm5lbChpbnB1dOG1oixpbnB1dOG1oikg4oiSIOKAlmNvbHVtbiBpIG9mIGts4oCWwrIuCiAgICBjb25zdCBuSW5wdXQgPSBpbnB1dHNNYXRyaXgubGVuZ3RoOwogICAgY29uc3QgdmFyaWFuY2VzID0gbmV3IEFycmF5KG5JbnB1dCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5JbnB1dDsgaSsrKSB7CiAgICAgIGNvbnN0IGJhc2VDb3YgPSB0aGlzLmtlcm5lbC5rZXJuZWwoaW5wdXRzTWF0cml4W2ldLCBpbnB1dHNNYXRyaXhbaV0pOwogICAgICBjb25zdCBwcmVkaWN0ZWRDb3YgPSBjb2x1bW5Ob3JtU3F1YXJlZChrbCwgaSk7CiAgICAgIHZhcmlhbmNlc1tpXSA9IGJhc2VDb3YgLSBwcmVkaWN0ZWRDb3Y7CiAgICB9CiAgICByZXR1cm4gZnJvbVZlY3Rvcih2YXJpYW5jZXMsIHNpbmdsZSk7CiAgfQoKICAvKioKICAgKiBQcmVkaWN0cyBib3RoIHRoZSBtZWFuIGFuZCB0aGUgdmFyaWFuY2UgZm9yIGVhY2ggcm93IG9mIGBpbnB1dHNgCiAgICogKGBtb2QucnM6MjkwYCkuIEZhc3RlciB0aGFuIGNhbGxpbmcgYHByZWRpY3RgIGFuZCBgcHJlZGljdF92YXJpYW5jZWAKICAgKiBzZXBhcmF0ZWx5LgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcmV0dXJucyB7W251bWJlcnxudW1iZXJbXSwgbnVtYmVyfG51bWJlcltdXX0gYFttZWFuLCB2YXJpYW5jZV1gLgogICAqLwogIHByZWRpY3RfbWVhbl92YXJpYW5jZShpbnB1dHMpIHsKICAgIGNvbnN0IHNpbmdsZSA9IGlzU2luZ2xlKGlucHV0cyk7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQogICAgY29uc3QgdHJhaW5NYXRyaXggPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CgogICAgLy8gY292X3RyYWluX2lucHV0cyAoblRyYWluIMOXIG5JbnB1dCk7ICB3ZWlnaHRzID0gS+KBu8K5IMK3IGNvdl90cmFpbl9pbnB1dHMuCiAgICBjb25zdCBjb3ZUcmFpbklucHV0cyA9IG1ha2VDb3ZhcmlhbmNlTWF0cml4KHRyYWluTWF0cml4LCBpbnB1dHNNYXRyaXgsIHRoaXMua2VybmVsKTsKICAgIGNvbnN0IHdlaWdodHMgPSB0aGlzLmNvdm1hdENob2xlc2t5LnNvbHZlKGNvdlRyYWluSW5wdXRzKTsKCiAgICAvLyAtLS0tLSBtZWFuIC0tLS0tCiAgICBjb25zdCBtZWFuVmVjID0gdGhpcy5fbWVhbkZyb21XZWlnaHRzKHdlaWdodHMsIGlucHV0c01hdHJpeCk7CiAgICBjb25zdCBtZWFuID0gZnJvbVZlY3RvcihtZWFuVmVjLCBzaW5nbGUpOwoKICAgIC8vIC0tLS0tIHZhcmlhbmNlIC0tLS0tCiAgICAvLyB2YXJpYW5jZVtpXSA9IGtlcm5lbChpbnB1dOG1oixpbnB1dOG1oikg4oiSIChjb2x1bW4gaSBvZiBjb3ZfdHJhaW5faW5wdXRzKcK3KGNvbHVtbiBpIG9mIHdlaWdodHMpLgogICAgY29uc3QgbklucHV0ID0gaW5wdXRzTWF0cml4Lmxlbmd0aDsKICAgIGNvbnN0IHZhcmlhbmNlcyA9IG5ldyBBcnJheShuSW5wdXQpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSW5wdXQ7IGkrKykgewogICAgICBjb25zdCBiYXNlQ292ID0gdGhpcy5rZXJuZWwua2VybmVsKGlucHV0c01hdHJpeFtpXSwgaW5wdXRzTWF0cml4W2ldKTsKICAgICAgY29uc3QgcHJlZGljdGVkQ292ID0gY29sdW1uRG90KGNvdlRyYWluSW5wdXRzLCB3ZWlnaHRzLCBpKTsKICAgICAgdmFyaWFuY2VzW2ldID0gYmFzZUNvdiAtIHByZWRpY3RlZENvdjsKICAgIH0KICAgIGNvbnN0IHZhcmlhbmNlID0gZnJvbVZlY3Rvcih2YXJpYW5jZXMsIHNpbmdsZSk7CiAgICByZXR1cm4gW21lYW4sIHZhcmlhbmNlXTsKICB9CgogIC8qKgogICAqIFJldHVybnMgdGhlIGZ1bGwgY292YXJpYW5jZSBtYXRyaXggZm9yIHRoZSByb3dzIG9mIGBpbnB1dHNgIChgbW9kLnJzOjMyOWApLgogICAqCiAgICogRm9ybXVsYToKICAgKiAgIGNvdihpbnB1dCxpbnB1dCkg4oiSIGNvdihpbnB1dCx0cmFpbinCt0vigbvCucK3Y292KHRyYWluLGlucHV0KQogICAqCiAgICogQUxXQVlTIHJldHVybnMgYSBgbnVtYmVyW11bXWAgbWF0cml4IChuZXZlciBzY2FsYXJpc2VkIOKAlCBtYXRjaGVzIFJ1c3Qgd2hpY2gKICAgKiBhbHdheXMgcmV0dXJucyBhIGBETWF0cml4YCkuCiAgICoKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IGlucHV0cwogICAqIEByZXR1cm5zIHtudW1iZXJbXVtdfSAobklucHV0IMOXIG5JbnB1dCkKICAgKi8KICBwcmVkaWN0X2NvdmFyaWFuY2UoaW5wdXRzKSB7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQogICAgY29uc3QgdHJhaW5NYXRyaXggPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CiAgICBjb25zdCBjb3ZUcmFpbklucHV0cyA9IG1ha2VDb3ZhcmlhbmNlTWF0cml4KHRyYWluTWF0cml4LCBpbnB1dHNNYXRyaXgsIHRoaXMua2VybmVsKTsKICAgIGNvbnN0IGNvdklucHV0c0lucHV0cyA9IG1ha2VDb3ZhcmlhbmNlTWF0cml4KGlucHV0c01hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CgogICAgLy8ga2wgPSBM4oG7wrkgwrcgY292X3RyYWluX2lucHV0cy4KICAgIGNvbnN0IGtsID0gc29sdmVMb3dlclRyaSh0aGlzLmNvdm1hdENob2xlc2t5LmwoKSwgY292VHJhaW5JbnB1dHMpOwoKICAgIC8vIHJlc3VsdCA9IGNvdl9pbnB1dHNfaW5wdXRzIOKIkiBrbOG1gMK3a2wgICAobWF0Y2hlcyBnZW1tX3RyKC0xLCBrbCwga2wsIDEpKS4KICAgIGNvbnN0IGtsdF9rbCA9IG1hdE11bCh0cmFuc3Bvc2Uoa2wpLCBrbCk7CiAgICByZXR1cm4gbWF0U3ViKGNvdklucHV0c0lucHV0cywga2x0X2tsKTsKICB9CgogIC8qKgogICAqIFByb2R1Y2VzIGEgbXVsdGl2YXJpYXRlIEdhdXNzaWFuIHRoYXQgY2FuIGJlIHNhbXBsZWQgYXQgdGhlIGlucHV0IHBvaW50cwogICAqIChgbW9kLnJzOjM3MWApLgogICAqCiAgICogQ292YXJpYW5jZToKICAgKiAgIGNvdihpbnB1dCxpbnB1dCkg4oiSIGNvdihpbnB1dCx0cmFpbinCt0vigbvCucK3Y292KHRyYWluLGlucHV0KQogICAqIE1lYW46CiAgICogICBwcmlvciArIGNvdihpbnB1dCx0cmFpbinCt0vigbvCucK3b3V0cHV0CiAgICoKICAgKiBUaGUgcmV0dXJuZWQge0BsaW5rIE11bHRpdmFyaWF0ZU5vcm1hbH0gaGFzIGEgYC5zYW1wbGUocm5nKWAgbWV0aG9kIHdoZXJlCiAgICogYHJuZ2AgaXMgYSBgKCkgPT4gbnVtYmVyIOKIiCBbMCwxKWAgKGUuZy4gZnJvbSBgbXVsYmVycnkzMmApLgogICAqCiAgICogQHBhcmFtIHtudW1iZXJbXXxudW1iZXJbXVtdfSBpbnB1dHMKICAgKiBAcmV0dXJucyB7TXVsdGl2YXJpYXRlTm9ybWFsfQogICAqLwogIHNhbXBsZV9hdChpbnB1dHMpIHsKICAgIGNvbnN0IHNpbmdsZSA9IGlzU2luZ2xlKGlucHV0cyk7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeChpbnB1dHMpOwogICAgaWYgKGlucHV0c01hdHJpeFswXS5sZW5ndGggIT09IHRoaXMudHJhaW5pbmdJbnB1dHMubmNvbHMpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dHMubmNvbHMoKSAoJHtpbnB1dHNNYXRyaXhbMF0ubGVuZ3RofSkgIT09IHRyYWluaW5nX2lucHV0cy5uY29scygpICgke3RoaXMudHJhaW5pbmdJbnB1dHMubmNvbHN9KWApOwogICAgfQogICAgY29uc3QgdHJhaW5NYXRyaXggPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CgogICAgLy8gd2VpZ2h0cyA9IEvigbvCuSDCtyBjb3YodHJhaW4sIGlucHV0cykuCiAgICBjb25zdCBjb3ZUcmFpbklucHV0cyA9IG1ha2VDb3ZhcmlhbmNlTWF0cml4KHRyYWluTWF0cml4LCBpbnB1dHNNYXRyaXgsIHRoaXMua2VybmVsKTsKICAgIGNvbnN0IHdlaWdodHMgPSB0aGlzLmNvdm1hdENob2xlc2t5LnNvbHZlKGNvdlRyYWluSW5wdXRzKTsKCiAgICAvLyBjb3YgPSBjb3YoaW5wdXQsaW5wdXQpIOKIkiBjb3ZfdHJhaW5faW5wdXRz4bWAwrd3ZWlnaHRzICAoZ2VtbV90cigtMSwgY292VHJhaW5JbnB1dHMsIHdlaWdodHMsIDEpKS4KICAgIGNvbnN0IGNvdklucHV0c0lucHV0cyA9IG1ha2VDb3ZhcmlhbmNlTWF0cml4KGlucHV0c01hdHJpeCwgaW5wdXRzTWF0cml4LCB0aGlzLmtlcm5lbCk7CiAgICBjb25zdCBjdF93ID0gbWF0TXVsKHRyYW5zcG9zZShjb3ZUcmFpbklucHV0cyksIHdlaWdodHMpOwogICAgY29uc3QgY292ID0gbWF0U3ViKGNvdklucHV0c0lucHV0cywgY3Rfdyk7CgogICAgLy8gbWVhbiA9IHByaW9yICsgd2VpZ2h0c+G1gMK3dHJhaW5pbmdPdXRwdXRzLgogICAgY29uc3QgbWVhbiA9IHRoaXMuX21lYW5Gcm9tV2VpZ2h0cyh3ZWlnaHRzLCBpbnB1dHNNYXRyaXgpOwogICAgcmV0dXJuIG5ldyBNdWx0aXZhcmlhdGVOb3JtYWwobWVhbiwgY292LCBzaW5nbGUpOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIEZJVAogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogRml0cyB0aGUgcmVxdWVzdGVkIHBhcmFtZXRlcnMgYW5kIHJldHJhaW5zIHRoZSBtb2RlbCAoYG1vZC5yczo0MDZgKS4KICAgKgogICAqIE5vaXNlIGFuZCBrZXJuZWwgcGFyYW1ldGVycyBhcmUgZml0dGVkIGJ5IGdyYWRpZW50IGFzY2VudCAoQURBTSkgb24gdGhlCiAgICogbWFyZ2luYWwgbG9nLWxpa2VsaWhvb2QuIFJ1bnMgZm9yIGF0IG1vc3QgYG1heEl0ZXJgIGl0ZXJhdGlvbnMsIHN0b3BwaW5nCiAgICogZWFybHkgd2hlbiBhbGwgZ3JhZGllbnRzIGFyZSBiZWxvdyBgY29udmVyZ2VuY2VGcmFjdGlvbmDCt3BhcmFtIG9yIGFmdGVyCiAgICogYG1heFRpbWVgLgogICAqCiAgICogQHBhcmFtIHtib29sZWFufSBmaXRQcmlvciAgICAgICAgICAgICAgZml0IHRoZSBwcmlvciB0byB0aGUgZGF0YS4KICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZpdEtlcm5lbCAgICAgICAgICAgICBmaXQgdGhlIGtlcm5lbCAoYW5kIG5vaXNlKSBwYXJhbWV0ZXJzLgogICAqIEBwYXJhbSB7bnVtYmVyfSAgbWF4SXRlciAgICAgICAgICAgICAgIG1heCBncmFkaWVudC1hc2NlbnQgaXRlcmF0aW9ucy4KICAgKiBAcGFyYW0ge251bWJlcn0gIGNvbnZlcmdlbmNlRnJhY3Rpb24gICByZWxhdGl2ZSBjb252ZXJnZW5jZSB0aHJlc2hvbGQuCiAgICogQHBhcmFtIHtudW1iZXJ9IFttYXhUaW1lPTM2MDAwMDBdICAgICAgbWF4IGZpdHRpbmcgdGltZSBpbiBNSUxMSVNFQ09ORFMKICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUnVzdCB1c2VzIGNocm9ubzo6RHVyYXRpb24gc2Vjb25kcykuCiAgICovCiAgZml0X3BhcmFtZXRlcnMoZml0UHJpb3IsIGZpdEtlcm5lbCwgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSA9IERFRkFVTFRfTUFYX1RJTUVfTVMpIHsKICAgIGlmIChmaXRQcmlvcikgewogICAgICBjb25zdCBpbnB1dHMgPSB0aGlzLnRyYWluaW5nSW5wdXRzLmFzTWF0cml4KCk7CgogICAgICAvLyBSZWNvdmVyIHRoZSBvcmlnaW5hbCAocmF3KSBvdXRwdXRzOiByZXNpZHVhbCArIHByaW9yX29sZChpbnB1dHMpLgogICAgICBjb25zdCByZXNpZHVhbE9sZCA9IHRoaXMudHJhaW5pbmdPdXRwdXRzLmFzVmVjdG9yKCk7CiAgICAgIGNvbnN0IHByaW9yT2xkID0gdGhpcy5wcmlvci5wcmlvcihpbnB1dHMpOwogICAgICBjb25zdCBvcmlnaW5hbE91dHB1dHMgPSBuZXcgQXJyYXkocmVzaWR1YWxPbGQubGVuZ3RoKTsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXNpZHVhbE9sZC5sZW5ndGg7IGkrKykgewogICAgICAgIG9yaWdpbmFsT3V0cHV0c1tpXSA9IHJlc2lkdWFsT2xkW2ldICsgcHJpb3JPbGRbaV07CiAgICAgIH0KCiAgICAgIC8vIFJlZml0IHRoZSBwcmlvciBvbiB0aGUgcmF3IG91dHB1dHMuCiAgICAgIHRoaXMucHJpb3IuZml0KGlucHV0cywgb3JpZ2luYWxPdXRwdXRzKTsKCiAgICAgIC8vIFJlLXJlc2lkdWFsaXNlIGFnYWluc3QgdGhlIG5ldyBwcmlvciBhbmQgc3RvcmUgYmFjay4KICAgICAgY29uc3QgcHJpb3JOZXcgPSB0aGlzLnByaW9yLnByaW9yKGlucHV0cyk7CiAgICAgIGNvbnN0IHJlc2lkdWFsTmV3ID0gbmV3IEFycmF5KG9yaWdpbmFsT3V0cHV0cy5sZW5ndGgpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yaWdpbmFsT3V0cHV0cy5sZW5ndGg7IGkrKykgewogICAgICAgIHJlc2lkdWFsTmV3W2ldID0gb3JpZ2luYWxPdXRwdXRzW2ldIC0gcHJpb3JOZXdbaV07CiAgICAgIH0KICAgICAgdGhpcy50cmFpbmluZ091dHB1dHMuYXNzaWduKHJlc2lkdWFsTmV3KTsKCiAgICAgIC8vIElmIHRoZSBrZXJuZWwgaXMgTk9UIGJlaW5nIGZpdHRlZCwgcmV0cmFpbiB0aGUgY292YXJpYW5jZSBDaG9sZXNreQogICAgICAvLyBmcm9tIHNjcmF0Y2ggKHRoZSByZXNpZHVhbHMgY2hhbmdlZCkuIFdoZW4gZml0S2VybmVsIGlzIHRydWUgdGhlCiAgICAgIC8vIG9wdGltaXplciByZWJ1aWxkcyBpdCBhbnl3YXkuCiAgICAgIGlmICghZml0S2VybmVsKSB7CiAgICAgICAgdGhpcy5jb3ZtYXRDaG9sZXNreSA9IG1ha2VDaG9sZXNreUNvdk1hdHJpeChpbnB1dHMsIHRoaXMua2VybmVsLCB0aGlzLm5vaXNlLCB0aGlzLmNob2xlc2t5RXBzaWxvbik7CiAgICAgIH0KICAgIH0KICAgIGlmIChmaXRLZXJuZWwpIHsKICAgICAgaWYgKHRoaXMua2VybmVsLmlzU2NhbGFibGUoKSkgewogICAgICAgIHNjYWxlZE9wdGltaXplUGFyYW1ldGVycyh0aGlzLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBvcHRpbWl6ZVBhcmFtZXRlcnModGhpcywgbWF4SXRlciwgY29udmVyZ2VuY2VGcmFjdGlvbiwgbWF4VGltZSk7CiAgICAgIH0KICAgIH0KICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBJTlRFUk5BTCBIRUxQRVJTCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBDb21wdXRlcyB0aGUgcG9zdGVyaW9yIG1lYW4gYHByaW9yICsgd2VpZ2h0c+G1gMK3dHJhaW5pbmdPdXRwdXRzYCwgaS5lLgogICAqIGBtZWFuW2ldID0gcHJpb3IoaW5wdXRzKVtpXSArIM6jX3Qgd2VpZ2h0c1t0XVtpXcK3dHJhaW5pbmdPdXRwdXRzW3RdYC4KICAgKgogICAqIFRoaXMgcmVwcm9kdWNlcyBuYWxnZWJyYSBgcHJpb3IuZ2VtbV90cigxLCB3ZWlnaHRzLCB0cmFpbmluZ091dHB1dHMsIDEpYCwKICAgKiB3aGVyZSBgd2VpZ2h0c2AgaXMgKG5UcmFpbiDDlyBuSW5wdXQpLCBgdHJhaW5pbmdPdXRwdXRzYCBpcyB0aGUgcmVzaWR1YWwKICAgKiB2ZWN0b3IgKGxlbmd0aCBuVHJhaW4pLCBhbmQgdGhlIHJlc3VsdCBoYXMgbGVuZ3RoIG5JbnB1dC4KICAgKgogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gd2VpZ2h0cyAgICAgIChuVHJhaW4gw5cgbklucHV0KQogICAqIEBwYXJhbSB7bnVtYmVyW11bXX0gaW5wdXRzTWF0cml4IChuSW5wdXQgw5cgZCkKICAgKiBAcmV0dXJucyB7bnVtYmVyW119IHBvc3RlcmlvciBtZWFuIChsZW5ndGggbklucHV0KSwgcHJpb3IgYWxyZWFkeSBhZGRlZC4KICAgKiBAcHJpdmF0ZQogICAqLwogIF9tZWFuRnJvbVdlaWdodHMod2VpZ2h0cywgaW5wdXRzTWF0cml4KSB7CiAgICBjb25zdCBuSW5wdXQgPSBpbnB1dHNNYXRyaXgubGVuZ3RoOwogICAgY29uc3QgblRyYWluID0gd2VpZ2h0cy5sZW5ndGg7CiAgICBjb25zdCBvdXRwdXRzID0gdGhpcy50cmFpbmluZ091dHB1dHMuYXNWZWN0b3IoKTsgLy8gcmVzaWR1YWwKICAgIGNvbnN0IHByaW9yVmVjID0gdGhpcy5wcmlvci5wcmlvcihpbnB1dHNNYXRyaXgpOwogICAgY29uc3QgbWVhbiA9IG5ldyBBcnJheShuSW5wdXQpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSW5wdXQ7IGkrKykgewogICAgICBsZXQgcyA9IHByaW9yVmVjW2ldOwogICAgICBmb3IgKGxldCB0ID0gMDsgdCA8IG5UcmFpbjsgdCsrKSB7CiAgICAgICAgcyArPSB3ZWlnaHRzW3RdW2ldICogb3V0cHV0c1t0XTsKICAgICAgfQogICAgICBtZWFuW2ldID0gczsKICAgIH0KICAgIHJldHVybiBtZWFuOwogIH0KfQoKLy8gTWl4aW4gdGhlIG9wdGltaXplciBmcmVlLWZ1bmN0aW9ucyBvbnRvIHRoZSBwcm90b3R5cGUgc28gdGhleSBhcmUgYWxzbwovLyByZWFjaGFibGUgYXMgbWV0aG9kcyAoZS5nLiBgZ3Aub3B0aW1pemVQYXJhbWV0ZXJzKC4uLilgKS4gYGZpdF9wYXJhbWV0ZXJzYAovLyBhYm92ZSBjYWxscyB0aGUgaW1wb3J0ZWQgZnJlZSBmdW5jdGlvbnMgZGlyZWN0bHk7IHRoZXNlIGFsaWFzZXMganVzdCBrZWVwIHRoZQovLyBzdXJmYWNlIGNvbnNpc3RlbnQgd2l0aCBQT1JUX1NQRUMgwqc3ICgiaW1wb3J0IHRoZW4gY2FsbCBhcyBtZXRob2RzIikuCkdhdXNzaWFuUHJvY2Vzcy5wcm90b3R5cGUub3B0aW1pemVQYXJhbWV0ZXJzID0gZnVuY3Rpb24gKG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpIHsKICByZXR1cm4gb3B0aW1pemVQYXJhbWV0ZXJzKHRoaXMsIG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24sIG1heFRpbWUpOwp9OwpHYXVzc2lhblByb2Nlc3MucHJvdG90eXBlLnNjYWxlZE9wdGltaXplUGFyYW1ldGVycyA9IGZ1bmN0aW9uIChtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKSB7CiAgcmV0dXJuIHNjYWxlZE9wdGltaXplUGFyYW1ldGVycyh0aGlzLCBtYXhJdGVyLCBjb252ZXJnZW5jZUZyYWN0aW9uLCBtYXhUaW1lKTsKfTsKR2F1c3NpYW5Qcm9jZXNzLnByb3RvdHlwZS5ncmFkaWVudE1hcmdpbmFsTGlrZWxpaG9vZCA9IGZ1bmN0aW9uICgpIHsKICByZXR1cm4gZ3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QodGhpcyk7Cn07CkdhdXNzaWFuUHJvY2Vzcy5wcm90b3R5cGUuc2NhbGVkR3JhZGllbnRNYXJnaW5hbExpa2VsaWhvb2QgPSBmdW5jdGlvbiAoKSB7CiAgcmV0dXJuIHNjYWxlZEdyYWRpZW50TWFyZ2luYWxMaWtlbGlob29kKHRoaXMpOwp9OwoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBHYXVzc2lhblByb2Nlc3NCdWlsZGVyCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgogKiBCdWlsZGVyIHRvIHNldCB0aGUgcGFyYW1ldGVycyBvZiBhIEdhdXNzaWFuIHByb2Nlc3MgKGBidWlsZGVyLnJzYCkuCiAqCiAqIENoYWluYWJsZSBzZXR0ZXJzIGN1bG1pbmF0aW5nIGluIGB0cmFpbigpYC4gUHJvZHVjZWQgYnkKICogYEdhdXNzaWFuUHJvY2Vzcy5idWlsZGVyKGlucHV0cywgb3V0cHV0cylgLgogKgogKiBEZWZhdWx0cyAoYGJ1aWxkZXIucnM6NjZgKToKICogICAtIGNvbnN0YW50IHByaW9yICgwIHVubGVzcyBmaXR0ZWQpCiAqICAgLSBhIEdhdXNzaWFuIGtlcm5lbAogKiAgIC0gbm9pc2UgPSAxMCUgb2YgdGhlIG91dHB1dCBzdGFuZGFyZCBkZXZpYXRpb24KICogICAtIGRvZXMgbm90IGZpdCBhbnkgcGFyYW1ldGVycwogKiAgIC0gZml0IHJ1bnMgZm9yIOKJpCAxMDAgaXRlcmF0aW9ucyAvIDEgaG91ciB1bmxlc3MgYWxsIGdyYWRpZW50cyBhcmUgYmVsb3cgNSUuCiAqCiAqIFNldHRlcnMgbXV0YXRlIGFuZCByZXR1cm4gYHRoaXNgIChSdXN0IHJldHVybnMgYSBuZXcgdHlwZWQgYnVpbGRlcjsgZm9yIEpTIHdlCiAqIGtlZXAgYSBzaW5nbGUgbXV0YWJsZSBidWlsZGVyIOKAlCBiZWhhdmlvdXIgaXMgaWRlbnRpY2FsIGZvciB0aGUgZmx1ZW50IEFQSSkuCiAqLwpjbGFzcyBHYXVzc2lhblByb2Nlc3NCdWlsZGVyIHsKICAvKioKICAgKiBAcGFyYW0ge251bWJlcltdfG51bWJlcltdW119IHRyYWluaW5nSW5wdXRzCiAgICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119ICAgICB0cmFpbmluZ091dHB1dHMKICAgKi8KICBjb25zdHJ1Y3Rvcih0cmFpbmluZ0lucHV0cywgdHJhaW5pbmdPdXRwdXRzKSB7CiAgICBjb25zdCBpbnB1dHNNYXRyaXggPSB0b01hdHJpeCh0cmFpbmluZ0lucHV0cyk7CiAgICBjb25zdCBvdXRwdXRzVmVjdG9yID0gdG9WZWN0b3IodHJhaW5pbmdPdXRwdXRzKTsKCiAgICAvKiogQHR5cGUge251bWJlcltdW119ICovCiAgICB0aGlzLnRyYWluaW5nSW5wdXRzID0gaW5wdXRzTWF0cml4OwogICAgLyoqIEB0eXBlIHtudW1iZXJbXX0gKi8KICAgIHRoaXMudHJhaW5pbmdPdXRwdXRzID0gb3V0cHV0c1ZlY3RvcjsKCiAgICAvLyBEZWZhdWx0IHByaW9yOiBDb25zdGFudFByaW9yKDApIChkaW0gaXMgaWdub3JlZCBieSBDb25zdGFudFByaW9yKS4KICAgIC8qKiBAdHlwZSB7b2JqZWN0fSAqLwogICAgdGhpcy5wcmlvciA9IENvbnN0YW50UHJpb3IuZGVmYXVsdChpbnB1dHNNYXRyaXgubGVuZ3RoID09PSAwID8gMCA6IGlucHV0c01hdHJpeFswXS5sZW5ndGgpOwogICAgLy8gRGVmYXVsdCBrZXJuZWw6IEdhdXNzaWFuIC8gU3F1YXJlZEV4cCB3aXRoIGRlZmF1bHQgcGFyYW1ldGVycy4KICAgIC8qKiBAdHlwZSB7b2JqZWN0fSAqLwogICAgdGhpcy5rZXJuZWwgPSBuZXcgR2F1c3NpYW4oKTsKICAgIC8vIERlZmF1bHQgbm9pc2U6IDEwJSBvZiB0aGUgb3V0cHV0IHN0YW5kYXJkIGRldmlhdGlvbi4KICAgIC8vICAgcm93X3ZhcmlhbmNlKG91dHB1dHMpWzBdID0gzqMoeeG1ouKIksizKcKyL04gIChkaXZpZGUgYnkgTiDigJQgc2VlIGZpdEFtcGxpdHVkZVZhcikuCiAgICAvKiogQHR5cGUge251bWJlcn0gKi8KICAgIHRoaXMubm9pc2UgPSAwLjEgKiBNYXRoLnNxcnQoZml0QW1wbGl0dWRlVmFyKG91dHB1dHNWZWN0b3IpKTsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfG51bGx9ICovCiAgICB0aGlzLmNob2xlc2t5RXBzaWxvbiA9IG51bGw7CgogICAgLyoqIEB0eXBlIHtib29sZWFufSAqLwogICAgdGhpcy5zaG91bGRGaXRLZXJuZWwgPSBmYWxzZTsKICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi8KICAgIHRoaXMuc2hvdWxkRml0UHJpb3IgPSBmYWxzZTsKCiAgICAvKiogQHR5cGUge251bWJlcn0gKi8KICAgIHRoaXMubWF4SXRlciA9IDEwMDsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqLwogICAgdGhpcy5jb252ZXJnZW5jZUZyYWN0aW9uID0gMC4wNTsKICAgIC8qKiBAdHlwZSB7bnVtYmVyfSBtYXggZml0dGluZyB0aW1lIGluIG1pbGxpc2Vjb25kcyAqLwogICAgdGhpcy5tYXhUaW1lID0gREVGQVVMVF9NQVhfVElNRV9NUzsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBTRVRURVJTIChjaGFpbmFibGUpCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBTZXRzIGEgbmV3IHByaW9yLgogICAqIEBwYXJhbSB7b2JqZWN0fSBwcmlvcgogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIHNldFByaW9yKHByaW9yKSB7CiAgICB0aGlzLnByaW9yID0gcHJpb3I7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFNldHMgdGhlIG5vaXNlIHBhcmFtZXRlciAoc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBvdXRwdXQgbm9pc2UpLgogICAqIEBwYXJhbSB7bnVtYmVyfSBub2lzZSAo4omlIDApCiAgICogQHJldHVybnMge3RoaXN9CiAgICovCiAgc2V0Tm9pc2Uobm9pc2UpIHsKICAgIGlmICghKG5vaXNlID49IDApKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIG5vaXNlIHBhcmFtZXRlciBzaG91bGQgYmUgbm9uLW5lZ2F0aXZlIGJ1dCB3ZSB0cmllZCB0byBzZXQgaXQgdG8gJHtub2lzZX1gKTsKICAgIH0KICAgIHRoaXMubm9pc2UgPSBub2lzZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQ2hhbmdlcyB0aGUga2VybmVsIG9mIHRoZSBHYXVzc2lhbiBwcm9jZXNzLgogICAqIEBwYXJhbSB7b2JqZWN0fSBrZXJuZWwKICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBzZXRLZXJuZWwoa2VybmVsKSB7CiAgICB0aGlzLmtlcm5lbCA9IGtlcm5lbDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogU2V0cyB0aGUgQ2hvbGVza3kgZXBzaWxvbi4gV2hlbiBhIHN0cmljdGx5IHBvc2l0aXZlIHZhbHVlIGlzIGdpdmVuLCB0aGUKICAgKiBDaG9sZXNreSBkZWNvbXBvc2l0aW9uIGlzIGd1YXJhbnRlZWQgdG8gc3VjY2VlZCAodGhlIHZhbHVlIGlzIHVzZWQgaW4KICAgKiBwbGFjZSBvZiBhIG5vbi1wb3NpdGl2ZSBkaWFnb25hbCBwaXZvdCkuIGBudWxsYCBpZ25vcmVzIGl0LgogICAqIEBwYXJhbSB7bnVtYmVyfG51bGx9IGNob2xlc2t5RXBzaWxvbgogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIHNldENob2xlc2t5RXBzaWxvbihjaG9sZXNreUVwc2lsb24pIHsKICAgIHRoaXMuY2hvbGVza3lFcHNpbG9uID0gY2hvbGVza3lFcHNpbG9uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBNb2RpZmllcyB0aGUgc3RvcHBpbmcgY3JpdGVyaWEgb2YgdGhlIGdyYWRpZW50IGRlc2NlbnQgdXNlZCB0byBmaXQgdGhlCiAgICogbm9pc2UgYW5kIGtlcm5lbCBwYXJhbWV0ZXJzLgogICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhJdGVyCiAgICogQHBhcmFtIHtudW1iZXJ9IGNvbnZlcmdlbmNlRnJhY3Rpb24KICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBzZXRGaXRQYXJhbWV0ZXJzKG1heEl0ZXIsIGNvbnZlcmdlbmNlRnJhY3Rpb24pIHsKICAgIHRoaXMubWF4SXRlciA9IG1heEl0ZXI7CiAgICB0aGlzLmNvbnZlcmdlbmNlRnJhY3Rpb24gPSBjb252ZXJnZW5jZUZyYWN0aW9uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBc2tzIGZvciB0aGUga2VybmVsIHBhcmFtZXRlcnMgdG8gYmUgZml0dGVkIG9uIHRoZSB0cmFpbmluZyBkYXRhIChhcHBsaWVkCiAgICogd2hlbiBgdHJhaW4oKWAgaXMgY2FsbGVkKS4KICAgKiBAcmV0dXJucyB7dGhpc30KICAgKi8KICBmaXRLZXJuZWwoKSB7CiAgICB0aGlzLnNob3VsZEZpdEtlcm5lbCA9IHRydWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEFza3MgZm9yIHRoZSBwcmlvciB0byBiZSBmaXR0ZWQgb24gdGhlIHRyYWluaW5nIGRhdGEgKGFwcGxpZWQgd2hlbgogICAqIGB0cmFpbigpYCBpcyBjYWxsZWQpLgogICAqIEByZXR1cm5zIHt0aGlzfQogICAqLwogIGZpdFByaW9yKCkgewogICAgdGhpcy5zaG91bGRGaXRQcmlvciA9IHRydWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBUUkFJTgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogVHJhaW5zIHRoZSBHYXVzc2lhbiBwcm9jZXNzLCBmaXR0aW5nIHRoZSBwYXJhbWV0ZXJzIGlmIHJlcXVlc3RlZAogICAqIChgYnVpbGRlci5yczoxODlgKS4KICAgKgogICAqIFN0ZXBzOgogICAqICAgMS4gaWYgYHNob3VsZEZpdEtlcm5lbGAg4oaSIGBrZXJuZWwuaGV1cmlzdGljRml0KGlucHV0cywgb3V0cHV0cylgIHVzaW5nIHRoZQogICAqICAgICAgUkFXIG91dHB1dHMgKHRoZSBidWlsZGVyIGhhcyBub3Qgc3VidHJhY3RlZCB0aGUgcHJpb3IgeWV0KS4KICAgKiAgIDIuIGNvbnN0cnVjdCB0aGUgR2F1c3NpYW5Qcm9jZXNzLgogICAqICAgMy4gYGdwLmZpdF9wYXJhbWV0ZXJzKHNob3VsZEZpdFByaW9yLCBzaG91bGRGaXRLZXJuZWwsIOKApilgLgogICAqCiAgICogQHJldHVybnMge0dhdXNzaWFuUHJvY2Vzc30KICAgKi8KICB0cmFpbigpIHsKICAgIC8vIDEuIEtlcm5lbCBoZXVyaXN0aWMgZml0ICh1c2VzIHJhdyBvdXRwdXRzKS4KICAgIGlmICh0aGlzLnNob3VsZEZpdEtlcm5lbCkgewogICAgICB0aGlzLmtlcm5lbC5oZXVyaXN0aWNGaXQodGhpcy50cmFpbmluZ0lucHV0cywgdGhpcy50cmFpbmluZ091dHB1dHMpOwogICAgfQoKICAgIC8vIDIuIEJ1aWxkIHRoZSBHUCAodGhpcyByZXNpZHVhbGlzZXMgdGhlIG91dHB1dHMgYW5kIGJ1aWxkcyB0aGUgQ2hvbGVza3kpLgogICAgY29uc3QgZ3AgPSBuZXcgR2F1c3NpYW5Qcm9jZXNzKHRoaXMucHJpb3IsIHRoaXMua2VybmVsLCB0aGlzLm5vaXNlLCB0aGlzLmNob2xlc2t5RXBzaWxvbiwgdGhpcy50cmFpbmluZ0lucHV0cywgdGhpcy50cmFpbmluZ091dHB1dHMpOwoKICAgIC8vIDMuIEZpdCBvbiB0aGUgdHJhaW5pbmcgZGF0YSwgaWYgcmVxdWVzdGVkLgogICAgZ3AuZml0X3BhcmFtZXRlcnModGhpcy5zaG91bGRGaXRQcmlvciwgdGhpcy5zaG91bGRGaXRLZXJuZWwsIHRoaXMubWF4SXRlciwgdGhpcy5jb252ZXJnZW5jZUZyYWN0aW9uLCB0aGlzLm1heFRpbWUpOwogICAgcmV0dXJuIGdwOwogIH0KfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBMT0NBTCBDT0xVTU4gSEVMUEVSUwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKioKICogU3F1YXJlZCBFdWNsaWRlYW4gbm9ybSBvZiBjb2x1bW4gYGNgIG9mIG1hdHJpeCBgTWAgKG51bWJlcltdW10pLgogKiBAcGFyYW0ge251bWJlcltdW119IE0KICogQHBhcmFtIHtudW1iZXJ9IGMKICogQHJldHVybnMge251bWJlcn0KICovCmZ1bmN0aW9uIGNvbHVtbk5vcm1TcXVhcmVkKE0sIGMpIHsKICBsZXQgcyA9IDA7CiAgZm9yIChsZXQgciA9IDA7IHIgPCBNLmxlbmd0aDsgcisrKSB7CiAgICBjb25zdCB2ID0gTVtyXVtjXTsKICAgIHMgKz0gdiAqIHY7CiAgfQogIHJldHVybiBzOwp9CgovKioKICogRG90IHByb2R1Y3Qgb2YgY29sdW1uIGBjYCBvZiBBIHdpdGggY29sdW1uIGBjYCBvZiBCIChib3RoIG51bWJlcltdW10pLgogKiBAcGFyYW0ge251bWJlcltdW119IEEKICogQHBhcmFtIHtudW1iZXJbXVtdfSBCCiAqIEBwYXJhbSB7bnVtYmVyfSBjCiAqIEByZXR1cm5zIHtudW1iZXJ9CiAqLwpmdW5jdGlvbiBjb2x1bW5Eb3QoQSwgQiwgYykgewogIGxldCBzID0gMDsKICBmb3IgKGxldCByID0gMDsgciA8IEEubGVuZ3RoOyByKyspIHsKICAgIHMgKz0gQVtyXVtjXSAqIEJbcl1bY107CiAgfQogIHJldHVybiBzOwp9CgovKioNCiAqIOWFi+WIqemHkeazlShLcmlnaW5nKeWFp+WkluaPkum7nuaVuOWAvA0KICoNCiAqIOWFi+WIqemHkeazleioiOeul+iIh+Wvpumam+mBi+eul+eTtumguOWVj+mhjOWPr+ips+imizogaHR0cHM6Ly9naXRodWIuY29tL2x2aXNlaS93ZWItZGV2ZWxvcGVyLXJlc291cmNlcy9ibG9iL21hc3Rlci93ZWJhc3NlbWJseS9rcmlnaW5nLm1kDQogKg0KICog6Iul5pivTm9kZS5qc+err+S9v+eUqOmgiOabtOmrmOioiOeul+mAn+W6pu+8jOWPr+S9v+eUqHcta3JpZ2luZzogaHR0cHM6Ly9naXRodWIuY29tL3l1ZGEtbHl1L3cta3JpZ2luZw0KICoNCiAqIFVuaXQgVGVzdDoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS95dWRhLWx5dS93LWdpcy9ibG9iL21hc3Rlci90ZXN0L2ludGVycDJLcmlnaW5nLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcHNTcmMg6Ly45YWl5LqM57at5bqn5qiZ5Yqg6KeA5ris5pW45pOa6bue6Zmj5YiX77yM54K6W3t4OngxLHk6eTEsejp6MX0se3g6eDIseTp5Mix6OnoyfSwuLi5d6bue54mp5Lu25LmL6Zmj5YiXDQogKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gcHNUYXIg6Ly45YWl5LqM57at5bqn5qiZ6bue6Zmj5YiX5oiW6bue54mp5Lu277yM54K6W3t4OngxLHk6eTF9LHt4OngyLHk6eTJ9LC4uLl3pu57nianku7bkuYvpmaPliJfvvIzmiJZ7eDp4MSx5Onkxfem7nueJqeS7tg0KICogQHBhcmFtIHtPYmplY3R9IFtvcHQ9e31dIOi8uOWFpeioreWumueJqeS7tu+8jOmgkOiorXt9DQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlYPSd4J10g6Ly45YWl6bue54mp5Lu25LmLeOashOS9jeWtl+S4su+8jOeCuuW6p+aome+8jOmgkOiorSd4Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5WT0neSddIOi8uOWFpem7nueJqeS7tuS5i3nmrITkvY3lrZfkuLLvvIzngrrluqfmqJnvvIzpoJDoqK0neScNCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVo9J3onXSDovLjlhaXpu57nianku7bkuYt65qyE5L2N5a2X5Liy77yM54K66KeA5ris5YC877yM6aCQ6KitJ3onDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5zY2FsZT0xXSDovLjlhaXmraPopo/ljJbnr4TlnI3mlbjlgLzvvIzlm6DomZXnkIblpJrpgorlvaLmmYLmnInmlbjlgLzlrrnoqLHoqqTlt67vvIzmlYXpoIjpgJrpgY7nuK7mlL7lgLzln5/kvobmuJvlsJHllY/poYzvvIzpoJDoqK0x5piv5q2j6KaP5YyWMOiHszHkuYvplpPvvIzkvb/nlKhzY2FsZVhZ5YmH5piv5q2j6KaP5YyW54K6MOiHs3NjYWxlWFnkuYvplpPvvIzpoJDoqK0xDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5tZXRob2Q9J2ZyaWVkcmljaCddIOi8uOWFpeW+jOerr+W8leaTjuWtl+S4su+8jOWPr+mBuCdmcmllZHJpY2gnKEdhdXNzaWFuIFByb2Nlc3MgUmVncmVzc2lvbu+8jOaguOWHveaVuO+8jGtyaWdpbmctZnJpZWRyaWNoKeOAgSdpbnZhbGwnKOe2k+WFuE9yZGluYXJ5IEtyaWdpbmfvvIzljYrorornlbDlnJbmk6zlkIjvvIxrcmlnaW5nLWludmFsbC9rcmlnaW5nLm1qcynvvIzpoJDoqK0nZnJpZWRyaWNoJw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQubW9kZWw9J2V4cG9uZW50aWFsJ10g6Ly45YWl5pOs5ZCI5qih5byP5a2X5Liy77yMbWV0aG9kPSdpbnZhbGwn5pmC5Y+v6YG4J2V4cG9uZW50aWFsJ+OAgSdnYXVzc2lhbifjgIEnc3BoZXJpY2FsJ++8m21ldGhvZD0nZnJpZWRyaWNoJ+aZgidnYXVzc2lhbiflsI3mh4lTcXVhcmVkRXhw44CB5YW26aSYKOWQq3NwaGVyaWNhbCnlsI3mh4lFeHBvbmVudGlhbO+8jOmgkOiorSdleHBvbmVudGlhbCcNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LnNpZ21hMj0wXSDovLjlhaXoh6rli5Xmk6zlkIjlj4PmlbhzaWdtYTLmlbjlgLzvvIzlg4VtZXRob2Q9J2ludmFsbCfmmYLmnInmlYjvvIzpoJDoqK0wDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5hbHBoYT0xMDBdIOi8uOWFpeiHquWLleaTrOWQiOWPg+aVuGFscGhh5pW45YC877yM5YOFbWV0aG9kPSdpbnZhbGwn5pmC5pyJ5pWI77yM6aCQ6KitMTAwDQogKiBAcGFyYW0ge051bWJlcn0gW29wdC5scz0wLjVdIOi8uOWFpWZyaWVkcmljaOaguOWHveaVuGxlbmd0aHNjYWxl5pW45YC8KOWwjeaHieato+imj+WMluW+jOWAvOWfnynvvIzlg4VtZXRob2Q9J2ZyaWVkcmljaCfmmYLmnInmlYjvvIzpoJDoqK0wLjUNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0Lm5vaXNlPTAuMDFdIOi8uOWFpWZyaWVkcmljaOingOa4rOWZqumfs+aomea6luW3rijlsI3mh4nmraPopo/ljJblvozlgLzln58p77yM5YOFbWV0aG9kPSdmcmllZHJpY2gn5pmC5pyJ5pWI77yM6aCQ6KitMC4wMQ0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnJldHVybldpdGhWYXJpb2dyYW09ZmFsc2VdIOi8uOWFpeaYr+WQpuWbnuWCs+aTrOWQiOWNiuiuiueVsOaVuOe1kOaenOW4g+ael+WAvO+8jG1ldGhvZD0nZnJpZWRyaWNoJ+aZgnZhcmlvZ3JhbeWbnuWCs251bGzvvIzpoJDoqK1mYWxzZQ0KICogQHJldHVybnMge0FycmF5fE9iamVjdH0g5Zue5YKz6bue54mp5Lu26Zmj5YiX5oiW6bue54mp5Lu277yM6Iul5L2/55SocmV0dXJuV2l0aFZhcmlvZ3JhbT10cnVl5YmH5Zue5YKz54mp5Lu26LOH6KiK77yM6Iul55m855Sf6Yyv6Kqk5YmH5Zue5YKz6Yyv6Kqk6KiK5oGv54mp5Lu2DQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHANCiAqIGxldCByDQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA1LCB6OiA5NC45NDkyNTg5ODc4NDUyNyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjgzLA0KICogICAgIHk6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI4MywgeTogMjA1LCB6OiAxMTcuMTQ4OTYzMTA2OTUxNDcgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDExNjAsDQogKiAgICAgeTogMzgwLA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMTE2MCwgeTogMzgwLCB6OiA4NC45ODMxNDY3MjAwNTMzNCB9DQogKg0KICogcHMgPSBbeyBhOiAyNDMsIGI6IDIwNiwgYzogOTUgfSwgeyBhOiAyMzMsIGI6IDIyNSwgYzogMTQ2IH0sIHsgYTogMjEsIGI6IDMyNSwgYzogMjIgfSwgeyBhOiA5NTMsIGI6IDI4LCBjOiAyMjMgfSwgeyBhOiAxMDkyLCBiOiAyOTAsIGM6IDM5IH0sIHsgYTogNzQ0LCBiOiAyMDAsIGM6IDE5MSB9LCB7IGE6IDE3NCwgYjogMywgYzogMjIgfSwgeyBhOiA1MzcsIGI6IDM2OCwgYzogMjQ5IH0sIHsgYTogMTE1MSwgYjogMzcxLCBjOiA4NiB9LCB7IGE6IDgxNCwgYjogMjUyLCBjOiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgYTogMjQzLA0KICogICAgIGI6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCwgeyBrZXlYOiAnYScsIGtleVk6ICdiJywga2V5WjogJ2MnIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyBhOiAyNDMsIGI6IDIwNSwgYzogOTQuOTQ5MjU4OTg3ODQ1MjcgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gWw0KICogICAgIHsNCiAqICAgICAgICAgeDogMjQzLA0KICogICAgICAgICB5OiAyMDUsDQogKiAgICAgfSwNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI4MywNCiAqICAgICAgICAgeTogMjA1LA0KICogICAgIH0sDQogKiBdDQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA1LCB6OiA5NC45NDkyNTg5ODc4NDUyNyB9LA0KICogLy8gICB7IHg6IDI4MywgeTogMjA1LCB6OiAxMTcuMTQ4OTYzMTA2OTUxNDcgfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHAsIHsgc2NhbGU6IDEwMDAsIG1ldGhvZDogJ2ludmFsbCcgfSkgLy9zY2FsZS1yb2J1c3TngrppbnZhbGzlsIjlsawsIGZyaWVkcmljaOWbuuWummtlcm5lbOmdnnNjYWxlLXJvYnVzdA0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDUsIHo6IDk0Ljg4NDc5OTQ4NDE4ODc4IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA1LA0KICogfQ0KICogciA9IGludGVycDJLcmlnaW5nKHBzLCBwLCB7IG1vZGVsOiAnZ2F1c3NpYW4nIH0pIC8vZnJpZWRyaWNo6buY6KqNLCBnYXVzc2lhbuWwjeaHiVNxdWFyZWRFeHDmoLgNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA1LCB6OiAxMTguOTA1ODI1MDA3NDc5ODMgfQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDUsDQogKiB9DQogKiByID0gaW50ZXJwMktyaWdpbmcocHMsIHAsIHsgc2lnbWEyOiAwLjAwMSwgYWxwaGE6IDcwLCBtZXRob2Q6ICdpbnZhbGwnIH0pIC8vc2lnbWEyL2FscGhh54K6aW52YWxs5Y2K6K6K55Ww5ZyW5pOs5ZCI5Y+D5pW4LCBmcmllZHJpY2jkuI3pgannlKgNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDI0MywgeTogMjA1LCB6OiA5MC44ODcwMjk0OTI3NjM0MyB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNSwNCiAqIH0NCiAqIHIgPSBpbnRlcnAyS3JpZ2luZyhwcywgcCwgeyByZXR1cm5XaXRoVmFyaW9ncmFtOiB0cnVlLCBtZXRob2Q6ICdpbnZhbGwnIH0pIC8vdmFyaW9ncmFt54K6aW52YWxs5bCI5bGsLCBmcmllZHJpY2jlm57lgrNudWxsDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gew0KICogLy8gICByZXN1bHQ6IHsgeDogMjQzLCB5OiAyMDUsIHo6IDk0Ljg4NDc5OTQ4NDE4NzIxIH0sDQogKiAvLyAgIHZhcmlvZ3JhbTogew0KICogLy8gICAgIHQ6IFsNCiAqIC8vICAgICAgIDAuMzIxNTg1OTAzMDgzNzAwNDQsDQogKiAvLyAgICAgICAwLjU0NjI1NTUwNjYwNzkyOTUsDQogKiAvLyAgICAgICAwLA0KICogLy8gICAgICAgMC44ODU0NjI1NTUwNjYwNzkzLA0KICogLy8gICAgICAgMC4wNzQ4ODk4Njc4NDE0MDk2OSwNCiAqIC8vICAgICAgIDAuNzQ0NDkzMzkyMDcwNDg0NiwNCiAqIC8vICAgICAgIDAsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC4yODE5MzgzMjU5OTExODk0NSwNCiAqIC8vICAgICAgIDAuNDUzNzQ0NDkzMzkyMDcwNDYNCiAqIC8vICAgICBdLA0KICogLy8gICAgIHg6IFsNCiAqIC8vICAgICAgIDAuMTk2NDYwMTc2OTkxMTUwNDUsDQogKiAvLyAgICAgICAwLjE4NzYxMDYxOTQ2OTAyNjU1LA0KICogLy8gICAgICAgMCwNCiAqIC8vICAgICAgIDAuODI0Nzc4NzYxMDYxOTQ2OSwNCiAqIC8vICAgICAgIDAuOTQ3Nzg3NjEwNjE5NDY5LA0KICogLy8gICAgICAgMC42Mzk4MjMwMDg4NDk1NTc2LA0KICogLy8gICAgICAgMC4xMzUzOTgyMzAwODg0OTU1OCwNCiAqIC8vICAgICAgIDAuNDU2NjM3MTY4MTQxNTkyOTQsDQogKiAvLyAgICAgICAxLA0KICogLy8gICAgICAgMC43MDE3Njk5MTE1MDQ0MjQ4DQogKiAvLyAgICAgXSwNCiAqIC8vICAgICB5OiBbDQogKiAvLyAgICAgICAwLjUxNjgxNDE1OTI5MjAzNTQsDQogKiAvLyAgICAgICAwLjUzMzYyODMxODU4NDA3MDgsDQogKiAvLyAgICAgICAwLjYyMjEyMzg5MzgwNTMwOTcsDQogKiAvLyAgICAgICAwLjM1OTI5MjAzNTM5ODIzMDA3LA0KICogLy8gICAgICAgMC41OTExNTA0NDI0Nzc4NzYxLA0KICogLy8gICAgICAgMC41MTE1MDQ0MjQ3Nzg3NjEsDQogKiAvLyAgICAgICAwLjMzNzE2ODE0MTU5MjkyMDM2LA0KICogLy8gICAgICAgMC42NjAxNzY5OTExNTA0NDI1LA0KICogLy8gICAgICAgMC42NjI4MzE4NTg0MDcwNzk3LA0KICogLy8gICAgICAgMC41NTc1MjIxMjM4OTM4MDUzDQogKiAvLyAgICAgXSwNCiAqIC8vICAgICBudWdnZXQ6IDAuMzM1Mjg1MzQ5MjM0MjgxNDQsDQogKiAvLyAgICAgcmFuZ2U6IDAuOTgxODI3NDIwNDEyMDQ4OCwNCiAqIC8vICAgICBzaWxsOiAwLjQ1ODQ1ODAzMzM0NDMwNzUsDQogKiAvLyAgICAgQTogMC4zMzMzMzMzMzMzMzMzMzMzLA0KICogLy8gICAgIG46IDEwLA0KICogLy8gICAgIG1vZGVsOiBbRnVuY3Rpb246IGtyaWdpbmdfdmFyaW9ncmFtX2V4cG9uZW50aWFsXSwNCiAqIC8vICAgICBzdnBkOiB7IGRhdGE6IFtBcnJheV0sIGJhcnM6IFtBcnJheV0gfSwNCiAqIC8vICAgICBLOiBbDQogKiAvLyAgICAgICAgICAtNzUuODUxNzAwNDE3NTI0NSwgICAgICAgNjcuOTI1NzIyOTIzNDg0LCAtMC4xNjMzNTg0MTAzNjk2NDY3NywNCiAqIC8vICAgICAgICAwLjI0MTMxNTE4OTc4MjcwODc3LCAgLTAuMDQyMzQyNDY4NjUwNDg3MzIsICAgMC44NzcwNTE4Mzk2MzI4OTEyLA0KICogLy8gICAgICAgICAgNS42MTY5NjAzNjIxNzAyNzksICAgICAxLjYyMTY1OTYzNzQ0MDIyNywgMC4wMjc4ODgwMDE2NTE4OTQ2MzUsDQogKiAvLyAgICAgICAtMC4yMTQxNTg1MzQxNjY1MjgwMywgICAgIDY3LjkyNTcyMjkyMzQ4NDAyLCAgIC03NS42MTc4NjQ3ODgyNDg2OCwNCiAqIC8vICAgICAgICAgIDUuNDEzMjMyMDc5NzI3MDY0LCAgIDAuMDQ5MDY5NDM0MzgzODU5NTgsICAwLjAzNjc5MTEzMjI5MzQ4NDY1LA0KICogLy8gICAgICAgLTAuMTE4NDcxMzkzNTI2OTg2NzcsICAgIDAuMzE0MjAxMjc2NzI5NzkxNywgICAxLjk1MzEwNzg4NTQ0MzAwMjQsDQogKiAvLyAgICAgICAgMC4xNDIxNjM3Nzg1NDA1NTM0MywgLTAuMDI2NTAzMTA0NjcyNTI1MTc0LCAgIC0wLjE2MzM1ODQxMDM2OTY1MSwNCiAqIC8vICAgICAgICAgIDUuNDEzMjMyMDc5NzI3MDY3LCAgIC0xMC4zNDEwODg3NDE2MDI0NzUsICAgIDAuNzA3NjkwMjU2NDE1MjA1LA0KICogLy8gICAgICAgICAwLjI3MTcyNTk0Nzc0ODEzNzUsICAgIC0wLjAzMjc1MTMzODMyNzgxOCwgICAyLjQwMjE1MTA0Njc3MzQ0MDYsDQogKiAvLyAgICAgICAgIDEuMTAzOTUyOTMwMzIwNDk1OCwgICAgMC45MzQzMjQxMTk5NjI2NzExLCAgMC4xNzU5MzkxMDY3NzE5OTU1MywNCiAqIC8vICAgICAgICAwLjI0MTMxNTE4OTc4MjY4ODIzLCAgIDAuMDQ5MDY5NDM0MzgzODg0NTMsICAgMC43MDc2OTAyNTY0MTUyMDA2LA0KICogLy8gICAgICAgIC0xMS4xOTU4OTU4MDkzMzI4MTgsICAgIDMuNjMxODMyNjc2NzE2ODI2NywgICAzLjA5MzUzODY1MDg4ODcwMzUsDQogKiAvLyAgICAgICAgIDEuMDQ1MTU1MzQ5OTU2ODEzNiwgICAwLjA3NjgxMTE1MTU5MDI1MTk4LCAgIDAuNTUwMDUyMDk4MTI1MzQxNiwNCiAqIC8vICAgICAgICAgIDIuMTc2OTI4MjA3NzEwMDQ4LCAgLTAuMDQyMzQyNDY4NjUwNDkwNTUsICAwLjAzNjc5MTEzMjI5MzQ4NTc4LA0KICogLy8gICAgICAgIDAuMjcxNzI1OTQ3NzQ4MTM4MTMsICAgIDMuNjMxODMyNjc2NzE2ODE4OCwgIC0yMS44MzM5OTE4MzMzOTc1MjYsDQogKiAvLyAgICAgICAgLTAuMzcwMzU0NDU2NzAzMTc4NCwgICAgMC4xNjMxOTQwNzk3MDg2ODE0LCAgIDAuMTQ3ODQ4NTI4NTMwMjEyMSwNCiAqIC8vICAgICAgICAgMTQuNTkyNjYxMTUzNjQ2MzQ5LCAgICAgMy41Mjk2NDA3NTk2NjA5NDksICAgIDAuODc3MDUxODM5NjMyODg0LA0KICogLy8gICAgICAgLTAuMTE4NDcxMzkzNTI2OTcxMTEsIC0wLjAzMjc1MTMzODMyNzgxOTY4NiwgICAzLjA5MzUzODY1MDg4ODY5ODYsDQogKiAvLyAgICAgICAtMC4zNzAzNTQ0NTY3MDMxODA3MywgICAtMjMuNDI4Mzg1MDU3ODAzNjk1LCAgIDAuODM0NjkwOTA3NTk4NDk1MiwNCiAqIC8vICAgICAgICAgIDMuNjgzODAwNDE1NDg1Nzc4LCAgLTAuMDcwOTQ1Mjg2NTk5NjgxNTIsICAgMTUuNjMwODM0NzgyNzM1NzIyLA0KICogLy8gICAgICAgICAgNS42MTY5NjAzNjIxNzAyMzgsICAgMC4zMTQyMDEyNzY3Mjk4MzI1NiwgICAyLjQwMjE1MTA0Njc3MzQzOTcsDQogKiAvLyAgICAgICAgICAxLjA0NTE1NTM0OTk1NjgxNSwgICAwLjE2MzE5NDA3OTcwODY4NTI3LCAgIDAuODM0NjkwOTA3NTk4NDkyMywNCiAqIC8vICAgICAgICAgLTExLjE1OTY3NjQzNTc0NzI4LCAgIDAuNDc5ODA1MDU3Mjc2MjM5MDcsICAgMC43NTI1MTE5NjM5ODY5NDczLA0KICogLy8gICAgICAgIC0wLjAzOTkwMjAyMTYyNjEzODQsICAgIDEuNjIxNjU5NjM3NDQwMjczOSwgICAxLjk1MzEwNzg4NTQ0Mjk1MzMsDQogKiAvLyAgICAgICAgIDEuMTAzOTUyOTMwMzIwNDk2MiwgICAwLjA3NjgxMTE1MTU5MDI0OTYyLCAgIDAuMTQ3ODQ4NTI4NTMwMjAxMywNCiAqIC8vICAgICAgICAgMy42ODM4MDA0MTU0ODU3OTM1LCAgICAgIDAuNDc5ODA1MDU3Mjc2MjQsICAtMTEuNTk0NTU1OTMwNzUzODM1LA0KICogLy8gICAgICAgICAwLjkyMzcyODQyMTQxNDAyMjYsICAgIDEuODk0Nzg1OTc3MjIyMzMwOCwgMC4wMjc4ODgwMDE2NTE5MTczNzcsDQogKiAvLyAgICAgICAgMC4xNDIxNjM3Nzg1NDA1MzQ3MiwgICAgMC45MzQzMjQxMTk5NjI2NzMyLCAgIDAuNTUwMDUyMDk4MTI1MzQ3NiwNCiAqIC8vICAgICAgICAgMTQuNTkyNjYxMTUzNjQ2MzQ3LCAgIC0wLjA3MDk0NTI4NjU5OTY3MzUsICAgMC43NTI1MTE5NjM5ODY5NDg2LA0KICogLy8gICAgICAgICAwLjkyMzcyODQyMTQxNDAxMTEsICAgLTE4LjI1MTIzMDI0NTY1MzMxOCwgICAgMC44Mzc5NTk2OTMzOTE4MDksDQogKiAvLyAgICAgICAtMC4yMTQxNTg1MzQxNjY1NDY5MywgLTAuMDI2NTAzMTA0NjcyNTE3ODc0LCAgIDAuMTc1OTM5MTA2NzcxOTk4OSwNCiAqIC8vICAgICAgICAgIDIuMTc2OTI4MjA3NzEwMDUzLCAgICAgMy41Mjk2NDA3NTk2NjA5NTIsICAgMTUuNjMwODM0NzgyNzM1NzA0LA0KICogLy8gICAgICAgLTAuMDM5OTAyMDIxNjI2MTM3NDQsICAgICAxLjg5NDc4NTk3NzIyMjM0MywgICAwLjgzNzk1OTY5MzM5MTgxNDgsDQogKiAvLyAgICAgICAgIC0yMy44OTIwNDAxNzE0NTI4MQ0KICogLy8gICAgIF0sDQogKiAvLyAgICAgTTogWw0KICogLy8gICAgICAgMTUuMTA3Nzc1NTI4MTczODAyLA0KICogLy8gICAgICAgLTE3LjUyMzU1MzE2NDAyNDM3LA0KICogLy8gICAgICAgNC45NzQyNzk3Njc2Njg4MjksDQogKiAvLyAgICAgICAtNi4wMTQzNzA4Mzg2MjgzNTksDQogKiAvLyAgICAgICA3LjE3NTA5NTI5NDc4OTQwMiwNCiAqIC8vICAgICAgIC0zLjc1NzI2NTczMzk4MDcxODMsDQogKiAvLyAgICAgICA0LjIxMDkyMDUyMTE1Nzc4OCwNCiAqIC8vICAgICAgIC02LjA2NDMyMzE0Mzg2MzAxMywNCiAqIC8vICAgICAgIC0yLjIyODA3MjQ0NTI5NTI0ODcsDQogKiAvLyAgICAgICA1LjAzNTc4NTM4NTU0OTExNw0KICogLy8gICAgIF0NCiAqIC8vICAgfQ0KICogLy8gfQ0KICoNCiAqLwpmdW5jdGlvbiBpbnRlcnAyS3JpZ2luZyhwc1NyYywgcHNUYXIsIG9wdCA9IHt9KSB7CiAgLy9jaGVjayBwc1NyYwogIGlmICghaXNlYXJyKHBzU3JjKSkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNTcmMgaXMgbm90IGFuIGVmZmVjdGl2ZSBhcnJheScKICAgIH07CiAgfQoKICAvL2NoZWNrIHBzVGFyCiAgaWYgKCFpc2VvYmoocHNUYXIpICYmICFpc2VhcnIocHNUYXIpKSB7CiAgICByZXR1cm4gewogICAgICBlcnI6ICdwc1RhciBpcyBub3QgYW4gZWZmZWN0aXZlIG9iamVjdCBvciBhcnJheScKICAgIH07CiAgfQoKICAvL2lzT25lCiAgbGV0IGlzT25lID0gaXNlb2JqKHBzVGFyKTsKICBpZiAoaXNPbmUpIHsKICAgIHBzVGFyID0gW3BzVGFyXTsKICB9CgogIC8va2V5WAogIGxldCBrZXlYID0gZ2V0KG9wdCwgJ2tleVgnKTsKICBpZiAoIWlzZXN0cihrZXlYKSkgewogICAga2V5WCA9ICd4JzsKICB9CgogIC8va2V5WQogIGxldCBrZXlZID0gZ2V0KG9wdCwgJ2tleVknKTsKICBpZiAoIWlzZXN0cihrZXlZKSkgewogICAga2V5WSA9ICd5JzsKICB9CgogIC8va2V5WgogIGxldCBrZXlaID0gZ2V0KG9wdCwgJ2tleVonKTsKICBpZiAoIWlzZXN0cihrZXlaKSkgewogICAga2V5WiA9ICd6JzsKICB9CgogIC8vc2NhbGUKICBsZXQgc2NhbGUgPSBnZXQob3B0LCAnc2NhbGUnKTsKICBpZiAoIWlzbnVtKHNjYWxlKSkgewogICAgc2NhbGUgPSAxOwogIH0KICBzY2FsZSA9IGNkYmwoc2NhbGUpOwoKICAvL21ldGhvZAogIGxldCBtZXRob2QgPSBnZXQob3B0LCAnbWV0aG9kJyk7CiAgaWYgKG1ldGhvZCAhPT0gJ2ZyaWVkcmljaCcgJiYgbWV0aG9kICE9PSAnaW52YWxsJykgewogICAgbWV0aG9kID0gJ2ZyaWVkcmljaCc7CiAgfQoKICAvL2tyaWdpbmdNb2RlbAogIGxldCBrcmlnaW5nTW9kZWwgPSBnZXQob3B0LCAnbW9kZWwnKTsKICBpZiAoa3JpZ2luZ01vZGVsICE9PSAnZXhwb25lbnRpYWwnICYmIGtyaWdpbmdNb2RlbCAhPT0gJ2dhdXNzaWFuJyAmJiBrcmlnaW5nTW9kZWwgIT09ICdzcGhlcmljYWwnKSB7CiAgICBrcmlnaW5nTW9kZWwgPSAnZXhwb25lbnRpYWwnOwogIH0KCiAgLy9rcmlnaW5nU2lnbWEyCiAgbGV0IGtyaWdpbmdTaWdtYTIgPSBnZXQob3B0LCAnc2lnbWEyJyk7CiAgaWYgKCFpc251bShrcmlnaW5nU2lnbWEyKSkgewogICAga3JpZ2luZ1NpZ21hMiA9IDA7CiAgfQogIGtyaWdpbmdTaWdtYTIgPSBjZGJsKGtyaWdpbmdTaWdtYTIpOwoKICAvL2tyaWdpbmdBbHBoYQogIGxldCBrcmlnaW5nQWxwaGEgPSBnZXQob3B0LCAnYWxwaGEnKTsKICBpZiAoIWlzbnVtKGtyaWdpbmdBbHBoYSkpIHsKICAgIGtyaWdpbmdBbHBoYSA9IDEwMDsKICB9CiAga3JpZ2luZ0FscGhhID0gY2RibChrcmlnaW5nQWxwaGEpOwoKICAvL2xzLCBmcmllZHJpY2jmoLjlh73mlbhsZW5ndGhzY2FsZQogIGxldCBscyA9IGdldChvcHQsICdscycpOwogIGlmICghaXNudW0obHMpKSB7CiAgICBscyA9IDAuNTsKICB9CiAgbHMgPSBjZGJsKGxzKTsKCiAgLy9ub2lzZSwgZnJpZWRyaWNo6KeA5ris5Zmq6Z+z5qiZ5rqW5beuCiAgbGV0IG5vaXNlID0gZ2V0KG9wdCwgJ25vaXNlJyk7CiAgaWYgKCFpc251bShub2lzZSkpIHsKICAgIG5vaXNlID0gMC4wMTsKICB9CiAgbm9pc2UgPSBjZGJsKG5vaXNlKTsKCiAgLy9yZXR1cm5XaXRoVmFyaW9ncmFtCiAgbGV0IHJldHVybldpdGhWYXJpb2dyYW0gPSBnZXQob3B0LCAncmV0dXJuV2l0aFZhcmlvZ3JhbScpOwogIGlmICghaXNib2wocmV0dXJuV2l0aFZhcmlvZ3JhbSkpIHsKICAgIHJldHVybldpdGhWYXJpb2dyYW0gPSBmYWxzZTsKICB9CiAgLy8gY29uc29sZS5sb2coJ3JldHVybldpdGhWYXJpb2dyYW0nLCByZXR1cm5XaXRoVmFyaW9ncmFtKQoKICAvL3B0c1hZWnRvQXJyCiAgcHNTcmMgPSBwdHNYWVp0b0Fycihwc1NyYywgb3B0KTsKCiAgLy9jaGVjayBwc1NyYwogIGlmIChzaXplKHBzU3JjKSA9PT0gMCkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNTcmMgaGFzIG5vIGVmZmVjdGl2ZSBkYXRhJwogICAgfTsKICB9CiAgLy8gY29uc29sZS5sb2coJ3B0c1hZWnRvQXJyIHBzU3JjJywgcHNTcmMpCgogIC8vcHRzWFl0b0FycgogIHBzVGFyID0gcHRzWFl0b0Fycihwc1Rhciwgb3B0KTsKCiAgLy9jaGVjayBwc1RhcgogIGlmIChzaXplKHBzVGFyKSA9PT0gMCkgewogICAgcmV0dXJuIHsKICAgICAgZXJyOiAncHNUYXIgaGFzIG5vIGVmZmVjdGl2ZSBkYXRhJwogICAgfTsKICB9CiAgLy8gY29uc29sZS5sb2coJ3B0c1hZdG9BcnIgcHNUYXInLCBwc1RhcikKCiAgLy9pbnRlcnAyTm9ybWFsaXplCiAgbGV0IGl0bm0gPSBpbnRlcnAyTm9ybWFsaXplKHBzU3JjLCB7CiAgICBzY2FsZQogIH0pOwogIHBzU3JjID0gaXRubS5wczsgLy/opIflr6vmraPopo/ljJbmlbjmk5oKICBsZXQgbnYgPSBpdG5tLm52OwogIGxldCBpbnYgPSBpdG5tLmludjsKCiAgLy9rcEtub3duCiAgbGV0IGtwS25vd24gPSB7fTsKICBmb3JFYWNoKHBzU3JjLCB2ID0+IHsKICAgIGxldCBrID0gYCR7di54fS0ke3YueX1gOyAvL+W3sue2k+iiq+ato+imj+WMluiHs3gseQogICAga3BLbm93bltrXSA9IHYuejsgLy/lt7LntpPooqvmraPopo/ljJboh7N4LHksegogIH0pOwoKICAvL3ZhcmlvZ3JhbSwgcHJlZGljdDog5L6dbWV0aG9k5YiH5o+b5b6M56uv5byV5pOOCiAgbGV0IHZhcmlvZ3JhbSA9IG51bGw7IC8vZnJpZWRyaWNo54Sh5Y2K6K6K55Ww5ZyW5qaC5b+1LCDlm57lgrPmmYLntq3mjIFudWxsCiAgbGV0IHByZWRpY3Q7IC8vKG54LCBueSkgPT4gbnoKICBpZiAobWV0aG9kID09PSAnZnJpZWRyaWNoJykgewogICAgLy9pbnB1dHMsIG91dHB1dHMgKOW3suato+imj+WMlikKICAgIGxldCBpbnB1dHMgPSBbXTsKICAgIGxldCBvdXRwdXRzID0gW107CiAgICBmb3JFYWNoKHBzU3JjLCB2ID0+IHsKICAgICAgaW5wdXRzLnB1c2goW3YueCwgdi55XSk7CiAgICAgIG91dHB1dHMucHVzaCh2LnopOwogICAgfSk7CgogICAgLy9rZXJuZWwsIG1vZGVs5bCN5oeJ5qC45Ye95pW4OiBnYXVzc2lhbi0+U3F1YXJlZEV4cCwg5YW26aSYKOWQq3NwaGVyaWNhbCktPkV4cG9uZW50aWFsCiAgICBsZXQga2VybmVsOwogICAgaWYgKGtyaWdpbmdNb2RlbCA9PT0gJ2dhdXNzaWFuJykgewogICAgICBrZXJuZWwgPSBuZXcgU3F1YXJlZEV4cChscywgMSk7CiAgICB9IGVsc2UgewogICAgICBrZXJuZWwgPSBuZXcgRXhwb25lbnRpYWwobHMsIDEpOwogICAgfQoKICAgIC8vZ3AsIOWbuuWummtlcm5lbOS4jeWBmkFEQU3lhKrljJYo6LOH5paZ5bey5q2j6KaP5YyWLCDlm7rlrppsZW5ndGhzY2FsZeWNs+WQiOeQhikKICAgIGxldCBncCA9IEdhdXNzaWFuUHJvY2Vzcy5idWlsZGVyKGlucHV0cywgb3V0cHV0cykuc2V0S2VybmVsKGtlcm5lbCkuc2V0Tm9pc2Uobm9pc2UpLnRyYWluKCk7CgogICAgLy9wcmVkaWN0CiAgICBwcmVkaWN0ID0gKG54LCBueSkgPT4gZ3AucHJlZGljdChbbngsIG55XSk7CiAgfSBlbHNlIHsKICAgIC8veCwgeSwgdAogICAgbGV0IHggPSBbXTsKICAgIGxldCB5ID0gW107CiAgICBsZXQgdCA9IFtdOwogICAgZm9yRWFjaChwc1NyYywgdiA9PiB7CiAgICAgIHgucHVzaCh2LngpOwogICAgICB5LnB1c2godi55KTsKICAgICAgdC5wdXNoKHYueik7CiAgICB9KTsKCiAgICAvL3ZhcmlvZ3JhbQogICAgdmFyaW9ncmFtID0ga3JpZ2luZy50cmFpbih0LCB4LCB5LCBrcmlnaW5nTW9kZWwsIGtyaWdpbmdTaWdtYTIsIGtyaWdpbmdBbHBoYSk7CiAgICAvLyBjb25zb2xlLmxvZygndmFyaW9ncmFtJywgdmFyaW9ncmFtKQoKICAgIC8vcHJlZGljdAogICAgcHJlZGljdCA9IChueCwgbnkpID0+IGtyaWdpbmcucHJlZGljdChueCwgbnksIHZhcmlvZ3JhbSk7CiAgfQoKICAvL2twZHQKICBsZXQga3BkdCA9IChueCwgbnkpID0+IHsKICAgIC8vY2hlY2sKICAgIGxldCBrID0gYCR7bnh9LSR7bnl9YDsgLy/lt7LntpPooqvmraPopo/ljJboh7N4LHkKICAgIGlmIChoYXNrZXkoa3BLbm93biwgaykpIHsKICAgICAgcmV0dXJuIGtwS25vd25ba107CiAgICB9CgogICAgLy9wcmVkaWN0CiAgICBsZXQgbnogPSBwcmVkaWN0KG54LCBueSk7CgogICAgLy9zYXZlCiAgICBrcEtub3duW2tdID0gbno7CiAgICByZXR1cm4gbno7CiAgfTsKCiAgLy9pdHYKICBsZXQgaXR2ID0gcCA9PiB7CiAgICAvL3gsIG54CiAgICBsZXQgeCA9IHAueDsKICAgIGxldCBueCA9IG52KHgsICd4Jyk7CiAgICBpZiAoIWlzTnVtYmVyKG54KSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgbnhbJHtueH1dYCk7IC8veCx56aCQ5pyf6YO95piv5pyJ5YC8CiAgICB9CgogICAgLy95LCBueQogICAgbGV0IHkgPSBwLnk7CiAgICBsZXQgbnkgPSBudih5LCAneScpOwogICAgaWYgKCFpc051bWJlcihueSkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG55WyR7bnl9XWApOyAvL3gseemgkOacn+mDveaYr+acieWAvAogICAgfQoKICAgIC8vbnosIHoKICAgIGxldCBueiA9IGtwZHQobngsIG55KTsKICAgIGxldCB6ID0gaW52KG56LCAneicpOwogICAgaWYgKCFpc051bWJlcih6KSkgewogICAgICB6ID0gbnVsbDsgLy966aCI5pSv5o+05Y+v6IO954Sh5rOV5YWn5o+SCiAgICB9CgogICAgLy8gY29uc29sZS5sb2coJ3gnLCB4LCAneScsIHksICd6JywgeikKICAgIC8vIGNvbnNvbGUubG9nKCdueCcsIG54LCAnbnknLCBueSwgJ256JywgbnopCgogICAgLy9yCiAgICBsZXQgciA9IHsKICAgICAgW2tleVhdOiB4LAogICAgICBba2V5WV06IHksCiAgICAgIFtrZXlaXTogegogICAgfTsKICAgIHJldHVybiByOwogIH07CgogIC8vcgogIGxldCByOwogIGlmIChpc09uZSkgewogICAgbGV0IHAgPSBwc1RhclswXTsKICAgIHIgPSBpdHYocCk7CiAgfSBlbHNlIHsKICAgIHIgPSBbXTsKICAgIGZvckVhY2gocHNUYXIsIHAgPT4gewogICAgICByLnB1c2goaXR2KHApKTsKICAgIH0pOwogIH0KCiAgLy9yZXR1cm5XaXRoVmFyaW9ncmFtCiAgaWYgKHJldHVybldpdGhWYXJpb2dyYW0pIHsKICAgIHIgPSB7CiAgICAgIHJlc3VsdDogciwKICAgICAgdmFyaW9ncmFtCiAgICB9OwogIH0KICByZXR1cm4gcjsKfQoKLyoqDQogKiDph53lsI3kuI3opo/liYfkuozntq3mlbjmk5rpgLLooYzmjIflrprlhafmj5Lpu57mlbjlgLwNCiAqDQogKiBVbml0IFRlc3Q6IHtAbGluayBodHRwczovL2dpdGh1Yi5jb20veXVkYS1seXUvdy1naXMvYmxvYi9tYXN0ZXIvdGVzdC9pbnRlcnAyLnRlc3QubWpzIEdpdGh1Yn0NCiAqIEBtZW1iZXJPZiB3LWdpcw0KICogQHBhcmFtIHtBcnJheX0gcHNTcmMg6Ly45YWl6bue6Zmj5YiX77yM54K6W3t4OngxLHk6eTF9LHt4OngyLHk6eTJ9LC4uLl3pu57nianku7bkuYvpmaPliJcNCiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBwc1RhciDovLjlhaXpu57pmaPliJfmiJbpu57nianku7bvvIzngrpbe3g6eDEseTp5MX0se3g6eDIseTp5Mn0sLi4uXem7nueJqeS7tuS5i+mZo+WIl++8jOaIlnt4OngxLHk6eTF96bue54mp5Lu2DQogKiBAcGFyYW0ge09iamVjdH0gW29wdD17fV0g6Ly45YWl6Kit5a6a54mp5Lu277yM6aCQ6Kite30NCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0LmtleVg9J3gnXSDovLjlhaXpu57nianku7bkuYt45bqn5qiZ5qyE5L2N5a2X5Liy77yM6aCQ6KitJ3gnDQogKiBAcGFyYW0ge1N0cmluZ30gW29wdC5rZXlZPSd5J10g6Ly45YWl6bue54mp5Lu25LmLeeW6p+aomeashOS9jeWtl+S4su+8jOmgkOiorSd5Jw0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQua2V5Wj0neiddIOi8uOWFpem7nueJqeS7tuS5i3rluqfmqJnmiJblgLzmrITkvY3lrZfkuLLvvIzpoJDoqK0neicNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LnNjYWxlPTFdIOi8uOWFpeato+imj+WMluevhOWcjeaVuOWAvO+8jOWboOiZleeQhuWkmumCiuW9ouaZguacieaVuOWAvOWuueioseiqpOW3ru+8jOaVhemgiOmAmumBjue4ruaUvuWAvOWfn+S+hua4m+WwkeWVj+mhjO+8jOmgkOiorTHmmK/mraPopo/ljJYw6IezMeS5i+mWk++8jOS9v+eUqHNjYWxlWFnliYfmmK/mraPopo/ljJbngrow6Iezc2NhbGVYWeS5i+mWk++8jOmgkOiorTENCiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0Lm1ldGhvZD0nbmF0dXJhbE5laWdoYm9yJ10g6Ly45YWl5YWn5o+S5pa55rOV5a2X5Liy77yM5Y+v6YG4J25hdHVyYWxOZWlnaGJvcifjgIEna3JpZ2luZyfvvIzpoJDoqK0nbmF0dXJhbE5laWdoYm9yJ++8m21ldGhvZD0na3JpZ2luZyfmmYLlkbzlj6tpbnRlcnAyS3JpZ2luZ+S4puWbuuWumuS9v+eUqOWFtmZyaWVkcmljaOW8leaTjijntpNpbnRlcnAy54Sh5rOV6YG455SoaW52YWxs5byV5pOOKQ0KICogQHBhcmFtIHtTdHJpbmd9IFtvcHQubW9kZWw9J2V4cG9uZW50aWFsJ10g6Ly45YWl6IulbWV0aG9kPSdrcmlnaW5nJ+aZguS5i+aguOWHveaVuOWwjeaHieaooeW8j+Wtl+S4su+8jCdnYXVzc2lhbiflsI3mh4lTcXVhcmVkRXhw44CB5YW26aSYKOWQqydleHBvbmVudGlhbCfjgIEnc3BoZXJpY2FsJynlsI3mh4lFeHBvbmVudGlhbO+8jOmgkOiorSdleHBvbmVudGlhbCcNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LmxzPTAuNV0g6Ly45YWl6IulbWV0aG9kPSdrcmlnaW5nJ+aZguS5i2ZyaWVkcmljaOaguOWHveaVuGxlbmd0aHNjYWxl5pW45YC8KOWwjeaHieato+imj+WMluW+jOWAvOWfnynvvIzpoJDoqK0wLjUNCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0Lm5vaXNlPTAuMDFdIOi8uOWFpeiLpW1ldGhvZD0na3JpZ2luZyfmmYLkuYtmcmllZHJpY2jop4DmuKzlmarpn7PmqJnmupblt64o5bCN5oeJ5q2j6KaP5YyW5b6M5YC85Z+fKe+8jOmgkOiorTAuMDENCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LnNpZ21hMj0wXSAo5YOF6IiKaW52YWxs5byV5pOO5LmL5Y2K6K6K55Ww5ZyW5pOs5ZCI5Y+D5pW477yM5ZugaW50ZXJwMuS5i2tyaWdpbmflm7rlrprotbBmcmllZHJpY2jmlYXkuI3nlJ/mlYgpIOi8uOWFpeiHquWLleaTrOWQiOWPg+aVuHNpZ21hMuaVuOWAvO+8jOmgkOiorTANCiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0LmFscGhhPTEwMF0gKOWDheiIimludmFsbOW8leaTjuS5i+WNiuiuiueVsOWcluaTrOWQiOWPg+aVuO+8jOWboGludGVycDLkuYtrcmlnaW5n5Zu65a6a6LWwZnJpZWRyaWNo5pWF5LiN55Sf5pWIKSDovLjlhaXoh6rli5Xmk6zlkIjlj4PmlbhhbHBoYeaVuOWAvO+8jOmgkOiorTEwMA0KICogQHBhcmFtIHtCb29sZWFufSBbb3B0LnJldHVybldpdGhWYXJpb2dyYW09ZmFsc2VdICjlg4XoiIppbnZhbGzlvJXmk47lj4PmlbjvvIzlm6BpbnRlcnAy5LmLa3JpZ2luZ+WbuuWumui1sGZyaWVkcmljaOaVheS4jeeUn+aViO+8jGZyaWVkcmljaOeEoeWNiuiuiueVsOWclikg6Ly45YWl5piv5ZCm5Zue5YKz5pOs5ZCI5Y2K6K6K55Ww5pW457WQ5p6c5biD5p6X5YC877yM6aCQ6KitZmFsc2UNCiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdC51c2VTeW5jPWZhbHNlXSDovLjlhaXmmK/lkKbkvb/nlKjlkIzmraXlh73mlbjluIPmnpflgLzvvIzpoJDoqK1mYWxzZQ0KICogQHJldHVybnMge1Byb21pc2V8QXJyYXl8T2JqZWN0fSDlm57lgrNQcm9taXNl5oiW6bue54mp5Lu26Zmj5YiX5oiW6bue54mp5Lu277yM6IuldXNlU3luYz1mYWxzZeWJh+WbnuWCs1Byb21pc2XvvIxyZXNvbHZl54K65Zue5YKz6bue54mp5Lu26Zmj5YiX5oiW6bue54mp5Lu277yMcmVqZWN054K65aSx5pWX6KiK5oGv77yM6IuldXNlU3luYz10cnVl5YmH5Zue5YKz6bue54mp5Lu26Zmj5YiX5oiW6bue54mp5Lu277yM6Iul55m855Sf6Yyv6Kqk5YmH5Zue5YKz6Yyv6Kqk6KiK5oGv54mp5Lu2DQogKiBAZXhhbXBsZQ0KICoNCiAqIGxldCBwcw0KICogbGV0IHANCiAqIGxldCByDQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyODMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyODMsIHk6IDIwNywgejogMTE0LjQzMDQwNDIxOTUxOTA4IH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAxMTYwLA0KICogICAgIHk6IDM4MCwNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwKQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMTE2MCwgeTogMzgwLCB6OiBudWxsIH0NCiAqDQogKiBwcyA9IFt7IGE6IDI0MywgYjogMjA2LCBjOiA5NSB9LCB7IGE6IDIzMywgYjogMjI1LCBjOiAxNDYgfSwgeyBhOiAyMSwgYjogMzI1LCBjOiAyMiB9LCB7IGE6IDk1MywgYjogMjgsIGM6IDIyMyB9LCB7IGE6IDEwOTIsIGI6IDI5MCwgYzogMzkgfSwgeyBhOiA3NDQsIGI6IDIwMCwgYzogMTkxIH0sIHsgYTogMTc0LCBiOiAzLCBjOiAyMiB9LCB7IGE6IDUzNywgYjogMzY4LCBjOiAyNDkgfSwgeyBhOiAxMTUxLCBiOiAzNzEsIGM6IDg2IH0sIHsgYTogODE0LCBiOiAyNTIsIGM6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICBhOiAyNDMsDQogKiAgICAgYjogMjA3LA0KICogfQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHAsIHsga2V5WDogJ2EnLCBrZXlZOiAnYicsIGtleVo6ICdjJyB9KQ0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgYTogMjQzLCBiOiAyMDcsIGM6IDk3LjI5NDQ3NjgyNDg2ODEzIH0NCiAqDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IFsNCiAqICAgICB7DQogKiAgICAgICAgIHg6IDI0MywNCiAqICAgICAgICAgeTogMjA3LA0KICogICAgIH0sDQogKiAgICAgew0KICogICAgICAgICB4OiAyODMsDQogKiAgICAgICAgIHk6IDIwNywNCiAqICAgICB9LA0KICogXQ0KICogciA9IGF3YWl0IGludGVycDIocHMsIHApDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4gWw0KICogLy8gICB7IHg6IDI0MywgeTogMjA3LCB6OiA5Ny4yOTQ0NzY4MjQ4NjgxMyB9LA0KICogLy8gICB7IHg6IDI4MywgeTogMjA3LCB6OiAxMTQuNDMwNDA0MjE5NTE5MDggfQ0KICogLy8gXQ0KICoNCiAqIHBzID0gW3sgeDogMjQzLCB5OiAyMDYsIHo6IDk1IH0sIHsgeDogMjMzLCB5OiAyMjUsIHo6IDE0NiB9LCB7IHg6IDIxLCB5OiAzMjUsIHo6IDIyIH0sIHsgeDogOTUzLCB5OiAyOCwgejogMjIzIH0sIHsgeDogMTA5MiwgeTogMjkwLCB6OiAzOSB9LCB7IHg6IDc0NCwgeTogMjAwLCB6OiAxOTEgfSwgeyB4OiAxNzQsIHk6IDMsIHo6IDIyIH0sIHsgeDogNTM3LCB5OiAzNjgsIHo6IDI0OSB9LCB7IHg6IDExNTEsIHk6IDM3MSwgejogODYgfSwgeyB4OiA4MTQsIHk6IDI1MiwgejogMTI1IH1dDQogKiBwID0gew0KICogICAgIHg6IDI0MywNCiAqICAgICB5OiAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCwgeyBtZXRob2Q6ICdrcmlnaW5nJyB9KSAvL21ldGhvZD0na3JpZ2luZyfotbBpbnRlcnAyS3JpZ2luZywg6buY6KqNZnJpZWRyaWNo5byV5pOODQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuNDk4NDYyMzUxMDgxMjMgfQ0KICoNCiAqIHBzID0gW3sgeDogMC4wMDAyNDMsIHk6IDAuMDAwMjA2LCB6OiA5NSB9LCB7IHg6IDAuMDAwMjMzLCB5OiAwLjAwMDIyNSwgejogMTQ2IH0sIHsgeDogMC4wMDAwMjEsIHk6IDAuMDAwMzI1LCB6OiAyMiB9LCB7IHg6IDAuMDAwOTUzLCB5OiAwLjAwMDAyOCwgejogMjIzIH0sIHsgeDogMC4wMDEwOTIsIHk6IDAuMDAwMjksIHo6IDM5IH0sIHsgeDogMC4wMDA3NDQsIHk6IDAuMDAwMjAwLCB6OiAxOTEgfSwgeyB4OiAwLjAwMDE3NCwgeTogMC4wMDAwMDMsIHo6IDIyIH0sIHsgeDogMC4wMDA1MzcsIHk6IDAuMDAwMzY4LCB6OiAyNDkgfSwgeyB4OiAwLjAwMTE1MSwgeTogMC4wMDAzNzEsIHo6IDg2IH0sIHsgeDogMC4wMDA4MTQsIHk6IDAuMDAwMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMC4wMDAyNDMsDQogKiAgICAgeTogMC4wMDAyMDcsDQogKiB9DQogKiByID0gYXdhaXQgaW50ZXJwMihwcywgcCkNCiAqIGNvbnNvbGUubG9nKHIpDQogKiAvLyA9PiB7IHg6IDAuMDAwMjQzLCB5OiAwLjAwMDIwNywgejogOTcuMjk0NDc2ODI0ODY3OCB9DQogKg0KICogcHMgPSBbeyB4OiAyNDMsIHk6IDIwNiwgejogOTUgfSwgeyB4OiAyMzMsIHk6IDIyNSwgejogMTQ2IH0sIHsgeDogMjEsIHk6IDMyNSwgejogMjIgfSwgeyB4OiA5NTMsIHk6IDI4LCB6OiAyMjMgfSwgeyB4OiAxMDkyLCB5OiAyOTAsIHo6IDM5IH0sIHsgeDogNzQ0LCB5OiAyMDAsIHo6IDE5MSB9LCB7IHg6IDE3NCwgeTogMywgejogMjIgfSwgeyB4OiA1MzcsIHk6IDM2OCwgejogMjQ5IH0sIHsgeDogMTE1MSwgeTogMzcxLCB6OiA4NiB9LCB7IHg6IDgxNCwgeTogMjUyLCB6OiAxMjUgfV0NCiAqIHAgPSB7DQogKiAgICAgeDogMjQzLA0KICogICAgIHk6IDIwNywNCiAqIH0NCiAqIHIgPSBhd2FpdCBpbnRlcnAyKHBzLCBwLCB7IHNjYWxlOiAxMDAwIH0pDQogKiBjb25zb2xlLmxvZyhyKQ0KICogLy8gPT4geyB4OiAyNDMsIHk6IDIwNywgejogOTcuMjk0NDc2ODI0ODY4NTUgfQ0KICoNCiAqIC8vZm9yIGludGVycDIud2sudW1kLmpzDQogKiBwcyA9IFt7IHg6IDI0MywgeTogMjA2LCB6OiA5NSB9LCB7IHg6IDIzMywgeTogMjI1LCB6OiAxNDYgfSwgeyB4OiAyMSwgeTogMzI1LCB6OiAyMiB9LCB7IHg6IDk1MywgeTogMjgsIHo6IDIyMyB9LCB7IHg6IDEwOTIsIHk6IDI5MCwgejogMzkgfSwgeyB4OiA3NDQsIHk6IDIwMCwgejogMTkxIH0sIHsgeDogMTc0LCB5OiAzLCB6OiAyMiB9LCB7IHg6IDUzNywgeTogMzY4LCB6OiAyNDkgfSwgeyB4OiAxMTUxLCB5OiAzNzEsIHo6IDg2IH0sIHsgeDogODE0LCB5OiAyNTIsIHo6IDEyNSB9XQ0KICogcCA9IHsNCiAqICAgICB4OiAyNDMsDQogKiAgICAgeTogMjA3LA0KICogfQ0KICogciA9IGludGVycDIocHMsIHAsIHsgdXNlU3luYzogdHJ1ZSB9KSAvL+S9v+eUqGludGVycDIud2sudW1kLmpz5YmH5LiN5pSv5o+0c3luY+aooeW8jw0KICogY29uc29sZS5sb2cocikNCiAqIC8vID0+IHsgeDogMjQzLCB5OiAyMDcsIHo6IDk3LjI5NDQ3NjgyNDg2ODEzIH0NCiAqDQogKi8KZnVuY3Rpb24gaW50ZXJwMihwc1NyYywgcHNUYXIsIG9wdCA9IHt9KSB7CiAgLy9tZXRob2QKICBsZXQgbWV0aG9kID0gZ2V0KG9wdCwgJ21ldGhvZCcpOwogIGlmIChtZXRob2QgIT09ICduYXR1cmFsTmVpZ2hib3InICYmIG1ldGhvZCAhPT0gJ2tyaWdpbmcnKSB7CiAgICBtZXRob2QgPSAnbmF0dXJhbE5laWdoYm9yJzsKICB9CgogIC8vdXNlU3luYwogIGxldCB1c2VTeW5jID0gZ2V0KG9wdCwgJ3VzZVN5bmMnKTsKICBpZiAoIWlzYm9sKHVzZVN5bmMpKSB7CiAgICB1c2VTeW5jID0gZmFsc2U7CiAgfQoKICAvL19zeW5jCiAgbGV0IF9zeW5jID0gKCkgPT4gewogICAgbGV0IHIgPSBudWxsOwogICAgdHJ5IHsKICAgICAgaWYgKG1ldGhvZCA9PT0gJ25hdHVyYWxOZWlnaGJvcicpIHsKICAgICAgICByID0gaW50ZXJwMk5hdHVyYWxOZWlnaGJvcihwc1NyYywgcHNUYXIsIG9wdCk7CiAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSAna3JpZ2luZycpIHsKICAgICAgICByID0gaW50ZXJwMktyaWdpbmcocHNTcmMsIHBzVGFyLCBvcHQpOwogICAgICB9CiAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgciA9IHsKICAgICAgICBlcnI6IGVyci50b1N0cmluZygpCiAgICAgIH07CiAgICB9CiAgICByZXR1cm4gcjsKICB9OwoKICAvL19hc3luYwogIGxldCBfYXN5bmMgPSBhc3luYyAoKSA9PiB7CiAgICBsZXQgciA9IG51bGw7CiAgICB0cnkgewogICAgICByID0gX3N5bmMoKTsKICAgICAgbGV0IGVyciA9IGdldChyLCAnZXJyJyk7CiAgICAgIGlmIChpc2VzdHIoZXJyKSkgewogICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiByOwogICAgICB9CiAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgY29uc29sZS5sb2coZXJyKTsKICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVyci50b1N0cmluZygpKTsKICAgIH0KICB9OwogIGlmICh1c2VTeW5jKSB7CiAgICByZXR1cm4gX3N5bmMoKTsKICB9IGVsc2UgewogICAgcmV0dXJuIF9hc3luYygpOwogIH0KfQoKCgpsZXQgaW5zdGFuY2UgPSBudWxsCmZ1bmN0aW9uIGluaXQoaW5wdXQpewoKICAgIC8vaW5pdAogICAgbGV0IHIKICAgIAogICAgICAgIHIgPSB7CiAgICAgICAgICAgIG1haW46IGludGVycDIKICAgICAgICB9CiAgICAgICAgCgogICAgLy9vbgogICAgCgogICAgLy9zYXZlCiAgICBpbnN0YW5jZSA9IHIKCn0KCmZ1bmN0aW9uIHNlbmRNZXNzYWdlKGRhdGEpIHsKICAgIAogICAgICAgIHNlbGYucG9zdE1lc3NhZ2UoZGF0YSkKICAgICAgICAKfQoKYXN5bmMgZnVuY3Rpb24gcnVuKGRhdGEpIHsKICAgIC8vIGNvbnNvbGUubG9nKCdpbm5lciB3b3JrZXIgcnVuJyxkYXRhKQoKICAgIC8vbW9kZQogICAgbGV0IG1vZGUgPSBkYXRhLm1vZGUKCiAgICAvL2NoZWNrCiAgICBpZihtb2RlICE9PSAnaW5pdCcgJiYgbW9kZSAhPT0gJ2NhbGwnKXsKICAgICAgICByZXR1cm4KICAgIH0KCiAgICAvL2luaXQKICAgIGlmKG1vZGUgPT09ICdpbml0Jyl7CiAgICAgICAgCiAgICAgICAgdHJ5ewoKICAgICAgICAgICAgLy90eXBlCiAgICAgICAgICAgIGxldCB0eXBlID0gZGF0YS50eXBlCgogICAgICAgICAgICAvL2lucHV0CiAgICAgICAgICAgIGxldCBpbnB1dCA9IGRhdGEuaW5wdXQKICAgIAogICAgICAgICAgICAvL2luc3RhbmNlCiAgICAgICAgICAgIGlmKHR5cGUgPT09ICdmdW5jdGlvbicpewogICAgICAgICAgICAgICAgaW5pdCguLi5pbnB1dCkKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHR5cGUgPT09ICdvYmplY3QnKXsKICAgICAgICAgICAgICAgIGluc3RhbmNlID0gaW50ZXJwMgogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICAgICBjYXRjaChlcnIpewogICAgICAgIAogICAgICAgICAgICAvL3NlbmRNZXNzYWdlCiAgICAgICAgICAgIGxldCByZXMgPSB7CiAgICAgICAgICAgICAgICBtb2RlOiAnZW1pdCcsCiAgICAgICAgICAgICAgICBldk5hbWU6ICdlcnJvcicsCiAgICAgICAgICAgICAgICBtc2c6IGVyciwKICAgICAgICAgICAgfQogICAgICAgICAgICBzZW5kTWVzc2FnZShyZXMpCgogICAgICAgIH0KICAgICAgICAgICAgCiAgICB9CgogICAgLy9jaGVjawogICAgaWYobW9kZSA9PT0gJ2NhbGwnKXsKICAgICAgICBsZXQgc3RhdGUgPSAnJwogICAgICAgIGxldCBtc2cgPSBudWxsCgogICAgICAgIHRyeXsKCiAgICAgICAgICAgIC8vZnVuCiAgICAgICAgICAgIGxldCBmdW4gPSBpbnN0YW5jZVtkYXRhLmZ1bl0KCiAgICAgICAgICAgIC8vaW5wdXQKICAgICAgICAgICAgbGV0IGlucHV0ID0gZGF0YS5pbnB1dAoKICAgICAgICAgICAgLy9leGVjCiAgICAgICAgICAgIGF3YWl0IGZ1biguLi5pbnB1dCkKICAgICAgICAgICAgICAgIC50aGVuKChzdWMpID0+IHsKICAgICAgICAgICAgICAgICAgICBzdGF0ZT0nc3VjY2VzcycKICAgICAgICAgICAgICAgICAgICBtc2c9c3VjCiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHsKICAgICAgICAgICAgICAgICAgICBzdGF0ZT0nZXJyb3InCiAgICAgICAgICAgICAgICAgICAgbXNnPWVycgogICAgICAgICAgICAgICAgfSkKCiAgICAgICAgfQogICAgICAgIGNhdGNoKGVycil7CiAgICAgICAgICAgIHN0YXRlID0gJ2Vycm9yJwogICAgICAgICAgICBtc2cgPSBlcnIKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy9zZW5kTWVzc2FnZQogICAgICAgIGxldCByZXMgPSB7CiAgICAgICAgICAgIG1vZGU6ICdyZXR1cm4nLAogICAgICAgICAgICBpZDogZGF0YS5pZCwKICAgICAgICAgICAgZnVuOiBkYXRhLmZ1biwKICAgICAgICAgICAgc3RhdGUsCiAgICAgICAgICAgIG1zZywKICAgICAgICB9CiAgICAgICAgc2VuZE1lc3NhZ2UocmVzKQoKICAgIH0KCn0KCmZ1bmN0aW9uIHJlY3ZNZXNzYWdlKGRhdGEpIHsKICAgIC8vIGNvbnNvbGUubG9nKCdpbm5lciB3b3JrZXIgcmVjdjonLCBkYXRhKQoKICAgIC8vZGF0YVJlY3YKICAgIGxldCBkYXRhUmVjdiA9IGRhdGEKCiAgICAvL3J1bgogICAgcnVuKGRhdGFSZWN2KQoKfQoKCiAgICAgICAgc2VsZi5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICByZWN2TWVzc2FnZShlLmRhdGEpCiAgICAgICAgfQogICAgICAgIAoKdHJ5ewoKICAgIC8v5YOF5LuldW5jYXVnaHRFeGNlcHRpb25Nb25pdG9y6KiY6YyELCDkuI3lj6/oqLvlhop1bmNhdWdodEV4Y2VwdGlvbuiIh3VuaGFuZGxlZFJlamVjdGlvbuebo+iBvToKICAgIC8v5pa8d29ya2Vy5YWn6Ki75YaK5q2k5LqM55uj6IG95pyD6Zi75q2iTm9kZemgkOioreeahHdvcmtlcue1guatouihjOeCuiwg5L2/d29ya2Vy5bSp5r2w5b6M5LuN5a2Y5rS756m66L2JLAogICAgLy/lpJblsaTmlLbkuI3liLBlcnJvci9leGl05LqL5Lu2LCBwZW5kaW5nIHByb21pc2XmsLjkuYXmh7jnva4sIOS4lOWtmOa0u+aureWxjXdvcmtlcuacg+S7pOWuv+S4u+eoi+W6j+eEoeazlemAgOWHujsKICAgIC8v56e76Zmk5b6Md29ya2Vy5L6d6aCQ6Kit6KGM54K65q275LqhLCBlcnJvcuS6i+S7tuWCs+iHs+WkluWxpCwg55Sx5aSW5bGk5pW05om5cmVqZWN0IHBlbmRpbmcKICAgIC8vIHByb2Nlc3Mub24oJ3VuaGFuZGxlZFJlamVjdGlvbicsIChlcnIpID0+IHsKICAgIC8vICAgICBjb25zb2xlLmxvZygnaW5uZXI6dW5oYW5kbGVkUmVqZWN0aW9uJywgZXJyKQogICAgLy8gfSkKICAgIC8vIHByb2Nlc3Mub24oJ3VuY2F1Z2h0RXhjZXB0aW9uJywgKGVycikgPT4gewogICAgLy8gICAgIGNvbnNvbGUubG9nKCdpbm5lcjp1bmNhdWdodEV4Y2VwdGlvbicsIGVycikKICAgIC8vIH0pCiAgICBwcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbk1vbml0b3InLCAoZXJyKSA9PiB7CiAgICAgICAgY29uc29sZS5sb2coJ2lubmVyOnVuY2F1Z2h0RXhjZXB0aW9uTW9uaXRvcicsIGVycikKICAgIH0pCgp9CmNhdGNoKGVycil7fQoK`;//code
|
|
395
395
|
let code=b642str(codeB64);function wrapWorker(){//evem
|
|
396
396
|
let ev=evem();//pendings, 呼叫中promise登記表; bDead, worker已死標記(死後呼叫立即reject); bTerminated, 由terminate()主動中止標記(exit事件不視為異常)
|
|
397
397
|
let pendings={};let bDead=false;function emitError(err){//先整批reject pending: 錯誤發生時呼叫端不得永久懸置(pending promise之settle僅靠worker回傳return訊息, worker崩潰即永無回音)
|
|
@@ -439,7 +439,7 @@
|
|
|
439
439
|
// process.on('uncaughtException', (err) => {
|
|
440
440
|
// console.log('outer:uncaughtException', err)
|
|
441
441
|
// })
|
|
442
|
-
process.on('uncaughtExceptionMonitor',err=>{console.log('outer:uncaughtExceptionMonitor',err);});}catch(err){}var ww$1=ww;return ww$1;});})(
|
|
442
|
+
process.on('uncaughtExceptionMonitor',err=>{console.log('outer:uncaughtExceptionMonitor',err);});}catch(err){}var ww$1=ww;return ww$1;});})(tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlIWw);var ww = tempAjh50w45SYSFg9WN6vQUBwa6ajL93PlIWwExports;
|
|
443
443
|
|
|
444
444
|
function isWindow() {
|
|
445
445
|
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|