Spaces:
Running
Running
; | |
var __defProp = Object.defineProperty; | |
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | |
var __getOwnPropNames = Object.getOwnPropertyNames; | |
var __hasOwnProp = Object.prototype.hasOwnProperty; | |
var __export = (target, all) => { | |
for (var name in all) | |
__defProp(target, name, { get: all[name], enumerable: true }); | |
}; | |
var __copyProps = (to, from, except, desc) => { | |
if (from && typeof from === "object" || typeof from === "function") { | |
for (let key of __getOwnPropNames(from)) | |
if (!__hasOwnProp.call(to, key) && key !== except) | |
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | |
} | |
return to; | |
}; | |
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | |
var dashycode_exports = {}; | |
__export(dashycode_exports, { | |
decode: () => decode, | |
encode: () => encode, | |
vizStream: () => vizStream | |
}); | |
module.exports = __toCommonJS(dashycode_exports); | |
/** | |
* Dashycode! | |
* | |
* Encodes a string in a restricted string containing only alphanumeric | |
* characters and dashes. | |
* | |
* (The name is a riff on Punycode, which is what I originally wanted | |
* to use for this purpose, but it turns out Punycode does not work on | |
* arbitrary strings.) | |
* | |
* @author Guangcong Luo <guangcongluo@gmail.com> | |
* @license MIT | |
*/ | |
const CODE_MAP = "23456789abcdefghijkmnpqrstuvwxyz"; | |
const UNSAFE_MAP = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; | |
function streamWrite(stream, writeBufLength, writeBuf) { | |
stream.buf += writeBuf << stream.bufLength; | |
stream.bufLength += writeBufLength; | |
while (stream.bufLength >= 5) { | |
stream.codeBuf += CODE_MAP.charAt(stream.buf & 31); | |
stream.buf >>= 5; | |
stream.bufLength -= 5; | |
} | |
} | |
function streamGetCode(stream) { | |
const buf = stream.codeBuf + CODE_MAP.charAt(stream.buf); | |
let end2Len = 0; | |
while (buf.charAt(buf.length - 1 - end2Len) === "2") | |
end2Len++; | |
return end2Len ? buf.slice(0, -end2Len) : buf; | |
} | |
function streamPeek(stream, readLength, readMask = 65535 >> 16 - readLength) { | |
while (stream.bufLength < readLength && stream.codeBuf.length) { | |
const next5Bits = CODE_MAP.indexOf(stream.codeBuf.charAt(0)); | |
if (next5Bits < 0) | |
throw new Error("Invalid character in coded buffer"); | |
stream.codeBuf = stream.codeBuf.slice(1); | |
stream.buf += next5Bits << stream.bufLength; | |
stream.bufLength += 5; | |
} | |
return stream.buf & readMask; | |
} | |
function streamRead(stream, readLength, readMask = 65535 >> 16 - readLength) { | |
const output = streamPeek(stream, readLength, readMask); | |
stream.buf >>= readLength; | |
stream.bufLength -= readLength; | |
return output; | |
} | |
function encode(str, allowCaps = false) { | |
if (!str) | |
return "0--0"; | |
let safePart = ""; | |
const unsafeStream = { | |
codeBuf: "", | |
buf: 0, | |
bufLength: 0 | |
}; | |
let isSafe = true; | |
let alphaIndex = 0; | |
let capBuffer = 0; | |
for (let i = 0; i < str.length + 1; i++) { | |
let curCharCode = i !== str.length ? str.charCodeAt(i) : -1; | |
const isLowercase = 97 <= curCharCode && curCharCode <= 122; | |
const isUppercase = 65 <= curCharCode && curCharCode <= 90; | |
const isNumeric = 48 <= curCharCode && curCharCode <= 57; | |
if (capBuffer && (!(isLowercase || isUppercase || isNumeric) || alphaIndex >= 8 || i === str.length)) { | |
if (capBuffer === 13) { | |
streamWrite(unsafeStream, 3, 1); | |
} else { | |
streamWrite(unsafeStream, 11, capBuffer); | |
} | |
alphaIndex -= 8; | |
capBuffer = 0; | |
} | |
if (i === str.length) | |
break; | |
if (isLowercase || isUppercase || isNumeric) { | |
if (alphaIndex < 0) | |
throw new Error("alphaIndex should be non-negative here"); | |
if (!isSafe) { | |
if (capBuffer) | |
throw new Error("capBuffer shouldn't exist here"); | |
streamWrite(unsafeStream, 2, 0); | |
isSafe = true; | |
} | |
if (isUppercase && !allowCaps) { | |
safePart += String.fromCharCode(curCharCode + 32); | |
while (alphaIndex >= 8) { | |
if (capBuffer) | |
throw new Error("capBuffer shouldn't exist here"); | |
alphaIndex -= 8; | |
streamWrite(unsafeStream, 11, 5); | |
} | |
if (!capBuffer) | |
capBuffer = 5; | |
capBuffer += 1 << alphaIndex + 3; | |
} else { | |
safePart += str.charAt(i); | |
} | |
if (isUppercase || isLowercase) | |
alphaIndex++; | |
continue; | |
} | |
if (capBuffer) | |
throw new Error("capBuffer shouldn't exist here"); | |
alphaIndex = 0; | |
if (isSafe && curCharCode === 32) { | |
const nextCharCode = str.charCodeAt(i + 1); | |
if (97 <= nextCharCode && nextCharCode <= 122 || 65 <= nextCharCode && nextCharCode <= 90 || 48 <= nextCharCode && nextCharCode <= 57) { | |
safePart += "-"; | |
streamWrite(unsafeStream, 2, 0); | |
continue; | |
} | |
} | |
if (isSafe) { | |
safePart += "-"; | |
isSafe = false; | |
} | |
let unsafeMapIndex = -1; | |
if (curCharCode === -1) { | |
streamWrite(unsafeStream, 2, 0); | |
} else if (curCharCode === 32) { | |
streamWrite(unsafeStream, 3, 3); | |
} else if ((unsafeMapIndex = UNSAFE_MAP.indexOf(str.charAt(i))) >= 0) { | |
curCharCode = (unsafeMapIndex << 2) + 2; | |
streamWrite(unsafeStream, 7, curCharCode); | |
} else { | |
curCharCode = (curCharCode << 3) + 7; | |
streamWrite(unsafeStream, 19, curCharCode); | |
} | |
} | |
let unsafePart = streamGetCode(unsafeStream); | |
if (safePart.startsWith("-")) { | |
safePart = safePart.slice(1); | |
unsafePart = `${unsafePart}2`; | |
} | |
if (safePart.endsWith("-")) { | |
safePart = safePart.slice(0, -1); | |
} | |
if (!safePart) { | |
safePart = "0"; | |
unsafePart = `0${unsafePart}`; | |
if (unsafePart.endsWith("2")) | |
unsafePart = unsafePart.slice(0, -1); | |
} | |
if (!unsafePart) | |
return safePart; | |
return `${safePart}--${unsafePart}`; | |
} | |
function decode(codedStr) { | |
let str = ""; | |
let lastDashIndex = codedStr.lastIndexOf("--"); | |
if (lastDashIndex < 0) { | |
return codedStr.replace(/-/g, " "); | |
} | |
if (codedStr.charAt(lastDashIndex + 2) === "0") { | |
if (!codedStr.startsWith("0") || lastDashIndex !== 1) { | |
throw new Error("Invalid Dashycode"); | |
} | |
lastDashIndex -= 1; | |
codedStr = "--" + codedStr.slice(4); | |
} | |
if (codedStr.endsWith("2")) { | |
codedStr = "-" + codedStr.slice(0, -1); | |
lastDashIndex += 1; | |
} | |
const unsafeStream = { | |
codeBuf: codedStr.slice(lastDashIndex + 2), | |
buf: 0, | |
bufLength: 0 | |
}; | |
let capBuffer = 1; | |
for (let i = 0; i < lastDashIndex + 1; i++) { | |
let curChar = codedStr.charAt(i); | |
if (curChar !== "-") { | |
const curCharCode = codedStr.charCodeAt(i); | |
const isLowercase = 97 <= curCharCode && curCharCode <= 122; | |
if (isLowercase) { | |
if (capBuffer === 1) { | |
capBuffer = 0; | |
if (streamPeek(unsafeStream, 2, 3) === 1) { | |
switch (streamRead(unsafeStream, 3, 7)) { | |
case 5: | |
capBuffer = streamRead(unsafeStream, 8, 255) + 256; | |
break; | |
case 1: | |
capBuffer = 257; | |
break; | |
} | |
} | |
} | |
const toCapitalize = capBuffer & 1; | |
capBuffer >>= 1; | |
if (toCapitalize) { | |
curChar = String.fromCharCode(curCharCode - 32); | |
} | |
} | |
str += curChar; | |
} else { | |
capBuffer = 1; | |
let isEmpty = true; | |
do { | |
switch (streamRead(unsafeStream, 2, 3)) { | |
case 0: | |
curChar = ""; | |
break; | |
case 1: | |
throw new Error("Invalid capitalization token"); | |
case 2: | |
curChar = UNSAFE_MAP.charAt(streamRead(unsafeStream, 5, 31)); | |
isEmpty = false; | |
break; | |
case 3: | |
if (streamRead(unsafeStream, 1, 1)) { | |
curChar = String.fromCharCode(streamRead(unsafeStream, 16, 65535)); | |
} else { | |
curChar = " "; | |
} | |
isEmpty = false; | |
break; | |
} | |
str += curChar; | |
} while (curChar); | |
if (isEmpty && i !== lastDashIndex) | |
str += " "; | |
} | |
} | |
return str; | |
} | |
function vizStream(codeBuf, translate = true) { | |
let spacedStream = ""; | |
if (codeBuf.startsWith("0")) { | |
codeBuf = codeBuf.slice(1); | |
spacedStream = " [no safe chars]" + spacedStream; | |
} | |
if (codeBuf.endsWith("2")) { | |
codeBuf = codeBuf.slice(0, -1); | |
spacedStream = " [start unsafe]" + spacedStream; | |
} | |
const stream = { | |
codeBuf, | |
buf: 0, | |
bufLength: 0 | |
}; | |
function vizBlock(s, bufLen) { | |
const buf = streamRead(s, bufLen); | |
return buf.toString(2).padStart(bufLen, "0"); | |
} | |
while (stream.bufLength > 0 || stream.codeBuf) { | |
switch (streamRead(stream, 2)) { | |
case 0: | |
spacedStream = (translate ? " |" : " 00") + spacedStream; | |
break; | |
case 1: | |
if (streamRead(stream, 1)) { | |
spacedStream = " " + vizBlock(stream, 8) + (translate ? "-cap" : "_1_01") + spacedStream; | |
} else { | |
spacedStream = (translate ? " capfirst" : " 0_01") + spacedStream; | |
} | |
break; | |
case 2: | |
spacedStream = " " + vizBlock(stream, 5) + (translate ? "-ascii" : "_10") + spacedStream; | |
break; | |
case 3: | |
if (streamRead(stream, 1)) { | |
spacedStream = " " + vizBlock(stream, 16) + (translate ? "-utf" : "_1_11") + spacedStream; | |
} else { | |
spacedStream = (translate ? " space" : " 0_11") + spacedStream; | |
} | |
break; | |
} | |
} | |
return spacedStream; | |
} | |
//# sourceMappingURL=dashycode.js.map | |