597 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			597 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | function parseContentType(str) { | ||
|  |   if (str.length === 0) | ||
|  |     return; | ||
|  | 
 | ||
|  |   const params = Object.create(null); | ||
|  |   let i = 0; | ||
|  | 
 | ||
|  |   // Parse type
 | ||
|  |   for (; i < str.length; ++i) { | ||
|  |     const code = str.charCodeAt(i); | ||
|  |     if (TOKEN[code] !== 1) { | ||
|  |       if (code !== 47/* '/' */ || i === 0) | ||
|  |         return; | ||
|  |       break; | ||
|  |     } | ||
|  |   } | ||
|  |   // Check for type without subtype
 | ||
|  |   if (i === str.length) | ||
|  |     return; | ||
|  | 
 | ||
|  |   const type = str.slice(0, i).toLowerCase(); | ||
|  | 
 | ||
|  |   // Parse subtype
 | ||
|  |   const subtypeStart = ++i; | ||
|  |   for (; i < str.length; ++i) { | ||
|  |     const code = str.charCodeAt(i); | ||
|  |     if (TOKEN[code] !== 1) { | ||
|  |       // Make sure we have a subtype
 | ||
|  |       if (i === subtypeStart) | ||
|  |         return; | ||
|  | 
 | ||
|  |       if (parseContentTypeParams(str, i, params) === undefined) | ||
|  |         return; | ||
|  |       break; | ||
|  |     } | ||
|  |   } | ||
|  |   // Make sure we have a subtype
 | ||
|  |   if (i === subtypeStart) | ||
|  |     return; | ||
|  | 
 | ||
|  |   const subtype = str.slice(subtypeStart, i).toLowerCase(); | ||
|  | 
 | ||
|  |   return { type, subtype, params }; | ||
|  | } | ||
|  | 
 | ||
