| 
									
										
										
										
											2017-02-03 20:50:45 +00:00
										 |  |  | function isval(x/*:?any*/)/*:boolean*/ { return x !== undefined && x !== null; } | 
					
						
							| 
									
										
										
										
											2014-05-16 00:33:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function keys(o/*:any*/)/*:Array<any>*/ { return Object.keys(o); } | 
					
						
							| 
									
										
										
										
											2014-05-16 00:33:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ { | 
					
						
							|  |  |  | 	var o = ([]/*:any*/), K = keys(obj); | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	for(var i = 0; i !== K.length; ++i) o[obj[K[i]][key]] = K[i]; | 
					
						
							|  |  |  | 	return o; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function evert(obj/*:any*/)/*:EvertType*/ { | 
					
						
							|  |  |  | 	var o = ([]/*:any*/), K = keys(obj); | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = K[i]; | 
					
						
							|  |  |  | 	return o; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function evert_num(obj/*:any*/)/*:EvertNumType*/ { | 
					
						
							|  |  |  | 	var o = ([]/*:any*/), K = keys(obj); | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = parseInt(K[i],10); | 
					
						
							|  |  |  | 	return o; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function evert_arr(obj/*:any*/)/*:EvertArrType*/ { | 
					
						
							|  |  |  | 	var o/*:EvertArrType*/ = ([]/*:any*/), K = keys(obj); | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	for(var i = 0; i !== K.length; ++i) { | 
					
						
							|  |  |  | 		if(o[obj[K[i]]] == null) o[obj[K[i]]] = []; | 
					
						
							|  |  |  | 		o[obj[K[i]]].push(K[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-16 00:33:34 +00:00
										 |  |  | 	return o; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-22 12:16:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
 | 
					
						
							|  |  |  | var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000; | 
					
						
							| 
									
										
										
										
											2017-03-09 05:24:32 +00:00
										 |  |  | function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ { | 
					
						
							|  |  |  | 	var epoch = v.getTime(); | 
					
						
							|  |  |  | 	if(date1904) epoch += 1462*24*60*60*1000; | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | 	return (epoch - dnthresh) / (24 * 60 * 60 * 1000); | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-25 01:36:40 +00:00
										 |  |  | function numdate(v/*:number*/)/*:Date*/ { | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | 	var out = new Date(); | 
					
						
							|  |  |  | 	out.setTime(v * 24 * 60 * 60 * 1000 + dnthresh); | 
					
						
							|  |  |  | 	return out; | 
					
						
							| 
									
										
										
										
											2017-03-25 01:36:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-10 01:09:18 +00:00
										 |  |  | /* ISO 8601 Duration */ | 
					
						
							|  |  |  | function parse_isodur(s) { | 
					
						
							|  |  |  | 	var sec = 0, mt = 0, time = false; | 
					
						
							|  |  |  | 	var m = s.match(/P([0-9\.]+Y)?([0-9\.]+M)?([0-9\.]+D)?T([0-9\.]+H)?([0-9\.]+M)?([0-9\.]+S)?/); | 
					
						
							|  |  |  | 	if(!m) throw new Error("|" + s + "| is not an ISO8601 Duration"); | 
					
						
							|  |  |  | 	for(var i = 1; i != m.length; ++i) { | 
					
						
							|  |  |  | 		if(!m[i]) continue; | 
					
						
							|  |  |  | 		mt = 1; | 
					
						
							|  |  |  | 		if(i > 3) time = true; | 
					
						
							|  |  |  | 		switch(m[i].substr(m[i].length-1)) { | 
					
						
							|  |  |  | 			case 'Y': | 
					
						
							|  |  |  | 				throw new Error("Unsupported ISO Duration Field: " + m[i].substr(m[i].length-1)); | 
					
						
							|  |  |  | 			case 'D': mt *= 24; | 
					
						
							|  |  |  | 				/* falls through */ | 
					
						
							|  |  |  | 			case 'H': mt *= 60; | 
					
						
							|  |  |  | 				/* falls through */ | 
					
						
							|  |  |  | 			case 'M': | 
					
						
							|  |  |  | 				if(!time) throw new Error("Unsupported ISO Duration Field: M"); | 
					
						
							|  |  |  | 				else mt *= 60; | 
					
						
							|  |  |  | 				/* falls through */ | 
					
						
							|  |  |  | 			case 'S': break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		sec += mt * parseInt(m[i], 10); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return sec; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-23 01:18:40 +00:00
										 |  |  | var good_pd_date = new Date('2017-02-19T19:06:09.000Z'); | 
					
						
							| 
									
										
										
										
											2017-05-17 04:23:36 +00:00
										 |  |  | if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17'); | 
					
						
							| 
									
										
										
										
											2017-03-23 01:18:40 +00:00
										 |  |  | var good_pd = good_pd_date.getFullYear() == 2017; | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | /* parses aa date as a local date */ | 
					
						
							|  |  |  | function parseDate(str/*:string|Date*/, fixdate/*:?number*/)/*:Date*/ { | 
					
						
							| 
									
										
										
										
											2017-05-17 04:23:36 +00:00
										 |  |  | 	var d = new Date(str); | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | 	if(good_pd) { | 
					
						
							|  |  |  | 		/*:: if(fixdate == null) fixdate = 0; */ | 
					
						
							|  |  |  | 		if(fixdate > 0) d.setTime(d.getTime() + d.getTimezoneOffset() * 60 * 1000); | 
					
						
							|  |  |  | 		else if(fixdate < 0) d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000); | 
					
						
							|  |  |  | 		return d; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-23 01:18:40 +00:00
										 |  |  | 	if(str instanceof Date) return str; | 
					
						
							| 
									
										
										
										
											2017-05-17 04:23:36 +00:00
										 |  |  | 	if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) { | 
					
						
							|  |  |  | 		var s = d.getFullYear(); | 
					
						
							|  |  |  | 		if(str.indexOf("" + s) > -1) return d; | 
					
						
							|  |  |  | 		d.setFullYear(d.getFullYear() + 100); return d; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-23 01:18:40 +00:00
										 |  |  | 	var n = str.match(/\d+/g)||["2017","2","19","0","0","0"]; | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | 	return new Date(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0)); | 
					
						
							| 
									
										
										
										
											2017-03-23 01:18:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 20:50:45 +00:00
										 |  |  | function cc2str(arr/*:Array<number>*/)/*:string*/ { | 
					
						
							| 
									
										
										
										
											2014-06-29 18:29:45 +00:00
										 |  |  | 	var o = ""; | 
					
						
							|  |  |  | 	for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]); | 
					
						
							|  |  |  | 	return o; | 
					
						
							| 
									
										
										
										
											2014-05-22 12:16:51 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-28 13:22:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 06:57:59 +00:00
										 |  |  | function str2cc(str) { | 
					
						
							|  |  |  | 	var o = []; | 
					
						
							|  |  |  | 	for(var i = 0; i != str.length; ++i) o.push(str.charCodeAt(i)); | 
					
						
							|  |  |  | 	return o; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 20:36:32 +00:00
										 |  |  | function dup(o/*:any*/)/*:any*/ { | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 	if(typeof JSON != 'undefined' && !Array.isArray(o)) return JSON.parse(JSON.stringify(o)); | 
					
						
							| 
									
										
										
										
											2017-03-19 23:46:41 +00:00
										 |  |  | 	if(typeof o != 'object' || o == null) return o; | 
					
						
							| 
									
										
										
										
											2017-02-19 20:36:32 +00:00
										 |  |  | 	var out = {}; | 
					
						
							|  |  |  | 	for(var k in o) if(o.hasOwnProperty(k)) out[k] = dup(o[k]); | 
					
						
							|  |  |  | 	return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; } | 
					
						
							| 
									
										
										
										
											2017-05-11 07:29:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* TODO: stress test */ | 
					
						
							|  |  |  | function fuzzydate(s/*:string*/)/*:Date*/ { | 
					
						
							|  |  |  | 	var o = new Date(s), n = new Date(NaN); | 
					
						
							|  |  |  | 	var y = o.getYear(), m = o.getMonth(), d = o.getDate(); | 
					
						
							|  |  |  | 	if(isNaN(d)) return n; | 
					
						
							|  |  |  | 	if(y < 0 || y > 8099) return n; | 
					
						
							|  |  |  | 	if((m > 0 || d > 1) && y != 101) return o; | 
					
						
							|  |  |  | 	if(s.toLowerCase().match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) return o; | 
					
						
							|  |  |  | 	if(!s.match(/[a-zA-Z]/)) return o; | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |