11/* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */
22/*jshint -W041 */
3- var SSF = { } ;
4- var make_ssf = function make_ssf ( SSF ) {
5- SSF . version = '0.9.4 ' ;
3+ var SSF /*:SSFModule*/ = ( { } /*:any*/ ) ;
4+ var make_ssf = function make_ssf ( SSF /*:SSFModule*/ ) {
5+ SSF . version = '0.10.0 ' ;
66function _strrev ( x /*:string*/ ) /*:string*/ { var o = "" , i = x . length - 1 ; while ( i >= 0 ) o += x . charAt ( i -- ) ; return o ; }
77function fill ( c /*:string*/ , l /*:number*/ ) /*:string*/ { var o = "" ; while ( o . length < l ) o += c ; return o ; }
88function pad0 ( v /*:any*/ , d /*:number*/ ) /*:string*/ { var t = "" + v ; return t . length >= d ?t :fill ( '0' , d - t . length ) + t ; }
@@ -13,16 +13,9 @@ function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=
1313var p2_32 = Math . pow ( 2 , 32 ) ;
1414function pad0r ( v /*:any*/ , d /*:number*/ ) /*:string*/ { if ( v > p2_32 || v < - p2_32 ) return pad0r1 ( v , d ) ; var i = Math . round ( v ) ; return pad0r2 ( i , d ) ; }
1515function isgeneral ( s /*:string*/ , i /*:?number*/ ) /*:boolean*/ { i = i || 0 ; return s . length >= 7 + i && ( s . charCodeAt ( i ) | 32 ) === 103 && ( s . charCodeAt ( i + 1 ) | 32 ) === 101 && ( s . charCodeAt ( i + 2 ) | 32 ) === 110 && ( s . charCodeAt ( i + 3 ) | 32 ) === 101 && ( s . charCodeAt ( i + 4 ) | 32 ) === 114 && ( s . charCodeAt ( i + 5 ) | 32 ) === 97 && ( s . charCodeAt ( i + 6 ) | 32 ) === 108 ; }
16- /* Options */
17- var opts_fmt /*:Array<Array<any> >*/ = [
18- [ "date1904" , 0 ] ,
19- [ "output" , "" ] ,
20- [ "WTF" , false ]
21- ] ;
22- function fixopts ( o ) {
23- for ( var y = 0 ; y != opts_fmt . length ; ++ y ) if ( o [ opts_fmt [ y ] [ 0 ] ] === undefined ) o [ opts_fmt [ y ] [ 0 ] ] = opts_fmt [ y ] [ 1 ] ;
24- }
25- SSF . opts = opts_fmt ;
16+ /*::
17+ type SSF_write_num = {(type:string, fmt:string, val:number):string};
18+ */
2619var days /*:Array<Array<string> >*/ = [
2720 [ 'Sun' , 'Sunday' ] ,
2821 [ 'Mon' , 'Monday' ] ,
@@ -101,7 +94,47 @@ function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/
10194 var q = Math . floor ( sgn * P / Q ) ;
10295 return [ q , sgn * P - q * Q , Q ] ;
10396}
104- function general_fmt_int ( v /*:number*/ ) /*:string*/ { return "" + v ; }
97+ function parse_date_code ( v /*:number*/ , opts /*:?any*/ , b2 /*:?boolean*/ ) {
98+ if ( v > 2958465 || v < 0 ) return null ;
99+ var date = ( v | 0 ) , time = Math . floor ( 86400 * ( v - date ) ) , dow = 0 ;
100+ var dout = [ ] ;
101+ var out = { D :date , T :time , u :86400 * ( v - date ) - time , y :0 , m :0 , d :0 , H :0 , M :0 , S :0 , q :0 } ;
102+ if ( Math . abs ( out . u ) < 1e-6 ) out . u = 0 ;
103+ if ( opts && opts . date1904 ) date += 1462 ;
104+ if ( out . u > 0.9999 ) {
105+ out . u = 0 ;
106+ if ( ++ time == 86400 ) { out . T = time = 0 ; ++ date ; ++ out . D ; }
107+ }
108+ if ( date === 60 ) { dout = b2 ? [ 1317 , 10 , 29 ] : [ 1900 , 2 , 29 ] ; dow = 3 ; }
109+ else if ( date === 0 ) { dout = b2 ? [ 1317 , 8 , 29 ] : [ 1900 , 1 , 0 ] ; dow = 6 ; }
110+ else {
111+ if ( date > 60 ) -- date ;
112+ /* 1 = Jan 1 1900 in Gregorian */
113+ var d = new Date ( 1900 , 0 , 1 ) ;
114+ d . setDate ( d . getDate ( ) + date - 1 ) ;
115+ dout = [ d . getFullYear ( ) , d . getMonth ( ) + 1 , d . getDate ( ) ] ;
116+ dow = d . getDay ( ) ;
117+ if ( date < 60 ) dow = ( dow + 6 ) % 7 ;
118+ if ( b2 ) dow = fix_hijri ( d , dout ) ;
119+ }
120+ out . y = dout [ 0 ] ; out . m = dout [ 1 ] ; out . d = dout [ 2 ] ;
121+ out . S = time % 60 ; time = Math . floor ( time / 60 ) ;
122+ out . M = time % 60 ; time = Math . floor ( time / 60 ) ;
123+ out . H = time ;
124+ out . q = dow ;
125+ return out ;
126+ }
127+ SSF . parse_date_code = parse_date_code ;
128+ var basedate = new Date ( 1899 , 11 , 31 , 0 , 0 , 0 ) ;
129+ var dnthresh = basedate . getTime ( ) ;
130+ var base1904 = new Date ( 1900 , 2 , 1 , 0 , 0 , 0 ) ;
131+ function datenum_local ( v /*:Date*/ , date1904 /*:?boolean*/ ) /*:number*/ {
132+ var epoch = v . getTime ( ) ;
133+ if ( date1904 ) epoch -= 1461 * 24 * 60 * 60 * 1000 ;
134+ else if ( v >= base1904 ) epoch += 24 * 60 * 60 * 1000 ;
135+ return ( epoch - ( dnthresh + ( v . getTimezoneOffset ( ) - basedate . getTimezoneOffset ( ) ) * 60000 ) ) / ( 24 * 60 * 60 * 1000 ) ;
136+ }
137+ function general_fmt_int ( v /*:number*/ ) /*:string*/ { return v . toString ( 10 ) ; }
105138SSF . _general_int = general_fmt_int ;
106139var general_fmt_num = ( function make_general_fmt_num ( ) {
107140var gnr1 = / \. ( \d * [ 1 - 9 ] ) 0 + $ / , gnr2 = / \. 0 * $ / , gnr4 = / \. ( \d * [ 1 - 9 ] ) 0 + / , gnr5 = / \. 0 * [ E e ] / , gnr6 = / ( E [ + - ] ) ( \d ) $ / ;
@@ -132,50 +165,20 @@ return function general_fmt_num(v/*:number*/)/*:string*/ {
132165 return gfn5 ( gfn4 ( o ) ) ;
133166} ; } ) ( ) ;
134167SSF . _general_num = general_fmt_num ;
135- function general_fmt ( v /*:any*/ ) {
168+ function general_fmt ( v /*:any*/ , opts /*:any*/ ) {
136169 switch ( typeof v ) {
137170 case 'string' : return v ;
138171 case 'boolean' : return v ? "TRUE" : "FALSE" ;
139- case 'number' : return ( v | 0 ) === v ? general_fmt_int ( v /*, opts*/ ) : general_fmt_num ( v /*, opts*/ ) ;
172+ case 'number' : return ( v | 0 ) === v ? general_fmt_int ( v ) : general_fmt_num ( v ) ;
140173 case 'undefined' : return "" ;
141- case 'object' : if ( v == null ) return "" ;
174+ case 'object' :
175+ if ( v == null ) return "" ;
176+ if ( v instanceof Date ) return format ( 14 , datenum_local ( v , opts && opts . date1904 ) , opts ) ;
142177 }
143178 throw new Error ( "unsupported value in General format: " + v ) ;
144179}
145180SSF . _general = general_fmt ;
146- function fix_hijri ( /*date, o*/ ) { return 0 ; }
147- function parse_date_code ( v /*:number*/ , opts /*:?any*/ , b2 /*:?boolean*/ ) {
148- if ( v > 2958465 || v < 0 ) return null ;
149- var date = ( v | 0 ) , time = Math . floor ( 86400 * ( v - date ) ) , dow = 0 ;
150- var dout = [ ] ;
151- var out = { D :date , T :time , u :86400 * ( v - date ) - time , y :0 , m :0 , d :0 , H :0 , M :0 , S :0 , q :0 } ;
152- if ( Math . abs ( out . u ) < 1e-6 ) out . u = 0 ;
153- fixopts ( opts != null ? opts : ( opts = [ ] ) ) ;
154- if ( opts . date1904 ) date += 1462 ;
155- if ( out . u > 0.9999 ) {
156- out . u = 0 ;
157- if ( ++ time == 86400 ) { out . T = time = 0 ; ++ date ; ++ out . D ; }
158- }
159- if ( date === 60 ) { dout = b2 ? [ 1317 , 10 , 29 ] : [ 1900 , 2 , 29 ] ; dow = 3 ; }
160- else if ( date === 0 ) { dout = b2 ? [ 1317 , 8 , 29 ] : [ 1900 , 1 , 0 ] ; dow = 6 ; }
161- else {
162- if ( date > 60 ) -- date ;
163- /* 1 = Jan 1 1900 in Gregorian */
164- var d = new Date ( 1900 , 0 , 1 ) ;
165- d . setDate ( d . getDate ( ) + date - 1 ) ;
166- dout = [ d . getFullYear ( ) , d . getMonth ( ) + 1 , d . getDate ( ) ] ;
167- dow = d . getDay ( ) ;
168- if ( date < 60 ) dow = ( dow + 6 ) % 7 ;
169- if ( b2 ) dow = fix_hijri ( d , dout ) ;
170- }
171- out . y = dout [ 0 ] ; out . m = dout [ 1 ] ; out . d = dout [ 2 ] ;
172- out . S = time % 60 ; time = Math . floor ( time / 60 ) ;
173- out . M = time % 60 ; time = Math . floor ( time / 60 ) ;
174- out . H = time ;
175- out . q = dow ;
176- return out ;
177- }
178- SSF . parse_date_code = parse_date_code ;
181+ function fix_hijri ( /*::date, o*/ ) { return 0 ; }
179182/*jshint -W086 */
180183function write_date ( type /*:number*/ , fmt /*:string*/ , val , ss0 /*:?number*/ ) /*:string*/ {
181184 var o = "" , ss = 0 , tt = 0 , y = val . y , out , outl = 0 ;
@@ -217,23 +220,17 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str
217220 default : throw 'bad minute format: ' + fmt ;
218221 } break ;
219222 case 115 : /* 's' seconds */
220- if ( val . u === 0 ) switch ( fmt ) {
221- case 's' : case 'ss' : return pad0 ( val . S , fmt . length ) ;
222- case '.0' : case '.00' : case '.000' :
223- }
224- switch ( fmt ) {
225- case 's' : case 'ss' : case '.0' : case '.00' : case '.000' :
226- /*::if(!ss0) ss0 = 0; */
227- if ( ss0 >= 2 ) tt = ss0 === 3 ? 1000 : 100 ;
228- else tt = ss0 === 1 ? 10 : 1 ;
229- ss = Math . round ( ( tt ) * ( val . S + val . u ) ) ;
230- if ( ss >= 60 * tt ) ss = 0 ;
231- if ( fmt === 's' ) return ss === 0 ? "0" : "" + ss / tt ;
232- o = pad0 ( ss , 2 + ss0 ) ;
233- if ( fmt === 'ss' ) return o . substr ( 0 , 2 ) ;
234- return "." + o . substr ( 2 , fmt . length - 1 ) ;
235- default : throw 'bad second format: ' + fmt ;
236- }
223+ if ( fmt != 's' && fmt != 'ss' && fmt != '.0' && fmt != '.00' && fmt != '.000' ) throw 'bad second format: ' + fmt ;
224+ if ( val . u === 0 && ( fmt == "s" || fmt == "ss" ) ) return pad0 ( val . S , fmt . length ) ;
225+ /*::if(!ss0) ss0 = 0; */
226+ if ( ss0 >= 2 ) tt = ss0 === 3 ? 1000 : 100 ;
227+ else tt = ss0 === 1 ? 10 : 1 ;
228+ ss = Math . round ( ( tt ) * ( val . S + val . u ) ) ;
229+ if ( ss >= 60 * tt ) ss = 0 ;
230+ if ( fmt === 's' ) return ss === 0 ? "0" : "" + ss / tt ;
231+ o = pad0 ( ss , 2 + ss0 ) ;
232+ if ( fmt === 'ss' ) return o . substr ( 0 , 2 ) ;
233+ return "." + o . substr ( 2 , fmt . length - 1 ) ;
237234 case 90 : /* 'Z' absolute time */
238235 switch ( fmt ) {
239236 case '[h]' : case '[hh]' : out = val . D * 24 + val . H ; break ;
@@ -248,12 +245,13 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str
248245}
249246/*jshint +W086 */
250247function commaify ( s /*:string*/ ) /*:string*/ {
251- if ( s . length <= 3 ) return s ;
252- var j = ( s . length % 3 ) , o = s . substr ( 0 , j ) ;
253- for ( ; j != s . length ; j += 3 ) o += ( o . length > 0 ? "," : "" ) + s . substr ( j , 3 ) ;
248+ var w = 3 ;
249+ if ( s . length <= w ) return s ;
250+ var j = ( s . length % w ) , o = s . substr ( 0 , j ) ;
251+ for ( ; j != s . length ; j += w ) o += ( o . length > 0 ? "," : "" ) + s . substr ( j , w ) ;
254252 return o ;
255253}
256- var write_num = ( function make_write_num ( ) {
254+ var write_num /*:SSF_write_num*/ = ( function make_write_num ( ) {
257255var pct1 = / % / g;
258256function write_num_pct ( type /*:string*/ , fmt /*:string*/ , val /*:number*/ ) /*:string*/ {
259257 var sfmt = fmt . replace ( pct1 , "" ) , mul = fmt . length - sfmt . length ;
@@ -591,7 +589,7 @@ function fmt_is_date(fmt/*:string*/)/*:boolean*/ {
591589}
592590SSF . is_date = fmt_is_date ;
593591function eval_fmt ( fmt /*:string*/ , v /*:any*/ , opts /*:any*/ , flen /*:number*/ ) {
594- var out = [ ] , o = "" , i = 0 , c = "" , lst = 't' , q , dt , j , cc ;
592+ var out = [ ] , o = "" , i = 0 , c = "" , lst = 't' , dt , j , cc ;
595593 var hr = 'H' ;
596594 /* Tokenize */
597595 while ( i < fmt . length ) {
@@ -619,12 +617,12 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
619617 case 'm' : case 'd' : case 'y' : case 'h' : case 's' : case 'e' : case 'g' :
620618 if ( v < 0 ) return "" ;
621619 if ( dt == null ) { dt = parse_date_code ( v , opts ) ; if ( dt == null ) return "" ; }
622- o = c ; while ( ++ i < fmt . length && fmt . charAt ( i ) . toLowerCase ( ) === c ) o += c ;
620+ o = c ; while ( ++ i < fmt . length && fmt . charAt ( i ) . toLowerCase ( ) === c ) o += c ;
623621 if ( c === 'm' && lst . toLowerCase ( ) === 'h' ) c = 'M' ;
624622 if ( c === 'h' ) c = hr ;
625623 out [ out . length ] = { t :c , v :o } ; lst = c ; break ;
626624 case 'A' : case 'a' :
627- q = { t :c , v :c } ;
625+ var q = { t :c , v :c } ;
628626 if ( dt == null ) dt = parse_date_code ( v , opts ) ;
629627 if ( fmt . substr ( i , 3 ) . toUpperCase ( ) === "A/P" ) { if ( dt != null ) q . v = dt . H >= 12 ? "P" : "A" ; q . t = 'T' ; hr = 'h' ; i += 3 ; }
630628 else if ( fmt . substr ( i , 5 ) . toUpperCase ( ) === "AM/PM" ) { if ( dt != null ) q . v = dt . H >= 12 ? "PM" : "AM" ; q . t = 'T' ; i += 5 ; hr = 'h' ; }
@@ -647,7 +645,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
647645 /* Numbers */
648646 case '.' :
649647 if ( dt != null ) {
650- o = c ; while ( ( c = fmt . charAt ( ++ i ) ) === "0" ) o += c ;
648+ o = c ; while ( ++ i < fmt . length && ( c = fmt . charAt ( i ) ) === "0" ) o += c ;
651649 out [ out . length ] = { t :'s' , v :o } ; break ;
652650 }
653651 /* falls through */
@@ -656,7 +654,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
656654 out [ out . length ] = { t :'n' , v :o } ; break ;
657655 case '?' :
658656 o = c ; while ( fmt . charAt ( ++ i ) === c ) o += c ;
659- q = { t :c , v :o } ; out [ out . length ] = q ; lst = c ; break ;
657+ out [ out . length ] = { t :c , v :o } ; lst = c ; break ;
660658 case '*' : ++ i ; if ( fmt . charAt ( i ) == ' ' || fmt . charAt ( i ) == '*' ) ++ i ; break ; // **
661659 case '(' : case ')' : out [ out . length ] = { t :( flen === 1 ?'t' :c ) , v :c } ; ++ i ; break ;
662660 case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' :
@@ -807,7 +805,7 @@ function chkcond(v, rr) {
807805 }
808806 return false ;
809807}
810- function choose_fmt ( f /*:string*/ , v ) {
808+ function choose_fmt ( f /*:string*/ , v /*:any*/ ) {
811809 var fmt = split_fmt ( f ) ;
812810 var l = fmt . length , lat = fmt [ l - 1 ] . indexOf ( "@" ) ;
813811 if ( l < 4 && lat > - 1 ) -- l ;
@@ -842,17 +840,37 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
842840 break ;
843841 }
844842 if ( isgeneral ( sfmt , 0 ) ) return general_fmt ( v , o ) ;
843+ if ( v instanceof Date ) v = datenum_local ( v , o . date1904 ) ;
845844 var f = choose_fmt ( sfmt , v ) ;
846845 if ( isgeneral ( f [ 1 ] ) ) return general_fmt ( v , o ) ;
847846 if ( v === true ) v = "TRUE" ; else if ( v === false ) v = "FALSE" ;
848847 else if ( v === "" || v == null ) return "" ;
849848 return eval_fmt ( f [ 1 ] , v , o , f [ 0 ] ) ;
850849}
850+ function load_entry ( fmt /*:string*/ , idx /*:?number*/ ) /*:number*/ {
851+ if ( typeof idx != 'number' ) {
852+ idx = + idx || - 1 ;
853+ /*::if(typeof idx != 'number') return 0x188; */
854+ for ( var i = 0 ; i < 0x0188 ; ++ i ) {
855+ /*::if(typeof idx != 'number') return 0x188; */
856+ if ( table_fmt [ i ] == undefined ) { if ( idx < 0 ) idx = i ; continue ; }
857+ if ( table_fmt [ i ] == fmt ) { idx = i ; break ; }
858+ }
859+ /*::if(typeof idx != 'number') return 0x188; */
860+ if ( idx < 0 ) idx = 0x187 ;
861+ }
862+ /*::if(typeof idx != 'number') return 0x188; */
863+ table_fmt [ idx ] = fmt ;
864+ return idx ;
865+ }
866+ SSF . load = load_entry ;
851867SSF . _table = table_fmt ;
852- SSF . load = function load_entry ( fmt /*:string*/ , idx /*:number*/ ) { table_fmt [ idx ] = fmt ; } ;
853- SSF . format = format ;
854- SSF . get_table = function get_table ( ) { return table_fmt ; } ;
855- SSF . load_table = function load_table ( tbl /*:{[n:number]:string}*/ ) { for ( var i = 0 ; i != 0x0188 ; ++ i ) if ( tbl [ i ] !== undefined ) SSF . load ( tbl [ i ] , i ) ; } ;
868+ SSF . get_table = function get_table ( ) /*:SSFTable*/ { return table_fmt ; } ;
869+ SSF . load_table = function load_table ( tbl /*:SSFTable*/ ) /*:void*/ {
870+ for ( var i = 0 ; i != 0x0188 ; ++ i )
871+ if ( tbl [ i ] !== undefined ) load_entry ( tbl [ i ] , i ) ;
872+ } ;
856873SSF . init_table = init_table ;
874+ SSF . format = format ;
857875} ;
858876make_ssf ( SSF ) ;
0 commit comments