randomp2p/crypto.js
Ole a7933315f3
All checks were successful
Pin to IPFS / pin (push) Successful in 9s
QR-Kompression: pako.deflateRaw + SDP-Dictionary statt base45
- base45/CompressionStream entfernt, durch pako.deflateRaw + base64 ersetzt
- SDP-Dictionary aus 10 echten SDP-JSONs (Chrome+Firefox) → 97.5% Kompression
- Korrupte pako.min.js durch CDN-Version ersetzt
- Tote Altlasten entfernt: hexToBuf, _fullSDPData/getFullSDPData, CRYPTO-UPDATE.md
- Debug-Panel: QR-Click kopiert base64, Raw-Data-Click kopiert JSON
- test-pairing.html an neue pack/unpack-API angepasst
2026-06-14 21:51:49 +02:00

80 lines
14 KiB
JavaScript

function generatePeerId() {
const bytes = new Uint8Array(8);
crypto.getRandomValues(bytes);
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
}
async function generateSecret() {
const secret = new Uint8Array(32);
crypto.getRandomValues(secret);
return secret;
}
async function commit(secret) {
const hash = await crypto.subtle.digest('SHA-256', secret);
return new Uint8Array(hash);
}
function arraysEqual(a, b) {
if (a.length !== b.length) return false;
let diff = 0;
for (let i = 0; i < a.length; i++) {
diff |= a[i] ^ b[i];
}
return diff === 0;
}
function combineAll(secrets) {
const result = new Uint8Array(32);
for (const secret of secrets) {
for (let i = 0; i < 32; i++) {
result[i] ^= secret[i];
}
}
return result;
}
async function computePeerResult(sharedSeed, peerId) {
const data = new TextEncoder().encode(peerId);
const combined = new Uint8Array(sharedSeed.length + data.length);
combined.set(sharedSeed);
combined.set(data, sharedSeed.length);
const hash = await crypto.subtle.digest('SHA-256', combined);
return new Uint8Array(hash)[0] & 1;
}
function bufToBase64(buf) {
const bytes = new Uint8Array(buf);
let binary = '';
for (let i = 0; i < bytes.length; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
function base64ToBuf(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes;
}
/* ─── QR compression: pako.deflateRaw + base64 + SDP dictionary ─── */
const _DICT_B64 = "eyJ2IjoxLCJpZCI6IjIxYzVhNDc0MjQ5Y2JiZGEiLCJzIjp7InR5cGUiOiJvZmZlciIsInNkcCI6InY9MFxyXG5vPS0gNDcyNzAxNTE1MzkwMDkxNjQ2MiAyIElOIElQNCAxMjcuMC4wLjFcclxucz0tXHJcbnQ9MCAwXHJcbmE9Z3JvdXA6QlVORExFIDBcclxuYT1leHRtYXAtYWxsb3ctbWl4ZWRcclxuYT1tc2lkLXNlbWFudGljOiBXTVNcclxubT1hcHBsaWNhdGlvbiA5IFVEUC9EVExTL1NDVFAgd2VicnRjLWRhdGFjaGFubmVsXHJcbmM9SU4gSVA0IDAuMC4wLjBcclxuYT1jYW5kaWRhdGU6MTYwMDY1Nzk0OSAxIHVkcCAyMTEzOTM3MTUxIDE5ZTYwZjI3LTdhNmItNDIwYi1iNDRiLTgwZmIxNmIxMGQ5Ni5sb2NhbCAzMjkyMiB0eXAgaG9zdCBnZW5lcmF0aW9uIDAgbmV0d29yay1jb3N0IDk5OVxyXG5hPWNhbmRpZGF0ZTozODU4MDYyNDQ2IDEgdWRwIDIxMTM5Mzk3MTEgNWFhNDBhYmItYjVjMy00NmQ0LThiMWMtMzM1ZjAwZjlkNTMyLmxvY2FsIDQ4MzE2IHR5cCBob3N0IGdlbmVyYXRpb24gMCBuZXR3b3JrLWNvc3QgOTk5XHJcbmE9aWNlLXVmcmFnOkhKM3BcclxuYT1pY2UtcHdkOjhmRjNmSk14RjNZY2kySHZOWk9tZCs2clxyXG5hPWZpbmdlcnByaW50OnNoYS0yNTYgMEQ6ODA6MDU6NzU6Rjk6NUE6QjY6Q0Q6MjY6MjY6OTI6RDg6MDQ6MUI6MTg6NzI6RkE6QUQ6MjA6RTY6QUQ6NkY6QjM6N0Y6Rjc6OEQ6MkI6RjE6MzY6OEU6NTA6MjlcclxuYT1zZXR1cDphY3RwYXNzXHJcbmE9bWlkOjBcclxuYT1zY3RwLXBvcnQ6NTAwMFxyXG5hPW1heC1tZXNzYWdlLXNpemU6MjYyMTQ0XHJcbiJ9fXsidiI6MSwiaWQiOiI0Yzc5ZmRjNmI1ZTIwZjRmIiwicyI6eyJ0eXBlIjoiYW5zd2VyIiwic2RwIjoidj0wXHJcbm89LSAyNDI2NDEyMTIwNzczMjMwNjYwIDIgSU4gSVA0IDEyNy4wLjAuMVxyXG5zPS1cclxudD0wIDBcclxuYT1ncm91cDpCVU5ETEUgMFxyXG5hPWV4dG1hcC1hbGxvdy1taXhlZFxyXG5hPW1zaWQtc2VtYW50aWM6IFdNU1xyXG5tPWFwcGxpY2F0aW9uIDQ1MzMwIFVEUC9EVExTL1NDVFAgd2VicnRjLWRhdGFjaGFubmVsXHJcbmM9SU4gSVA0IDE5Mi4xNjguMC45OVxyXG5hPWNhbmRpZGF0ZToxMDQwMDYwNDExIDEgdGNwIDE1MTgyMTQ5MTEgMTkyLjE2OC4wLjk5IDkgdHlwIGhvc3QgdGNwdHlwZSBhY3RpdmUgZ2VuZXJhdGlvbiAwIG5ldHdvcmstaWQgMSBuZXR3b3JrLWNvc3QgMTBcclxuYT1jYW5kaWRhdGU6MjI3MTQzMTA0OCAxIHRjcCAxNTE4MjgzMDA3IDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA5IHR5cCBob3N0IHRjcHR5cGUgYWN0aXZlIGdlbmVyYXRpb24gMCBuZXR3b3JrLWlkIDIgbmV0d29yay1jb3N0IDEwXHJcbmE9Y2FuZGlkYXRlOjMyNzcxMTgzMTkgMSB1ZHAgMjEyMjE5NDY4NyAxOTIuMTY4LjAuOTkgNDUzMzAgdHlwIGhvc3QgZ2VuZXJhdGlvbiAwIG5ldHdvcmstaWQgMSBuZXR3b3JrLWNvc3QgMTBcclxuYT1jYW5kaWRhdGU6MjA0MzI1NjA5MiAxIHVkcCAyMTIyMjYyNzgzIDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA1MDEzNSB0eXAgaG9zdCBnZW5lcmF0aW9uIDAgbmV0d29yay1pZCAyIG5ldHdvcmstY29zdCAxMFxyXG5hPWljZS11ZnJhZzpqVGo0XHJcbmE9aWNlLXB3ZDpKVGdJbUs2dFNWNFhyRkVUWDRkMU5lV29cclxuYT1maW5nZXJwcmludDpzaGEtMjU2IDEwOkZGOkE3OkExOjREOkM0OkU2OkM4OjU4OjgwOkJFOkRFOjg5OjM1OjY0OjBGOjA4OjQ2OjVGOjYyOkU0OjlBOjI2OkY4OjM1OjZGOjlEOjIzOjlFOjE5OjBBOjVCXHJcbmE9c2V0dXA6YWN0aXZlXHJcbmE9bWlkOjBcclxuYT1zY3RwLXBvcnQ6NTAwMFxyXG5hPW1heC1tZXNzYWdlLXNpemU6MjYyMTQ0XHJcbiJ9LCJ0byI6IjIxYzVhNDc0MjQ5Y2JiZGEifXsidiI6MSwiaWQiOiJlYTg1MTNhZmM5NmE2NmM0IiwicyI6eyJ0eXBlIjoib2ZmZXIiLCJzZHAiOiJ2PTBcclxubz0tIDczNDU2ODE1ODU5OTE5MzU2NjEgMiBJTiBJUDQgMTI3LjAuMC4xXHJcbnM9LVxyXG50PTAgMFxyXG5hPWdyb3VwOkJVTkRMRSAwXHJcbmE9ZXh0bWFwLWFsbG93LW1peGVkXHJcbmE9bXNpZC1zZW1hbnRpYzogV01TXHJcbm09YXBwbGljYXRpb24gOSBVRFAvRFRMUy9TQ1RQIHdlYnJ0Yy1kYXRhY2hhbm5lbFxyXG5jPUlOIElQNCAwLjAuMC4wXHJcbmE9Y2FuZGlkYXRlOjM2ODI4ODk2NTQgMSB1ZHAgMjExMzkzNzE1MSAyZmJlMTYxNy01YmVmLTQzODktOGI4Ni0wZGM4ZDI3ZjAxZmUubG9jYWwgNTIyMzkgdHlwIGhvc3QgZ2VuZXJhdGlvbiAwIG5ldHdvcmstY29zdCA5OTlcclxuYT1jYW5kaWRhdGU6MjUzMjU3OTY1MCAxIHVkcCAyMTEzOTM5NzExIGJhM2Q1NGM1LTBiMDEtNGRmMC1iNjc3LTIxMjYxN2NhMTk5NC5sb2NhbCAzODQ0NyB0eXAgaG9zdCBnZW5lcmF0aW9uIDAgbmV0d29yay1jb3N0IDk5OVxyXG5hPWljZS11ZnJhZzpEV2xoXHJcbmE9aWNlLXB3ZDpiRzFoaURWbHdidnR5RG9DL2w1ZWRYaDFcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IERGOkE3OjBGOjNFOjAwOkFBOjdBOkNCOkU5Ojg0OjY1OjJGOjhCOjlEOkU4OkMxOjM5OkE3OjQ3OkMzOkRFOkI4OjcyOkNGOjgwOjRBOjRBOkZBOjFEOkM1OkVCOkU1XHJcbmE9c2V0dXA6YWN0cGFzc1xyXG5hPW1pZDowXHJcbmE9c2N0cC1wb3J0OjUwMDBcclxuYT1tYXgtbWVzc2FnZS1zaXplOjI2MjE0NFxyXG4ifX17InYiOjEsImlkIjoiMmQyMmI3YTI5NmY5MmFiOSIsInMiOnsidHlwZSI6ImFuc3dlciIsInNkcCI6InY9MFxyXG5vPS0gNjI4NDY1NjgxOTMxMjY5NTI1IDIgSU4gSVA0IDEyNy4wLjAuMVxyXG5zPS1cclxudD0wIDBcclxuYT1ncm91cDpCVU5ETEUgMFxyXG5hPWV4dG1hcC1hbGxvdy1taXhlZFxyXG5hPW1zaWQtc2VtYW50aWM6IFdNU1xyXG5tPWFwcGxpY2F0aW9uIDU5Mzk3IFVEUC9EVExTL1NDVFAgd2VicnRjLWRhdGFjaGFubmVsXHJcbmM9SU4gSVA0IDE5Mi4xNjguMC45OVxyXG5hPWNhbmRpZGF0ZTo4MTE1MzIyNDAgMSB0Y3AgMTUxODIxNDkxMSAxOTIuMTY4LjAuOTkgOSB0eXAgaG9zdCB0Y3B0eXBlIGFjdGl2ZSBnZW5lcmF0aW9uIDAgbmV0d29yay1pZCAxIG5ldHdvcmstY29zdCAxMFxyXG5hPWNhbmRpZGF0ZToyMzI4MDgyODUxIDEgdGNwIDE1MTgyODMwMDcgMmEwMjo4MTA4OjMxMGQ6YjAwMDo2NmM0OmVkMWM6NTdiMDoxOTRmIDkgdHlwIGhvc3QgdGNwdHlwZSBhY3RpdmUgZ2VuZXJhdGlvbiAwIG5ldHdvcmstaWQgMiBuZXR3b3JrLWNvc3QgMTBcclxuYT1jYW5kaWRhdGU6MzQ3MjEwODM1NiAxIHVkcCAyMTIyMTk0Njg3IDE5Mi4xNjguMC45OSA1OTM5NyB0eXAgaG9zdCBnZW5lcmF0aW9uIDAgbmV0d29yay1pZCAxIG5ldHdvcmstY29zdCAxMFxyXG5hPWNhbmRpZGF0ZToxOTUzMDY2Mjk1IDEgdWRwIDIxMjIyNjI3ODMgMmEwMjo4MTA4OjMxMGQ6YjAwMDo2NmM0OmVkMWM6NTdiMDoxOTRmIDM0MDk3IHR5cCBob3N0IGdlbmVyYXRpb24gMCBuZXR3b3JrLWlkIDIgbmV0d29yay1jb3N0IDEwXHJcbmE9aWNlLXVmcmFnOlc0cndcclxuYT1pY2UtcHdkOmFzVUVHTkFUazdORGFpQWwvcUFhNmxIWFxyXG5hPWZpbmdlcnByaW50OnNoYS0yNTYgQTg6Nzg6NDA6Nzk6MkQ6RDk6Rjc6Mzc6NTg6RkQ6MUI6MTg6NDE6MTI6RDI6MkU6NDk6NkQ6MUU6MjY6RjM6NkE6RUM6RTM6RTU6OUM6Rjc6QkM6MzM6RjY6ODE6NzlcclxuYT1zZXR1cDphY3RpdmVcclxuYT1taWQ6MFxyXG5hPXNjdHAtcG9ydDo1MDAwXHJcbmE9bWF4LW1lc3NhZ2Utc2l6ZToyNjIxNDRcclxuIn0sInRvIjoiZWE4NTEzYWZjOTZhNjZjNCJ9eyJ2IjoxLCJpZCI6IjZiNjQzMzQ5MGJiODgxNTkiLCJzIjp7InR5cGUiOiJvZmZlciIsInNkcCI6InY9MFxyXG5vPW1vemlsbGEuLi5USElTX0lTX1NEUEFSVEEtOTkuMCA1ODU1OTUwMzk3Mzk0NDk0OTI5IDAgSU4gSVA0IDAuMC4wLjBcclxucz0tXHJcbnQ9MCAwXHJcbmE9c2VuZHJlY3ZcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IEJDOkQwOjU3OjVBOjdCOjQ0OkFBOkNGOkUwOkQ3OjA1OkMyOkNEOkQ4OkMyOkY5OjI2OkQ3OjhEOjgyOkQ1Ojk5OkNDOjU0OjUxOkE4OjYxOjY0OjNDOjY3OjUzOkE5XHJcbmE9Z3JvdXA6QlVORExFIDBcclxuYT1tc2lkLXNlbWFudGljOldNUyAqXHJcbm09YXBwbGljYXRpb24gMzgxMTUgVURQL0RUTFMvU0NUUCB3ZWJydGMtZGF0YWNoYW5uZWxcclxuYz1JTiBJUDQgMTkyLjE2OC4wLjk5XHJcbmE9Y2FuZGlkYXRlOjAgMSBVRFAgMjEyMjE4NzAwNyAxOTIuMTY4LjAuOTkgMzgxMTUgdHlwIGhvc3RcclxuYT1jYW5kaWRhdGU6MSAxIFVEUCAyMTIyMjUyNTQzIDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA1MDc1MSB0eXAgaG9zdFxyXG5hPWNhbmRpZGF0ZToyIDEgVENQIDIxMDU0NTg5NDMgMTkyLjE2OC4wLjk5IDkgdHlwIGhvc3QgdGNwdHlwZSBhY3RpdmVcclxuYT1jYW5kaWRhdGU6MyAxIFRDUCAyMTA1NTI0NDc5IDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA5IHR5cCBob3N0IHRjcHR5cGUgYWN0aXZlXHJcbmE9c2VuZHJlY3ZcclxuYT1lbmQtb2YtY2FuZGlkYXRlc1xyXG5hPWljZS1wd2Q6ZTcxZjAxMjBkODRhYzE5MWI1NzkzNmQ3YzJjNjdiYmRcclxuYT1pY2UtdWZyYWc6MzM5MWNkM2JcclxuYT1taWQ6MFxyXG5hPXNldHVwOmFjdHBhc3NcclxuYT1zY3RwLXBvcnQ6NTAwMFxyXG5hPW1heC1tZXNzYWdlLXNpemU6MTA3Mzc0MTgyM1xyXG4ifX17InYiOjEsImlkIjoiYWI4MzBiMzc2ZjQ2NjgzYiIsInMiOnsidHlwZSI6ImFuc3dlciIsInNkcCI6InY9MFxyXG5vPS0gNzgwMzE2ODc0NzM4NTY3NDM2MSAyIElOIElQNCAxMjcuMC4wLjFcclxucz0tXHJcbnQ9MCAwXHJcbmE9Z3JvdXA6QlVORExFIDBcclxuYT1tc2lkLXNlbWFudGljOiBXTVNcclxubT1hcHBsaWNhdGlvbiA1MjA5MyBVRFAvRFRMUy9TQ1RQIHdlYnJ0Yy1kYXRhY2hhbm5lbFxyXG5jPUlOIElQNCAxOTIuMTY4LjAuOTlcclxuYT1jYW5kaWRhdGU6NDgwMDU4ODA2IDEgdGNwIDE1MTgyMTQ5MTEgMTkyLjE2OC4wLjk5IDkgdHlwIGhvc3QgdGNwdHlwZSBhY3RpdmUgZ2VuZXJhdGlvbiAwIG5ldHdvcmstaWQgMSBuZXR3b3JrLWNvc3QgMTBcclxuYT1jYW5kaWRhdGU6Mjc4NTA0MTM0OSAxIHRjcCAxNTE4MjgzMDA3IDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA5IHR5cCBob3N0IHRjcHR5cGUgYWN0aXZlIGdlbmVyYXRpb24gMCBuZXR3b3JrLWlkIDIgbmV0d29yay1jb3N0IDEwXHJcbmE9Y2FuZGlkYXRlOjM3OTUzMDY3ODYgMSB1ZHAgMjEyMjE5NDY4NyAxOTIuMTY4LjAuOTkgNTIwOTMgdHlwIGhvc3QgZ2VuZXJhdGlvbiAwIG5ldHdvcmstaWQgMSBuZXR3b3JrLWNvc3QgMTBcclxuYT1jYW5kaWRhdGU6MTQ4NzU3MjgxNyAxIHVkcCAyMTIyMjYyNzgzIDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA0Mjc2MSB0eXAgaG9zdCBnZW5lcmF0aW9uIDAgbmV0d29yay1pZCAyIG5ldHdvcmstY29zdCAxMFxyXG5hPWljZS11ZnJhZzo2WjJXXHJcbmE9aWNlLXB3ZDptZHVJbldEcTFURVFQVjBtS25WaXZxN2xcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IEY2OkE0OjQyOkJCOjhFOjVGOjg1OkNGOkExOkFCOkUxOkU3OjRFOjNFOjcxOjQ5OjRDOkZBOjAzOjY4OjFCOkUyOjkzOkI2OjI1OjA5OjUwOkI0OjIyOkZCOjVCOjIwXHJcbmE9c2V0dXA6YWN0aXZlXHJcbmE9bWlkOjBcclxuYT1zY3RwLXBvcnQ6NTAwMFxyXG5hPW1heC1tZXNzYWdlLXNpemU6MjYyMTQ0XHJcbiJ9LCJ0byI6IjZiNjQzMzQ5MGJiODgxNTkifXsidiI6MSwiaWQiOiI2YjY0MzM0OTBiYjg4MTU5IiwicyI6eyJ0eXBlIjoib2ZmZXIiLCJzZHAiOiJ2PTBcclxubz1tb3ppbGxhLi4uVEhJU19JU19TRFBBUlRBLTk5LjAgNTg1NTk1MDM5NzM5NDQ5NDkyOSAwIElOIElQNCAwLjAuMC4wXHJcbnM9LVxyXG50PTAgMFxyXG5hPXNlbmRyZWN2XHJcbmE9ZmluZ2VycHJpbnQ6c2hhLTI1NiBCQzpEMDo1Nzo1QTo3Qjo0NDpBQTpDRjpFMDpENzowNTpDMjpDRDpEODpDMjpGOToyNjpENzo4RDo4MjpENTo5OTpDQzo1NDo1MTpBODo2MTo2NDozQzo2Nzo1MzpBOVxyXG5hPWdyb3VwOkJVTkRMRSAwXHJcbmE9bXNpZC1zZW1hbnRpYzpXTVMgKlxyXG5tPWFwcGxpY2F0aW9uIDM4MTE1IFVEUC9EVExTL1NDVFAgd2VicnRjLWRhdGFjaGFubmVsXHJcbmM9SU4gSVA0IDE5Mi4xNjguMC45OVxyXG5hPWNhbmRpZGF0ZTowIDEgVURQIDIxMjIxODcwMDcgMTkyLjE2OC4wLjk5IDM4MTE1IHR5cCBob3N0XHJcbmE9Y2FuZGlkYXRlOjEgMSBVRFAgMjEyMjI1MjU0MyAyYTAyOjgxMDg6MzEwZDpiMDAwOjY2YzQ6ZWQxYzo1N2IwOjE5NGYgNTA3NTEgdHlwIGhvc3RcclxuYT1jYW5kaWRhdGU6MiAxIFRDUCAyMTA1NDU4OTQzIDE5Mi4xNjguMC45OSA5IHR5cCBob3N0IHRjcHR5cGUgYWN0aXZlXHJcbmE9Y2FuZGlkYXRlOjMgMSBUQ1AgMjEwNTUyNDQ3OSAyYTAyOjgxMDg6MzEwZDpiMDAwOjY2YzQ6ZWQxYzo1N2IwOjE5NGYgOSB0eXAgaG9zdCB0Y3B0eXBlIGFjdGl2ZVxyXG5hPXNlbmRyZWN2XHJcbmE9ZW5kLW9mLWNhbmRpZGF0ZXNcclxuYT1pY2UtcHdkOmU3MWYwMTIwZDg0YWMxOTFiNTc5MzZkN2MyYzY3YmJkXHJcbmE9aWNlLXVmcmFnOjMzOTFjZDNiXHJcbmE9bWlkOjBcclxuYT1zZXR1cDphY3RwYXNzXHJcbmE9c2N0cC1wb3J0OjUwMDBcclxuYT1tYXgtbWVzc2FnZS1zaXplOjEwNzM3NDE4MjNcclxuIn19eyJ2IjoxLCJpZCI6ImZiYjYzMDNiMDFmOWUxOGQiLCJzIjp7InR5cGUiOiJvZmZlciIsInNkcCI6InY9MFxyXG5vPW1vemlsbGEuLi5USElTX0lTX1NEUEFSVEEtOTkuMCA5MjIyNjk5MjU0NDcxNDI4MjU1IDAgSU4gSVA0IDAuMC4wLjBcclxucz0tXHJcbnQ9MCAwXHJcbmE9c2VuZHJlY3ZcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IDE5OjJCOjQ5OkRCOkVCOjE4OkE2OjhFOjREOkVGOjg2OjczOjUwOkVDOkFCOjU5Ojk2OkJCOjI2OkVFOkM0OjM0OkQ1OjBCOjVEOjFBOjJFOjEyOjE4OjNCOjM0OkU4XHJcbmE9Z3JvdXA6QlVORExFIDBcclxuYT1tc2lkLXNlbWFudGljOldNUyAqXHJcbm09YXBwbGljYXRpb24gNDk0MzcgVURQL0RUTFMvU0NUUCB3ZWJydGMtZGF0YWNoYW5uZWxcclxuYz1JTiBJUDQgMTkyLjE2OC4wLjk5XHJcbmE9Y2FuZGlkYXRlOjAgMSBVRFAgMjEyMjE4NzAwNyAxOTIuMTY4LjAuOTkgNDk0MzcgdHlwIGhvc3RcclxuYT1jYW5kaWRhdGU6MSAxIFVEUCAyMTIyMjUyNTQzIDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiAzMzc5NSB0eXAgaG9zdFxyXG5hPWNhbmRpZGF0ZToyIDEgVENQIDIxMDU0NTg5NDMgMTkyLjE2OC4wLjk5IDkgdHlwIGhvc3QgdGNwdHlwZSBhY3RpdmVcclxuYT1jYW5kaWRhdGU6MyAxIFRDUCAyMTA1NTI0NDc5IDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA5IHR5cCBob3N0IHRjcHR5cGUgYWN0aXZlXHJcbmE9c2VuZHJlY3ZcclxuYT1lbmQtb2YtY2FuZGlkYXRlc1xyXG5hPWljZS1wd2Q6YzM0MTVkYjc5MjBmMTRhMzMwOTE5ZTcyMzllMGQzNTNcclxuYT1pY2UtdWZyYWc6Njg1YTY4OWNcclxuYT1taWQ6MFxyXG5hPXNldHVwOmFjdHBhc3NcclxuYT1zY3RwLXBvcnQ6NTAwMFxyXG5hPW1heC1tZXNzYWdlLXNpemU6MTA3Mzc0MTgyM1xyXG4ifX17InYiOjEsImlkIjoiNmNjZDE3YTRiNzk3MTU1ZCIsInMiOnsidHlwZSI6ImFuc3dlciIsInNkcCI6InY9MFxyXG5vPW1vemlsbGEuLi5USElTX0lTX1NEUEFSVEEtOTkuMCAxNTYzNjQzMjE1MzkyNTM2OTIxIDAgSU4gSVA0IDAuMC4wLjBcclxucz0tXHJcbnQ9MCAwXHJcbmE9c2VuZHJlY3ZcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IDc1OkVDOjhCOjAyOjg2OjdDOkM4OjA0OkM3OkRGOkIzOkNFOkQ1OkVEOjVCOjI5OjhBOjJCOjMzOjdEOkIyOkIwOkZGOkMzOjNGOjg5OkIyOjE0OkI3OkZGOjk4OjVCXHJcbmE9Z3JvdXA6QlVORExFIDBcclxuYT1tc2lkLXNlbWFudGljOldNUyAqXHJcbm09YXBwbGljYXRpb24gMzMzMDEgVURQL0RUTFMvU0NUUCB3ZWJydGMtZGF0YWNoYW5uZWxcclxuYz1JTiBJUDQgMTkyLjE2OC4wLjk5XHJcbmE9Y2FuZGlkYXRlOjAgMSBVRFAgMjEyMjE4NzAwNyAxOTIuMTY4LjAuOTkgMzMzMDEgdHlwIGhvc3RcclxuYT1jYW5kaWRhdGU6MSAxIFVEUCAyMTIyMjUyNTQzIDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA1NTc3MiB0eXAgaG9zdFxyXG5hPWNhbmRpZGF0ZToyIDEgVENQIDIxMDU0NTg5NDMgMTkyLjE2OC4wLjk5IDkgdHlwIGhvc3QgdGNwdHlwZSBhY3RpdmVcclxuYT1jYW5kaWRhdGU6MyAxIFRDUCAyMTA1NTI0NDc5IDJhMDI6ODEwODozMTBkOmIwMDA6NjZjNDplZDFjOjU3YjA6MTk0ZiA5IHR5cCBob3N0IHRjcHR5cGUgYWN0aXZlXHJcbmE9c2VuZHJlY3ZcclxuYT1lbmQtb2YtY2FuZGlkYXRlc1xyXG5hPWljZS1wd2Q6MTI2YzFjYjEyMDkyNDg1N2QyNDE0YzNhNWVmM2FjZTlcclxuYT1pY2UtdWZyYWc6ZWY0N2U1YzlcclxuYT1taWQ6MFxyXG5hPXNldHVwOmFjdGl2ZVxyXG5hPXNjdHAtcG9ydDo1MDAwXHJcbmE9bWF4LW1lc3NhZ2Utc2l6ZToxMDczNzQxODIzXHJcbiJ9LCJ0byI6IjZiNjQzMzQ5MGJiODgxNTkifXsidiI6MSwiaWQiOiJmNzFmMGZhZTA3MmQ4MzI5IiwicyI6eyJ0eXBlIjoiYW5zd2VyIiwic2RwIjoidj0wXHJcbm89bW96aWxsYS4uLlRISVNfSVNfU0RQQVJUQS05OS4wIDc3MDEwNzcyNDk5OTAwMTE5MjMgMCBJTiBJUDQgMC4wLjAuMFxyXG5zPS1cclxudD0wIDBcclxuYT1zZW5kcmVjdlxyXG5hPWZpbmdlcnByaW50OnNoYS0yNTYgMEM6QjI6RTY6RUM6NjE6OTU6MkE6NTI6MkM6QzQ6NjE6MEI6ODE6RkU6OTA6OTM6NDY6RTg6MUM6NDY6RDI6MEQ6NDk6OTg6RDI6NjE6MDI6OTg6NDg6QzA6Mjc6NDRcclxuYT1ncm91cDpCVU5ETEUgMFxyXG5hPW1zaWQtc2VtYW50aWM6V01TICpcclxubT1hcHBsaWNhdGlvbiAzNzA0OSBVRFAvRFRMUy9TQ1RQIHdlYnJ0Yy1kYXRhY2hhbm5lbFxyXG5jPUlOIElQNCAxOTIuMTY4LjAuOTlcclxuYT1jYW5kaWRhdGU6MCAxIFVEUCAyMTIyMTg3MDA3IDE5Mi4xNjguMC45OSAzNzA0OSB0eXAgaG9zdFxyXG5hPWNhbmRpZGF0ZToxIDEgVURQIDIxMjIyNTI1NDMgMmEwMjo4MTA4OjMxMGQ6YjAwMDo2NmM0OmVkMWM6NTdiMDoxOTRmIDM2Njk5IHR5cCBob3N0XHJcbmE9Y2FuZGlkYXRlOjIgMSBUQ1AgMjEwNTQ1ODk0MyAxOTIuMTY4LjAuOTkgOSB0eXAgaG9zdCB0Y3B0eXBlIGFjdGl2ZVxyXG5hPWNhbmRpZGF0ZTozIDEgVENQIDIxMDU1MjQ0NzkgMmEwMjo4MTA4OjMxMGQ6YjAwMDo2NmM0OmVkMWM6NTdiMDoxOTRmIDkgdHlwIGhvc3QgdGNwdHlwZSBhY3RpdmVcclxuYT1zZW5kcmVjdlxyXG5hPWVuZC1vZi1jYW5kaWRhdGVzXHJcbmE9aWNlLXB3ZDpmMjgwNTBiMWIzMWJjMjA5YjMwMzRjYmQ4ODQ0ZGExNVxyXG5hPWljZS11ZnJhZzo1MWEwZDQ1MVxyXG5hPW1pZDowXHJcbmE9c2V0dXA6YWN0aXZlXHJcbmE9c2N0cC1wb3J0OjUwMDBcclxuYT1tYXgtbWVzc2FnZS1zaXplOjEwNzM3NDE4MjNcclxuIn0sInRvIjoiZmJiNjMwM2IwMWY5ZTE4ZCJ9";
const SDP_DICT = base64ToBuf(_DICT_B64);
async function pack(obj) {
const json = JSON.stringify(obj);
const bytes = new TextEncoder().encode(json);
const compressed = pako.deflateRaw(bytes, {dictionary: SDP_DICT});
return bufToBase64(compressed);
}
async function unpack(str) {
const compressed = base64ToBuf(str);
const bytes = pako.inflateRaw(compressed, {dictionary: SDP_DICT});
return JSON.parse(new TextDecoder().decode(bytes));
}