cacophony 0.5.21 → 0.5.22
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/dist/cacophony.cjs.js +1 -1
- package/dist/cacophony.cjs.js.map +1 -1
- package/dist/cacophony.es.js +5 -6
- package/dist/cacophony.es.js.map +1 -1
- package/dist/cacophony.iife.js +1 -1
- package/dist/cacophony.iife.js.map +1 -1
- package/dist/cacophony.umd.js +1 -1
- package/dist/cacophony.umd.js.map +1 -1
- package/dist/playback.d.ts +4 -5
- package/docs/assets/search.js +1 -1
- package/docs/classes/Cacophony.html +5 -5
- package/docs/classes/Group.html +3 -3
- package/docs/classes/MicrophonePlayback.html +2 -2
- package/docs/classes/MicrophoneStream.html +3 -3
- package/docs/classes/Playback.html +30 -31
- package/docs/classes/Sound.html +18 -18
- package/docs/enums/SoundType.html +2 -2
- package/docs/interfaces/BaseSound.html +2 -2
- package/docs/types/FadeType.html +1 -1
- package/docs/types/LoopCount.html +1 -1
- package/docs/types/Orientation.html +1 -1
- package/docs/types/PanType.html +1 -1
- package/docs/types/Position.html +1 -1
- package/package.json +1 -1
- package/src/playback.ts +13 -10
package/dist/cacophony.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Z=require("standardized-audio-context"),w="data:text/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class W{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],a=Uint8Array.from(atob(t),s=>s.charCodeAt(0));return I.decodeAudioData(a.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class d{_filters=[];addFilter(g){this._filters.push(g)}removeFilter(g){this._filters=this._filters.filter(I=>I!==g)}applyFilters(g){return this._filters.reduce((I,C)=>(I.connect(C),C),g),this._filters.length>0?this._filters[this._filters.length-1]:g}get filters(){return this._filters}addFilters(g){g.forEach(I=>this.addFilter(I))}removeFilters(g){g.forEach(I=>this.removeFilter(I))}}class m{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class h extends d{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");this.source.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(H(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop=()=>{if(!(!this.source||!this.panner)){if(this.loopCount!=="infinite"&&this.currentLoop>this.loopCount){this.playing=!1;return}this.loopCount!=="infinite"&&this.currentLoop++,this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.source.connect(this.panner),this.source.onended=this.handleLoop.bind(this),(this.loopCount==="infinite"||this.currentLoop<=this.loopCount)&&this.source.start(0)):this.seek(0),this.playing=!0}};play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();if(this.stop(),"mediaElement"in this.source&&this.source.mediaElement)this.source.mediaElement.currentTime=g,I&&this.source.mediaElement.play();else if(this.buffer)this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g);else throw new Error("Unsupported source type for seeking")}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this._filters.forEach(g=>{g&&g.disconnect()}),this._filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}else if("loop"in this.source)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.value=I,e.positionY.value=C,e.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}clone(g={}){if(!this.source||!this.gainNode||!this.context)throw new Error("Cannot clone a sound that has been cleaned up");const I=g.panType||this.panType,C=this.context.createGain(),A=g.loopCount!==void 0?g.loopCount:this.loopCount;return new h(this.source,C,this.context,A,I)}}function H(o,g,I){return Math.min(Math.max(o,g),I)}class l extends d{constructor(g,I,C,A,e=p.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(g={}){const I=g.panType||this.panType;g.stereoPan||this.stereoPan;const C=g.threeDOptions||this.threeDOptions,A=g.loopCount||this.loopCount,e=g.playbackRate||this.playbackRate,t=g.volume||this.volume,a=g.position||this.position,s=g.filters||this.filters,n=new l(this.url,this.buffer,this.context,this.globalGainNode,this.type,I);return n.loopCount=A,n._playbackRate=e,n._volume=t,n._position=a,n._threeDOptions=C,n.addFilters(s),n}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new h(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this._filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop()),this.playbacks=[]}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.loop(g)),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const S=(o,g)=>{var I=new Uint8Array(o.byteLength+g.byteLength);return I.set(new Uint8Array(o),0),I.set(new Uint8Array(g),o.byteLength),I.buffer};function D(o,g){const I=[];let C=0;fetch(o).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let a=new ArrayBuffer(0);function s(){return t.read().then(({value:n,done:u})=>{let c=null;if(n){if(a.byteLength?c=S(a,n.buffer):(a=n.buffer.slice(0,44),c=n.buffer),g.decodeAudioData(c,function(r){I.push(r),I.length&&A()},function(r){console.log("err(decodeAudioData): "+r)}),u){console.log("done");return}s()}})}s()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var p=(o=>(o.HTML="HTML",o.Streaming="Streaming",o.Buffer="Buffer",o))(p||{});class K{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new Z.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",w):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new Z.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new Z.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new l("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new l(A,void 0,this.context,this.globalGainNode,"HTML",C)}return W.getAudioBuffer(A,this.context).then(e=>new l(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new m;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new m;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await D(g,this.context),new l(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:a,channelInterpretation:s,panningModel:n,refDistance:u,rolloffFactor:c,positionX:r,positionY:B,positionZ:y,orientationX:X,orientationY:V,orientationZ:R}){const i=this.context.createPanner();return i.coneInnerAngle=g||360,i.coneOuterAngle=I||360,i.coneOuterGain=C||0,i.distanceModel=A||"inverse",i.maxDistance=e||1e4,i.channelCount=t||2,i.channelCountMode=a||"clamped-max",i.channelInterpretation=s||"speakers",i.panningModel=n||"HRTF",i.refDistance=u||1,i.rolloffFactor=c||1,i.positionX.value=r||0,i.positionY.value=B||0,i.positionZ.value=y||0,i.orientationX.value=X||0,i.orientationY.value=V||0,i.orientationZ.value=R||0,i}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new G(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[a,s,n]=C;this.listener.forwardX.value=A,this.listener.forwardY.value=e,this.listener.forwardZ.value=t,this.listener.upX.value=a,this.listener.upY.value=s,this.listener.upZ.value=n}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.value=I,this.listener.upY.value=C,this.listener.upZ.value=A}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.value=I,this.listener.forwardY.value=C,this.listener.forwardZ.value=A}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g,e=this.context.currentTime;this.listener.positionX.setValueAtTime(I,e),this.listener.positionY.setValueAtTime(C,e),this.listener.positionZ.setValueAtTime(A,e)}}class b extends d{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class G extends d{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new b(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}exports.Cacophony=K;exports.Group=m;exports.MicrophonePlayback=b;exports.MicrophoneStream=G;exports.Playback=h;exports.Sound=l;exports.SoundType=p;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Z=require("standardized-audio-context"),w="data:text/javascript;base64,KGZ1bmN0aW9uIChleHBvcnRzKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKICAgIGNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwogICAgLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KICAgIGNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgbmJJbnB1dHM7CiAgICAgICAgbmJPdXRwdXRzOwogICAgICAgIGJsb2NrU2l6ZTsKICAgICAgICBob3BTaXplOwogICAgICAgIG5iT3ZlcmxhcHM7CiAgICAgICAgaW5wdXRCdWZmZXJzID0gW107CiAgICAgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwogICAgICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwogICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKICAgICAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKICAgICAgICB9CiAgICAgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CiAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwogICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gaW5wdXRzW2ldLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChuYkNoYW5uZWxzICE9PSB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGxldCBuYkNoYW5uZWxzID0gb3V0cHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCBuYkNoYW5uZWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZWFkSW5wdXRzKGlucHV0cykgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGxldCB3ZWJBdWRpb0Jsb2NrID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB3ZWJBdWRpb0Jsb2NrLnNldCh0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uc3ViYXJyYXkoMCwgV0VCQVVESU9fQkxPQ0tfU0laRSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0SW5wdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRPdXRwdXRCdWZmZXJzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmNvcHlXaXRoaW4oMCwgV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLmZpbGwoMCwgdGhpcy5ibG9ja1NpemUgLSBXRUJBVURJT19CTE9DS19TSVpFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmlucHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2ldW2pdLnNldCh0aGlzLmlucHV0QnVmZmVyc0hlYWRbaV1bal0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5vdXRwdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB0aGlzLmJsb2NrU2l6ZTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXVtrXSArPSB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW2ldW2pdW2tdIC8gdGhpcy5uYk92ZXJsYXBzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICB0aGlzLnJlYWxsb2NhdGVDaGFubmVsc0lmTmVlZGVkKGlucHV0cywgb3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMucmVhZElucHV0cyhpbnB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0SW5wdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHRoaXMucHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpOwogICAgICAgICAgICB0aGlzLnByb2Nlc3NPTEEodGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmQsIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmUsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICB0aGlzLmhhbmRsZU91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlKCk7CiAgICAgICAgICAgIHRoaXMud3JpdGVPdXRwdXRzKG91dHB1dHMpOwogICAgICAgICAgICB0aGlzLnNoaWZ0T3V0cHV0QnVmZmVycygpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHsKICAgIAlyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdkZWZhdWx0JykgPyB4WydkZWZhdWx0J10gOiB4OwogICAgfQoKICAgIGZ1bmN0aW9uIEZGVChzaXplKSB7CiAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfCAwOwogICAgICBpZiAodGhpcy5zaXplIDw9IDEgfHwgKHRoaXMuc2l6ZSAmICh0aGlzLnNpemUgLSAxKSkgIT09IDApCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGRlQgc2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGFuZCBiaWdnZXIgdGhhbiAxJyk7CgogICAgICB0aGlzLl9jc2l6ZSA9IHNpemUgPDwgMTsKCiAgICAgIC8vIE5PVEU6IFVzZSBvZiBgdmFyYCBpcyBpbnRlbnRpb25hbCBmb3Igb2xkIFY4IHZlcnNpb25zCiAgICAgIHZhciB0YWJsZSA9IG5ldyBBcnJheSh0aGlzLnNpemUgKiAyKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5QSSAqIGkgLyB0aGlzLnNpemU7CiAgICAgICAgdGFibGVbaV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICAgICAgdGFibGVbaSArIDFdID0gLU1hdGguc2luKGFuZ2xlKTsKICAgICAgfQogICAgICB0aGlzLnRhYmxlID0gdGFibGU7CgogICAgICAvLyBGaW5kIHNpemUncyBwb3dlciBvZiB0d28KICAgICAgdmFyIHBvd2VyID0gMDsKICAgICAgZm9yICh2YXIgdCA9IDE7IHRoaXMuc2l6ZSA+IHQ7IHQgPDw9IDEpCiAgICAgICAgcG93ZXIrKzsKCiAgICAgIC8vIENhbGN1bGF0ZSBpbml0aWFsIHN0ZXAncyB3aWR0aDoKICAgICAgLy8gICAqIElmIHdlIGFyZSBmdWxsIHJhZGl4LTQgLSBpdCBpcyAyeCBzbWFsbGVyIHRvIGdpdmUgaW5pdGFsIGxlbj04CiAgICAgIC8vICAgKiBPdGhlcndpc2UgaXQgaXMgdGhlIHNhbWUgYXMgYHBvd2VyYCB0byBnaXZlIGxlbj00CiAgICAgIHRoaXMuX3dpZHRoID0gcG93ZXIgJSAyID09PSAwID8gcG93ZXIgLSAxIDogcG93ZXI7CgogICAgICAvLyBQcmUtY29tcHV0ZSBiaXQtcmV2ZXJzYWwgcGF0dGVybnMKICAgICAgdGhpcy5fYml0cmV2ID0gbmV3IEFycmF5KDEgPDwgdGhpcy5fd2lkdGgpOwogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuX2JpdHJldi5sZW5ndGg7IGorKykgewogICAgICAgIHRoaXMuX2JpdHJldltqXSA9IDA7CiAgICAgICAgZm9yICh2YXIgc2hpZnQgPSAwOyBzaGlmdCA8IHRoaXMuX3dpZHRoOyBzaGlmdCArPSAyKSB7CiAgICAgICAgICB2YXIgcmV2U2hpZnQgPSB0aGlzLl93aWR0aCAtIHNoaWZ0IC0gMjsKICAgICAgICAgIHRoaXMuX2JpdHJldltqXSB8PSAoKGogPj4+IHNoaWZ0KSAmIDMpIDw8IHJldlNoaWZ0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICB9CiAgICB2YXIgZmZ0ID0gRkZUOwoKICAgIEZGVC5wcm90b3R5cGUuZnJvbUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGZyb21Db21wbGV4QXJyYXkoY29tcGxleCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCBuZXcgQXJyYXkoY29tcGxleC5sZW5ndGggPj4+IDEpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXgubGVuZ3RoOyBpICs9IDIpCiAgICAgICAgcmVzW2kgPj4+IDFdID0gY29tcGxleFtpXTsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jcmVhdGVDb21wbGV4QXJyYXkgPSBmdW5jdGlvbiBjcmVhdGVDb21wbGV4QXJyYXkoKSB7CiAgICAgIGNvbnN0IHJlcyA9IG5ldyBBcnJheSh0aGlzLl9jc2l6ZSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKQogICAgICAgIHJlc1tpXSA9IDA7CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudG9Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiB0b0NvbXBsZXhBcnJheShpbnB1dCwgc3RvcmFnZSkgewogICAgICB2YXIgcmVzID0gc3RvcmFnZSB8fCB0aGlzLmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkgKz0gMikgewogICAgICAgIHJlc1tpXSA9IGlucHV0W2kgPj4+IDFdOwogICAgICAgIHJlc1tpICsgMV0gPSAwOwogICAgICB9CiAgICAgIHJldHVybiByZXM7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUuY29tcGxldGVTcGVjdHJ1bSA9IGZ1bmN0aW9uIGNvbXBsZXRlU3BlY3RydW0oc3BlY3RydW0pIHsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKICAgICAgdmFyIGhhbGYgPSBzaXplID4+PiAxOwogICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGhhbGY7IGkgKz0gMikgewogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpXSA9IHNwZWN0cnVtW2ldOwogICAgICAgIHNwZWN0cnVtW3NpemUgLSBpICsgMV0gPSAtc3BlY3RydW1baSArIDFdOwogICAgICB9CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLnJlYWxUcmFuc2Zvcm0gPSBmdW5jdGlvbiByZWFsVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAwOwogICAgICB0aGlzLl9yZWFsVHJhbnNmb3JtNCgpOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5pbnZlcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24gaW52ZXJzZVRyYW5zZm9ybShvdXQsIGRhdGEpIHsKICAgICAgaWYgKG91dCA9PT0gZGF0YSkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKICAgICAgdGhpcy5fb3V0ID0gb3V0OwogICAgICB0aGlzLl9kYXRhID0gZGF0YTsKICAgICAgdGhpcy5faW52ID0gMTsKICAgICAgdGhpcy5fdHJhbnNmb3JtNCgpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykKICAgICAgICBvdXRbaV0gLz0gdGhpcy5zaXplOwogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgIH07CgogICAgLy8gcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IFVzZXMgb2YgYHZhcmAgYXJlIGludGVudGlvbmFsIGZvciBvbGRlciBWOCB2ZXJzaW9uIHRoYXQgZG8gbm90CiAgICAvLyBzdXBwb3J0IGJvdGggYGxldCBjb21wb3VuZCBhc3NpZ25tZW50c2AgYW5kIGBjb25zdCBwaGlgCiAgICBGRlQucHJvdG90eXBlLl90cmFuc2Zvcm00ID0gZnVuY3Rpb24gX3RyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbGVuID09PSA4CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLCBzdGVwKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gbGVuID4+PiAyOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgLy8gRnVsbCBjYXNlCiAgICAgICAgICB2YXIgbGltaXQgPSBvdXRPZmYgKyBxdWFydGVyTGVuOwogICAgICAgICAgZm9yICh2YXIgaSA9IG91dE9mZiwgayA9IDA7IGkgPCBsaW1pdDsgaSArPSAyLCBrICs9IHN0ZXApIHsKICAgICAgICAgICAgY29uc3QgQSA9IGk7CiAgICAgICAgICAgIGNvbnN0IEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgY29uc3QgQyA9IEIgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIGNvbnN0IEFpID0gb3V0W0EgKyAxXTsKICAgICAgICAgICAgY29uc3QgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIGNvbnN0IEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgY29uc3QgQ3IgPSBvdXRbQ107CiAgICAgICAgICAgIGNvbnN0IENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgY29uc3QgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIGNvbnN0IERpID0gb3V0W0QgKyAxXTsKCiAgICAgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgTUFyID0gQXI7CiAgICAgICAgICAgIGNvbnN0IE1BaSA9IEFpOwoKICAgICAgICAgICAgY29uc3QgdGFibGVCciA9IHRhYmxlW2tdOwogICAgICAgICAgICBjb25zdCB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICBjb25zdCBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIGNvbnN0IE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CiAgICAgICAgICAgIGNvbnN0IE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIGNvbnN0IHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwogICAgICAgICAgICBjb25zdCBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIGNvbnN0IE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgVDByID0gTUFyICsgTUNyOwogICAgICAgICAgICBjb25zdCBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgY29uc3QgVDFpID0gTUFpIC0gTUNpOwogICAgICAgICAgICBjb25zdCBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIGNvbnN0IFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgY29uc3QgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CiAgICAgICAgICAgIGNvbnN0IFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKICAgICAgICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICAgICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgICAgICAgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKICAgICAgICAgICAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CiAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKICAgICAgICAgICAgb3V0W0RdID0gRkRyOwogICAgICAgICAgICBvdXRbRCArIDFdID0gRkRpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IGV2ZW5JID0gZGF0YVtvZmYgKyAxXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IG9kZEkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKCiAgICAgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwogICAgICBjb25zdCBsZWZ0SSA9IGV2ZW5JICsgb2RkSTsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwogICAgICBjb25zdCByaWdodEkgPSBldmVuSSAtIG9kZEk7CgogICAgICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBsZWZ0STsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSByaWdodEk7CiAgICB9OwoKICAgIC8vIHJhZGl4LTQKICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQWkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CiAgICAgIGNvbnN0IEJpID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CiAgICAgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CiAgICAgIGNvbnN0IENpID0gZGF0YVtvZmYgKyBzdGVwMiArIDFdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwogICAgICBjb25zdCBEaSA9IGRhdGFbb2ZmICsgc3RlcDMgKyAxXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDBpID0gQWkgKyBDaTsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDFpID0gQWkgLSBDaTsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDJpID0gQmkgKyBEaTsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwogICAgICBjb25zdCBUM2kgPSBpbnYgKiAoQmkgLSBEaSk7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICBjb25zdCBGQnIgPSBUMXIgKyBUM2k7CiAgICAgIGNvbnN0IEZCaSA9IFQxaSAtIFQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gRkFpOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKICAgICAgb3V0W291dE9mZiArIDRdID0gRkNyOwogICAgICBvdXRbb3V0T2ZmICsgNV0gPSBGQ2k7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICAvLyBSZWFsIGlucHV0IHJhZGl4LTQgaW1wbGVtZW50YXRpb24KICAgIEZGVC5wcm90b3R5cGUuX3JlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3JlYWxUcmFuc2Zvcm00KCkgewogICAgICB2YXIgb3V0ID0gdGhpcy5fb3V0OwogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKICAgICAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCiAgICAgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwogICAgICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CiAgICAgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgogICAgICB2YXIgb3V0T2ZmOwogICAgICB2YXIgdDsKICAgICAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKICAgICAgaWYgKGxlbiA9PT0gNCkgewogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIExvb3AgdGhyb3VnaCBzdGVwcyBpbiBkZWNyZWFzaW5nIG9yZGVyCiAgICAgIHZhciBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIHZhciB0YWJsZSA9IHRoaXMudGFibGU7CiAgICAgIGZvciAoc3RlcCA+Pj0gMjsgc3RlcCA+PSAyOyBzdGVwID4+PSAyKSB7CiAgICAgICAgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwogICAgICAgIHZhciBoYWxmTGVuID0gbGVuID4+PiAxOwogICAgICAgIHZhciBxdWFydGVyTGVuID0gaGFsZkxlbiA+Pj4gMTsKICAgICAgICB2YXIgaHF1YXJ0ZXJMZW4gPSBxdWFydGVyTGVuID4+PiAxOwoKICAgICAgICAvLyBMb29wIHRocm91Z2ggb2Zmc2V0cyBpbiB0aGUgZGF0YQogICAgICAgIGZvciAob3V0T2ZmID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbikgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGsgPSAwOyBpIDw9IGhxdWFydGVyTGVuOyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICB2YXIgQSA9IG91dE9mZiArIGk7CiAgICAgICAgICAgIHZhciBCID0gQSArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIHZhciBEID0gQyArIHF1YXJ0ZXJMZW47CgogICAgICAgICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEFyID0gb3V0W0FdOwogICAgICAgICAgICB2YXIgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICB2YXIgQnIgPSBvdXRbQl07CiAgICAgICAgICAgIHZhciBCaSA9IG91dFtCICsgMV07CiAgICAgICAgICAgIHZhciBDciA9IG91dFtDXTsKICAgICAgICAgICAgdmFyIENpID0gb3V0W0MgKyAxXTsKICAgICAgICAgICAgdmFyIERyID0gb3V0W0RdOwogICAgICAgICAgICB2YXIgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICB2YXIgTUFyID0gQXI7CiAgICAgICAgICAgIHZhciBNQWkgPSBBaTsKCiAgICAgICAgICAgIHZhciB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIHZhciB0YWJsZUJpID0gaW52ICogdGFibGVbayArIDFdOwogICAgICAgICAgICB2YXIgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwogICAgICAgICAgICB2YXIgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgdmFyIHRhYmxlQ3IgPSB0YWJsZVsyICoga107CiAgICAgICAgICAgIHZhciB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgdmFyIE1DaSA9IENyICogdGFibGVDaSArIENpICogdGFibGVDcjsKCiAgICAgICAgICAgIHZhciB0YWJsZURyID0gdGFibGVbMyAqIGtdOwogICAgICAgICAgICB2YXIgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIHZhciBNRHIgPSBEciAqIHRhYmxlRHIgLSBEaSAqIHRhYmxlRGk7CiAgICAgICAgICAgIHZhciBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgogICAgICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIHZhciBUMGkgPSBNQWkgKyBNQ2k7CiAgICAgICAgICAgIHZhciBUMXIgPSBNQXIgLSBNQ3I7CiAgICAgICAgICAgIHZhciBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIHZhciBUMnIgPSBNQnIgKyBNRHI7CiAgICAgICAgICAgIHZhciBUMmkgPSBNQmkgKyBNRGk7CiAgICAgICAgICAgIHZhciBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgdmFyIFQzaSA9IGludiAqIChNQmkgLSBNRGkpOwoKICAgICAgICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgICAgICAgIHZhciBGQXIgPSBUMHIgKyBUMnI7CiAgICAgICAgICAgIHZhciBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICB2YXIgRkJyID0gVDFyICsgVDNpOwogICAgICAgICAgICB2YXIgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgb3V0W0FdID0gRkFyOwogICAgICAgICAgICBvdXRbQSArIDFdID0gRkFpOwogICAgICAgICAgICBvdXRbQl0gPSBGQnI7CiAgICAgICAgICAgIG91dFtCICsgMV0gPSBGQmk7CgogICAgICAgICAgICAvLyBPdXRwdXQgZmluYWwgbWlkZGxlIHBvaW50CiAgICAgICAgICAgIGlmIChpID09PSAwKSB7CiAgICAgICAgICAgICAgdmFyIEZDciA9IFQwciAtIFQycjsKICAgICAgICAgICAgICB2YXIgRkNpID0gVDBpIC0gVDJpOwogICAgICAgICAgICAgIG91dFtDXSA9IEZDcjsKICAgICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcndyaXRlIG91cnNlbHZlcwogICAgICAgICAgICBpZiAoaSA9PT0gaHF1YXJ0ZXJMZW4pCiAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBJbiB0aGUgZmxpcHBlZCBjYXNlOgogICAgICAgICAgICAvLyBNQWkgPSAtTUFpCiAgICAgICAgICAgIC8vIE1Ccj0tTUJpLCBNQmk9LU1CcgogICAgICAgICAgICAvLyBNQ3I9LU1DcgogICAgICAgICAgICAvLyBNRHI9TURpLCBNRGk9TURyCiAgICAgICAgICAgIHZhciBTVDByID0gVDFyOwogICAgICAgICAgICB2YXIgU1QwaSA9IC1UMWk7CiAgICAgICAgICAgIHZhciBTVDFyID0gVDByOwogICAgICAgICAgICB2YXIgU1QxaSA9IC1UMGk7CiAgICAgICAgICAgIHZhciBTVDJyID0gLWludiAqIFQzaTsKICAgICAgICAgICAgdmFyIFNUMmkgPSAtaW52ICogVDNyOwogICAgICAgICAgICB2YXIgU1QzciA9IC1pbnYgKiBUMmk7CiAgICAgICAgICAgIHZhciBTVDNpID0gLWludiAqIFQycjsKCiAgICAgICAgICAgIHZhciBTRkFyID0gU1QwciArIFNUMnI7CiAgICAgICAgICAgIHZhciBTRkFpID0gU1QwaSArIFNUMmk7CgogICAgICAgICAgICB2YXIgU0ZCciA9IFNUMXIgKyBTVDNpOwogICAgICAgICAgICB2YXIgU0ZCaSA9IFNUMWkgLSBTVDNyOwoKICAgICAgICAgICAgdmFyIFNBID0gb3V0T2ZmICsgcXVhcnRlckxlbiAtIGk7CiAgICAgICAgICAgIHZhciBTQiA9IG91dE9mZiArIGhhbGZMZW4gLSBpOwoKICAgICAgICAgICAgb3V0W1NBXSA9IFNGQXI7CiAgICAgICAgICAgIG91dFtTQSArIDFdID0gU0ZBaTsKICAgICAgICAgICAgb3V0W1NCXSA9IFNGQnI7CiAgICAgICAgICAgIG91dFtTQiArIDFdID0gU0ZCaTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH07CgogICAgLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTIob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoKICAgICAgY29uc3QgZXZlblIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKICAgICAgb3V0W291dE9mZiArIDNdID0gMDsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlUmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewogICAgICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CiAgICAgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CiAgICAgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgogICAgICAvLyBPcmlnaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgQXIgPSBkYXRhW29mZl07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCiAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgVDByID0gQXIgKyBDcjsKICAgICAgY29uc3QgVDFyID0gQXIgLSBDcjsKICAgICAgY29uc3QgVDJyID0gQnIgKyBEcjsKICAgICAgY29uc3QgVDNyID0gaW52ICogKEJyIC0gRHIpOwoKICAgICAgLy8gRmluYWwgdmFsdWVzCiAgICAgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCiAgICAgIGNvbnN0IEZCciA9IFQxcjsKICAgICAgY29uc3QgRkJpID0gLVQzcjsKCiAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCiAgICAgIGNvbnN0IEZEciA9IFQxcjsKICAgICAgY29uc3QgRkRpID0gVDNyOwoKICAgICAgb3V0W291dE9mZl0gPSBGQXI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IDA7CiAgICAgIG91dFtvdXRPZmYgKyA2XSA9IEZEcjsKICAgICAgb3V0W291dE9mZiArIDddID0gRkRpOwogICAgfTsKCiAgICB2YXIgRkZUJDEgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoZmZ0KTsKCiAgICBjb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKICAgIGZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CiAgICAgICAgbGV0IHdpbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHdpbltpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoMiAqIE1hdGguUEkgKiBpIC8gbGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB3aW47CiAgICB9CiAgICBjbGFzcyBQaGFzZVZvY29kZXJQcm9jZXNzb3IgZXh0ZW5kcyBPTEFQcm9jZXNzb3IgewogICAgICAgIGZmdFNpemU7CiAgICAgICAgdGltZUN1cnNvcjsKICAgICAgICBoYW5uV2luZG93OwogICAgICAgIGZmdDsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlcjsKICAgICAgICBmcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQ7CiAgICAgICAgdGltZUNvbXBsZXhCdWZmZXI7CiAgICAgICAgbWFnbml0dWRlczsKICAgICAgICBwZWFrSW5kZXhlczsKICAgICAgICBuYlBlYWtzOwogICAgICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBbewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwaXRjaEZhY3RvcicsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAKICAgICAgICAgICAgICAgIH1dOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwogICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgIH0KICAgICAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewogICAgICAgICAgICAvLyBAdHMtaWdub3JlCiAgICAgICAgICAgIGNvbnN0IHBpdGNoRmFjdG9yID0gcGFyYW1ldGVycy5waXRjaEZhY3RvcltwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yLmxlbmd0aCAtIDFdOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJJbnB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dHNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3coaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmZ0LnJlYWxUcmFuc2Zvcm0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlciwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHV0ZU1hZ25pdHVkZXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRQZWFrcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRQZWFrcyhwaXRjaEZhY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuY29tcGxldGVTcGVjdHJ1bSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuaW52ZXJzZVRyYW5zZm9ybSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQuZnJvbUNvbXBsZXhBcnJheSh0aGlzLnRpbWVDb21wbGV4QnVmZmVyLCBvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KG91dHB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy50aW1lQ3Vyc29yICs9IHRoaXMuaG9wU2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGFwcGx5SGFubldpbmRvdyhpbnB1dCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlucHV0W2ldICo9IHRoaXMuaGFubldpbmRvd1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wdXRlTWFnbml0dWRlcygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgdGhpcy5tYWduaXR1ZGVzLmxlbmd0aDsgaSsrLCBqICs9IDIpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2pdOwogICAgICAgICAgICAgICAgY29uc3QgaW1hZyA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaiArIDFdOwogICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2ldID0gcmVhbCAqKiAyICsgaW1hZyAqKiAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmRQZWFrcygpIHsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDIsIGVuZCA9IHRoaXMubWFnbml0dWRlcy5sZW5ndGggLSAyOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1hZyA9IHRoaXMubWFnbml0dWRlc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hZ25pdHVkZXNbaSAtIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fCB0aGlzLm1hZ25pdHVkZXNbaSArIDJdID49IG1hZykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5wZWFrSW5kZXhlc1t0aGlzLm5iUGVha3MrK10gPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQuZmlsbCgwKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iUGVha3M7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4ID0gdGhpcy5wZWFrSW5kZXhlc1tpXTsKICAgICAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleFNoaWZ0ZWQgPSBNYXRoLnJvdW5kKHBlYWtJbmRleCAqIHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgIGlmIChwZWFrSW5kZXhTaGlmdGVkID4gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAoaSA+IDApID8gcGVha0luZGV4IC0gTWF0aC5mbG9vcigocGVha0luZGV4IC0gdGhpcy5wZWFrSW5kZXhlc1tpIC0gMV0pIC8gMikgOiAwOwogICAgICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gKGkgPCB0aGlzLm5iUGVha3MgLSAxKSA/IHBlYWtJbmRleCArIE1hdGguY2VpbCgodGhpcy5wZWFrSW5kZXhlc1tpICsgMV0gLSBwZWFrSW5kZXgpIC8gMikgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gMiAqIE1hdGguUEkgKiAoYmluSW5kZXhTaGlmdGVkIC0gYmluSW5kZXgpIC8gdGhpcy5mZnRTaXplOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBAdHMtaWdub3JlCiAgICByZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7CiAgICBjb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCiAgICBleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsK";class W{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static async getAudioBufferFromCache(g,I,C){try{const A=await I.match(g);if(A){const e=await A.arrayBuffer();return C.decodeAudioData(e)}return null}catch(A){throw console.error("Failed to get audio data from cache:",A),A}}static async fetchAndCacheAudioBuffer(g,I,C){try{const A=await fetch(g),e=A.clone();I.put(g,e);const t=await A.arrayBuffer();return C.decodeAudioData(t)}catch(A){throw console.error("Failed to fetch and cache audio data:",A),A}}static async getAudioBuffer(g,I){if(g.startsWith("data:")){const t=g.split(",")[1],a=Uint8Array.from(atob(t),s=>s.charCodeAt(0));return I.decodeAudioData(a.buffer)}const C=await this.openCache();let A=this.pendingRequests.get(g);if(A)return A;const e=await this.getAudioBufferFromCache(g,C,I);return e||(A=this.fetchAndCacheAudioBuffer(g,C,I),this.pendingRequests.set(g,A),A)}}class d{_filters=[];addFilter(g){this._filters.push(g)}removeFilter(g){this._filters=this._filters.filter(I=>I!==g)}applyFilters(g){return this._filters.reduce((I,C)=>(I.connect(C),C),g),this._filters.length>0?this._filters[this._filters.length-1]:g}get filters(){return this._filters}addFilters(g){g.forEach(I=>this.addFilter(I))}removeFilters(g){g.forEach(I=>this.removeFilter(I))}}class m{sounds=[];_position=[0,0,0];loopCount=0;playIndex=0;playRandom(){if(this.sounds.length===0)throw new Error("Cannot play a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length),C=this.sounds[g].preplay();return C.forEach(A=>A.play()),C[0]}playOrdered(g=!0){if(this.sounds.length===0)throw new Error("Cannot play an ordered sound from an empty group");const C=this.sounds[this.playIndex].preplay();return C.forEach(A=>A.play()),this.playIndex++,this.playIndex>=this.sounds.length&&(g?this.playIndex=0:this.playIndex=this.sounds.length),C[0]}get duration(){return this.sounds.map(g=>g.duration).reduce((g,I)=>Math.max(g,I),0)}seek(g){this.sounds.forEach(I=>I.seek&&I.seek(g))}addSound(g){this.sounds.push(g)}preplay(){return this.sounds.reduce((g,I)=>(I.loop&&I.loop(this.loopCount),g.concat(I.preplay())),[])}play(){return this.preplay().map(g=>(g.play(),g))}isPlaying(){return this.sounds.some(g=>g.isPlaying())}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}resume(){this.sounds.forEach(g=>g.resume())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(I=>I.loop&&I.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(I=>I.addFilter(g))}removeFilter(g){this.sounds.forEach(I=>I.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(I=>I.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,I)=>g+I,0)/this.sounds.length}set volume(g){this.sounds.forEach(I=>I.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(I=>I.playbackRate=g)}}class h extends d{constructor(g,I,C,A=0,e="HRTF"){if(super(),this.panType=e,this.loopCount=A,this.panType=e,this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),"mediaElement"in g&&g.mediaElement?g.mediaElement.onended=this.handleLoop.bind(this):"onended"in g&&(g.onended=this.handleLoop.bind(this)),this.gainNode=I,this.context=C,this.panType==="HRTF")this.panner=C.createPanner();else if(this.panType==="stereo")this.panner=C.createStereoPanner();else throw new Error("Invalid pan type");this.source.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");this.panner.pan.setValueAtTime(H(g,-1,1),this.context.currentTime)}get duration(){if(!this.buffer)throw new Error("Cannot get duration of a sound that has been cleaned up");return this.buffer.duration}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(g){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g)}handleLoop=()=>{if(!(!this.source||!this.panner)){if(this.loopCount!=="infinite"&&this.currentLoop>this.loopCount){this.stop();return}this.loopCount!=="infinite"&&this.currentLoop++,this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.source.connect(this.panner),this.source.onended=this.handleLoop.bind(this),(this.loopCount==="infinite"||this.currentLoop<=this.loopCount)&&this.source.start(0)):this.seek(0)}};play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const I=this.panner;I.coneInnerAngle=g.coneInnerAngle||I.coneInnerAngle,I.coneOuterAngle=g.coneOuterAngle||I.coneOuterAngle,I.coneOuterGain=g.coneOuterGain||I.coneOuterGain,I.distanceModel=g.distanceModel||I.distanceModel,I.maxDistance=g.maxDistance||I.maxDistance,I.channelCount=g.channelCount||I.channelCount,I.channelCountMode=g.channelCountMode||I.channelCountMode,I.channelInterpretation=g.channelInterpretation||I.channelInterpretation,I.panningModel=g.panningModel||I.panningModel,I.refDistance=g.refDistance||I.refDistance,I.rolloffFactor=g.rolloffFactor||I.rolloffFactor,I.positionX.value=g.positionX||I.positionX.value,I.positionY.value=g.positionY||I.positionY.value,I.positionZ.value=g.positionZ||I.positionZ.value,I.orientationX.value=g.orientationX||I.orientationX.value,I.orientationY.value=g.orientationY||I.orientationY.value,I.orientationZ.value=g.orientationZ||I.orientationZ.value}seek(g){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const I=this.isPlaying();if(this.stop(),"mediaElement"in this.source&&this.source.mediaElement)this.source.mediaElement.currentTime=g,I&&this.source.mediaElement.play();else if(this.buffer)this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),I&&this.source.start(0,g);else throw new Error("Unsupported source type for seeking")}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}fadeIn(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const A=1;switch(this.gainNode.gain.value=0,I){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(A,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(A,this.context.currentTime+g);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=A,C()},g*1e3)})}fadeOut(g,I="linear"){return new Promise(C=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,I){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+g);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+g)}setTimeout(()=>C(),g*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?!this.source.mediaElement.paused:"playbackState"in this.source?this.source.playbackState==="running":!1}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this._filters.forEach(g=>{g&&g.disconnect()}),this._filters=[]}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if("mediaElement"in this.source&&this.source.mediaElement){const I=this.source.mediaElement;return g===void 0||(I.loop=!0),I.loop===!0?"infinite":0}else if("loop"in this.source)return g===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0))}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[I,C,A]=g,e=this.panner;e.positionX.value=I,e.positionY.value=C,e.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}clone(g={}){if(!this.source||!this.gainNode||!this.context)throw new Error("Cannot clone a sound that has been cleaned up");const I=g.panType||this.panType,C=this.context.createGain(),A=g.loopCount!==void 0?g.loopCount:this.loopCount;return new h(this.source,C,this.context,A,I)}}function H(o,g,I){return Math.min(Math.max(o,g),I)}class l extends d{constructor(g,I,C,A,e=p.Buffer,t="HRTF"){super(),this.url=g,this.type=e,this.panType=t,this.buffer=I,this.context=C,this.globalGainNode=A}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;clone(g={}){const I=g.panType||this.panType;g.stereoPan||this.stereoPan;const C=g.threeDOptions||this.threeDOptions,A=g.loopCount||this.loopCount,e=g.playbackRate||this.playbackRate,t=g.volume||this.volume,a=g.position||this.position,s=g.filters||this.filters,n=new l(this.url,this.buffer,this.context,this.globalGainNode,this.type,I);return n.loopCount=A,n._playbackRate=e,n._volume=t,n._position=a,n._threeDOptions=C,n.addFilters(s),n}preplay(){let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const A=new Audio;A.crossOrigin="anonymous",A.src=this.url,A.preload="auto",g=this.context.createMediaElementSource(A)}const I=this.context.createGain();I.connect(this.globalGainNode);const C=new h(g,I,this.context,this.loopCount,this.panType);return C.volume=this.volume,C.playbackRate=this.playbackRate,this._filters.forEach(A=>C.addFilter(A)),this.panType==="HRTF"?(C.threeDOptions=this.threeDOptions,C.position=this.position):this.panType==="stereo"&&(C.stereoPan=this.stereoPan),this.playbacks.push(C),[C]}play(){const g=this.preplay();return g.forEach(I=>I.play()),g}stop(){this.playbacks.forEach(g=>g.stop()),this.playbacks=[]}pause(){this.playbacks.forEach(g=>g.pause())}resume(){this.playbacks.forEach(g=>g.resume())}seek(g){this.playbacks.forEach(I=>I.seek(g))}get duration(){return this.buffer?.duration||0}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(I=>I.position=g)}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(I=>I.stereoPan=g)}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(I=>I.loop(g)),this.loopCount)}addFilter(g){super.addFilter(g),this.playbacks.forEach(I=>I.addFilter(g))}removeFilter(g){super.removeFilter(g),this.playbacks.forEach(I=>I.removeFilter(g))}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(I=>I.volume=g)}isPlaying(){return this.playbacks.some(g=>g.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(I=>I.playbackRate=g)}}const S=(o,g)=>{var I=new Uint8Array(o.byteLength+g.byteLength);return I.set(new Uint8Array(o),0),I.set(new Uint8Array(g),o.byteLength),I.buffer};function D(o,g){const I=[];let C=0;fetch(o).then(function(e){if(!e.ok)throw new Error("HTTP error, status = "+e.status);if(!e.body)throw new Error("Missing body");var t=e.body.getReader();let a=new ArrayBuffer(0);function s(){return t.read().then(({value:n,done:u})=>{let c=null;if(n){if(a.byteLength?c=S(a,n.buffer):(a=n.buffer.slice(0,44),c=n.buffer),g.decodeAudioData(c,function(r){I.push(r),I.length&&A()},function(r){console.log("err(decodeAudioData): "+r)}),u){console.log("done");return}s()}})}s()});function A(){for(;I.length;){let e=I.shift();const t=g.createBufferSource();if(!e)return;t.buffer=e,t.connect(g.destination),C==0&&(C=g.currentTime+.02),t.start(C),C+=t.buffer.duration}}}var p=(o=>(o.HTML="HTML",o.Streaming="Streaming",o.Buffer="Buffer",o))(p||{});class K{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(g){this.context=g||new Z.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(I=>{I.cleanup()})}async loadWorklets(){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",w):console.warn("AudioWorklet not supported")}async createWorkletNode(g,I){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new Z.AudioWorkletNode(this.context,g)}catch(C){console.error(C),console.log("Loading worklet from url",I);try{await this.context.audioWorklet.addModule(I)}catch(A){throw console.error(A),new Error(`Could not load worklet from url ${I}`)}return new Z.AudioWorkletNode(this.context,g)}}createOscillator=({frequency:g,type:I,periodicWave:C})=>{g===void 0&&(g=440);const A=this.context.createOscillator();return A.type=I||"sine",C&&A.setPeriodicWave(C),A.frequency.setValueAtTime(g,this.context.currentTime),A.connect(this.globalGainNode),A};async createSound(g,I="Buffer",C="HRTF"){if(g instanceof AudioBuffer)return Promise.resolve(new l("",g,this.context,this.globalGainNode,"Buffer",C));const A=g;if(I==="HTML"){const e=new Audio;return e.src=A,e.crossOrigin="anonymous",new l(A,void 0,this.context,this.globalGainNode,"HTML",C)}return W.getAudioBuffer(A,this.context).then(e=>new l(A,e,this.context,this.globalGainNode,I,C))}async createGroup(g){const I=new m;return g.forEach(C=>I.addSound(C)),I}async createGroupFromUrls(g,I="Buffer",C="HRTF"){const A=new m;return(await Promise.all(g.map(t=>this.createSound(t,I,C)))).forEach(t=>A.addSound(t)),A}async createStream(g){return await D(g,this.context),new l(g,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter=({type:g,frequency:I,gain:C,Q:A})=>{I===void 0&&(I=350);const e=this.context.createBiquadFilter();return e.type=g||"lowpass",e.frequency.value=I,e.gain.value=C||0,e.Q.value=A||1,e};createPanner({coneInnerAngle:g,coneOuterAngle:I,coneOuterGain:C,distanceModel:A,maxDistance:e,channelCount:t,channelCountMode:a,channelInterpretation:s,panningModel:n,refDistance:u,rolloffFactor:c,positionX:r,positionY:B,positionZ:y,orientationX:X,orientationY:V,orientationZ:R}){const i=this.context.createPanner();return i.coneInnerAngle=g||360,i.coneOuterAngle=I||360,i.coneOuterGain=C||0,i.distanceModel=A||"inverse",i.maxDistance=e||1e4,i.channelCount=t||2,i.channelCountMode=a||"clamped-max",i.channelInterpretation=s||"speakers",i.panningModel=n||"HRTF",i.refDistance=u||1,i.rolloffFactor=c||1,i.positionX.value=r||0,i.positionY.value=B||0,i.positionZ.value=y||0,i.orientationX.value=X||0,i.orientationY.value=V||0,i.orientationZ.value=R||0,i}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,I)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(C=>{const A=new G(this.context);A.play(),g(A)}).catch(C=>{I(C)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(g){const{forward:I,up:C}=g,[A,e,t]=I,[a,s,n]=C;this.listener.forwardX.value=A,this.listener.forwardY.value=e,this.listener.forwardZ.value=t,this.listener.upX.value=a,this.listener.upY.value=s,this.listener.upZ.value=n}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[I,C,A]=g;this.listener.upX.value=I,this.listener.upY.value=C,this.listener.upZ.value=A}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[I,C,A]=g;this.listener.forwardX.value=I,this.listener.forwardY.value=C,this.listener.forwardZ.value=A}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[I,C,A]=g,e=this.context.currentTime;this.listener.positionX.setValueAtTime(I,e),this.listener.positionY.setValueAtTime(C,e),this.listener.positionZ.setValueAtTime(A,e)}}class b extends d{context;source;gainNode;panner;constructor(g,I,C,A=0){super(),this.source=g,this.gainNode=I,this.context=C,this.panner=C.createPanner(),g.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[I,C,A]=g;this.panner.positionX.value=I,this.panner.positionY.value=C,this.panner.positionZ.value=A}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class G extends d{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new b(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}exports.Cacophony=K;exports.Group=m;exports.MicrophonePlayback=b;exports.MicrophoneStream=G;exports.Playback=h;exports.Sound=l;exports.SoundType=p;
|
|
2
2
|
//# sourceMappingURL=cacophony.cjs.js.map
|