2017-09-22 22:18:51 +00:00
var XML _HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n' ;
2017-04-16 04:32:13 +00:00
var attregexg = /([^"\s?>\/]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g ;
2017-08-08 15:57:33 +00:00
var tagregex = /<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+=(?:"[^"]*"|'[^']*'|[^'">\s]+))*\s?[\/\?]?>/g ;
2017-09-22 22:18:51 +00:00
if ( ! ( XML _HEADER . match ( tagregex ) ) ) tagregex = /<[^>]*>/g ;
2014-06-29 18:29:45 +00:00
var nsregex = /<\w*:/ , nsregex2 = /<(\/?)\w+:/ ;
2017-02-10 19:23:01 +00:00
function parsexmltag ( tag /*:string*/ , skip _root /*:?boolean*/ ) /*:any*/ {
2017-03-22 07:50:11 +00:00
var z = ( { } /*:any*/ ) ;
2014-06-29 18:29:45 +00:00
var eq = 0 , c = 0 ;
for ( ; eq !== tag . length ; ++ eq ) if ( ( c = tag . charCodeAt ( eq ) ) === 32 || c === 10 || c === 13 ) break ;
if ( ! skip _root ) z [ 0 ] = tag . substr ( 0 , eq ) ;
if ( eq === tag . length ) return z ;
2017-04-16 04:32:13 +00:00
var m = tag . match ( attregexg ) , j = 0 , v = "" , i = 0 , q = "" , cc = "" , quot = 1 ;
2014-06-02 05:19:07 +00:00
if ( m ) for ( i = 0 ; i != m . length ; ++ i ) {
2014-06-29 18:29:45 +00:00
cc = m [ i ] ;
for ( c = 0 ; c != cc . length ; ++ c ) if ( cc . charCodeAt ( c ) === 61 ) break ;
2017-04-16 04:32:13 +00:00
q = cc . substr ( 0 , c ) ;
quot = ( ( eq = cc . charCodeAt ( c + 1 ) ) == 34 || eq == 39 ) ? 1 : 0 ;
v = cc . substring ( c + 1 + quot , cc . length - quot ) ;
2014-06-29 18:29:45 +00:00
for ( j = 0 ; j != q . length ; ++ j ) if ( q . charCodeAt ( j ) === 58 ) break ;
2017-03-10 01:09:18 +00:00
if ( j === q . length ) {
2016-10-11 05:08:51 +00:00
if ( q . indexOf ( "_" ) > 0 ) q = q . substr ( 0 , q . indexOf ( "_" ) ) ; // from ods
2017-03-10 01:09:18 +00:00
z [ q ] = v ;
}
else {
var k = ( j === 5 && q . substr ( 0 , 5 ) === "xmlns" ? "xmlns" : "" ) + q . substr ( j + 1 ) ;
2016-10-11 05:08:51 +00:00
if ( z [ k ] && q . substr ( j - 3 , 3 ) == "ext" ) continue ; // from ods
2017-03-10 01:09:18 +00:00
z [ k ] = v ;
}
2014-06-02 05:19:07 +00:00
}
2013-05-02 16:59:27 +00:00
return z ;
}
2017-02-10 19:23:01 +00:00
function strip _ns ( x /*:string*/ ) /*:string*/ { return x . replace ( nsregex2 , "<$1" ) ; }
2013-05-02 16:59:27 +00:00
var encodings = {
'"' : '"' ,
''' : "'" ,
'>' : '>' ,
'<' : '<' ,
'&' : '&'
} ;
2014-01-29 06:00:09 +00:00
var rencoding = evert ( encodings ) ;
2017-05-09 18:07:57 +00:00
//var rencstr = "&<>'\"".split("");
2014-01-29 06:00:09 +00:00
2013-05-02 16:59:27 +00:00
// TODO: CP remap (need to read file version to determine OS)
2017-02-10 19:23:01 +00:00
var unescapexml /*:StringConv*/ = ( function ( ) {
2017-03-06 02:27:21 +00:00
/* 22.4.2.4 bstr (Basic String) */
2017-03-16 01:17:24 +00:00
var encregex = /&(?:quot|apos|gt|lt|amp|#x?([\da-fA-F]+));/g , coderegex = /_x([\da-fA-F]{4})_/g ;
2017-02-10 19:23:01 +00:00
return function unescapexml ( text /*:string*/ ) /*:string*/ {
2017-08-10 23:46:34 +00:00
var s = text + '' , i = s . indexOf ( "<![CDATA[" ) ;
if ( i == - 1 ) return s . replace ( encregex , function ( $$ , $1 ) { return encodings [ $$ ] || String . fromCharCode ( parseInt ( $1 , $$ . indexOf ( "x" ) > - 1 ? 16 : 10 ) ) || $$ ; } ) . replace ( coderegex , function ( m , c ) { return String . fromCharCode ( parseInt ( c , 16 ) ) ; } ) ;
var j = s . indexOf ( "]]>" ) ;
return unescapexml ( s . slice ( 0 , i ) ) + s . slice ( i + 9 , j ) + unescapexml ( s . slice ( j + 3 ) ) ;
2015-04-02 20:32:22 +00:00
} ;
} ) ( ) ;
2014-06-29 18:29:45 +00:00
var decregex = /[&<>'"]/g , charegex = /[\u0000-\u0008\u000b-\u001f]/g ;
2017-03-16 01:17:24 +00:00
function escapexml ( text /*:string*/ , xml /*:?boolean*/ ) /*:string*/ {
2014-01-28 16:38:02 +00:00
var s = text + '' ;
2017-02-22 06:57:59 +00:00
return s . replace ( decregex , function ( y ) { return rencoding [ y ] ; } ) . replace ( charegex , function ( s ) { return "_x" + ( "000" + s . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 4 ) + "_" ; } ) ;
2014-01-28 16:38:02 +00:00
}
2017-03-14 08:19:51 +00:00
function escapexmltag ( text /*:string*/ ) /*:string*/ { return escapexml ( text ) . replace ( / /g , "_x0020_" ) ; }
2014-01-28 16:38:02 +00:00
2017-04-16 04:32:13 +00:00
var htmlcharegex = /[\u0000-\u001f]/g ;
2017-04-13 18:28:16 +00:00
function escapehtml ( text ) {
var s = text + '' ;
2017-04-16 04:32:13 +00:00
return s . replace ( decregex , function ( y ) { return rencoding [ y ] ; } ) . replace ( htmlcharegex , function ( s ) { return "&#x" + ( "000" + s . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 4 ) + ";" ; } ) ;
2017-04-13 18:28:16 +00:00
}
2015-04-02 20:32:22 +00:00
/* TODO: handle codepages */
2017-02-10 19:23:01 +00:00
var xlml _fixstr /*:StringConv*/ = ( function ( ) {
2015-04-02 20:32:22 +00:00
var entregex = /&#(\d+);/g ;
2017-02-10 19:23:01 +00:00
function entrepl ( $$ /*:string*/ , $1 /*:string*/ ) /*:string*/ { return String . fromCharCode ( parseInt ( $1 , 10 ) ) ; }
return function xlml _fixstr ( str /*:string*/ ) /*:string*/ { return str . replace ( entregex , entrepl ) ; } ;
2015-04-02 20:32:22 +00:00
} ) ( ) ;
2017-04-02 06:47:25 +00:00
var xlml _unfixstr /*:StringConv*/ = ( function ( ) {
return function xlml _unfixstr ( str /*:string*/ ) /*:string*/ { return str . replace ( /(\r\n|[\r\n])/g , "\ " ) ; } ;
} ) ( ) ;
2015-04-02 20:32:22 +00:00
2017-02-10 19:23:01 +00:00
function parsexmlbool ( value /*:any*/ , tag /*:?string*/ ) /*:boolean*/ {
2013-05-02 16:59:27 +00:00
switch ( value ) {
2017-06-01 21:22:11 +00:00
case 1 : case true : case '1' : case 'true' : case 'TRUE' : return true ;
2014-06-29 18:29:45 +00:00
/* case '0': case 'false': case 'FALSE':*/
default : return false ;
2013-05-02 16:59:27 +00:00
}
}
2017-02-10 19:23:01 +00:00
var utf8read /*:StringConv*/ = function utf8reada ( orig ) {
2014-06-29 18:29:45 +00:00
var out = "" , i = 0 , c = 0 , d = 0 , e = 0 , f = 0 , w = 0 ;
2013-05-02 16:59:27 +00:00
while ( i < orig . length ) {
c = orig . charCodeAt ( i ++ ) ;
2014-06-29 18:29:45 +00:00
if ( c < 128 ) { out += String . fromCharCode ( c ) ; continue ; }
d = orig . charCodeAt ( i ++ ) ;
2017-07-10 22:18:18 +00:00
if ( c > 191 && c < 224 ) { f = ( ( c & 31 ) << 6 ) ; f |= ( d & 63 ) ; out += String . fromCharCode ( f ) ; continue ; }
2014-06-29 18:29:45 +00:00
e = orig . charCodeAt ( i ++ ) ;
if ( c < 240 ) { out += String . fromCharCode ( ( ( c & 15 ) << 12 ) | ( ( d & 63 ) << 6 ) | ( e & 63 ) ) ; continue ; }
f = orig . charCodeAt ( i ++ ) ;
w = ( ( ( c & 7 ) << 18 ) | ( ( d & 63 ) << 12 ) | ( ( e & 63 ) << 6 ) | ( f & 63 ) ) - 65536 ;
out += String . fromCharCode ( 0xD800 + ( ( w >>> 10 ) & 1023 ) ) ;
out += String . fromCharCode ( 0xDC00 + ( w & 1023 ) ) ;
2013-05-02 16:59:27 +00:00
}
2014-06-29 18:29:45 +00:00
return out ;
2013-05-02 16:59:27 +00:00
} ;
2017-09-30 06:18:11 +00:00
var utf8write /*:StringConv*/ = function ( orig ) {
var out = [ ] , i = 0 , c = 0 , d = 0 ;
while ( i < orig . length ) {
c = orig . charCodeAt ( i ++ ) ;
switch ( true ) {
case c < 128 : out . push ( String . fromCharCode ( c ) ) ; break ;
case c < 2048 :
out . push ( String . fromCharCode ( 192 + ( c >> 6 ) ) ) ;
out . push ( String . fromCharCode ( 128 + ( c & 63 ) ) ) ;
break ;
case c >= 55296 && c < 57344 :
c -= 55296 ; d = orig . charCodeAt ( i ++ ) - 56320 + ( c << 10 ) ;
out . push ( String . fromCharCode ( 240 + ( ( d >> 18 ) & 7 ) ) ) ;
out . push ( String . fromCharCode ( 144 + ( ( d >> 12 ) & 63 ) ) ) ;
out . push ( String . fromCharCode ( 128 + ( ( d >> 6 ) & 63 ) ) ) ;
out . push ( String . fromCharCode ( 128 + ( d & 63 ) ) ) ;
break ;
default :
out . push ( String . fromCharCode ( 224 + ( c >> 12 ) ) ) ;
out . push ( String . fromCharCode ( 128 + ( ( c >> 6 ) & 63 ) ) ) ;
out . push ( String . fromCharCode ( 128 + ( c & 63 ) ) ) ;
}
}
return out . join ( "" ) ;
} ;
2014-06-29 18:29:45 +00:00
2014-07-28 13:22:32 +00:00
if ( has _buf ) {
2014-06-29 18:29:45 +00:00
var utf8readb = function utf8readb ( data ) {
var out = new Buffer ( 2 * data . length ) , w , i , j = 1 , k = 0 , ww = 0 , c ;
for ( i = 0 ; i < data . length ; i += j ) {
j = 1 ;
if ( ( c = data . charCodeAt ( i ) ) < 128 ) w = c ;
else if ( c < 224 ) { w = ( c & 31 ) * 64 + ( data . charCodeAt ( i + 1 ) & 63 ) ; j = 2 ; }
else if ( c < 240 ) { w = ( c & 15 ) * 4096 + ( data . charCodeAt ( i + 1 ) & 63 ) * 64 + ( data . charCodeAt ( i + 2 ) & 63 ) ; j = 3 ; }
else { j = 4 ;
w = ( c & 7 ) * 262144 + ( data . charCodeAt ( i + 1 ) & 63 ) * 4096 + ( data . charCodeAt ( i + 2 ) & 63 ) * 64 + ( data . charCodeAt ( i + 3 ) & 63 ) ;
w -= 65536 ; ww = 0xD800 + ( ( w >>> 10 ) & 1023 ) ; w = 0xDC00 + ( w & 1023 ) ;
}
if ( ww !== 0 ) { out [ k ++ ] = ww & 255 ; out [ k ++ ] = ww >>> 8 ; ww = 0 ; }
out [ k ++ ] = w % 256 ; out [ k ++ ] = w >>> 8 ;
}
2017-05-13 18:21:22 +00:00
return out . slice ( 0 , k ) . toString ( 'ucs2' ) ;
2014-06-29 18:29:45 +00:00
} ;
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3" ;
if ( utf8read ( corpus ) == utf8readb ( corpus ) ) utf8read = utf8readb ;
2017-03-12 18:02:43 +00:00
// $FlowIgnore
2014-06-29 18:29:45 +00:00
var utf8readc = function utf8readc ( data ) { return Buffer ( data , 'binary' ) . toString ( 'utf8' ) ; } ;
if ( utf8read ( corpus ) == utf8readc ( corpus ) ) utf8read = utf8readc ;
2017-09-30 06:18:11 +00:00
utf8write = function ( data ) { return new Buffer ( data , 'utf8' ) . toString ( "binary" ) ; } ;
2014-06-29 18:29:45 +00:00
}
2013-05-02 16:59:27 +00:00
// matches <foo>...</foo> extracts content
2014-06-29 18:29:45 +00:00
var matchtag = ( function ( ) {
2017-03-12 18:02:43 +00:00
var mtcache /*:{[k:string]:RegExp}*/ = ( { } /*:any*/ ) ;
return function matchtag ( f , g /*:?string*/ ) /*:RegExp*/ {
2017-02-10 19:23:01 +00:00
var t = f + "|" + ( g || "" ) ;
2017-03-12 18:02:43 +00:00
if ( mtcache [ t ] ) return mtcache [ t ] ;
2017-06-24 06:51:37 +00:00
return ( mtcache [ t ] = new RegExp ( '<(?:\\w+:)?' + f + '(?: xml:space="preserve")?(?:[^>]*)>([\\s\\S]*?)</(?:\\w+:)?' + f + '>' , ( ( g || "" ) /*:any*/ ) ) ) ;
2014-06-29 18:29:45 +00:00
} ;
} ) ( ) ;
2013-05-02 16:59:27 +00:00
2017-09-30 06:18:11 +00:00
function htmldecode ( str /*:string*/ ) /*:string*/ {
return str . trim ( ) . replace ( /\s+/g , " " ) . replace ( /<\s*[bB][rR]\s*\/?/g , "\n" ) . replace ( /<[^>]*>/g , "" ) . replace ( / /g , " " ) ;
}
2014-06-29 18:29:45 +00:00
var vtregex = ( function ( ) { var vt _cache = { } ;
return function vt _regex ( bt ) {
if ( vt _cache [ bt ] !== undefined ) return vt _cache [ bt ] ;
2017-07-05 22:27:54 +00:00
return ( vt _cache [ bt ] = new RegExp ( "<(?:vt:)?" + bt + ">([\\s\\S]*?)</(?:vt:)?" + bt + ">" , 'g' ) ) ;
2014-06-29 18:29:45 +00:00
} ; } ) ( ) ;
2017-07-05 22:27:54 +00:00
var vtvregex = /<\/?(?:vt:)?variant>/g , vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</ ;
2017-08-03 15:51:16 +00:00
function parseVector ( data , opts ) {
2013-05-02 16:59:27 +00:00
var h = parsexmltag ( data ) ;
2014-06-29 18:29:45 +00:00
var matches = data . match ( vtregex ( h . baseType ) ) || [ ] ;
2013-05-02 16:59:27 +00:00
var res = [ ] ;
2017-08-03 15:51:16 +00:00
if ( matches . length != h . size ) {
if ( opts . WTF ) throw new Error ( "unexpected vector length " + matches . length + " != " + h . size ) ;
return res ;
}
2013-05-02 16:59:27 +00:00
matches . forEach ( function ( x ) {
2014-06-29 18:29:45 +00:00
var v = x . replace ( vtvregex , "" ) . match ( vtmregex ) ;
2017-03-25 18:14:28 +00:00
res . push ( { v : utf8read ( v [ 2 ] ) , t : v [ 1 ] } ) ;
2013-05-02 16:59:27 +00:00
} ) ;
return res ;
}
2014-06-29 18:29:45 +00:00
var wtregex = /(^\s|\s$|\n)/ ;
function writetag ( f , g ) { return '<' + f + ( g . match ( wtregex ) ? ' xml:space="preserve"' : "" ) + '>' + g + '</' + f + '>' ; }
2014-05-16 00:33:34 +00:00
2017-02-10 19:23:01 +00:00
function wxt _helper ( h ) /*:string*/ { return keys ( h ) . map ( function ( k ) { return " " + k + '="' + h [ k ] + '"' ; } ) . join ( "" ) ; }
function writextag ( f , g , h ) { return '<' + f + ( isval ( h ) /*:: && h */ ? wxt _helper ( h ) : "" ) + ( isval ( g ) /*:: && g */ ? ( g . match ( wtregex ) ? ' xml:space="preserve"' : "" ) + '>' + g + '</' + f : "/" ) + '>' ; }
2014-05-16 00:33:34 +00:00
2017-02-10 19:23:01 +00:00
function write _w3cdtf ( d /*:Date*/ , t /*:?boolean*/ ) /*:string*/ { try { return d . toISOString ( ) . replace ( /\.\d*/ , "" ) ; } catch ( e ) { if ( t ) throw e ; } return "" ; }
2014-05-16 00:33:34 +00:00
function write _vt ( s ) {
2014-06-29 18:29:45 +00:00
switch ( typeof s ) {
case 'string' : return writextag ( 'vt:lpwstr' , s ) ;
case 'number' : return writextag ( ( s | 0 ) == s ? 'vt:i4' : 'vt:r8' , String ( s ) ) ;
case 'boolean' : return writextag ( 'vt:bool' , s ? 'true' : 'false' ) ;
}
2014-05-16 00:33:34 +00:00
if ( s instanceof Date ) return writextag ( 'vt:filetime' , write _w3cdtf ( s ) ) ;
throw new Error ( "Unable to serialize " + s ) ;
}
2017-02-10 19:23:01 +00:00
var XMLNS = ( {
2014-05-16 00:33:34 +00:00
'dc' : 'http://purl.org/dc/elements/1.1/' ,
'dcterms' : 'http://purl.org/dc/terms/' ,
'dcmitype' : 'http://purl.org/dc/dcmitype/' ,
'mx' : 'http://schemas.microsoft.com/office/mac/excel/2008/main' ,
'r' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' ,
'sjs' : 'http://schemas.openxmlformats.org/package/2006/sheetjs/core-properties' ,
'vt' : 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes' ,
'xsi' : 'http://www.w3.org/2001/XMLSchema-instance' ,
'xsd' : 'http://www.w3.org/2001/XMLSchema'
2017-02-10 19:23:01 +00:00
} /*:any*/ ) ;
2014-05-16 00:33:34 +00:00
XMLNS . main = [
'http://schemas.openxmlformats.org/spreadsheetml/2006/main' ,
'http://purl.oclc.org/ooxml/spreadsheetml/main' ,
'http://schemas.microsoft.com/office/excel/2006/main' ,
'http://schemas.microsoft.com/office/excel/2006/2'
] ;
2015-04-02 20:32:22 +00:00
2017-03-14 08:19:51 +00:00
var XLMLNS = ( {
'o' : 'urn:schemas-microsoft-com:office:office' ,
'x' : 'urn:schemas-microsoft-com:office:excel' ,
'ss' : 'urn:schemas-microsoft-com:office:spreadsheet' ,
'dt' : 'uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' ,
2017-04-02 06:47:25 +00:00
'mv' : 'http://macVmlSchemaUri' ,
'v' : 'urn:schemas-microsoft-com:vml' ,
2017-03-14 08:19:51 +00:00
'html' : 'http://www.w3.org/TR/REC-html40'
} /*:any*/ ) ;