|  | function parseContentTypeParams(str, i, params) { | ||
|  |   while (i < str.length) { | ||
|  |     // Consume whitespace
 | ||
|  |     for (; i < str.length; ++i) { | ||
|  |       const code = str.charCodeAt(i); | ||
|  |       if (code !== 32/* ' ' */ && code !== 9/* '\t' */) | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     // Ended on whitespace
 | ||
|  |     if (i === str.length) | ||
|  |       break; | ||
|  | 
 | ||
|  |     // Check for malformed parameter
 | ||
|  |     if (str.charCodeAt(i++) !== 59/* ';' */) | ||
|  |       return; | ||
|  | 
 | ||
|  |     // Consume whitespace
 | ||
|  |     for (; i < str.length; ++i) { | ||
|  |       const code = str.charCodeAt(i); | ||
|  |       if (code !== 32/* ' ' */ && code !== 9/* '\t' */) | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     // Ended on whitespace (malformed)
 | ||
|  |     if (i === str.length) | ||
|  |       return; | ||
|  | 
 | ||
|  |     let name; | ||
|  |     const nameStart = i; | ||
|  |     // Parse parameter name
 | ||
|  |     for (; i < str.length; ++i) { | ||
|  |       const code = str.charCodeAt(i); | ||
|  |       if (TOKEN[code] !== 1) { | ||
|  |         if (code !== 61/* '=' */) | ||
|  |           return; | ||
|  |         break; | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     // No value (malformed)
 | ||
|  |     if (i === str.length) | ||
|  |       return; | ||
|  | 
 | ||
|  |     name = str.slice(nameStart, i); | ||
|  |     ++i; // Skip over '='
 | ||
|  | 
 | ||
|  |     // No value (malformed)
 | ||
|  |     if (i === str.length) | ||
|  |       return; | ||
|  | 
 | ||
|  |     let value = ''; | ||
|  |     let valueStart; | ||
|  |     if (str.charCodeAt(i) === 34/* '"' */) { | ||
|  |       valueStart = ++i; | ||
|  |       let escaping = false; | ||
|  |       // Parse quoted value
 | ||
|  |       for (; i < str.length; ++i) { | ||
|  |         const code = str.charCodeAt(i); | ||
|  |         if (code === 92/* '\\' */) { | ||
|  |           if (escaping) { | ||
|  |             valueStart = i; | ||
|  |             escaping = false; | ||
|  |           } else { | ||
|  |             value += str.slice(valueStart, i); | ||
|  |             escaping = true; | ||
|  |           } | ||
|  |           continue; | ||
|  |         } | ||
|  |         if (code === 34/* '"' */) { | ||
|  |           if (escaping) { | ||
|  |             valueStart = i; | ||
|  |             escaping = false; | ||
|  |             continue; | ||
|  |           } | ||
|  |           value += str.slice(valueStart, i); | ||
|  |           break; | ||
|  |         } | ||
|  |         if (escaping) { | ||
|  |           valueStart = i - 1; | ||
|  |           escaping = false; | ||
|  |         } | ||
|  |         // Invalid unescaped quoted character (malformed)
 | ||
|  |         if (QDTEXT[code] !== 1) | ||
|  |           return; | ||
|  |       } | ||
|  | 
 | ||
|  |       // No end quote (malformed)
 | ||
|  |       if (i === str.length) | ||
|  |         return; | ||
|  | 
 | ||
|  |       ++i; // Skip over double quote
 | ||
|  |     } else { | ||
|  |       valueStart = i; | ||
|  |       // Parse unquoted value
 | ||
|  |       for (; i < str.length; ++i) { | ||
|  |         const code = str.charCodeAt(i); | ||
|  |         if (TOKEN[code] !== 1) { | ||
|  |           // No value (malformed)
 | ||
|  |           if (i === valueStart) | ||
|  |             return; | ||
|  |           break; | ||
|  |         } | ||
|  |       } | ||
|  |       value = str.slice(valueStart, i); | ||
|  |     } | ||
|  | 
 | ||
|  |     name = name.toLowerCase(); | ||
|  |     if (params[name] === undefined) | ||
|  |       params[name] = value; | ||
|  |   } | ||
|  | 
 | ||
|  |   return params; | ||
|  | } | ||
|  | 
 | ||
|  | function parseDisposition(str, defDecoder) { | ||
|  |   if (str.length === 0) | ||
|  |     return; | ||
|  | 
 | ||
|  |   const params = Object.create(null); | ||
|  |   let i = 0; | ||
|  | 
 | ||
|  |   for (; i < str.length; ++i) { | ||
|  |     const code = str.charCodeAt(i); | ||
|  |     if (TOKEN[code] !== 1) { | ||
|  |       if (parseDispositionParams(str, i, params, defDecoder) === undefined) | ||
|  |         return; | ||
|  |       break; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   const type = str.slice(0, i).toLowerCase(); | ||
|  | 
 | ||
|  |   return { type, params }; | ||
|  | } | ||
|  | 
 | ||
|  | function parseDispositionParams(str, i, params, defDecoder) { | ||
|  |   while (i < str.length) { | ||
|  |     // Consume whitespace
 | ||
|  |     for (; i < str.length; ++i) { | ||
|  |       const code = str.charCodeAt(i); | ||
|  |       if (code !== 32/* ' ' */ && code !== 9/* '\t' */) | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     // Ended on whitespace
 | ||
|  |     if (i === str.length) | ||
|  |       break; | ||
|  | 
 | ||
|  |     // Check for malformed parameter
 | ||
|  |     if (str.charCodeAt(i++) !== 59/* ';' */) | ||
|  |       return; | ||
|  | 
 | ||
|  |     // Consume whitespace
 | ||
|  |     for (; i < str.length; ++i) { | ||
|  |       const code = str.charCodeAt(i); | ||
|  |       if (code !== 32/* ' ' */ && code !== 9/* '\t' */) | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     // Ended on whitespace (malformed)
 | ||
|  |     if (i === str.length) | ||
|  |       return; | ||
|  | 
 | ||
|  |     let name; | ||
|  |     const nameStart = i; | ||
|  |     // Parse parameter name
 | ||
|  |     for (; i < str.length; ++i) { | ||
|  |       const code = str.charCodeAt(i); | ||
|  |       if (TOKEN[code] !== 1) { | ||
|  |         if (code === 61/* '=' */) | ||
|  |           break; | ||
|  |         return; | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     // No value (malformed)
 | ||
|  |     if (i === str.length) | ||
|  |       return; | ||
|  | 
 | ||
|  |     let value = ''; | ||
|  |     let valueStart; | ||
|  |     let charset; | ||
|  |     //~ let lang;
 | ||
|  |     name = str.slice(nameStart, i); | ||
|  |     if (name.charCodeAt(name.length - 1) === 42/* '*' */) { | ||
|  |       // Extended value
 | ||
|  | 
 | ||
|  |       const charsetStart = ++i; | ||
|  |       // Parse charset name
 | ||
|  |       for (; i < str.length; ++i) { | ||
|  |         const code = str.charCodeAt(i); | ||
|  |         if (CHARSET[code] !== 1) { | ||
|  |           if (code !== 39/* '\'' */) | ||
|  |             return; | ||
|  |           break; | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       // Incomplete charset (malformed)
 | ||
|  |       if (i === str.length) | ||
|  |         return; | ||
|  | 
 | ||
|  |       charset = str.slice(charsetStart, i); | ||
|  |       ++i; // Skip over the '\''
 | ||
|  | 
 | ||
|  |       //~ const langStart = ++i;
 | ||
|  |       // Parse language name
 | ||
|  |       for (; i < str.length; ++i) { | ||
|  |         const code = str.charCodeAt(i); | ||
|  |         if (code === 39/* '\'' */) | ||
|  |           break; | ||
|  |       } | ||
|  | 
 | ||
|  |       // Incomplete language (malformed)
 | ||
|  |       if (i === str.length) | ||
|  |         return; | ||
|  | 
 | ||
|  |       //~ lang = str.slice(langStart, i);
 | ||
|  |       ++i; // Skip over the '\''
 | ||
|  | 
 | ||
|  |       // No value (malformed)
 | ||
|  |       if (i === str.length) | ||
|  |         return; | ||
|  | 
 | ||
|  |       valueStart = i; | ||
|  | 
 | ||
|  |       let encode = 0; | ||
|  |       // Parse value
 | ||
|  |       for (; i < str.length; ++i) { | ||
|  |         const code = str.charCodeAt(i); | ||
|  |         if (EXTENDED_VALUE[code] !== 1) { | ||
|  |           if (code === 37/* '%' */) { | ||
|  |             let hexUpper; | ||
|  |             let hexLower; | ||
|  |             if (i + 2 < str.length | ||
|  |                 && (hexUpper = HEX_VALUES[str.charCodeAt(i + 1)]) !== -1 | ||
|  |                 && (hexLower = HEX_VALUES[str.charCodeAt(i + 2)]) !== -1) { | ||
|  |               const byteVal = (hexUpper << 4) + hexLower; | ||
|  |               value += str.slice(valueStart, i); | ||
|  |               value += String.fromCharCode(byteVal); | ||
|  |               i += 2; | ||
|  |               valueStart = i + 1; | ||
|  |               if (byteVal >= 128) | ||
|  |                 encode = 2; | ||
|  |               else if (encode === 0) | ||
|  |                 encode = 1; | ||
|  |               continue; | ||
|  |             } | ||
|  |             // '%' disallowed in non-percent encoded contexts (malformed)
 | ||
|  |             return; | ||
|  |           } | ||
|  |           break; | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       value += str.slice(valueStart, i); | ||
|  |       value = convertToUTF8(value, charset, encode); | ||
|  |       if (value === undefined) | ||
|  |         return; | ||
|  |     } else { | ||
|  |       // Non-extended value
 | ||
|  | 
 | ||
|  |       ++i; // Skip over '='
 | ||
|  | 
 | ||
|  |       // No value (malformed)
 | ||
|  |       if (i === str.length) | ||
|  |         return; | ||
|  | 
 | ||
|  |       if (str.charCodeAt(i) === 34/* '"' */) { | ||
|  |         valueStart = ++i; | ||
|  |         let escaping = false; | ||
|  |         // Parse quoted value
 | ||
|  |         for (; i < str.length; ++i) { | ||
|  |           const code = str.charCodeAt(i); | ||
|  |           if (code === 92/* '\\' */) { | ||
|  |             if (escaping) { | ||
|  |               valueStart = i; | ||
|  |               escaping = false; | ||
|  |             } else { | ||
|  |               value += str.slice(valueStart, i); | ||
|  |               escaping = true; | ||
|  |             } | ||
|  |             continue; | ||
|  |           } | ||
|  |           if (code === 34/* '"' */) { | ||
|  |             if (escaping) { | ||
|  |               valueStart = i; | ||
|  |               escaping = false; | ||
|  |               continue; | ||
|  |             } | ||
|  |             value += str.slice(valueStart, i); | ||
|  |             break; | ||
|  |           } | ||
|  |           if (escaping) { | ||
|  |             valueStart = i - 1; | ||
|  |             escaping = false; | ||
|  |           } | ||
|  |           // Invalid unescaped quoted character (malformed)
 | ||
|  |           if (QDTEXT[code] !== 1) | ||
|  |             return; | ||
|  |         } | ||
|  | 
 | ||
|  |         // No end quote (malformed)
 | ||
|  |         if (i === str.length) | ||
|  |           return; | ||
|  | 
 | ||
|  |         ++i; // Skip over double quote
 | ||
|  |       } else { | ||
|  |         valueStart = i; | ||
|  |         // Parse unquoted value
 | ||
|  |         for (; i < str.length; ++i) { | ||
|  |           const code = str.charCodeAt(i); | ||
|  |           if (TOKEN[code] !== 1) { | ||
|  |             // No value (malformed)
 | ||
|  |             if (i === valueStart) | ||
|  |               return; | ||
|  |             break; | ||
|  |           } | ||
|  |         } | ||
|  |         value = str.slice(valueStart, i); | ||
|  |       } | ||
|  | 
 | ||
|  |       value = defDecoder(value, 2); | ||
|  |       if (value === undefined) | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     name = name.toLowerCase(); | ||
|  |     if (params[name] === undefined) | ||
|  |       params[name] = value; | ||
|  |   } | ||
|  | 
 | ||
|  |   return params; | ||
|  | } | ||
|  | 
 | ||
|  | function getDecoder(charset) { | ||
|  |   let lc; | ||
|  |   while (true) { | ||
|  |     switch (charset) { | ||
|  |       case 'utf-8': | ||
|  |       case 'utf8': | ||
|  |         return decoders.utf8; | ||
|  |       case 'latin1': | ||
|  |       case 'ascii': // TODO: Make these a separate, strict decoder?
 | ||
|  |       case 'us-ascii': | ||
|  |       case 'iso-8859-1': | ||
|  |       case 'iso8859-1': | ||
|  |       case 'iso88591': | ||
|  |       case 'iso_8859-1': | ||
|  |       case 'windows-1252': | ||
|  |       case 'iso_8859-1:1987': | ||
|  |       case 'cp1252': | ||
|  |       case 'x-cp1252': | ||
|  |         return decoders.latin1; | ||
|  |       case 'utf16le': | ||
|  |       case 'utf-16le': | ||
|  |       case 'ucs2': | ||
|  |       case 'ucs-2': | ||
|  |         return decoders.utf16le; | ||
|  |       case 'base64': | ||
|  |         return decoders.base64; | ||
|  |       default: | ||
|  |         if (lc === undefined) { | ||
|  |           lc = true; | ||
|  |           charset = charset.toLowerCase(); | ||
|  |           continue; | ||
|  |         } | ||
|  |         return decoders.other.bind(charset); | ||
|  |     } | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | const decoders = { | ||
|  |   utf8: (data, hint) => { | ||
|  |     if (data.length === 0) | ||
|  |       return ''; | ||
|  |     if (typeof data === 'string') { | ||
|  |       // If `data` never had any percent-encoded bytes or never had any that
 | ||
|  |       // were outside of the ASCII range, then we can safely just return the
 | ||
|  |       // input since UTF-8 is ASCII compatible
 | ||
|  |       if (hint < 2) | ||
|  |         return data; | ||
|  | 
 | ||
|  |       data = Buffer.from(data, 'latin1'); | ||
|  |     } | ||
|  |     return data.utf8Slice(0, data.length); | ||
|  |   }, | ||
|  | 
 | ||
|  |   latin1: (data, hint) => { | ||
|  |     if (data.length === 0) | ||
|  |       return ''; | ||
|  |     if (typeof data === 'string') | ||
|  |       return data; | ||
|  |     return data.latin1Slice(0, data.length); | ||
|  |   }, | ||
|  | 
 | ||
|  |   utf16le: (data, hint) => { | ||
|  |     if (data.length === 0) | ||
|  |       return ''; | ||
|  |     if (typeof data === 'string') | ||
|  |       data = Buffer.from(data, 'latin1'); | ||
|  |     return data.ucs2Slice(0, data.length); | ||
|  |   }, | ||
|  | 
 | ||
|  |   base64: (data, hint) => { | ||
|  |     if (data.length === 0) | ||
|  |       return ''; | ||
|  |     if (typeof data === 'string') | ||
|  |       data = Buffer.from(data, 'latin1'); | ||
|  |     return data.base64Slice(0, data.length); | ||
|  |   }, | ||
|  | 
 | ||
|  |   other: (data, hint) => { | ||
|  |     if (data.length === 0) | ||
|  |       return ''; | ||
|  |     if (typeof data === 'string') | ||
|  |       data = Buffer.from(data, 'latin1'); | ||
|  |     try { | ||
|  |       const decoder = new TextDecoder(this); | ||
|  |       return decoder.decode(data); | ||
|  |     } catch {} | ||
|  |   }, | ||
|  | }; | ||
|  | 
 | ||
|  | function convertToUTF8(data, charset, hint) { | ||
|  |   const decode = getDecoder(charset); | ||
|  |   if (decode) | ||
|  |     return decode(data, hint); | ||
|  | } | ||
|  | 
 | ||
|  | function basename(path) { | ||
|  |   if (typeof path !== 'string') | ||
|  |     return ''; | ||
|  |   for (let i = path.length - 1; i >= 0; --i) { | ||
|  |     switch (path.charCodeAt(i)) { | ||
|  |       case 0x2F: // '/'
 | ||
|  |       case 0x5C: // '\'
 | ||
|  |         path = path.slice(i + 1); | ||
|  |         return (path === '..' || path === '.' ? '' : path); | ||
|  |     } | ||
|  |   } | ||
|  |   return (path === '..' || path === '.' ? '' : path); | ||
|  | } | ||
|  | 
 | ||
|  | const TOKEN = [ | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  | ]; | ||
|  | 
 | ||
|  | const QDTEXT = [ | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  | ]; | ||
|  | 
 | ||
|  | const CHARSET = [ | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  | ]; | ||
|  | 
 | ||
|  | const EXTENDED_VALUE = [ | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
|  |   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  |   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
|  | ]; | ||
|  | 
 | ||
|  | /* eslint-disable no-multi-spaces */ | ||
|  | const HEX_VALUES = [ | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  |   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
|  | ]; | ||
|  | /* eslint-enable no-multi-spaces */ | ||
|  | 
 | ||
|  | module.exports = { | ||
|  |   basename, | ||
|  |   convertToUTF8, | ||
|  |   getDecoder, | ||
|  |   parseContentType, | ||
|  |   parseDisposition, | ||
|  | }; |