      1 ﻿
      2 /**
      3  * @name	CeL function for compatibility
      4  * @fileoverview
      5  * 本檔案包含了相容性 test 專用的 functions。
      6  * @since
      7  * @see
      8  * <a href="http://msdn.microsoft.com/en-us/library/s4esdbwz%28v=VS.85%29.aspx" accessdate="2010/4/16 20:4">Version Information (Windows Scripting - JScript)</a>
      9  */
     10
     11 /*
     12 http://www.comsharp.com/GetKnowledge/zh-CN/It_News_K875.aspx
     13 8進制數字表示被禁止， 010 代表 10 而不是 8
     14 引入 JSON
     15 Array 對象內置了一些標準函數，如 indexOf(), map(), filter(), reduce()
     16 # Object.keys() 會列出對象中所有可以枚舉的屬性
     17 # Object.getOwnPropertyNames() 會列出對象中所有可枚舉以及不可枚舉的屬性
     18 # Object.getPrototypeof() 返回給定對象的原型
     19
     20 http://jquerymobile.com/gbs/
     21 */
     22
     23 if (typeof CeL === 'function'){
     24
     25 /**
     26  * 本 module 之 name(id)，<span style="text-decoration:line-through;">不設定時會從呼叫時之 path 取得</span>。
     27  * @type	String
     28  * @constant
     29  * @inner
     30  * @ignore
     31  */
     32 var module_name = 'code.compatibility';
     33
     34 //===================================================
     35 /**
     36  * 若欲 include 整個 module 時，需囊括之 code。
     37  * @type	Function
     38  * @param	{Function} library_namespace	namespace of library
     39  * @param	load_arguments	呼叫時之 argument(s)
     40  * @return
     41  * @name	CeL.code.compatibility
     42  * @constant
     43  * @inner
     44  * @ignore
     45  */
     46 var code_for_including = function(library_namespace, load_arguments) {
     47
     48 //	**	no requires
     49
     50
     51 /**
     52  * null module constructor
     53  * @class	相容性 test 專用的 functions
     54  */
     55 CeL.code.compatibility
     56 = function() {
     57 	//	null module constructor
     58 };
     59
     60 /**
     61  * for JSDT: 有 prototype 才會將之當作 Class
     62  */
     63 CeL.code.compatibility
     64 .prototype = {
     65 };
     66
     67
     68
     69
     70
     71
     72 /*	對於舊版沒有Array.push()等函數時之判別及處置,舊版adapter
     73 	從(typeof object.reverse=='function')可偵測object是否為Array
     74 	http://www.coolcode.cn/?p=126
     75 */
     76 //oldVadapter[generateCode.dLK]='*oldVadapter();';
     77 function oldVadapter(){
     78  //var _Global=typeof window=='object'?window:this;
     79  // Global undefined variable
     80 /*
     81  if(typeof _Global=='undefined')window.undefined=_Global;
     82  else _Global.undefined=_Global.undefined;
     83 */
     84
     85  if(!Array.prototype.push&&typeof Apush=='function')Array.prototype.push=Apush;
     86  if(!Array.prototype.pop&&typeof Apop=='function')Array.prototype.pop=Apop;
     87  if(!Array.prototype.shift&&typeof Ashift=='function')Array.prototype.shift=Ashift;
     88  if(!Array.prototype.unshift&&typeof Aunshift=='function')Array.prototype.unshift=Aunshift;
     89  //	apply & call: after ECMAScript 3rd Edition	不直接用undefined: for JS5
     90  if(typeof Function.prototype.apply=='undefined'&&typeof Fapply=='function')Function.prototype.apply=Fapply;
     91  if(typeof Function.prototype.call=='undefined'&&typeof Fcall=='function')Function.prototype.call=Fcall;
     92  //if(typeof isNaN!='function'&&typeof NisNaN=='function')isNaN=NisNaN;
     93  if(typeof encodeURI!='function'&&typeof escape=='function')encodeURI=escape;
     94  if(typeof decodeURI!='function'&&typeof unescape=='function')decodeURI=unescape;
     95  if(typeof encodeURIComponent!='function'&&typeof encodeURI=='function')encodeURIComponent=encodeURI;
     96  if(typeof decodeURIComponent!='function'&&typeof decodeURI=='function')decodeURIComponent=decodeURI;
     97 }
     98
     99 //	在 FF3 僅用 this[this.length]=o; 效率略好於 Array.push()，但 Chrome 6 相反。
    100 function Apush(o){this[this.length]=o;return this.length;}
    101 //	將 element_toPush 加入 array_pushTo 並篩選重複的（本來已經加入的並不會變更）
    102 //	array_reverse[value of element_toPush]=index of element_toPush
    103 function pushUnique(array_pushTo,element_toPush,array_reverse){
    104  if(!array_pushTo||!element_toPush)return array_pushTo;
    105  var i;
    106  if(!array_reverse)
    107   for(array_reverse=new Array,i=0;i<array_pushTo;i++)
    108    array_reverse[array_pushTo[i]]=i;
    109
    110  if(typeof element_toPush!='object')
    111   i=element_toPush,element_toPush=new Array,element_toPush.push(i);
    112
    113  var l;
    114  for(i in element_toPush)
    115   if(!array_reverse[element_toPush])
    116    //array_pushTo.push(element_toPush),array_reverse[element_toPush]=array_pushTo.length;
    117    array_reverse[array_pushTo[l = array_pushTo.length] = element_toPush[i]] = l;
    118
    119  return array_pushTo;
    120 }
    121
    122 //	e.g., Array.prototype.concat does not change the existing arrays, it only returns a copy of the joined arrays.
    123 function Aappend(a) {
    124 	var t = this, s = t.length, i = 0, l = a && a.length || 0;
    125 	for (; i < l; i++)
    126 		t[s + i] = a[i];
    127 	return t;
    128 }
    129
    130 function Apop(){
    131  if(!this.length)return;
    132  var t=this.slice(-1);this.length--;return t;//不能用return this[--this.length];
    133 }
    134 function Ashift(){
    135  //var t=this[0],s=this.join('\0');s=s.substr(s.indexOf('\0')+1);this.length=0;this.push(s.split('\0'));return t;
    136  var t=this[0];
    137  this.value=this.slice(1);	//	ECMAScript 不允許設定 this=
    138  return t;
    139 }
    140 function Aunshift(o){
    141  if(!this.length)return;
    142  //var t=this.join('\0');this.length=0;this.push(o);this.push(t.split('\0'));return this;
    143  return this.value=[o].concat(this);	//	ECMAScript 不允許設定 this=
    144 }	//	不能用t=this.valueOf(); .. this.push(t);
    145 //	奇怪的是，這個版本(5.1版)尚不提供isNaN。(should be isNaN, NOT isNAN)
    146 //	變數可以與其本身比較。如果比較結果不相等，則它會是 NaN。原因是 NaN 是唯一與其本身不相等的值。
    147 //function NisNaN(v){var a=typeof v=='number'?v:parseInt(v);return /*typeof v=='number'&&*/a!=a;}//parseFloat(v)	alert(typeof a+','+a+','+(a===a));
    148 //oldVadapter();
    149
    150 /*	http://www.cnblogs.com/sunwangji/archive/2007/06/26/791428.html	http://www.cnblogs.com/sunwangji/archive/2006/08/21/482341.html
    151 	http://msdn.microsoft.com/en-us/library/4zc42wh1(VS.85).aspx
    152 	http://www.interq.or.jp/student/exeal/dss/ejs/3/1.html
    153 	http://blog.mvpcn.net/fason/
    154 	http://d.hatena.ne.jp/m-hiyama/20051017/1129510043
    155 	http://noir.s7.xrea.com/archives/000203.html
    156
    157 http://msdn.microsoft.com/en-us/library/4zc42wh1(VS.85).aspx
    158 傳回某物件的方法，以另一個物件取代目前的物件。
    159 apply是將現在正在執行的function其this改成apply的引數。所有函數內部的this指針都會被賦值為oThis，這可實現將函數作為另外一個對象的方法運行的目的
    160 xxx.apply(oThis,arrayArgs): 執行xxx，執行時以oThis作為 this，arrayArgs作為 arguments
    161
    162 http://www.tohoho-web.com/js/object.htm#inheritClass
    163 クラスを継承する	親のクラスが持っている機能をすべて使用することができます。
    164
    165 to make classChild inheritance classParent:	http://www.interq.or.jp/student/exeal/dss/ejs/3/2.html
    166 function classChild(_args1,_args2,..){
    167  處理arguments：arguments.pop() or other way
    168
    169  classParent.call(this,_args1,_args2,..);	//	way1
    170  classParent.apply(this,arguments);	//	way2
    171  //this.constructor=classChild;	//	maybe needless
    172
    173  // ..
    174 }
    175 classChild.prototype=new classParent;	//	for (objChild instanceof objParent)	關鍵字: 繼承，原型
    176 classChild.prototype.methodOfParent=function(..){..};	//	オーバーライド
    177
    178 var objChild=new classChild(_args);
    179 classParent.prototype.methodOfParent.call(objChild, ..);	//	基底プロトタイプのメソッドを呼び出す。ただしこの呼び出し自体は Programmer が Person を継承しているかどうかを何も考慮していません。
    180
    181
    182 因 arguments 非instanceof Array，arguments.join(sp) → Array.prototype.join.call(arguments,sp)
    183 */
    184 /**
    185  * @ignore
    186  */
    187 if(0)
    188 function Fapply(/* object */ oThis /* = null */, /* Array */ arrayArgs /* = null */) {
    189  if(oThis == null || oThis == undefined)	//	グローバルオブジェクトに適用
    190   return arrayArgs == null || arrayArgs == undefined? this(): this(arrayArgs);
    191  if(!(oThis instanceof Object))
    192   return undefined;	//	実際は throw TypeError();
    193
    194  oThis.$_funcTmp000 = this;
    195
    196  var oReturn;
    197  if(arrayArgs == null || arrayArgs == undefined)
    198   oReturn = oThis.$_funcTmp000();
    199  else if(arrayArgs instanceof Array){
    200   var i=0,args=[];
    201   for(;i<arrayArgs.length;i++)
    202    args[i]='arrayArgs['+i+']';//args.push('arrayArgs['+i+']');
    203   oReturn = eval("oThis.$_funcTmp000("+args.join(",")+");");	//	因為arrayArgs[i]之type不固定，故不能直接用arrayArgs.join(",")
    204  }//else{delete oThis.$_funcTmp000;throw TypeError();}
    205
    206  delete oThis.$_funcTmp000;
    207  return oReturn;
    208 }
    209 /*	http://msdn.microsoft.com/library/CHT/jscript7/html/jsmthcall.asp
    210 call 方法是用來呼叫代表另一個物件的方法。call 方法可讓您將函式的物件內容從原始內容變成由 thisObj 所指定的新物件。
    211 如果未提供 thisObj 的話，將使用 global 物件作為 thisObj。
    212 */
    213 /**
    214  * @ignore
    215  */
    216 if(0)
    217 function Fcall(/* object */ oThis /* = null [, arg1[, arg2[, ... [, argN]]]]] */){
    218  var argu=[];//Array.prototype.slice.call(arguments);
    219  for(var i=1;i<arguments.length;i++)
    220   argu[i-1]=arguments[i];	//	argu.push(arguments[i]);
    221  return this.apply(oThis, argu);
    222 }
    223
    224
    225
    226
    227 CeL.code.compatibility
    228 .
    229 /**
    230  * Are we in a web environment?
    231  * @param W3CDOM	Are we in a W3C DOM environment?
    232  * @return	We're in a web environment.
    233  * @since	2009/12/29 19:18:53
    234  * @see
    235  * use lazy evaluation
    236  * @memberOf	CeL.code.compatibility
    237  */
    238 is_web = function is_web(W3CDOM) {
    239 	var _s = is_web;
    240 	if (!('web' in _s))
    241 		_s.W3CDOM =
    242 				(
    243 				_s.web = typeof window === 'object'
    244 						&& typeof document === 'object'
    245 						&& window.document === document
    246 						// 下兩個在 IE5.5 中都是 Object
    247 						//&& library_namespace.is_type(window, 'global')
    248 						//&& library_namespace.is_type(document, 'HTMLDocument')
    249 				)
    250 				// W3CDOM, type: Object @ IE5.5
    251 				&& document.createElement
    252 				// &&!!document.createElement
    253 				//	type: Object @ IE5.5
    254 				&& document.getElementsByTagName;
    255
    256 	return W3CDOM ? _s.W3CDOM : _s.web;
    257 };
    258
    259
    260 CeL.code.compatibility
    261 .
    262 /**
    263  * 判斷為 DOM。
    264  * @param	name	various name @ name-space window. e.g., document, location
    265  * @return	{Boolean}	various is object of window
    266  * @since	2010/1/14 22:04:37
    267  * @memberOf	CeL.code.compatibility
    268  */
    269 is_DOM = function(name) {
    270 	var r = _.is_web();
    271 	if (!r || !name)
    272 		return r;
    273
    274 	// CeL.debug(CeL.is_type(window[name]));
    275 	try {
    276 		r = eval(name + '===window.' + name);
    277 	} catch (e) {
    278 		r = false;
    279 	}
    280 	return r;
    281 };
    282
    283
    284 //is_HTA[generateCode.dLK]='is_web';
    285 CeL.code.compatibility
    286 .
    287 /**
    288  * Are we run in HTA?<br/>
    289  * ** HTA 中應該在 onload 中呼叫，否則 document.getElementsByTagName 不會有東西！
    290  * @param [id]	HTA tag id (only used in low version that we have no document.getElementsByTagName)
    291  * @return	We're in HTA
    292  * @require	is_web
    293  * @since	2009/12/29 19:18:53
    294  * @memberOf	CeL.code.compatibility
    295  * @see
    296  * http://msdn2.microsoft.com/en-us/library/ms536479.aspx
    297  * http://www.microsoft.com/technet/scriptcenter/resources/qanda/apr05/hey0420.mspx
    298  * http://www.msfn.org/board/lofiversion/index.php/t61847.html
    299  * lazy evaluation
    300  * http://peter.michaux.ca/articles/lazy-function-definition-pattern
    301  */
    302 is_HTA = function is_HTA(id) {
    303 	var _s = is_HTA, a;
    304 	if ('HTA' in _s)
    305 		return _s.HTA;
    306
    307 	if (is_web(1)) {
    308 		a = document.getElementsByTagName('APPLICATION');
    309 		a = a && a.length === 1 && a[0];
    310 	} else
    311 		a = is_web() && id && document.all && document.all[id];
    312
    313 	return _s.HTA = a;
    314 };
    315
    316
    317
    318 //	版本檢查
    319 function checkVer(ver) {
    320 	if (!ver || ver < 5)
    321 		ver = 5; // WScript.FullName,WScript.Path
    322 	with (WScript)
    323 	if (Version < ver)
    324 		with (WshShell) {
    325 		var promptTitle = Locale == 0x411 ? 'アップグレードしませんか？'
    326 				: '請升級', promptC = Locale == 0x411 ? "今使ってる "
    327 						+ WScript.Name
    328 						+ " のバージョンは古過ぎるから、\nMicrosoft Windows スクリプト テクノロジ Web サイトより\nバージョン "
    329 						+ Version + " から " + ver + " 以上にアップグレードしましょう。"
    330 						: "正使用的 "
    331 							+ WScript.Name
    332 							+ " 版本過舊，\n請至 Microsoft Windows 網站將版本由 "
    333 							+ Version + " 升級到 " + ver + " 以上。", url = /* Locale==0x411? */"http://www.microsoft.com/japan/developer/scripting/default.htm";
    334 		if (1 == Popup(promptC, 0, promptTitle, 1 + 48))
    335 			Run(url);
    336 		Quit(1);
    337 	}
    338 }
    339
    340
    341
    342
    343
    344
    345
    346 /*	2008/12/21 18:53:42
    347 value to json
    348 JavaScript Object Notation	ECMA-262 3rd Edition
    349
    350 http://stackoverflow.com/questions/1500745/how-to-pass-parameters-in-eval-in-an-object-form
    351 json={name:'~',values:..,description:'~'}
    352 window[json.name].apply(null, json.values)
    353
    354
    355 usage:
    356 json(value)
    357
    358 parse:
    359 data=eval('('+data+')');	//	字串的前後記得要加上刮號 ()，這是用來告知 Javascript Interpreter 這是個物件描述，不是要執行的 statement。
    360 eval('data='+data);
    361
    362 TODO:
    363
    364 useObj
    365 加入function object成員，.prototype可用with()。加入函數相依性(dependency)
    366
    367 array用name:
    368 (function(){
    369 var o;
    370 o=[..];
    371 var i,v={..};
    372 for(i in v)o[i]=v[i];
    373 return o;
    374 })()
    375
    376
    377 recursion 循環參照
    378 (function(){
    379 var o;
    380 o={a:[]};
    381 o['b']=[o['a']],
    382 o['a'].push([o['b']]);
    383 return o;
    384 })()
    385
    386
    387
    388 BUG:
    389 function 之名稱被清除掉了，這可能會產生問題！
    390 (function(){
    391 var f=function(){..};
    392 f.a=..;
    393 f.b=..;
    394 f.prototype={
    395 a:..,
    396 b:..
    397 }
    398 return f;
    399 })()
    400
    401
    402 */
    403 //json[generateCode.dLK]='qNum,dQuote';
    404
    405
    406
    407 /*
    408 var a=[],b;a.push(b=[a]);json(a);
    409
    410 test recursion 循環參照
    411 (function(){
    412 var o=[],_1=[o];
    413 o.push(_1);
    414 return o;
    415 })();
    416
    417 */
    418
    419 /*
    420 改用 window.JSON, jQuery.parseJSON
    421 據說toJSONString跟parseJSON有可能成為ECMAScript第四版的標準
    422
    423 須判別來源是否為 String or Number!
    424
    425
    426 九个PHP很有用的功能 | 酷壳 - CoolShell.cn
    427 http://coolshell.cn/?p=2394
    428 你是否會把一個比較複雜的數據結構存到數據庫或是文件中？你並不需要自己去寫自己的算法。PHP早已為你做好了，其提供了兩個函數：?serialize()  和 unserialize()
    429 JSON越來越流行，所以在PHP5.2以後，PHP開始支持JSON，你可以使用 json_encode() 和 json_decode() 函數。但是對於一些非常複雜的數據結構，可能會造成數據丟失。
    430
    431
    432 json.dL='dependencyList';	//	dependency List Key
    433 json.forceArray=1;
    434
    435 json.indentString='	';
    436 json.NewLine='\n';
    437 json.separator=' ';
    438 function json(val,name,type){	//	type==2: inside object, treat undefined as ''
    439 var _f=json,expA=[],expC=[],vType=typeof val
    440 ,addE=function(o,l,n){
    441 	if(l){
    442 	 o=_f(o,0,2);
    443 	 n=typeof n=='undefined'||n===''?''
    444 		:(/^(\d{1,8})?(\.\d{1,8})?$/.test(n)||/^[a-z_][a-z_\d]{0,30}$/i.test(n)?n:dQuote(n))+':'+_f.separator;
    445 	 expA.push(n,o[1]);
    446
    447 	 //expC.push(_f.indentString+n+o[0].join(_f.NewLine+_f.indentString)+',');
    448 	 o=o[0];
    449 	 o[0]=n+(typeof o[0]=='undefined'?'':o[0]);
    450 	 o[o.length-1]+=',';
    451 	 for(var i=0;i<o.length;i++)
    452 	  o[i]=_f.indentString+(typeof o[i]=='undefined'?'':o[i]);
    453 	 expC=expC.concat(o);
    454 	}else expA.push(o),expC.push(o);
    455 }
    456 //	去掉最後一組的 ',' 並作結
    457 ,closeB=function(c){
    458 	var v=expC[expC.length-1];
    459 	if(v.charAt(v.length-1)==',')
    460 	 expC[expC.length-1]=v.slice(0,v.length-1);
    461 	addE(c);
    462 };
    463
    464 switch(vType){
    465 case 'number':
    466 //	http://msdn2.microsoft.com/zh-tw/library/y382995a(VS.80).aspx
    467 //	isFinite(value) ? String(value)
    468 var k=0,m='MAX_VALUE,MIN_VALUE,NEGATIVE_INFINITY,POSITIVE_INFINITY,NaN'.split(','),t=0;
    469 if(val===NaN||val===Infinity||val===-Infinity)t=''+val;
    470 else for(;k<m.length;k++)
    471  if(val===Number[m[k]]){t='Number.'+m[k];break;}
    472 if(!t){
    473  //	http://msdn2.microsoft.com/zh-tw/library/shydc6ax(VS.80).aspx
    474  for(k=0,m='E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2'.split(',');k<m.length;k++)
    475   if(val===Math[m[k]]){t='Math.'+m[k];break;}
    476  if(!t)
    477   if(k=(''+val).match(/^(-?\d*[1-9])(0{3,})$/))
    478    t=k[1]+'e'+k[2].length;
    479   else{
    480
    481    //	有理數判別
    482    k=qNum(val);
    483
    484    //	小數不以分數顯示. m==1:非分數
    485    m=k[1];
    486    while(m%2==0)m/=2;
    487    while(m%5==0)m/=5;
    488
    489    t=k[2]==0 && m!=1?k[0]+'/'+k[1]:
    490 	//	TODO: 加速(?)
    491 	(t=Math.floor(val))==val&&(''+t).length>(t='0x'+val.toString(16)).length?t:val;
    492   }
    493
    494 }
    495 addE(t);
    496 break;
    497 case 'null':
    498 addE(''+val);
    499 break;
    500 case 'boolean':
    501 addE(val);
    502 break;
    503 case 'string':
    504 addE(dQuote(val));
    505 break;
    506 case 'undefined':
    507 addE(type==2?'':'undefined');
    508 break;
    509
    510 case 'function':
    511 //	加入function object成員，.prototype可用with()。加入函數相依性(dependency)
    512 var toS,f;
    513 //	這在多執行緒有機會出問題！
    514 if(typeof val.toString!='undefined'){toS=val.toString;delete val.toString;}
    515 f=''+val;
    516 if(typeof toS!='undefined')val.toString=toS;
    517
    518 f=f.replace(/\r?\n/g,_f.NewLine);	//	function 才會產生 \r\n 問題，所以先處理掉
    519 var r=/^function\s+([^(\s]+)/,m=f.match(r),t;
    520 if(m)m=m[1],addE('//	function ['+m+']'),t=f.replace(r,'function'+_f.separator);
    521 if(m&&t.indexOf(m)!=-1)alert('function ['+m+'] 之名稱被清除掉了，這可能會產生問題！');
    522 addE(t||f);
    523 //	UNDO
    524 break;
    525
    526 case 'object':
    527 try{
    528 if(val===null){addE(''+val);break;}
    529 var c=val.constructor;
    530 if(c==RegExp){
    531  addE(val);
    532  break;
    533 }
    534 if(c==Date || vType=='date'){	//	typeof val.getTime=='function'
    535  //	與 now 相隔過短(<1e7, 約3h)視為 now。但若是 new Date()+3 之類的會出現誤差！
    536  addE('new Date'+((val-new Date)>1e7?'('+val.getTime()+')':''));	//	date被當作object
    537  break;
    538 }
    539 if((''+c).indexOf('Error')!=-1){
    540  addE('new Error'+(val.number||val.description?'('+(val.number||'')+(val.description?(val.number?',':'')+dQuote(val.description):'')+')':''));
    541  break;
    542 }
    543
    544 var useObj=0;
    545 if(c==Array){
    546  var i,l=0;
    547  if(!_f.forceArray)for(i in val)
    548   if(isNaN(i)){useObj=1;break;}else l++;
    549
    550  if(_f.forceArray || !useObj && l>val.length*.8){
    551   addE('[');
    552   for(i=0;i<val.length;i++)
    553    addE(val[i],1);
    554   closeB(']');
    555   break;
    556  }else useObj=1;
    557 }
    558
    559 if(useObj||c==Object){// instanceof
    560  addE('{');
    561  for(var i in val)
    562   addE(val[i],1,i);
    563  closeB('}');
    564  break;
    565 }
    566 addE(dQuote(val));
    567 break;
    568 }catch(e){
    569 if(28==(e.number&0xFFFF))
    570  alert('json: Too much recursion?\n循環參照？');
    571 return;
    572 }
    573
    574 case 'unknown':	//	sometimes we have this kind of type
    575 default:
    576 alert('Unknown type: ['+vType+'] (constructor: '+val.constructor+'), please contract me!\n'+val);
    577 break;
    578 //alert(vType);
    579 }
    580 return type?[expC,expA]:expC.join(_f.NewLine);
    581 }
    582
    583 */
    584
    585
    586
    587
    588
    589
    590
    591
    592 return (
    593 	CeL.code.compatibility
    594 );
    595 };
    596
    597 //===================================================
    598
    599 CeL.setup_module(module_name, code_for_including);
    600
    601 };
    602