1 
  2 /*
  3 	本檔案為自動生成,請勿編輯!
  4 	This file is auto created from _structure\structure.js, base.js, module.js, initialization.js
  5 		by tool: build main script.
  6 */
  7 
  8 
  9 //<![CDATA[
 10 
 11 
 12 /**
 13  * @name	JavaScript framework: CeL base loader
 14  * @fileoverview
 15  * Colorless echo JavaScript kit/library base loader.
 16  * 本檔案包含了呼叫其他 library 需要用到的 function,以及常用 base functions。<br/>
 17  * A JavaScript module framework that is simple to use.<br/>
 18  * 本計畫希望能建立一個能簡單上手的 JavaScript 模組架構。
 19  * <br/>
 20  * 2002-, kanashimi <kanasimi@gmail.com>.<br/>
 21  * <br/>
 22  * This file is in tab wide of 4 chars, documentation with JsDoc Toolkit (<a href="http://code.google.com/p/jsdoc-toolkit/wiki/TagReference">tags</a>).<br/>
 23  * <br/>
 24  * <br/>Please visit <a href="http://lyrics.meicho.com.tw/program/">Colorless echo program room</a> for more informations.
 25  * @since	自 function.js 0.2 改寫
 26  * @since	JavaScript 1.2
 27  * @since	2010/1/9 00:01:52 建立
 28  * @author	kanasimi@gmail.com
 29  * @version	$Id: ce.js,v 0.2 2009/11/26 18:37:11 kanashimi Exp $
 30  */
 31 
 32 
 33 /*
 34 引用:參照
 35 function addCode
 36 
 37 CeL.module
 38 
 39 
 40 駝峰式大小寫命名規則 CamelCase → embedded_underscore/Snake case
 41 
 42 
 43 單一JS引用:
 44 //	[function.js]_iF
 45 function _iF(){}_iF.p='HKCU\\Software\\Colorless echo\\function.js.path';if(typeof WScript=="object")try{eval(getU((new ActiveXObject("WScript.Shell")).RegRead(_iF.p)));}catch(e){}
 46 function getU(p,enc){var o;try{o=new ActiveXObject('Microsoft.XMLHTTP');}catch(e){o=new XMLHttpRequest();}if(o)with(o){open('GET',p,false);if(enc&&o.overrideMimeType)overrideMimeType('text/xml;charset='+enc);send(null);return responseText;}}
 47 //	[function.js]End
 48 
 49 
 50 初始化:參照
 51 initialization of function.js
 52 
 53 http://www.w3school.com.cn/html5/html5_script.asp
 54 <script type="text/javascript" async="true" src="path/to/function.js"></script>
 55 <script type="application/javascript;version=1.7" async="true" src="path/to/function.js"></script>
 56 
 57 JSDoc:
 58 	http://code.google.com/p/jsdoc-toolkit/w/list
 59 	http://jsdoc.sourceforge.net/
 60 
 61 Javadoc:
 62 	http://java.sun.com/j2se/javadoc/writingdoccomments/
 63 
 64 VSdoc:
 65 	JScript IntelliSense in Visual Studio
 66 	http://weblogs.asp.net/bleroy/archive/2007/04/23/the-format-for-javascript-doc-comments.aspx
 67 	http://blogs.msdn.com/b/webdevtools/archive/2008/11/07/hotfix-to-enable-vsdoc-js-intellisense-doc-files-is-now-available.aspx
 68 	Create JScript XML Code Comments
 69 	http://msdn.microsoft.com/zh-tw/library/bb514138.aspx
 70 	http://blog.miniasp.com/post/2010/04/Visual-Studio-2010-jQuery-Development-Tips.aspx
 71 
 72 */
 73 
 74 
 75 
 76 /*
 77 TODO
 78 
 79 本 library 大量使用了 arguments.callee,但這與 ECMAScript design principles 不甚相符,需要避免。
 80 	http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in-javascript
 81 	http://wiki.ecmascript.org/doku.php?id=es3.1:design_principles
 82 
 83 
 84 reset environment (__defineSetter__, __defineGetter__, ..)
 85 in case of
 86 	<a href="http://haacked.com/archive/2009/06/25/json-hijacking.aspx" accessdate="2009/12/2 0:7">JSON Hijacking</a>,
 87 	<a href="http://blog.miniasp.com/post/2009/11/JavaScript-JSON-Hijacking.aspx" accessdate="2009/12/2 0:18">在 Web 2.0 時代必須重視 JavaScript/JSON Hijacking 攻擊</a>,
 88 	etc.
 89 */
 90 
 91 
 92 //try{
 93 
 94 
 95 
 96 
 97 
 98 
 99 /*
100 TODO
101 將 module_name 改成 arguments
102 http://threecups.org/?p=129
103 
104 listen language change event
105 play board
106 
107 use <a href="http://prototyp.ical.ly/index.php/2007/03/01/javascript-design-patterns-1-the-singleton/" accessdate="2010/4/25 0:23" title="prototyp.ical.ly  &raquo; Javascript Design Patterns - 1. The Singleton">Singleton pattern</a>,
108 Module 模式或單例模式(<a href="http://zh.wikipedia.org/wiki/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F" accessdate="2010/4/25 0:25" title="单例模式">Singleton</a>)<a href="http://www.comsharp.com/GetKnowledge/zh-CN/TeamBlogTimothyPage_K950.aspx" accessdate="2010/4/25 0:24" title="那些相见恨晚的 JavaScript 技巧 - 基于 COMSHARP CMS">為 Douglas Crockford 所推崇</a>,並被大量應用在 Yahoo User Interface Library YUI。
109 
110 http://wiki.forum.nokia.com/index.php/JavaScript_Performance_Best_Practices
111 http://ioio.name/core-javascript-pitfalls.html
112 
113 CommonJS
114 http://www.heliximitate.cn/studyblog/archives/tag/commonjs
115 
116 */
117 
118 
119 /*
120 TODO
121 
122 
123 
124 //module
125 
126 //typeof CeL_id === 'string' && typeof this[CeL_id] === 'function' &&
127 typeof CeL === 'function' && CeL.setup_module({
128 name:[module_name],
129 require:[function_name,module_name],
130 
131 code:function(CeL){
132 
133 var private_value=1;
134 
135 function module_function_1(arg) {
136 	;
137 }
138 module_function_1.required='';
139 
140 
141 function module_class_1(arg) {
142 	;
143 }
144 
145 function get_value(){
146 	return private_value;
147 }
148 
149 module_class_1.prototype.print=function(){};
150 module_class_1.print=function(){};
151 
152 
153 return {module_function_1,module_class_1};
154 
155 }
156 
157 });
158 
159 2011/7/31 21:18:01
160 
161 
162 
163 
164 */
165 
166 //void(
167 //typeof CeL !== 'function' &&
168 (
169 /*
170  * We can redefine native values only for undefined.<br/>
171  * http://weblogs.asp.net/bleroy/archive/2006/08/02/Define-undefined.aspx<br/>
172  * <br/>
173  * Will speed up references to undefined, and allows redefining its name. (from jQuery)<br/>
174  * <br/>
175  * 用在比較或是 return undefined<br/>
176  * 在舊的 browser 中,undefined 可能不存在。
177  */
178 function (undefined) {
179 
180 /*
181  * ECMA-262 5th edition, ECMAScript 5 strict mode
182  * http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
183  * http://davidflanagan.com/Talks/es5/slides.html
184  * http://kangax.github.com/es5-compat-table/
185  */
186 'use strict';
187 
188 
189 //if(typeof global !== 'function') throw new Error('No global object specified!');
190 
191 
192 var
193 	library_name = 'CeL'
194 
195 	/**
196 	 * default debug level
197 	 * @type	{Integer}
198 	 * @ignore
199 	 */
200 	, debug = 0
201 
202 	/**
203 	 * library version
204 	 * @type	{String}
205 	 * @ignore
206 	 */
207 	, version = '2011.08.04'
208 
209 	//,window
210 
211 	, old_namespace
212 
213 	//	library base name-space
214 	, _
215 
216 	//, _base_function_to_extend
217 
218 	, function_name_pattern
219 	;
220 
221 
222 //		members of library	-----------------------------------------------
223 ;
224 
225 
226 /**
227  * Global Scope object<br/>
228  * 於 CeL.eval_code 使用
229  * @ignore
230  * @see
231  * <a href="http://stackoverflow.com/questions/3277182/how-to-get-the-global-object-in-javascript" accessdate="2011/8/6 10:7">How to get the Global Object in JavaScript? - Stack Overflow</a>
232  */
233 var global = Function('return this')();	//	isWeb()?window:this;
234 
235 old_namespace = global && global[library_name];
236 
237 
238 /*
239 var _Global=(function(){return this;})();
240 _Global.JustANumber=2;	//	var _GlobalPrototype=_Global.constructor.prototype;_GlobalPrototype.JustANumber=2;
241 if(typeof _Global=='undefined')_Global=this;
242 for(i in _Global)alert(i);
243 */
244 
245 //	若已經定義過,跳過。因為已有對 conflict 的對策,因此跳過。
246 //if(global[library_name] !== undefined) return;
247 
248 
249 /**
250  * Will speed up references to DOM: window, and allows redefining its name. (from jQuery)
251  * @ignore
252  */
253 //window = this;
254 
255 
256 /**
257  * 本 JavaScript framework 的框架基本宣告<br/>
258  * base name-space declaration of JavaScript library framework
259  * @example
260  * //	load library
261  * <script type="text/javascript" src="../ce.js"></script>
262  * //	預防 initialization 到一半彈出警告視窗,所以設大一點。
263  * CeL.log.max_length = 20;
264  * //	set debug
265  * CeL.set_debug();
266  *
267  * //	判別是否已經 load 過
268  * if(typeof CeL !== 'function' || CeL.Class !== 'CeL')
269  * 	;	//	CeL has not been loaded
270  * @name	CeL
271  * @class	Colorless echo JavaScript kit/library: base name-space declaration
272  */
273 function _() {
274 	//	function CeL: library root
275 	//	declaration for debug
276 	//this.global = arguments[0] || arguments.callee.ce_doc;
277 	return new (this.init.apply(global, arguments));
278 };
279 
280 
281 //	name-space 歸屬設定
282 
283 /**
284  * Map over main name-space in case of overwrite (from jQuery)
285  * @ignore
286  */
287 global[library_name] = _;
288 
289 CeL
290 .
291 get_old_namespace = function(){
292 	return old_namespace;
293 };
294 
295 CeL
296 .
297 recover_namespace = function(){
298 	if (old_namespace === undefined)
299 		delete global[library_name];
300 	else
301 		global[library_name] = old_namespace;
302 	return _;
303 };
304 
305 if (typeof _.prototype !== 'object')
306 	CeL
307 	.
308 	/**
309 	 * framework main prototype definition
310 	 * for JSDT: 有 prototype 才會將之當作 Class
311 	 */
312 	prototype = {
313 	};
314 
315 
316 CeL
317 .
318 /**
319  * JavaScript library framework main class name.
320  * @see	<a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf">ECMA-262</a>: Object.Class: A string value indicating the kind of this object.
321  * @constant
322  */
323 Class = library_name;
324 
325 
326 
327 
328 CeL
329 .
330 /**
331  * 本 library 專用之 evaluate()。
332  * 
333  * 若在 function 中 eval 以獲得 local variable,在舊 browser 中須加 var。
334  * e.g., 'var local_variable=' + ..
335  * 不加 var 在舊 browser 中會變成 global 變數。
336  * @param code	script code to evaluate
337  * @returns	value that evaluate process returned
338  * @see	window.eval === window.parent.eval
339  * http://stackoverflow.com/questions/3277182/how-to-get-the-global-object-in-javascript
340  */
341 eval_code = function eval_code(code) {
342 	/*
343 		JSC eval() takes an optional second argument which can be 'unsafe'.
344 		Mozilla/SpiderMonkey eval() takes an optional second argument which is the scope object for new symbols.
345 
346 		use window.execScript(code,"JavaScript") in IE: window.execScript() 將直接使用全局上下文環境,因此,execScript(Str)中的字符串Str可以影響全局變量。——也包括聲明全局變量、函數以及對象構造器。
347 	*/
348 	//this.debug(global.eval, 2);
349 	//this.debug(global && global.eval && global.eval !== arguments.callee);
350 	return global && global.eval && global.eval !== eval_code ? global.eval.call(global, code) : eval(code);
351 };
352 
353 
354 CeL
355 .
356 /**
357  * evaluate @ Global scope.
358  * By the ECMA-262, new Function() will 'Pass in the Global Environment as the Scope parameter.'
359  * copy from jQuery core.js
360  * @param code	script code to evaluate
361  * @returns	value that evaluate process returned
362  * @see
363  * <a href="http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context" accessdate="2011/8/6 8:56">Eval JavaScript in a global context | Java.net</a>
364  * use execScript on Internet Explorer
365  */
366 global_eval = new Function('code', 'return '
367 		+ (global.execScript ? 'global.execScript('
368 		: global.eval ? 'global.eval.call(global,'
369 		: window && window.eval ? 'window.eval.call(window,'
370 		: 'eval.call(null,')
371 		+ 'code);');
372 
373 
374 
375 CeL
376 .
377 /**
378  * simple evaluates to get value of specified variable identifier name.
379  * 不使用 eval().
380  * @param {String} variable_name	variable identifier name. e.g., /[a-z\d$_]+(.[a-z\d_]+)+/i
381  * @param {Object|Function} [name_space]	initialize name-space. default: global
382  * @returns	value of specified variable identifier name
383  * @since	2010/1/1 18:11:40
384  * @note
385  * 'namespace' 是 JScript.NET 的保留字
386  * 
387  * 在兩個子層(a.b.c)下,這樣作效率較差 @User agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.29 Safari/533.4:
388  * function(v){try{return(new Function('return('+v+')'))();}catch(e){}}
389  */
390 get_variable = function(variable_name, name_space) {
391 	//this.debug('get value of [' + variable_name + ']');
392 	if (typeof variable_name !== 'string' || !variable_name)
393 		return variable_name;
394 
395 	var i = 0,
396 	//	TODO: 可處理 e.g., obj1  . obj2 [ ' obj3.4 * \[ ' ] [''] . obj5 [ " obj6 \" \' \] . " ]
397 	//	or detect obj1 .. obj2
398 	s = variable_name.split('.'),
399 	l = s.length,
400 	v = name_space ||
401 		//this.env.global
402 		global
403 		;
404 	//this.debug('global.' + this.Class + ' = ' + this.env.global[this.Class]);
405 
406 	try {
407 		while (i < l)
408 			if (v)
409 				// this.debug('to [' + s[i] + ']: ' + v[s[i]]),
410 				v = v[s[i++]];
411 			else
412 				throw 1;
413 	} catch (e) {
414 		s[i - 1] = '<em>' + s[i - 1] + '</em><span class="debug_weaken">';
415 		//alert(this.log.buffer.length+','+this.log.max_length+'\n'+this.debug);
416 		this.debug('Cannot get [<span title="' + variable_name + '">' + s.join('.') + '</span></span>]!', 2, 'get_variable');
417 		return;
418 	}
419 
420 	return v;
421 };
422 
423 
424 
425 
426 CeL
427 .
428 /**
429  * 取得執行 script 之 path, 在 .hta 中取代 WScript.ScriptFullName。
430  * @returns	{String}	執行 script 之 path
431  * @returns	''	unknown environment
432  */
433 get_script_full_name = function() {
434 	//	在 IE8, IE9 中,get_object_type.call(WScript) 為 '[object Object]' !!
435 	return typeof WScript === 'object' && (!this.is_Object(WScript) || String(WScript) === 'Windows Script Host')
436 				&& WScript.ScriptFullName
437 		|| typeof location === 'object' && location === window.location && unescape(location.pathname)
438 		|| '';
439 };
440 
441 CeL
442 .
443 /**
444  * 取得執行 script 之名稱
445  * @returns	{String} 執行 script 之 名稱
446  * @returns	''	unknown environment
447  */
448 get_script_name = function() {
449 	var n, i, j;
450 
451 	//	在 IE8, IE9 中,get_object_type.call(WScript) 為 '[object Object]' !!
452 	if (typeof WScript === 'object'
453 		&& (!this.is_Object(WScript) || String(WScript) === 'Windows Script Host')) {
454 		n = WScript.ScriptName;
455 		i = n.lastIndexOf('.');
456 		return i == -1 ? n : n.slice(0, i);
457 	}
458 
459 	if (typeof location === 'object' && location === window.location) {
460 		n = unescape(location.pathname), j = n.lastIndexOf('.');
461 		if (!(i = n.lastIndexOf('\\') + 1))
462 			//	location.pathname 在 .hta 中會回傳 '\' 形式的 path
463 			i = n.lastIndexOf('/') + 1;
464 		return i < j ? n.slice(i, j) : n.slice(i);
465 	}
466 
467 	return typeof document === 'object' && document === window.document ? document.title : '';
468 };
469 
470 
471 
472 
473 /*
474 測試各 type:
475 
476 undefined:
477 變數值存在且變數 'undefined' 存在時: variable === undefined
478 否則: typeof(variable) === 'undefined'
479 
480 number, boolean, string:
481 typeof(variable) === '~'
482 
483 ** NaN
484 ** int/float
485 
486 object:
487 null
488 
489 不同frame中的Array擁有不同的constructor
490 */
491 /**
492  * A cache to the function we use to get the type of specified value.<br/>
493  * Get the [[Class]] property of this object.<br/>
494  * 不使用 Object.toString() 是怕被 overridden
495  * @type	{Function}
496  * @inner
497  */
498 var get_object_type = Object.prototype.toString;
499 
500 CeL
501 .
502 /**
503  * 判斷為何種 type。主要用在 Error, DOMException 等 native object 之判別。
504  * @param	value	variable or class instance to test
505  * @param	{String} [want_type]	type to compare: number, string, boolean, undefined, object, function
506  * @param	{Boolean} [get_Class]	get the class name of a class(function) instance.
507  * @returns	{Boolean}	The type is matched.
508  * @returns	{String}	The type of value
509  * @returns	{undefined}	error occurred
510  * @example
511  * CeL.is_type(value_to_test, 'Array');
512  * @since	2009/12/14 19:50:14
513  * @see
514  * <a href="http://lifesinger.org/blog/2009/02/javascript-type-check-2/" accessdate="2009/12/6 19:10">JavaScript类型检测小结(下) - 岁月如歌</a><br/>
515  * <a href="http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/" accessdate="2009/12/6 19:10">Perfection kills » `instanceof` considered harmful (or how to write a robust `isArray`)</a>
516  */
517 is_type = function(value, want_type, get_Class) {
518 	var type;
519 	if (want_type && (type = typeof want_type) !== 'string')
520 		want_type = type;
521 
522 	type = value === null ? String(value) : typeof value;
523 
524 	if (get_Class)
525 		try {
526 			if(type === 'function' && value.Class)
527 				//	get the class name of a class
528 				//	若 value 為 function 時,測試其本身之 Class。
529 				type = value.Class;
530 			else if (type === 'function' || type === 'object')
531 				if (('constructor' in value) && (get_Class = value.constructor).Class)
532 					// get the class name of a class instance
533 					// 若 value 為 function 且無 Class,或為 object 時,測試其 constructor 之 Class。
534 					type = get_Class.Class;
535 				else if (get_Class = this.get_function_name(get_Class))
536 					// get Class by function name
537 					type = get_Class;
538 		} catch (e) {
539 			this.err(this.Class + '.is_type: Fault to get ths class name of value!');
540 		}
541 
542 	if (type !== 'object')
543 		//	type maybe 'unknown' or 'date'!
544 		return want_type ? type === want_type.toLowerCase() : type;
545 
546 	try {
547 		get_Class = get_object_type.call(value);
548 	} catch (e) {
549 		this.err(this.Class + '.is_type: Fault to get object type of value!');
550 		get_Class = '';
551 	}
552 
553 	if (want_type)
554 		return get_Class === (want_type.charAt(0) === '[' ? want_type
555 				: '[object ' + want_type + ']');
556 
557 	if (want_type = get_Class.match(
558 					/^\[object ([^\]]+)\]$/))
559 		return want_type[1];
560 
561 	return type;
562 };
563 
564 
565 CeL
566 .
567 /**
568  * get a type test function
569  * @param	{String} want_type	object type to compare
570  * @param	{String} [toString_reference]	a reference name to Object.prototype.toString
571  * @returns	{Function}	type test function
572  * @since	2009/12/20 08:38:26
573  * @example
574  * // 大量驗證時,推薦另外在本身 scope 中造出捷徑:
575  * this.OtS = Object.prototype.toString;
576  * var is_Array = CeL.object_tester('Array', 'OtS');
577  * // test
578  * if(is_Array(value))
579  * 	//	it's really a native Array
580  * 	;
581  */
582 object_tester = function(want_type, toString_reference) {
583 	var t = '[object ' + want_type + ']';
584 
585 /*
586 	return new Function('v', 'return "' + t + '"==='
587 				+ (toString_reference ||
588 						//	在 Google Chrome 中 'Object.prototype.toString' 可以與其 reference 同速度,但其他的 reference 會快些。
589 						'Object.prototype.toString'
590 						//'get_object_type'
591 						)
592 				+ '.call(v);');
593 */
594 
595 	return typeof toString_reference === 'string'
596 		&& toString_reference ?
597 			new Function('v', 'return "' + t
598 				+ '"===' + toString_reference + '.call(v);')
599 
600 			//	slow@Chrome
601 			: function(v) { return t === get_object_type.call(v); };
602 			//	faster@Chrome
603 			//: new Function('v', 'return "' + t + '"===Object.prototype.toString.call(v);');
604 
605 };
606 
607 CeL
608 .
609 /**
610  * Test if the value is a native Array.
611  * @param	v	value to test
612  * @returns	{Boolean}	the value is a native Array.
613  * @since	2009/12/20 08:38:26
614  */
615 is_Array =
616 	// _.object_tester('Array');
617 	function(v) {
618 		// instanceof 比 Object.prototype.toString 快
619 		return v instanceof Array
620 				|| get_object_type.call(v) === '[object Array]';
621 	};
622 
623 CeL
624 .
625 /**
626  * Test if the value is a native Object.
627  * TODO:
628  * test null
629  * @param	v	value to test
630  * @returns	{Boolean}	the value is a native Object.
631  * @since	2009/12/20 08:38:26
632  */
633 is_Object =
634 	//	Object.prototype.toString.call(undefined) === '[object Object]' @ MSIE 6.0
635 	get_object_type.call(undefined) === '[object Object]'?
636 	function(v) {
637 		return typeof v !== 'undefined'
638 				&& get_object_type.call(v) === '[object Object]';
639 	}
640 	:
641 	//_.object_tester('Object');
642 	function(v) {
643 		//	非如此不得與 jQuery 平起平坐…
644 		return get_object_type.call(v) === '[object Object]';
645 	};
646 
647 CeL
648 .
649 /**
650  * Test if the value is a native Function.
651  * @param	v	value to test
652  * @returns	{Boolean}	the value is a native Function.
653  * @since	2009/12/20 08:38:26
654  */
655 is_Function =
656 	//_.object_tester('Function');
657 	function(v) {
658 		//	typeof 比 Object.prototype.toString 快,不過得注意有些 native object 可能 type 是 'function',但不具有 function 特性。
659 		return get_object_type.call(v) === '[object Function]';
660 
661 		//	須注意,在 firefox 3 中,typeof [object HTMLObjectElement] 之外的 HTMLElement 皆 === 'function',
662 		//	因此光用 typeof() === 'function' 而執行下去會得出 [XPCWrappedNative_NoHelper] Component is not available
663 		//return typeof v === 'function' || get_object_type.call(v) === '[object Function]';
664 	};
665 
666 
667 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
668 
669 
670 CeL
671 .
672 /**
673  * 取得/設定環境變數 enumeration<br/>
674  * (雖然不喜歡另開 name-space,但以 2009 當下的 JsDoc Toolkit 來說,似乎沒辦法創造 enumeration。)
675  * @class	環境變數 (environment variables) 與程式會用到的 library 相關變數 / configuration。
676  * @param {String} name	環境變數名稱
677  * @param value	環境變數之值
678  * @returns	舊環境變數之值
679  * @memberOf	CeL
680  */
681 env = function env(name, value) {
682 	if (!name)
683 		//return undefined;
684 		return;
685 
686 	var _s = env, v = _s[name];
687 
688 	if (arguments.length > 1) _s[name] = value;
689 	//if (typeof value !== 'undefined') _s[name] = value;
690 
691 	return isNaN(v) ? String(v) : v;
692 };
693 
694 
695 CeL
696 .
697 /**
698  * Setup environment variables
699  * @param	{String} [OS_type]	type of OS
700  * @param	{Boolean} [reset]	reset the environment variables 
701  * @returns	{Object}	environment variables set
702  */
703 initial_env = function(OS_type, reset){
704 	if (reset)
705 		this.env = {};
706 
707 	var OS, env = this.env;
708 
709 	/**
710 	 * default extension of script file.
711 	 * 設定成 '.' 時由 CeL.get_script_base_path 設定
712 	 * @type	String
713 	 * @see
714 	 * <a href="http://soswitcher.blogspot.com/2009/05/blogger-host-javascript-file-for-free.html" accessdate="2010/3/11 23:30">Blogger - Host Javascript File for Free - Blogger,Javascript - Blogger Blog by Switcher</a>
715 	 * @name	CeL.env.script_extension
716 	 */
717 	env.script_extension = typeof WScript === 'undefined' ? '.' : '.js';//'.txt'
718 
719 	/**
720 	 * library main file base name
721 	 * @name	CeL.env.main_script_name
722 	 * @type	String
723 	 */
724 	env.main_script_name = 'ce';
725 
726 	/**
727 	 * library main file name<br/>
728 	 * full path: {@link CeL.env.registry_path} + {@link CeL.env.main_script}
729 	 * @example:
730 	 * CeL.log('full path: ['+CeL.env.registry_path+CeL.env.main_script+']');
731 	 * @name	CeL.env.main_script
732 	 * @type	String
733 	 */
734 	env.main_script = env.main_script_name + env.script_extension;
735 
736 	/**
737 	 * module 中的這 member 定義了哪些 member 不被 extend
738 	 * @name	CeL.env.not_to_extend_keyword
739 	 * @type	String
740 	 */
741 	env.not_to_extend_keyword = 'no_extend';
742 
743 	/**
744 	 * 本 library source 檔案使用之 encoding<br/>
745 	 * 不使用會產生語法錯誤
746 	 * @name	CeL.env.source_encoding
747 	 * @type	String
748 	 */
749 	env.source_encoding = 'UTF-16';
750 
751 	/**
752 	 * default global object.
753 	 * 有可能為 undefined!
754 	 * @name	CeL.env.global
755 	 * @type	Object
756 	 */
757 	env.global = global;
758 
759 	/**
760 	 * creator group / 組織名稱 organization name
761 	 * @name	CeL.env.organization
762 	 * @type	String
763 	 */
764 	env.organization = 'Colorless echo';
765 
766 	/**
767 	 * 在 registry 中存放 library 資料的 base path
768 	 * @name	CeL.env.registry_base
769 	 * @type	String
770 	 */
771 	env.registry_base = 'HKCU\\Software\\' + env.organization + '\\' + this.Class
772 				+ '\\';
773 	/**
774 	 * 在 registry 中存放 library 在 File System 中的 base path 的 key name
775 	 * @name	CeL.env.registry_base
776 	 * @type	String
777 	 */
778 	env.registry_path_key_name = env.registry_base + 'path';
779 	//if(typeof WScript === 'object')
780 	try {
781 		//WScript.Echo(env.registry_path_key_name);
782 
783 		/**
784 		 * 存放在 registry 中的 path,通常指的是 library 在 File System 中的 base path
785 		 * @name	CeL.env.registry_path
786 		 * @type	String
787 		 */
788 		env.registry_path = (WScript.CreateObject("WScript.Shell"))
789 			.RegRead(env.registry_path_key_name)
790 			// 去除 filename
791 			//.replace(/[^\\\/]+$/, '')
792 			;
793 		//this.debug(env.registry_path);
794 	} catch (e) {
795 		// this.warn(e.message);
796 	}
797 
798 
799 	//條件式編譯(条件コンパイル) for version>=4, 用 /*@ and @*/ to 判別
800 	/*@cc_on
801 	@if(@_PowerPC||@_mac)
802 	 OS='Mac';
803 	@else
804 	 @if(@_win32||@_win64||@_win16)
805 	  OS='DOS';
806 	 @else
807 	  OS='unix';	//	unknown
808 	 @end
809 	@end@*/
810 
811 	/**
812 	 * 本次執行所在 OS 平台
813 	 * @name	CeL.env.OS
814 	 * @type	String
815 	 */
816 	env.OS = OS = typeof OS_type === 'string' ? OS_type
817 			// 假如未設定則取預設值
818 			: (OS || 'unix');
819 
820 	/**
821 	 * 文件預設 new line
822 	 * @name	CeL.env.new_line
823 	 * @type	String
824 	 */
825 	env.new_line=		OS == 'unix' ? '\n' : OS == 'Mac' ? '\r' : '\r\n';	//	in VB: vbCrLf
826 	/**
827 	 * file system 預設 path separator<br/>
828 	 * platform-dependent path separator character, 決定目錄(directory)分隔
829 	 * @name	CeL.env.path_separator
830 	 * @type	String
831 	 */
832 	env.path_separator	=	OS == 'unix' ? '/' : '\\';
833 	/**
834 	 * 預設 module name separator
835 	 * @name	CeL.env.module_name_separator
836 	 * @type	String
837 	 */
838 	env.module_name_separator = '.';
839 	/**
840 	 * path_separator in 通用(regular)運算式
841 	 * @name	CeL.env.path_separator_RegExp
842 	 * @type	RegExp
843 	 */
844 	env.path_separator_RegExp = this.to_RegExp_pattern ? this
845 			.to_RegExp_pattern(env.path_separator)
846 			: (env.path_separator === '\\' ? '\\' : '') + env.path_separator;
847 	/**
848 	 * 預設語系
849 	 * 0x404:中文-台灣,0x0411:日文-日本
850 	 * @name	CeL.env.locale
851 	 * @see	<a href="http://msdn.microsoft.com/zh-tw/library/system.globalization.cultureinfo(VS.80).aspx">CultureInfo 類別</a>
852 	 * @type	Number
853 	 */
854 	env.locale = 0x404;
855 
856 	/**
857 	 * script name
858 	 * @name	CeL.env.script_name
859 	 * @type	String
860 	 */
861 	env.script_name = this.get_script_name();
862 	/**
863 	 * base path of script.
864 	 * TODO
865 	 * 以 reg 代替
866 	 * @name	CeL.env.script_base_path
867 	 * @type	String
868 	 */
869 	env.script_base_path = this.get_script_full_name()
870 		// 去除 filename
871 		.replace(/[^\\\/]+$/, '');
872 
873 	/**
874 	 * Legal identifier name in RegExp.
875 	 * 這 pattern 會佔去兩個筆紀錄: first letter, and least.
876 	 * .replace(/_/ [g],'for first letter')
877 	 * .replace(/\\d/,'for least')
878 	 * 這邊列出的只是合法 identifier 的*子集*,且未去除 reserved words!
879 	 * 請注意實際判別須加入 ^..$
880 	 * 
881 	 * 不用 \d 而用 0-9 是因為 \d 還包括了 MATHEMATICAL BOLD DIGIT。
882 	 * <a href="http://blog.est.im/archives/3229" accessdate="2010/11/16 20:6">基于正则的URL匹配安全性考虑</a>
883 	 * @name	CeL.env.identifier_RegExp
884 	 * @see
885 	 * ECMA-262	7.6 Identifier Names and Identifiers
886 	 * @type	RegExp
887 	 */
888 	env.identifier_RegExp = /([a-zA-Z$_]|\\u[0-9a-fA-F]{4})([a-zA-Z$_0-9]+|\\u[0-9a-fA-F]{4}){0,63}/;
889 
890 	/**
891 	 * Legal identifier name in String from env.identifier_RegExp.
892 	 * @name	CeL.env.identifier_String
893 	 */
894 	env.identifier_String = env.identifier_RegExp.source;
895 
896 	return env;
897 };
898 
899 
900 CeL
901 .
902 //	TODO
903 get_identifier_RegExp = function(pattern, flag, add_for_first_letter, add_for_all_letter) {
904 	var s = this.env.identifier_String;
905 	if (add_for_first_letter)
906 		s = s.replace(/_/g, add_for_first_letter);
907 	if (add_for_all_letter)
908 		s = s.replace(/0-9/g, add_for_all_letter);
909 
910 	return new RegExp(
911 			(get_object_type.call(pattern) === '[object RegExp]' ? pattern.source : pattern)
912 				.replace(/$identifier/g, s), flag || '');
913 };
914 
915 
916 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
917 
918 
919 CeL
920 .
921 /**
922  * Tell if it's now debugging.
923  * @param {Integer} [debug_level]	if it's now in this debug level.
924  * @returns	{Boolean}	It's now in specified debug level.
925  * @returns	{Number}	It's now in what debug level (Integer).
926  */
927 is_debug = function(debug_level){
928 	return typeof debug_level === 'undefined' ? debug
929 				: debug >= debug_level;
930 };
931 
932 CeL
933 .
934 /**
935  * Set debugging level
936  * @param {Integer} [debug_level]	The debugging level to set.
937  * @type	Integer
938  * @returns	{Number} debugging level now
939  */
940 set_debug = function (debug_level) {
941 	if (!isNaN(debug_level))
942 		debug = debug_level;
943 
944 	else if (typeof debug_level === 'undefined' && !debug)
945 		debug = 1;
946 
947 	return debug;
948 };
949 
950 
951 /*
952 CeL.extend(function f_name(){}, object || string, initial arguments);
953 CeL.extend({name:function(){},.. }, object || string);
954 CeL.extend([function1,function12,..], object || string);
955 
956 set .name
957 */
958 
959 
960 
961 
962 
963 
964 
965 CeL
966 .
967 /**
968  * Get the hash key of text.
969  * @param {String} text	text to test
970  * @returns	{String}	hash key
971  */
972 _get_hash_key = function(text) {
973 	//text = String(text);
974 	//text = '' + text;
975 	var l = text.length, take = 30, from = .3;
976 	from = Math.floor(l * from);
977 	//this.log(from + '~' + l + ': ' + (l - from < take ? text : text.substr(from, take)));
978 	return l - from < take ? text : text.substr(from, take);
979 };
980 
981 
982 //	for JScript<=5
983 try {
984 	function_name_pattern = new RegExp('^function[\\s\\n]+(\\w+)[\\s\\n]*\\(');
985 } catch (e) {
986 	function_name_pattern = function emulate_function_name(fs) {
987 		fs = String(fs);
988 		var l = 'function ', r, s;
989 
990 		if (fs.indexOf(l) === 0) {
991 			l = l.length;
992 			s = {
993 					' ' : 1,
994 					'\n' : 1,
995 					'\r' : 1,
996 					'\t' : 1
997 			};
998 			while (fs.charAt(l) in s)
999 				l++;
1000 			r = fs.indexOf('(', l);
1001 			while (fs.charAt(--r) in s)
1002 				;
1003 
1004 			return [ , fs.slice(l, r + 1) ];
1005 		}
1006 	};
1007 	if (typeof RegExp != 'object')
1008 		eval('RegExp = function(){};');
1009 }
1010 
1011 CeL
1012 .
1013 /**
1014  * 獲得函數名
1015  * @param {Function} fr	function reference
1016  * @param {String} ns	name-space
1017  * @param {Boolean} force_load	force reload this name-space
1018  * @returns
1019  * @see
1020  * 可能的話請改用 {@link CeL.native.parse_function}(F).funcName
1021  * @since	2010/1/7 22:10:27
1022  */
1023 get_function_name = function(fr, ns, force_load) {
1024 	var _s = _.get_function_name,
1025 	//	初始化變數 'm'
1026 	m = 0, ft, b, load, k, i;
1027 	if (!fr)
1028 		try{
1029 			fr = _s.caller;
1030 		}catch (e) {
1031 			// TODO: handle exception
1032 		}
1033 
1034 	//	get function text (函數的解譯文字)
1035 	//	不用 insteadof 是怕傳入奇怪的東西,例如 {string} script code
1036 	m = typeof fr;
1037 	if (m === 'function') {
1038 		//	勿更改傳入之 argument
1039 		/*
1040 		if ('toString' in fr) {
1041 			m = fr.toString;
1042 			delete fr.toString;
1043 		}
1044 		ft = String(fr);
1045 		if (m)
1046 			fr.toString = m;
1047 		*/
1048 		//	TODO: cache Function.prototype.toString
1049 		ft = Function.prototype.toString.call(fr);
1050 	} else if(m === 'string')
1051 		// typeof fr === 'string'
1052 		ft = fr;
1053 	else
1054 		return '';
1055 
1056 	//	以函數的解譯文字獲得函數名
1057 	if (m = function_name_pattern instanceof RegExp ?
1058 			//	包含引數:	+ '(' + (f ? m[2] : '') + ')';
1059 			((m = ft.match(function_name_pattern)) && m[1] || 0)
1060 			: function_name_pattern instanceof Function ?
1061 				function_name_pattern(ft)
1062 				: 0){
1063 		//this.debug('matched ' + m, 1, this.Class + '.get_function_name');
1064 		return m;
1065 	}
1066 	//	無法從 function code 本身得到 name 之資訊。
1067 
1068 	//	查詢是否是已註冊之 function
1069 	if (b = _s.b)
1070 		load = _s.ns;
1071 	else
1072 		_s.b = b = {}, _s.ns = load = {};
1073 
1074 	if (!ns)
1075 		ns = this;
1076 
1077 	//	cache functions
1078 	if ((typeof ns === 'function' || this.is_Object(ns)) && ns.Class
1079 					&& (force_load || !load[ns.Class])) {
1080 		for (i in ns)
1081 			if (typeof ns[i] === 'function'){
1082 				k = this._get_hash_key(String(ns[i]));
1083 				m = ns.Class + this.env.module_name_separator + i;
1084 				//this.debug(m + ': ' + k + (', ' + ns[i]).slice(0, 200));
1085 				if(!(m in load)){
1086 					load[m] = 1;
1087 					if (!b[k])
1088 						b[k] = [];
1089 					b[k].push( [ m, ns[i] ]);
1090 				}
1091 			}
1092 		load[ns.Class] = 1;
1093 	}
1094 
1095 	//	將函數與 cache 比對以獲得函數名
1096 	if (m = b[this._get_hash_key(ft)])
1097 		for (i = 0; i < m.length; i++) {
1098 			b= m[i][1];
1099 			if (// typeof fr === 'function' &&
1100 					fr === b)
1101 				return m[i][0];
1102 			if (ft === String(b))
1103 				return m[i];
1104 		}
1105 };
1106 
1107 
1108 
1109 
1110 
1111 
1112 
1113 CeL
1114 .
1115 null_function = function() {};
1116 
1117 
1118 //	Initialization
1119 
1120 //	temporary decoration in case we call for nothing and raise error
1121 _.debug = _.err = _.warn = _.log = function(m) {
1122 	/*
1123 	 * 請注意:
1124 	 * _.log.buffer === this.log.buffer !== log.buffer
1125 	 * 在 WScript 中 需要用 _.log,其他則可用 log。
1126 	 * 因此應該將所有類似的值指定給雙方,並注意非[常數]的情況。
1127 	 */
1128 	var _s = this.log;
1129 	//_s.function_to_call.apply(null,arguments);
1130 	//_s.function_to_call.apply(global, arguments);
1131 
1132 	_s.buffer.push(m);
1133 
1134 	if (!_s.max_length)
1135 		_s.max_length = 0;
1136 
1137 	if (debug && _s.buffer.length > _s.max_length)
1138 		_s.function_to_call.call(global, _s.buffer.join('\n\n')),
1139 		_s.buffer = [];
1140 };
1141 
1142 
1143 /*
1144  * test:
1145  * var k=function l(){alert(l.m);};k.m=1;alert(l.m+','+k.m);k();
1146  * 
1147  * JScript 中
1148  * k();
1149  * 為 undefined, 其他會把 "l." 代換成 "k."?
1150  * 
1151  * @inner
1152  */
1153 //_.debug.buffer = _.err.buffer = _.warn.buffer =
1154 _.log.buffer = [];
1155 
1156 
1157 //_.debug.max_length = _.err.max_length = _.warn.max_length =
1158 _.log.max_length = 0;
1159 
1160 
1161 var max_log_length = 1000;
1162 //_.debug.function_to_call = _.err.function_to_call = _.warn.function_to_call =
1163 _.log.function_to_call =
1164 	typeof JSalert === 'function' ? JSalert :
1165 	typeof WScript === 'object' ? function(m){m=String(m);if(m.length>2*max_log_length)m=m.slice(0,max_log_length)+'\n\n..\n\n'+m.slice(-max_log_length);WScript.Echo(m);} :
1166 	typeof alert === 'object' || typeof alert === 'function' ? function(m){m=String(m);if(m.length>2*max_log_length)m=m.slice(0,max_log_length)+'\n\n..\n\n'+m.slice(-max_log_length);alert(m);} :
1167 	_.null_function;
1168 
1169 
1170 _.initial_env();
1171 
1172 
1173 /*
1174 var test_obj = _(2, 'test: Initialization');
1175 
1176 test_obj.test_print('OK!');
1177 */
1178 ;
1179 
1180 
1181 }
1182 )(
1183 	//	In strict mode, this inside globe functions is undefined.
1184 	//	https://developer.mozilla.org/en/JavaScript/Strict_mode
1185 	//this	// || typeof window === 'undefined' || window
1186 )
1187 //)	//	void(
1188 ;
1189 
1190 
1191 
1192 //==========================================================================================================================================================//
1193 
1194 
1195 
1196 
1197 
1198 
1199 /*
1200 TODO:
1201 
1202 瘦身
1203 
1204 use -> using because of 'use' is a keyword of JScript.
1205 
1206 等呼叫時才 initialization
1207 
1208 
1209 http://headjs.com/#theory
1210 Head JS :: The only script in your HEAD
1211 
1212 
1213 do not use eval.
1214 以其他方法取代 eval 的使用。
1215 
1216 http://msdn.microsoft.com/en-us/library/2b36h1wa(VS.71).aspx
1217 The arguments object is not available when running in fast mode, the default for JScript .NET. To compile a program from the command line that uses the arguments object, you must turn off the fast option by using /fast-. It is not safe to turn off the fast option in ASP.NET because of threading issues.
1218 
1219 
1220 Multiversion Support
1221 http://requirejs.org/docs/api.html
1222 
1223 */
1224 
1225 
1226 typeof CeL === 'function' &&
1227 (function (_) {
1228 
1229 'use strict';
1230 
1231 
1232 //var _// JSDT:_module_
1233 //= this;
1234 
1235 
1236 CeL
1237 .
1238 /**
1239  * 延展物件 (learned from jQuery):
1240  * 將 from_name_space 下的 variable_set 延展/覆蓋到 name_space。
1241  * @since	2009/11/25 21:17:44
1242  * @param	variable_set	variable set
1243  * @param	{Object|Function} name_space	extend to what name-space
1244  * @param	{Object|Function} from_name_space	When inputing function names, we need a base name-space to search these functions.
1245  * @returns	library names-pace
1246  * @see
1247  * <a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/03/01/jquery-extend.aspx" accessdate="2009/11/17 1:24" title="jQuery.extend的用法 - 黑暗執行緒">jQuery.extend的用法</a>,
1248  * <a href="http://www.cnblogs.com/rubylouvre/archive/2009/11/21/1607072.html" accessdate="2010/1/1 1:40">jQuery源码学习笔记三 - Ruby's Louvre - 博客园</a>
1249  */
1250 extend = function extend(variable_set, name_space, from_name_space) {
1251 	var _s = extend, i, l;
1252 
1253 	if(typeof name_space === 'undefined' || name_space === null)
1254 		//	如果沒有指定擴展的對象,則擴展到 library 自身
1255 		name_space = _s.default_target;
1256 
1257 	if (typeof from_name_space === 'undefined')
1258 		from_name_space = _s.default_target;
1259 	else if (variable_set === null && _.is_Function(from_name_space))
1260 		variable_set = from_name_space;
1261 
1262 	if (typeof variable_set === 'function') {
1263 		if (_.parse_function) {
1264 		} else {
1265 			_.warn('Warning: Please include ' + _.Class + '.parse_function() first!');
1266 		}
1267 
1268 	} else if (typeof variable_set === 'string') {
1269 		if (!from_name_space)
1270 			from_name_space = _;
1271 
1272 		if(name_space === from_name_space)
1273 			;
1274 		else if(variable_set in from_name_space){
1275 			//_.debug('extend (' + (typeof variable_set) + ') ' + variable_set + '\n=' + from_name_space[variable_set] + '\n\nto:\n' + name_space);
1276 			name_space[variable_set] = from_name_space[variable_set];
1277 		}else
1278 			try{
1279 				name_space[variable_set] = _.get_variable(variable_set);
1280 				//_.debug(variable_set + ' = ' + name_space[variable_set]);
1281 			}catch(e){
1282 				_.warn(_.Class + '.extend:\n' + e.message);
1283 			}
1284 
1285 	} else if (_.is_Array(variable_set)
1286 						&& !_.is_Array(name_space)) {
1287 		for (i = 0, l = variable_set.length; i < l; i++) {
1288 			_s(variable_set[i], name_space, from_name_space);
1289 		}
1290 
1291 	} else if (_.is_Object(variable_set)
1292 			//|| _.is_Function(variable_set)
1293 			) {
1294 		for (i in variable_set) {
1295 			if (from_name_space)
1296 				name_space[i] = from_name_space[variable_set[i] || i];
1297 			else
1298 				name_space[i] = variable_set[i];
1299 		}
1300 	}
1301 
1302 	return _;
1303 };
1304 
1305 //_.extend.default_target = _;
1306 
1307 
1308 CeL
1309 .
1310 /**
1311  * workaround.
1312  * 把 name_space 下的 function_name (name_space[function_name]) 換成 new_function。
1313  * for Lazy Function Definition Pattern.
1314  * 惰性求值(Lazy Evaluation),又稱懶惰求值、懶漢求值
1315  * @example
1316  * library_namespace.replace_function(_, 'to_SI_prefix', to_SI_prefix);
1317  * @param name_space	in which name-space
1318  * @param {String} function_name	name_space.function_name
1319  * @param {Function} new_function	replace to what function
1320  * @returns	new_function
1321  * @see
1322  * http://realazy.org/blog/2007/08/16/lazy-function-definition-pattern/,
1323  * http://peter.michaux.ca/article/3556
1324  */
1325 replace_function = function(name_space, function_name, new_function) {
1326 	if(!name_space)
1327 		return;//name_space = this;
1328 
1329 	var old_function = name_space[function_name], type = typeof new_function;
1330 
1331 	//	TODO: RegExp
1332 	if (type === 'bool' || type === 'string' || type === 'number')
1333 		new_function = new Function('return'
1334 				//	對 String 只是做簡單處理,勢必得再加強。
1335 				+ (type === 'string' ? '"' + type.replace(/\\/g, '\\').replace(/"/g, '\"').replace(/\n/g, '\\n')
1336 						+ '"' : ' '+type));
1337 
1338 	name_space[function_name] = new_function;
1339 	//	search for other extends
1340 	if (_[function_name] === old_function)
1341 		_[function_name] = new_function;
1342 
1343 	return new_function.apply(name_space, arguments);
1344 };
1345 
1346 
1347 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
1348 
1349 /**
1350  * XMLHttpRequest object type cache.
1351  * {Number} 0: no XMLHttpRequest, 1: new XMLHttpRequest_type(), 2: new ActiveXObject('Microsoft.XMLHTTP').
1352  * @inner
1353  * @ignore
1354  */
1355 var XMLHttpRequest_type = 0;
1356 try{
1357 	if(new XMLHttpRequest())
1358 		XMLHttpRequest_type = 1;
1359 	else
1360 		throw 1;
1361 }catch(e){
1362 	try{
1363 		if(new ActiveXObject('Microsoft.XMLHTTP'))
1364 			XMLHttpRequest_type = 2;
1365 	}catch(e){
1366 	}
1367 }
1368 
1369 var is_Opera = typeof navigator === 'object'
1370 	&& navigator.appName === 'Opera';
1371 
1372 CeL
1373 .
1374 /**
1375  * Get file resource by {@link XMLHttpRequest}<br/>
1376  * 依序載入 resource,用於 include JavaScript 檔之類需求時,取得檔案內容之輕量級函數。<br/>
1377  * 除 Ajax,本函數亦可用在 CScript 執行中。
1378  * @example
1379  * //	get contents of [path/to/file]:
1380  * var file_contents = CeL.get_file('path/to/file');
1381  * @param	{String} path	URI / full path. <em style="text-decoration:line-through;">不能用相對path!</em>
1382  * @param	{String} [encoding]	file encoding
1383  * @returns	{String} data	content of path
1384  * @returns	{undefined}	when error occurred: no Ajax function, ..
1385  * @throws	uncaught exception @ Firefox: 0x80520012 (NS_ERROR_FILE_NOT_FOUND), <a href="http://www.w3.org/TR/2007/WD-XMLHttpRequest-20070227/#exceptions">NETWORK_ERR</a> exception
1386  * @throws	'Access to restricted URI denied' 當 access 到上一層目錄時 @ Firefox
1387  * @see
1388  * <a href=http://blog.joycode.com/saucer/archive/2006/10/03/84572.aspx">Cross Site AJAX</a>,
1389  * <a href="http://domscripting.com/blog/display/91">Cross-domain Ajax</a>,
1390  * <a href="http://forums.mozillazine.org/viewtopic.php?f=25&t=737645" accessdate="2010/1/1 19:37">FF3 issue with iFrames and XSLT standards</a>,
1391  * <a href="http://kb.mozillazine.org/Security.fileuri.strict_origin_policy" accessdate="2010/1/1 19:38">Security.fileuri.strict origin policy - MozillaZine Knowledge Base</a>
1392  * Chrome: <a href="http://code.google.com/p/chromium/issues/detail?id=37586" title="between builds 39339 (good) and 39344 (bad)">NETWORK_ERR: XMLHttpRequest Exception 101</a>
1393  */
1394 get_file = XMLHttpRequest_type ? function(path, encoding) {
1395 	//with(typeof window.XMLHttpRequest=='undefined'?new ActiveXObject('Microsoft.XMLHTTP'):new XMLHttpRequest()){
1396 
1397 	//_.debug('XMLHttpRequest type: ' + XMLHttpRequest_type, 1, 'get_file');
1398 
1399 	var _s = _.get_file,
1400 	data,
1401 	type = 'GET',
1402 	/**
1403 	 * XMLHttpRequest object.
1404 	 * Can't cache this object.
1405 	 * @inner
1406 	 * @ignore
1407 	 */
1408 	o = XMLHttpRequest_type === 1 ?
1409 			new XMLHttpRequest()
1410 			: new ActiveXObject('Microsoft.XMLHTTP');
1411 
1412 	//	4096: URL 長度限制,與瀏覽器有關。
1413 	if (typeof path === 'string' && path.length > 4096
1414 			&& (data = path.match(/^([^?]{6,200})\?(.+)$/)))
1415 		path = data[1], data = data[2], type = 'PUT';
1416 	else
1417 		data = null;
1418 
1419 	o.open(type, path, false);
1420 
1421 	if (encoding && o.overrideMimeType)
1422 		/*
1423 		 * old: o.overrideMimeType('text/xml;charset='+encoding);
1424 		 * 但這樣會被當作 XML 解析,產生語法錯誤。
1425 		 */
1426 		o.overrideMimeType('application/json;charset=' + encoding);
1427 
1428 	try {
1429 		//	http://www.w3.org/TR/2007/WD-XMLHttpRequest-20070227/#dfn-send
1430 		//	Invoking send() without the data argument must give the same result as if it was invoked with null as argument.
1431 		o.send(data);
1432 		delete _s.error;
1433 
1434 	} catch (e) {
1435 		//	Chome: XMLHttpRequest cannot load file:///X:/*.js. Cross origin requests are only supported for HTTP.
1436 		//	Opera 11.50: 不會 throw,但是 .responseText === ''。
1437 		//	Apple Safari 3.0.3 may throw NETWORK_ERR: XMLHttpRequest Exception 101
1438 		_s.error = e;
1439 
1440 		//_.warn(_.Class + '.get_file: Loading [' + path + '] failed: ' + e);
1441 		//_.err(e);
1442 		//_.debug('Loading [' + path + '] failed.');
1443 
1444 		//e.object = o;	//	[XPCWrappedNative_NoHelper] Cannot modify properties of a WrappedNative @ firefox
1445 
1446 		if (typeof location === 'object'
1447 						&& (o = path.match(/:(\/\/)?([^\/]+)/))
1448 						&& o[2] !== location.hostname) {
1449 			_.warn('get_file: 所要求檔案之 domain [' + o[2]
1450 						+ '] 與所處之 domain [' + location.hostname + '] 不同!<br/>\n您可能需要嘗試使用 '
1451 						+ _.Class + '.include_resource()!');
1452 			throw new Error('get_file: Different domain!');
1453 		}
1454 
1455 		o = _.require_netscape_privilege(e, [_s, arguments]);
1456 		//_.debug('require_netscape_privilege return [' + typeof (o) + ('] ' + o).slice(0, 200) + ' ' + (e === o ? '=' : '!') + '== ' + 'error (' + e + ')');
1457 		if (e === o)
1458 			throw e;
1459 
1460 		return o;
1461 	}
1462 
1463 	//	workaround for Opera: Opera 11.50: 不會 throw,但是 .responseText === ''。
1464 	if (o.responseText === '' && is_Opera)
1465 		throw new Error('get_file: Nothing get @ Opera');
1466 
1467 	//	當在 local 時,成功的話 status === 0。失敗的話,除 IE 外,status 亦總是 0。
1468 	//	status was introduced in Windows Internet Explorer 7.	http://msdn.microsoft.com/en-us/library/ms534650%28VS.85%29.aspx
1469 	//	因此,在 local 失敗時,僅 IE 可由 status 探測,其他得由 responseText 判別。
1470 	//_.debug('Get [' + path + '], status: [' + o.status + '] ' + o.statusText);
1471 
1472 	return Math.floor(o.status / 100) > 3 ? [ o.status, o.responseText ] : o.responseText;
1473 }
1474 : function() {
1475 	//	No XMLHttpRequest object.
1476 
1477 	throw new Error('get_file: This browser does not support XMLHttpRequest.');
1478 	//	firefox: This function must return a result of type any.
1479 	//return undefined;
1480 };
1481 
1482 
1483 CeL
1484 .
1485 /**
1486  * Ask privilege in mozilla projects: Firefox 2, 3.
1487  * get_file() 遇到需要提高權限時使用。
1488  * enablePrivilege 似乎只能在執行的 function 本身或 caller 呼叫才有效果,跳出函數即無效,不能 cache,因此提供 callback。
1489  * 就算按下「記住此決定」,重開瀏覽器後需要再重新授權。
1490  * @param {String|Error} privilege	privilege that asked 或因權限不足導致的 Error
1491  * @param {Function|Array} callback|[callback,arguments]	Run this callback if getting the privilege. If it's not a function but a number(經過幾層/loop層數), detect if there's a loop or run the caller.
1492  * @returns	OK / the return of callback
1493  * @throws	error
1494  * @since	2010/1/2 00:40:42
1495  */
1496 require_netscape_privilege = function require_netscape_privilege(privilege, callback) {
1497 	var _s = require_netscape_privilege, f, i,
1498 	/**
1499 	 * raise error.
1500 	 * error 有很多種,所以僅以 'object' 判定。
1501 	 * @inner
1502 	 * @ignore
1503 	 */
1504 	re = function(m) {
1505 		//_.debug('Error: ' + m);
1506 		throw privilege && typeof privilege === 'object' ?
1507 			//	Error object
1508 			privilege :
1509 			//	new Error (message)
1510 			new Error(m);
1511 	};
1512 
1513 	if (!_s.enabled)
1514 		re('Privilege requiring disabled.');
1515 
1516 	//	test loop
1517 	//	得小心使用: 指定錯可能造成 loop!
1518 	if (!isNaN(callback) && callback > 0 && callback < 32) {
1519 		try{
1520 			//	@Firefox 4: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
1521 			for (f = _s, i = 0; i < callback; i++)
1522 				if (f = f.caller)
1523 					//	TODO: do not use arguments
1524 					f = f.arguments.callee;
1525 
1526 			if (f === _s)
1527 				// It's looped
1528 				re('Privilege requiring looped.');
1529 
1530 			callback = 1;
1531 
1532 		}catch (e) {
1533 			// TODO: handle exception
1534 		}
1535 
1536 	}
1537 
1538 	f = _s.enablePrivilege;
1539 	//_.debug('enablePrivilege: ' + f);
1540 	if (!f && !(_s.enablePrivilege = f =
1541 					_.get_variable('netscape.security.PrivilegeManager.enablePrivilege')))
1542 		//	更改設定,預防白忙。
1543 		_s.enabled = false,
1544 		re('No enablePrivilege get.');
1545 
1546 	if (_.is_type(privilege, 'DOMException')
1547 					&& privilege.code === 1012)
1548 		//	http://jck11.pixnet.net/blog/post/11630232
1549 		//	Mozilla的安全機制是透過PrivilegeManager來管理,透過PrivilegeManager的enablePrivilege()函式來開啟這項設定。
1550 		//	須在open()之前呼叫enablePrivilege()開啟UniversalBrowserRead權限。
1551 
1552 		//	http://code.google.com/p/ubiquity-xforms/wiki/CrossDomainSubmissionDeployment
1553 		//	Or: In the URL type "about:config", get to "signed.applets.codebase_principal_support" and change its value to true.
1554 
1555 		//	由任何網站或視窗讀取私密性資料
1556 		privilege = 'UniversalBrowserRead';
1557 
1558 	else if (!privilege || typeof privilege !== 'string')
1559 		re('Unknown privilege.');
1560 
1561 	//_.debug('privilege: ' + privilege);
1562 	try {
1563 		//_.log(_.Class + '.require_netscape_privilege: Asking privilege [' + privilege + ']..');
1564 		f(privilege);
1565 	} catch (e) {
1566 		if (privilege !== 'UniversalBrowserRead' || !_.is_local())
1567 			_.warn(_.Class + '.require_netscape_privilege: User denied privilege [' + privilege + '].');
1568 		throw e;
1569 	}
1570 
1571 	//_.debug('OK. Get [' + privilege + ']');
1572 
1573 
1574 	if (callback === 1) {
1575 		//_.debug('再執行一次 caller..');
1576 		try{
1577 			callback = _s.caller;
1578 		}catch (e) {
1579 			// TODO: handle exception
1580 		}
1581 		return callback.apply(_, callback.arguments);
1582 
1583 /*		i = callback.apply(_, callback.arguments);
1584 		_.debug(('return ' + i).slice(0, 200));
1585 		return i;
1586 */
1587 	} else if (_.is_Function(callback))
1588 		// 已審查過,為 function
1589 		return callback();
1590 	else if (_.is_Array(callback))
1591 		return callback[0].apply(_, callback[1]);
1592 };
1593 
1594 CeL
1595 .
1596 /**
1597  * 當需要要求權限時,是否執行。(這樣可能彈出對話框)
1598  * Firefox 5 之後,就算要求了,對 local 也沒用,甚至會 hang 住掛掉,因此取消了。
1599  * @type	Boolean
1600  */
1601 require_netscape_privilege.enabled = false;
1602 
1603 
1604 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
1605 
1606 
1607 CeL
1608 .
1609 /**
1610  * 得知 script file 之相對 base path
1611  * @param	{String} JSFN	script file name
1612  * @returns	{String} relative base path
1613  * @example
1614  * <script type="text/javascript" src="../baseFunc.js"></script>
1615  * //	引數為本.js檔名。若是更改.js檔名,亦需要同步更動此值!
1616  * var basePath=get_script_base_path('baseFunc.js');
1617  * perl: use File::Basename;
1618  */
1619 get_script_base_path = function(JSFN){
1620 	//alert(JSFN);
1621 	if(!JSFN)
1622 		return (typeof location === 'object' ?
1623 				// location.pathname
1624 				location.href
1625 				: typeof WScript === 'object' ? WScript.ScriptFullName
1626 				//	用在把檔案拉到此檔上時不方便
1627 				//: typeof WshShell === 'object' ? WshShell.CurrentDirectory
1628 				: '').replace(/[^\/\\]+$/, '');
1629 
1630 	//	We don't use is_Object or so.
1631 	//	通常會傳入的,都是已經驗證過的值,不會出現需要特殊認證的情況。
1632 	//	因此精確繁複的驗證只用在可能輸入奇怪引數的情況。
1633 	if (typeof document !== 'object')
1634 			return '';
1635 
1636 	//	form dojo: d.config.baseUrl = src.substring(0, m.index);
1637 	var i = 0, o = document.getElementsByTagName('script'), l = o.length, j, b, I;
1638 
1639 	for (; i < l; i++)
1640 		try {
1641 			//	o[i].src 多是 full path, o[i].getAttribute('src') 僅取得其值,因此可能是相對的。
1642 			j = o[i].getAttribute ? o[i].getAttribute('src') : o[i].src;
1643 			I = j.lastIndexOf(JSFN);
1644 			//alert(j + ',' + JSFN + ',' + I);
1645 			if (I !== -1){
1646 				//	TODO: dirty hack
1647 				if (_.env.script_extension === '.') {
1648 					b = j.slice(I + JSFN.length);
1649 					if (b === 'js' || b === 'txt')
1650 						_.env.script_extension += b,
1651 						_.env.main_script += b;
1652 					else{
1653 						b = '';
1654 						//	遇到奇怪的 extension
1655 						continue;
1656 					}
1657 				}
1658 				//	TODO: test 是否以 JSFN 作為結尾
1659 				b = j.slice(0, I);
1660 			}
1661 		} catch (e) {
1662 		}
1663 
1664 	//_.log()
1665 
1666 	//	b || './'
1667 	return b || '';
1668 };
1669 
1670 
1671 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
1672 
1673 
1674 CeL
1675 .
1676 /**
1677  * test 是否符合 module pattern.
1678  * TODO: improve
1679  * @param {String} test_string	string to test
1680  * @returns	{Boolean}	是否符合 module pattern
1681  */
1682 is_module_pattern = function(test_string){
1683 	var r = _.env.module_identifier_RegExp;
1684 	if (!r) {
1685 		//	initial module_identifier_RegExp
1686 		r = _.env.identifier_RegExp.source;
1687 		r = _.env.module_identifier_RegExp = new RegExp('^' + r
1688 				+ '(\\.' + r + ')*$');
1689 	}
1690 
1691 	return r.test(test_string);
1692 };
1693 
1694 
1695 CeL
1696 .
1697 /**
1698  * test function.request 的項目是否為 module.
1699  * TODO
1700  * 現在還有很大問題!
1701  * @param {String} resource_string	resource to test
1702  * @returns	{Boolean}	resource 是否為 module (true: is module, false: is URL?)
1703  */
1704 request_item_maybe_module = function(resource_string) {
1705 	return resource_string.charAt(0) === '.'
1706 		|| resource_string.charAt(0) === '/'
1707 			|| resource_string.indexOf(':') !== -1
1708 			// || resource_string.indexOf('%')!==-1
1709 			|| /\.(js|css)$/i.test(resource_string) ? false :
1710 				/\.$/.test(resource_string)
1711 				|| _.is_module_pattern(resource_string);
1712 };
1713 
1714 
1715 var library_base_path;
1716 CeL
1717 .
1718 /**
1719  * get the path of specified module.
1720  * @example
1721  * //	存放 data 的 path
1722  * path = library_namespace.get_module_path(this, '');
1723  * 
1724  * @param {String} module_name	module name
1725  * @param	{String} file_name	取得在同一目錄下檔名為 file_name 之 path。若填入 '' 可取得 parent 目錄。
1726  * @returns	{String} module path
1727  */
1728 get_module_path = function(module_name, file_name){
1729 	module_name = get_module_name(module_name);
1730 	var m;
1731 	if (!module_name || !(m = _.split_module_name(module_name)))
1732 		return module_name;
1733 
1734 	//_.debug('load [' + module_name + ']', 1, 'get_module_path');
1735 	var module_path = library_base_path
1736 	|| (library_base_path =
1737 			_.env.registry_path
1738 			|| _.get_script_base_path(_.env.main_script)
1739 			|| _.get_script_base_path()
1740 		);
1741 	//_.debug('library_base_path: ' + library_base_path, 1, 'get_module_path');
1742 
1743 	module_path += m.join(/\//.test(module_path)?'/':'\\') + _.env.script_extension;
1744 	//_.debug('module_path: ' + module_path, 1, 'get_module_path');
1745 
1746 	if (typeof file_name !== 'undefined')
1747 		module_path = module_path.replace(/[^\/]+$/, file_name);
1748 	else if (_.getFP)
1749 		module_path = _.getFP(module_path, 1);
1750 
1751 	//_.debug(module_name + ': return [' + module_path + ']', 1, 'get_module_path');
1752 
1753 	return module_path;
1754 };
1755 
1756 
1757 /*
1758 sample to test:
1759 
1760 ./a/b
1761 ./a/b/
1762 ../a/b
1763 ../a/b/
1764 a/../b		./b
1765 a/./b		a/b
1766 /../a/b		/a/b
1767 /./a/b		/a/b
1768 /a/./b		/a/b
1769 /a/../b		/b
1770 /a/../../../b	/b
1771 /a/b/..		/a
1772 /a/b/../	/a/
1773 a/b/..		a
1774 a/b/../		a/
1775 a/..		.
1776 ./a/b/../../../a.b/../c	../c
1777 ../../../a.b/../c	../../../c
1778 
1779 */
1780 
1781 //	2009/11/23 22:12:5
1782 if(0)
1783 CeL
1784 .
1785 deprecated_simplify_path = function(path){
1786 	if(typeof path === 'string'){
1787 		//	去除前後空白
1788 		path = path.replace(/\s+$|^\s+/,'').replace(/\/\/+/g,'/');
1789 
1790 		var p, is_absolute = '/' === path.charAt(0);
1791 
1792 		while( path !== (p=path.replace(/\/\.(\/|$)/g,function($0,$1){return $1;})) )
1793 			path = p;
1794 		_.debug('1. '+p);
1795 
1796 		while (path !== (p = path.replace(
1797 				/\/([^\/]+)\/\.\.(\/|$)/g, function($0, $1, $2) {
1798 					alert( [ $0, $1, $2 ].join('\n'));
1799 					return $1 === '..' ? $0 : $2;
1800 				})))
1801 			path = p;
1802 		_.debug('2. '+p);
1803 
1804 		if(is_absolute)
1805 			path = path.replace(/^(\/\.\.)+/g,'');
1806 		else
1807 			path = path.replace(/^(\.\/)+/g,'');
1808 		_.debug('3. '+p);
1809 
1810 		if(!path)
1811 			path = '.';
1812 	}
1813 
1814 	return path;
1815 };
1816 
1817 CeL
1818 .
1819 /**
1820  * 轉化所有 /., /.., //
1821  * @since	2009/11/23 22:32:52
1822  * @param {String} path	欲轉化之 path
1823  * @returns	{String} path
1824  */
1825 simplify_path = function(path){
1826 	if(typeof path === 'string'){
1827 		var i, j, l, is_absolute, head;
1828 
1829 		path = path
1830 			.replace(/^[\w\d\-]+:\/\//,function($0){head = $0; return '';})
1831 			//	去除前後空白
1832 			//.replace(/\s+$|^\s+/g,'')
1833 			//.replace(/\/\/+/g,'/')
1834 			.split('/');
1835 
1836 		i = 0;
1837 		l = path.length;
1838 		is_absolute = !path[0];
1839 
1840 		for(;i<l;i++){
1841 			if(path[i] === '.')
1842 				path[i] = '';
1843 
1844 			else if(path[i] === '..'){
1845 				j=i;
1846 				while(j>0)
1847 					if(path[--j] && path[j]!='..'){
1848 						path[i] = path[j] = '';	//	相消
1849 						break;
1850 					}
1851 			}
1852 		}
1853 
1854 		if(!is_absolute && !path[0])
1855 			path[0] = '.';
1856 
1857 		path = path.join('/')
1858 			.replace(/\/\/+/g,'/')
1859 			.replace(is_absolute? /^(\/\.\.)+/g: /^(\.\/)+/g,'')
1860 			;
1861 
1862 		if(!path)
1863 			path = '.';
1864 
1865 		if(head)
1866 			path = head + path;
1867 	}
1868 
1869 	return path;
1870 };
1871 
1872 
1873 
1874 /**
1875  * 載入 module 時執行 extend 工作
1876  * @param module
1877  * @param extend_to
1878  * @param {Function} callback
1879  * @returns
1880  * @inner
1881  * @ignore
1882  */
1883 var extend_module_member = function(module, extend_to, callback) {
1884 	var i, l;
1885 
1886 	//typeof name_space !== 'undefined' && _.debug(name_space);
1887 	//	處理 extend to what name-space
1888 	if (!extend_to && extend_to !== false
1889 			//	若是在 .setup_module 中的話,可以探測得到 name_space?(忘了)
1890 			//|| typeof name_space !== 'function'
1891 			|| !_.is_Object(extend_to))
1892 		//	預設會 extend 到 library 本身下
1893 		extend_to = _;
1894 
1895 	if (extend_to && (i = _.get_module(module))) {
1896 		var ns = i, kw = _.env.not_to_extend_keyword, no_extend = {};
1897 		//_.debug('load [' + module + ']:\nextend\n' + ns);
1898 
1899 		if (kw in ns) {
1900 			l = ns[kw];
1901 			if (typeof l === 'string' && l.indexOf(',') > 0)
1902 				l = l.split(',');
1903 
1904 			if (typeof l === 'string') {
1905 				no_extend[l] = 1;
1906 			} else if (_.is_Array(l)) {
1907 				for (i = 0; i < l.length; i++)
1908 					// WScript.Echo('no_extend '+l[i]),
1909 					no_extend[l[i]] = 1;
1910 			} else if (_.is_Object(l)) {
1911 				no_extend = l;
1912 			}
1913 
1914 			no_extend[kw] = 1;
1915 		}
1916 
1917 		//	'*': 完全不 extend
1918 		if (!no_extend['*']) {
1919 			no_extend.Class = 1;
1920 			//	this: 連 module 本身都不 extend 到 library name-space 下
1921 			var no_self = 'this' in no_extend;
1922 			if(no_self)
1923 				delete no_extend['this'];
1924 
1925 			l = [];
1926 			for (i in ns)
1927 				if (!(i in no_extend))
1928 					l.push(i);
1929 
1930 			//_.debug('load [' + module + ']:\nextend\n' + l + '\n\nto:\n' + (extend_to.Class || extend_to));
1931 			_.extend(l, extend_to, ns);
1932 
1933 			/*
1934 			 * extend module itself.
1935 			 * e.g., .net.web -> .web
1936 			 */
1937 			if (!no_self && (i = _.split_module_name(module))
1938 							&& (i = i.pop()) && !(i in _))
1939 						_[i] = ns;
1940 		}
1941 
1942 	}
1943 
1944 
1945 	try {
1946 		i = _.is_Function(callback) && callback(undefined, module);
1947 	} catch (e) {
1948 	}
1949 	return i;
1950 };
1951 
1952 
1953 
1954 
1955 CeL
1956 .
1957 /**
1958  * 不使用 eval 的方法,get the module namespace of specific module name.
1959  * @param	{String} module_name	module name
1960  * @returns	null	some error occurred
1961  * @returns	namespace of specific module name
1962  */
1963 get_module = function(module_name) {
1964 	module_name = _.split_module_name.call(_, module_name);
1965 
1966 	//	TODO: test module_name.length
1967 	if(!module_name)
1968 		return null;
1969 
1970 	var i = 0, l = module_name.length, name_space = _;
1971 	//	一層一層 call name-space
1972 	while (i < l)
1973 		try {
1974 			name_space = name_space[module_name[i++]];
1975 		} catch (e) {
1976 			return null;
1977 		}
1978 
1979 	return name_space;
1980 };
1981 
1982 
1983 
1984 
1985 CeL
1986 .
1987 /**
1988  * 載入 module。
1989  * <p>
1990  * 本函數會預先準備好下層 module 定義時的環境,但請盡量先 call 上層 name-space
1991  * 再定義下層的,否則可能會出現問題,如 memory leak 等。
1992  * </p>
1993  * 
1994  * @param {String}
1995  *            [module_name]
1996  *            <p>
1997  *            module name to register: 本 module 之 name(id)
1998  *            </p>
1999  * @param {Function}
2000  *            code_for_including
2001  *            <p>
2002  *            若欲 include 整個 module 時,需囊括之 code。
2003  *            </p>
2004  *            code_for_including(
2005  *            		{Function} library_namespace:	namespace of library,
2006  *            		load_arguments:	呼叫時之 argument(s)
2007  *            )
2008  * @returns null
2009  *          <p>
2010  *          invalid module
2011  *          </p>
2012  * @returns {Object}
2013  *          <p>
2014  *          下層 module 之 name-space
2015  *          </p>
2016  * @returns undefined
2017  *          <p>
2018  *          something error, e.g., 未成功 load,code_for_including
2019  *          return null, ..
2020  *          </p>
2021  */
2022 setup_module = function(module_name, code_for_including, parent_module_name) {
2023 	// adapt arguments
2024 	var i, l, name_space, allow_inherit,
2025 	/**
2026 	 * translate {String} code_for_including to function
2027 	 */
2028 	name = function() {
2029 		//	null module constructor
2030 		if (!code_for_including)
2031 			code_for_including = function() {
2032 				return function() {};
2033 			};
2034 
2035 		else if (typeof code_for_including === 'string')
2036 			code_for_including =
2037 				// (new Function(code_for_including)).bind(CeL)
2038 				new Function(code_for_including);
2039 	};
2040 
2041 	if (typeof module_name === 'string') {
2042 		name();
2043 		if (_.is_Function(code_for_including)
2044 				|| _.is_Object(code_for_including))
2045 			code_for_including.module_name = module_name;
2046 
2047 	} else {
2048 		code_for_including = module_name;
2049 		// TODO: 不設定時會從呼叫時之 path (directory + file name) 取得
2050 	}
2051 
2052 	if (_.is_Object(code_for_including)) {
2053 		name_space = code_for_including;
2054 		code_for_including = name_space.code;
2055 		delete name_space.code;
2056 		name();
2057 
2058 		_.extend(name_space, code_for_including);
2059 
2060 	} else
2061 		name();
2062 
2063 	if (!module_name && !(module_name = code_for_including.module_name)) {
2064 		_.err('The module name is not specified!');
2065 		_.debug(code_for_including);
2066 		return null;
2067 	}
2068 
2069 	//	sub module
2070 	if (_.is_Object(l = code_for_including.sub_module)) {
2071 		name_space = module_name + _.env.module_name_separator;
2072 		for (i in l)
2073 			_.setup_module(name_space + i, l[i], module_name);
2074 	}
2075 
2076 	//_.debug('prepare to setup module [' + module_name + ']', 1, 'setup_module');
2077 
2078 	/**
2079 	 * 測試 dependency list 是不是皆已 loaded。
2080 	 * 會合併 parent module 之 request。
2081 	 * <dl>
2082 	 * <dt>依 (module name-space).require 設定 dependency list</dt>
2083 	 * <dd>(module name-space).require_module = module name[]</dd>
2084 	 * <dd>(module name-space).require_variable = {variable_name: full_name_with_module_name}</dd>
2085 	 * <dd>(module name-space).require_URL = URL[]</dd>
2086 	 * </dl>
2087 	 * TODO:
2088 	 * 就算輸入 module path 亦可自動判別出為 module 而非普通 resource。
2089 	 */
2090 	var require = _.parse_require(code_for_including.require, code_for_including.require_separator, parent_module_name && module_require_chain[parent_module_name]), URL_to_load, module_to_load;
2091 	if (_.is_Object(require)) {
2092 		_.extend( {
2093 			require_module : 'module_to_load',
2094 			require_variable : 'variable',
2095 			require_URL : 'URL_to_load'
2096 		}, code_for_including, require);
2097 
2098 		if (_.is_Array(require.module_to_load)
2099 				&& require.module_to_load.length)
2100 			module_to_load = require.module_to_load;
2101 
2102 		if (_.is_Array(require.URL_to_load)
2103 				&& require.URL_to_load.length)
2104 			URL_to_load = require.URL_to_load;
2105 	}
2106 
2107 
2108 	if (module_to_load || URL_to_load) {
2109 
2110 		//_.debug('module [' + (typeof module_name === 'string' ? module_name: undefined) + '] need to load:\n' + module_to_load, 1, 'setup_module');
2111 
2112 		//	check 登錄
2113 		if (module_name in module_require_chain) {
2114 			//	可能是循環參照(circular dependencies),還是執行 module code_for_including
2115 			//	若本身已經在需求名單中則放行,避免相互需要造成堆疊空間不足(Out of stack space)或 Stack overflow。
2116 			_.warn('Skip to load dependencies [' + module_to_load + '] of module [' + module_name + '] because the module is already in the require chain.\nmodule 正在需求鏈中。也許是循環參照(circular dependencies)?');
2117 
2118 		}else{
2119 
2120 			//	登錄: module_name 正在 call。若由其他 module call 的,那就登錄此 parent module。
2121 			module_require_chain[parent_module_name || module_name] = require;
2122 
2123 			// include required modules
2124 			if (module_to_load && _.use(module_to_load)) {
2125 				//	若有未載入之 dependencies,則不載入 module。
2126 				if(!_.is_local() || _.is_debug(2))
2127 					_.warn(_.Class + '.setup_module: Module [' + module_name + '] fault to load dependencies [' + module_to_load + ']. You have to load it later.');
2128 
2129 				//	throw and wait .include_resource() to call callback(path, module_name)
2130 				//	為了預防後面還有 code 而繼續執行下去,所以採用 throw 而非 return。
2131 				throw new Error(_.Class + '.setup_module: Module [' + module_name + '] 無法以 Ajax load required module!\nrequired module list: ['+module_to_load+']');
2132 			}
2133 
2134 			if (URL_to_load) {
2135 				// 嘗試直接載入
2136 				for (i in URL_to_load)
2137 					try {
2138 						if (l = _.get_file(i = URL_to_load[i]))
2139 							_.eval_code(l);
2140 						else
2141 							throw 1;
2142 					} catch (e) {
2143 						_ .err('module [' + (typeof module_name === 'string' ? module_name : undefined) + '] load URL [' + i
2144 								+ '] error. You have to load it later.');
2145 						// return and wait .include_resource() to call callback(path, module_name)
2146 						throw new Error(_.Class + '.setup_module: module [' + module_name + '] 無法以 Ajax load required URL [' + i + ']!');
2147 					}
2148 			}
2149 
2150 		}
2151 
2152 	}
2153 	// else	所有需求皆已在 queue 中,因此最後總**有機會(不包括發生錯誤的情況!)**會被 load,故 skip。
2154 
2155 
2156 	var module_name_list = _.split_module_name(module_name);
2157 	if (!module_name_list) {
2158 		_.err('Illegal module name: [' + module_name + ']!');
2159 		_.debug(code_for_including);
2160 
2161 		//	執行完清除載入中之登錄
2162 		if(module_name in module_require_chain)
2163 			delete module_require_chain[module_name];
2164 
2165 		return null;
2166 	}
2167 
2168 	//	若皆載入: 準備執行 module code_for_including
2169 	//	一層一層準備好、預定義 name-space
2170 	for (i = 0, l = module_name_list.length - 1, name_space = _; i < l; i++) {
2171 		if (!name_space[name = module_name_list[i]])
2172 			/**
2173 			 * <code>
2174 			 * _.debug('預先定義 module [' + _.to_module_name(module_name.slice(0, i + 1)) + ']'),
2175 			 * </code>
2176 			 */
2177 			name_space[name] = new Function(
2178 					'//	null constructor for module ' +
2179 					_.to_module_name(module_name_list.slice(0, i + 1)));
2180 		name_space = name_space[name];
2181 	}
2182 	//	name_space 這時是 module 的 parent module。
2183 
2184 	if (
2185 			// 尚未被定義或宣告過
2186 			!name_space[name = module_name_list[l]] ||
2187 			// 可能是之前簡單定義過,例如被上面處理過。這時重新定義,並把原先的 member 搬過來。
2188 			!name_space[name].Class) {
2189 
2190 		// 保留原先的 name-space,for 重新定義
2191 		l = name_space[name];
2192 
2193 		// extend code, 起始 name-space
2194 		try {
2195 			/**
2196 			 * 真正執行 module code.
2197 			 * <code>
2198 			 * _.debug('including code of [' + _.to_module_name(module_name) + ']..'),
2199 			 * </code>
2200 			 * TODO: code_for_including(_, load_arguments)
2201 			 */
2202 			i = code_for_including.call(code_for_including, _);
2203 			i.prototype.constructor = i;
2204 			if('allow_inherit' in i){
2205 				allow_inherit = i.allow_inherit;
2206 				delete i.allow_inherit;
2207 			}
2208 			//code_for_including.toString = function() { return '[class_template ' + name + ']'; };
2209 			//i.toString = function() { return '[class ' + name + ']'; };
2210 		} catch (e) {
2211 			_.err(_.Class + '.setup_module: load module ['
2212 					+ _.to_module_name(module_name) + '] error!\n' + e.message);
2213 			i = undefined;
2214 		}
2215 
2216 		if (i === undefined)
2217 			//	error?
2218 			return;
2219 
2220 		name_space = name_space[name] = i;
2221 
2222 		// 把原先的 member 搬過來
2223 		if (l) {
2224 			delete l.Class;
2225 			//	may use: _.extend()
2226 			for (i in l)
2227 				name_space[i] = l[i];
2228 		}
2229 		name_space.Class = _.to_module_name(module_name);
2230 	}
2231 
2232 /*
2233 	l=[];
2234 	for(i in name_space)
2235 		l.push(i);
2236 	WScript.Echo('Get members:\n'+l.join(', '));
2237 */
2238 
2239 	//	執行完清除載入中之登錄
2240 	if(module_name in module_require_chain)
2241 		delete module_require_chain[module_name];
2242 
2243 	set_loaded(name_space.Class, code_for_including, allow_inherit);
2244 
2245 	//_.debug('module [' + module_name + '] 設定 OK.', 1, 'setup_module');
2246 
2247 	return name_space;
2248 };
2249 
2250 
2251 
2252 CeL
2253 .
2254 /**
2255  * 是否 cache code。
2256  * 若不是要重構 code 則不需要。
2257  * undefined: 依照預設
2258  * Boolean: 明確設定,但如此即無法繼承。
2259  * @type	Boolean, undefined
2260  */
2261 cache_code = /*_.is_debug() || */ undefined;
2262 
2263 /**
2264  * cache 已經 include 之函式或 class。
2265  * loaded_module[module_name] =
2266  * 		undefined: 尚未載入。
2267  * 		{Boolean} true	已經載入,但未 cache code。
2268  * 		{Function} code	已經載入,這是 cache 了的 code。
2269  * @inner
2270  * @ignore
2271  * @type Object
2272  */
2273 var loaded_module = {
2274 };
2275 
2276 
2277 /**
2278  * 紀錄 **正在 load** 之 module 所需之 dependency list。
2279  * module_require_chain[module_name] = [未載入之 dependency list by .parse_require()] requesting now.
2280  * 
2281  * ** 這一項僅在 .setup_module() 發現 dependency list 尚未載入完時,預防循環 request 而用。
2282  * @inner
2283  * @ignore
2284  * @type Object
2285  */
2286 var module_require_chain = {
2287 };
2288 
2289 
2290 
2291 CeL
2292 .
2293 /**
2294  * 將輸入的 string 分割成各 module 單元。<br/>
2295  * need environment_adapter()<br/>
2296  * ** 並沒有對 module 做完善的審核!
2297  * @param {String} module_name	module name
2298  * @returns	{Array}	module unit array
2299  */
2300 split_module_name = function(module_name) {
2301 	//_.debug('[' + module_name + ']→[' + module_name.replace(/\.\.+|\\\\+|\/\/+/g, '.').split(/\.|\\|\/|::/) + ']');
2302 	if (typeof module_name === 'string')
2303 		module_name = module_name
2304 			//.replace(/\.\.+|\\\\+|\/\/+/g, '.')
2305 			.replace(/[\\\/]/g, '.')
2306 			.split(/[.\\\/]|::/);
2307 
2308 	if (_.is_Array(module_name) && module_name.length) {
2309 		//	去除 library name
2310 		if (module_name.length > 1 && _.Class === module_name[0])
2311 			module_name.shift();
2312 		return module_name;
2313 	} else
2314 		return null;
2315 };
2316 
2317 
2318 /**
2319  * 取得建構 code 之 module name。不以 library name 起始。
2320  * // get_module_name()
2321  * code_for_including.module_name === 'module_name';
2322  * // _.to_module_name()
2323  * library_name.module_parent.module_child.Class === 'library_name.module_parent.module_child' === 'library_name.module_name';
2324  * TODO:
2325  * 有效率的整合 get_module_name() 與 _.to_module_name()
2326  * @param code_for_including
2327  * @returns {String} module name
2328  */
2329 var get_module_name = function(code_for_including) {
2330 	//_.debug('module_name: ' + (_.is_Function(code_for_including) && code_for_including.module_name ? code_for_including.module_name : code_for_including), 1, 'get_module_name');
2331 	//_.debug('Class: ' + (_.is_Function(code_for_including) && code_for_including.Class ? code_for_including.Class : code_for_including), 1, 'get_module_name');
2332 
2333 	return _.is_Function(code_for_including) && code_for_including.module_name ?
2334 			code_for_including.module_name
2335 			: code_for_including;
2336 };
2337 
2338 
2339 CeL
2340 .
2341 /**
2342  * 取得 module 之 name。以 library name 起始。
2343  * @returns {String} module name start with library name
2344  */
2345 to_module_name = function(module, separator) {
2346 	if (_.is_Function(module))
2347 		module = module.Class;
2348 	else if (module === _.env.main_script_name)
2349 		module = _.Class;
2350 
2351 	if (typeof module === 'string')
2352 		module = _.split_module_name(module);
2353 
2354 	var name = '';
2355 	if (_.is_Array(module)) {
2356 		if (typeof separator !== 'string')
2357 			separator = _.env.module_name_separator;
2358 		if (module[0] !== _.Class)
2359 			name = _.Class + separator;
2360 		name += module.join(separator);
2361 	}
2362 
2363 	return name;
2364 };
2365 
2366 
2367 
2368 //TODO
2369 CeL
2370 .
2371 get_require = function(func) {
2372 	if (_.is_Function(func) || _.is_Object(func))
2373 		return func.require;
2374 
2375 	if (_.is_Function(func = loaded_module[_.to_module_name(func)]))
2376 		return func.require_module;
2377 };
2378 
2379 //TODO
2380 CeL
2381 .
2382 unload_module = function(module, g){
2383 	///	<returns>error</returns>
2384 	if(_.is_debug())
2385 		throw new Error('UNDO');
2386 
2387 };
2388 
2389 
2390 CeL
2391 .
2392 /**
2393  * 判斷 module 是否存在,
2394  * TODO
2395  * 以及是否破損。
2396  * @param	{String} module_name	module name
2397  * @param	{Array} module_name	module name list
2398  * @returns	{Boolean} 所指定 module 是否全部存在以及良好。
2399  */
2400 is_loaded = function(module_name) {
2401 	if (_.is_Array(module_name)) {
2402 		for ( var i = 0, l = module_name.length; i < l; i++)
2403 			if (!loaded_module[_.to_module_name(module_name[i])])
2404 				return false;
2405 		return true;
2406 	}
2407 
2408 	// var _s = arguments.callee;
2409 	//_.debug('test ' + _.to_module_name(module_name));
2410 
2411 	/*
2412 	var code = loaded_module[_.to_module_name(module_name)], sub_module, prefix;
2413 	if (_.is_Function(code) && (sub_module = code.sub_module)) {
2414 		sub_module = sub_module.split('|');
2415 		prefix = module_name + _.env.module_name_separator;
2416 		for ( var i = 0, l = module_name.length; i < l; i++){
2417 			_.debug('check [' + prefix + sub_module[i] + ']', 1, 'is_loaded');
2418 			if (!_.is_loaded(prefix + sub_module[i]))
2419 				return false;
2420 		}
2421 		return true;
2422 	}
2423 	*/
2424 
2425 	return !!loaded_module[_.to_module_name(module_name)];
2426 };
2427 
2428 
2429 
2430 /**
2431  * 設定登記 module 已載入。
2432  * @inner
2433  * @private
2434  */
2435 var set_loaded = function(module_name, code_for_including,
2436 		cache_code) {
2437 	// _.debug(_.to_module_name(module_name));
2438 	loaded_module[_.to_module_name(module_name)] = (_.cache_code === undefined
2439 			&& cache_code || _.cache_code)
2440 			&& code_for_including || true;
2441 };
2442 
2443 
2444 
2445 
2446 
2447 function get_include_resource(split) {
2448 	if (typeof document !== 'object' || !document.getElementsByTagName)
2449 		//	document!=='object': 誤在非 HTML 環境執行,卻要求 HTML 環境下的 resource?
2450 		//if(typeof document==='object')_.warn(_.Class + ".include_resource: Can't load [" + path + "]!");
2451 		return;
2452 
2453 	var i, nodes = document.getElementsByTagName('script'), h, hn, count = 0, p, l;
2454 	if (split)
2455 		h = {
2456 			script : {},
2457 			css : {}
2458 		},
2459 		hn = h.script;
2460 	else
2461 		hn = h = {};
2462 
2463 	l = nodes.length;
2464 	for (i = 0; i < l; i++)
2465 		if (p = _.simplify_path(nodes[i].src))
2466 			hn[p] = 1, count++;
2467 
2468 	nodes = document.getElementsByTagName('link');
2469 	if (split)
2470 		hn = l.css;
2471 
2472 	l = nodes.length;
2473 	for (i = 0; i < l; i++)
2474 		if (p = _.simplify_path(nodes[i].href))
2475 			hn[p] = 1, count++;
2476 
2477 	return [ h, count ];
2478 };
2479 
2480 /**
2481  * 已經 include_resource 了哪些 JavaScript 檔(存有其路徑).
2482  * included_path[path] =
2483  * 		undefined: 尚未載入。
2484  * 		true	已經載入。
2485  * 
2486  * TODO:
2487  * included_path[index] = [time stamp, path],
2488  * @inner
2489  * @ignore
2490  * @type Object
2491  */
2492 var included_path;
2493 
2494 function included_path_init(){
2495 	var s = get_include_resource();
2496 	if(s)
2497 		included_path = s[0];
2498 	return included_path || {};
2499 }
2500 
2501 
2502 CeL
2503 .
2504 is_included = function(path) {
2505 	return !!(included_path || included_path_init())[path];
2506 };
2507 
2508 var set_included = function(path, timeout_id) {
2509 	(included_path || included_path_init())[path] = timeout_id;
2510 },
2511 
2512 get_included = function(path) {
2513 	return (included_path || included_path_init())[path];
2514 };
2515 
2516 
2517 
2518 CeL
2519 .
2520 /**
2521  * include resource of module.
2522  * @example
2523  * //	外部程式使用時,通常用在 include 相對於 library 本身路徑固定的檔案。
2524  * //	例如 file_name 改成相對於 library 本身來說的路徑。
2525  * CeL.include_module_resource('../../game/game.css');
2526  * 
2527  * library_namespace.include_module_resource('select_input.css', this);
2528  * 
2529  * @param {String} file_name	與 module 位於相同目錄下的 resource file name
2530  * @param {String} [module_name]	呼叫的 module name。未提供則設成 library base path,此時 file_name 為相對於 library 本身路徑的檔案。
2531  * @returns
2532  * @since	2010/1/1-2 13:58:09
2533  */
2534 include_module_resource = function(file_name, module_name) {
2535 	//var m = _.split_module_name.call(_, module_name);
2536 	//if (m)m[m.length - 1] = file_name;
2537 	return _.include_resource.call(_,
2538 			_.get_module_path(get_module_name(module_name) || _.Class, file_name));
2539 };
2540 
2541 
2542 
2543 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
2544 
2545 
2546 CeL
2547 .
2548 /**
2549  * Include specified module.<br/>
2550  * 
2551  * 會先嘗試以依序載入(asynchronous)的方式取得 module。
2552  * 無法以 Ajax 載入時,若未設定 callback,會回傳錯誤。若設定 callback,會以同步(synchronous)的方式載入 module,於載入完成執行 callback。
2553  * 		若因為 browser 安全性設定而無法取得則會回傳 -1,表示將以同步的方式載入 module。因為 module 尚未載入,在此階段尚無法判別此 module 所需之 dependency list。此 list 會被作為引數傳入 callback。
2554  * 
2555  * 注意:以下的 code 中,CeL.warn 不一定會被執行(可能會、可能不會),因為執行時 log 可能尚未被 include。<br/>
2556  * 此時應該改用 CeL.set_run('application.log', callback);<br/>
2557  * code in head/script/:
2558  * <code>
2559  * CeL.use('code.log');
2560  * CeL.warn('WARNING message');
2561  * </code>
2562  * **	在指定 callback 時 name_space 無效!
2563  * **	預設會 extend 到 library 本身之下!
2564  * @param	{String} module	module name
2565  * @param	{Function} [callback]	callback function | [callback, 進度改變時之 function (TODO)]
2566  * @param	{Object|Boolean} [extend_to]	extend to which name-space<br/>
2567  * 		false:	just load, don't extend to library name-space<br/>
2568  * 		this:	extend to global<br/>
2569  * 		object:	extend to specified name-space that you can use [name_space]._func_ to run it<br/>
2570  * 		(others, including undefined):	extend to root of this library. e.g., call CeL._function_name_ and we can get the specified function.
2571  * @returns	{Error}
2572  * @returns	-1	will execute callback after load, 不代表 load module 了!
2573  * @returns	{undefined}	no error, OK
2574  * @example
2575  * CeL.use('code.log', function(){..});
2576  * CeL.use(['code.log', 'code.debug']);
2577  * @note
2578  * 'use' 是 JScript.NET 的保留字.
2579  */
2580 use = function requires(module, callback, extend_to, force){
2581 	var _s = requires, i, l, module_path;
2582 
2583 	//_.debug('load [' + module + ']');
2584 	if (!module)
2585 		return;
2586 
2587 	/*
2588 	if (arguments.length > 3) {
2589 		l = arguments.length;
2590 		name_space = arguments[--l];
2591 		callback = arguments[--l];
2592 		--l;
2593 		for (i = 0; i < l; i++)
2594 			_s.call(_, arguments[i], callback, name_space);
2595 		return;
2596 	}
2597 	*/
2598 
2599 	if (_.is_Array(module)) {
2600 		var error;
2601 		for (i = 0, l = module.length; i < l; i++)
2602 			if (error = _s.call(_, module[i], 0, extend_to))
2603 				return error;
2604 		try {
2605 			i = _.is_Function(callback) && callback(undefined, module);
2606 		} catch (e) {
2607 		}
2608 		return i;
2609 	}
2610 
2611 	if (!force && _.is_loaded(module)
2612 			|| !(module_path = _.get_module_path(module))) {
2613 		try {
2614 			i = _.is_Function(callback)
2615 			&& callback(undefined, module);
2616 		} catch (e) {
2617 		}
2618 		return i;
2619 	}
2620 
2621 	//_.debug('load [' + module + ']:\ntry to load [' + module_path + ']');
2622 
2623 	//	including code
2624 	try {
2625 		try{
2626 			// _.debug('load ['+module_path+']');
2627 			// _.debug('load ['+module_path+']:\n'+_.get_file(module_path, _.env.source_encoding));
2628 			//WScript.Echo(_.eval);
2629 			if (i = _.get_file(module_path, _.env.source_encoding))
2630 				//	eval @ global. 這邊可能會出現 security 問題。
2631 				//	TODO: 以其他方法取代 eval 的使用。
2632 				_.eval_code(i);
2633 			else
2634 				_.warn('Get no result from [' + module_path + ']! Some error occurred?');
2635 			i = 0;
2636 		} catch (e) {
2637 			i = e;
2638 		}
2639 
2640 		if (!i)
2641 			return extend_module_member(module, extend_to, callback);
2642 
2643 		//	依序載入失敗
2644 		if (callback && typeof window !== 'undefined') {
2645 			//	不能直接用 .get_file(),得採用其他方法的狀況。但只在有 callback 時才 include,否則當下 block 的都沒執行,可能出亂子。
2646 			//	** 較新之 browser 通常需要使用 callback 的方法,不能使用 "CeL.use('module');_do_some_thing_;"!!
2647 			// TODO: 在指定 callback 時使 name_space 依然有效。
2648 			_.include_resource(module_path, {
2649 				module : module,
2650 				callback : function(){
2651 					extend_module_member(module, extend_to, callback);
2652 				},
2653 				start : new Date(),
2654 				timeout : 80,
2655 				global : _
2656 			},
2657 			//	正在 call(循環參照?)則強制 include
2658 			module in module_require_chain);
2659 			//	TODO: 一次指定多個 module 時可以知道進度,全部 load 完才 callback()。
2660 			//	此時 callback=[callback, 進度改變時之 function]
2661 			//	return 進度 Object
2662 			return -1;
2663 		}
2664 		throw i;
2665 
2666 	} catch (e) {
2667 		//_.err(e);
2668 
2669 		// http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html
2670 		// http://reference.sitepoint.com/javascript/DOMException
2671 		if (_.is_type(e, 'DOMException') && e.code === 1012) {
2672 			if(!_.is_local() || _.is_debug(2))
2673 				_.err(_.Class
2674 					+ '.use:\n'
2675 					+ e.message + '\n'
2676 					+ module_path
2677 					+ '\n\n程式可能呼叫了一個'
2678 					+ (_.is_local() ? '不存在的,\n或是繞經上層目錄'
2679 								: 'cross domain')
2680 								+ '的檔案?\n\n請嘗試使用相對路徑,\n或加入  callback: '
2681 								+ _.Class
2682 								+ '.use(module, callback function, name_space)');
2683 		} else if (_.is_type(e, 'Error') && (e.number & 0xFFFF) == 5
2684 				|| _.is_type(e, 'XPCWrappedNative_NoHelper')
2685 						&& ('' + e.message).indexOf('NS_ERROR_FILE_NOT_FOUND') !== -1) {
2686 			_.err(_.Class + '.use: 檔案可能不存在或存取被拒?\n[' + module_path + ']' +
2687 					(_.get_error_message
2688 							? ('<br/>' + _.get_error_message(e))
2689 							: '\n' + e.message
2690 					)
2691 				);
2692 		} else if(!_.is_local() || _.is_debug(2))
2693 			_.err(_.Class + '.use: Cannot load [<a href="' + module_path + '">' + module + '</a>]!'
2694 					+ (_.get_error_message
2695 							? ('<br/>' + _.get_error_message(e) + '<br/>')
2696 							: '\n[' + (e.constructor) + '] ' + (e.number ? (e.number & 0xFFFF) : e.code) + ': ' + e.message + '\n'
2697 					)
2698 					+ '抱歉!在載入其他網頁時發生錯誤,有些功能可能失常。\n重新讀取(reload),或是過段時間再嘗試或許可以解決問題。');
2699 		//_.log('Cannot load [' + module + ']!', _.log.ERROR, e);
2700 
2701 		return e;
2702 	}
2703 
2704 };
2705 
2706 
2707 CeL
2708 .
2709 is_local = function() {
2710 	return typeof window !== 'object'
2711 		|| typeof location !== 'object'
2712 			|| window.location !== location
2713 			|| location.protocol === 'file:';
2714 };
2715 
2716 /*
2717 bad: sometimes doesn't work. e.g. Google Maps API in IE
2718 push inside window.onload:
2719 window.onload=function(){
2720 include_resource(p);
2721 setTimeout('init();',2000);
2722 };
2723 
2724 way 3:	ref. dojo.provide();, dojo.require();
2725 document.write('<script type="text/javascript" src="'+encodeURI(p)+'"><\/script>');
2726 
2727 TODO:
2728 encode
2729 
2730 */
2731 ;
2732 
2733 CeL
2734 .
2735 /**
2736  * Including other JavaScript/CSS files synchronously.
2737  * 
2738  * TODO:
2739  * timeout for giving up
2740  * use document.createElementNS()
2741  * http://headjs.com/#theory
2742  * 
2743  * @param {String} resource path
2744  * @param {Function|Object} callback
2745  * 		use_write ? test function{return } : callback function(path)
2746  * 		/	{callback: callback function(path, module), module: module name, global: global object when run callback}
2747  * @param {Boolean} [use_write]	use document.write() instead of insert a element to <head>
2748  * @param {Number} [type]	1: is a .css file, others: script
2749  */
2750 include_resource = function include_resource(path, callback, force, timeout, type, use_write) {
2751 	var _s = _.include_resource, s, t, h;
2752 
2753 	if (_.is_Array(path)) {
2754 		for (s = 0, t = path.length; s < t; s++)
2755 			_s(path[s], callback, use_write, type);
2756 		return;
2757 	}
2758 
2759 	if (_.is_Object(force) && arguments.length === 3) {
2760 		timeout = force.timeout;
2761 		type = force.type;
2762 		use_write = force.use_write;
2763 		force = force.force;
2764 	}
2765 
2766 	if(!force && _.is_included(path)){
2767 		//	已經載入完成
2768 		_.is_Function(callback) && _s.wait_to_call(callback, path);
2769 		return;
2770 	}
2771 	set_included(path);
2772 
2773 	//_.debug('Including [' + path + '].', 1, 'include_resource');
2774 	if (typeof type === 'undefined')
2775 		type = /\.css$/i.test(path) ? 1 : 0;
2776 
2777 	t = 'text/' + (type === 1 ? 'css' : 'javascript');
2778 /*@cc_on
2779 //use_write=1;	//	old old IE hack
2780 @*/
2781 	if (!use_write)
2782 		try {
2783 			// Dynamic Loading / lazy loading
2784 			// http://code.google.com/apis/ajax/documentation/#Dynamic
2785 			//	http://en.wikipedia.org/wiki/Futures_and_promises
2786 			s = document.createElement(type === 1 ? 'link' : 'script');
2787 			s.type = t;
2788 			if (type === 1)
2789 				s.href = path,
2790 				// s.media = 'all',//'print'
2791 				s.rel = 'stylesheet';
2792 			else
2793 				//	TODO: see jquery-1.4a2.js: globalEval
2794 				//	if (is_code) s.text = path;
2795 				//s.setAttribute('src', path);
2796 				s.src = path,
2797 				s.async = true;
2798 
2799 			s.width = s.height = 0;
2800 
2801 			//	http://wiki.forum.nokia.com/index.php/JavaScript_Performance_Best_Practices
2802 			//	** onload 在 local 好像無效
2803 			var done = false;
2804 			s.onload = s.onreadstatechange = function(e) {
2805 				var r;
2806 				//_.debug('Loading [' + path + '] .. ' + this.readyState);
2807 				//	navigator.platform === 'PLAYSTATION 3' 時僅用 'complete'? from requireJS
2808 				if (!done && (!(r = this.readyState /* 'readyState' in this ? this.readyState : e.type !== 'load' */) || r === 'loaded' || r === 'complete')) {
2809 					done = true;
2810 					//_.debug('[' + (this.src || s.href) + '] loaded.');
2811 
2812 					//this.onload = this.onreadystatechange = null;
2813 					try{
2814 						delete this.onload;
2815 					}catch (e) {
2816 						//	error on IE5–7: Error: Object doesn't support this action
2817 						this.onload = null;
2818 					}
2819 					try{
2820 						delete this.onreadystatechange;
2821 					}catch (e) {
2822 						//	error on IE5–7: Error: Object doesn't support this action
2823 						this.onreadystatechange = null;
2824 					}
2825 
2826 					//	callback 完自動移除 .js。隨即移除會無效。 .css 移除會失效。
2827 					setTimeout(function() {
2828 						if (type !== 1)
2829 							h.removeChild(s);
2830 						h = s = null;
2831 					}, 1);
2832 
2833 					//	css 無 timeout 功能。
2834 					var tid = get_included(path);
2835 					if (tid) {
2836 						clearTimeout(tid);
2837 						set_included(path, 0);
2838 					}
2839 
2840 					if(callback)
2841 						_s.wait_to_call(callback, path);
2842 
2843 				}
2844 			};
2845 
2846 			//	HTML5: document.head === document.getElementsByTagName('head')[0]
2847 			h = document.head || document.getElementsByTagName('head')[0]
2848 				|| (document.body.parentNode || document.body).appendChild(document.createElement('head'));
2849 
2850 			h.appendChild(s);
2851 			//h.parentNode.insertBefore(s, h);
2852 
2853 			//_.debug('HTML:\n' + document.getElementsByTagName('html')[0].innerHTML);
2854 			/*
2855 			 * from jquery-1.4a2.js:
2856 			 * Use insertBefore instead of appendChild to circumvent an IE6 bug
2857 			 *  when using globalEval and a base node is found.
2858 			 * This arises when a base node is used (#2709).
2859 			 * @see
2860 			 * http://github.com/jquery/jquery/commit/d44c5025c42645a6e2b6e664b689669c3752b236
2861 			 * 不過這會有問題: 後加的 CSS file 優先權會比較高。因此,可以的話還是用 appendChild。
2862 			 */
2863 			//h.insertBefore(s, h.firstChild);
2864 
2865 			//	css 無 timeout 功能。
2866 			if (type !== 1)
2867 				set_included(path, setTimeout(function() {
2868 					_.warn('include_resource: Loading failed (timeout ' + timeout + ' ms): [' + path + ']');
2869 					// 自動移除 .js。
2870 					h.removeChild(s);
2871 					h = s = null;
2872 
2873 					if(callback)
2874 						_s.wait_to_call(callback, path, true);
2875 				}, timeout || (timeout = _.is_local() ? 2000 : 8000)));
2876 
2877 			return s;
2878 
2879 		} catch (e) {
2880 		}
2881 
2882 	//_.debug('Writing code for [' + path + '].');
2883 	//	直接寫入,若非正在 load 頁面時使用會出問題!
2884 	if (use_write
2885 			|| typeof use_write === 'undefined' // && TODO: 正在 load 頁面
2886 			)
2887 		document.write(type === 1 ?
2888 				'<link type="' + t + '" rel="stylesheet" href="' + path + '"><\/link>'
2889 				: '<script type="' + t + '" src="' + path
2890 					// language="JScript"
2891 					+ '"><\/script>');
2892 
2893 	//	若是到這邊還沒 load,會造成問題。
2894 	//set_included(path);
2895 
2896 	if (callback)
2897 		_s.wait_to_call(callback, path);
2898 };
2899 
2900 
2901 CeL
2902 .
2903 /**
2904  * 準備 callback
2905  * @inner
2906  * @private
2907  * @ignore
2908  */
2909 include_resource.wait_to_call = function(callback, path, failed) {
2910 	//alert('include_resource.wait_to_call:\n' + _.to_module_name(callback.module));
2911 
2912 	if (_.is_Function(callback))
2913 		//	不是 module,僅僅為指定 function 的話,直接等一下再看看。
2914 		//	TODO: 等太久時 error handle
2915 		setTimeout(function() {
2916 			callback(path, undefined, failed);
2917 		}, 200);
2918 
2919 	else if (_.is_Object(callback) && callback.global)
2920 		//	是 module。
2921 		if (callback.global.is_loaded(callback.module)
2922 							|| (new Date() - callback.start) > callback.timeout) {
2923 			//	依 callback 的類型處理 callback
2924 			if(_.is_Function(callback.callback))
2925 				//	直接執行
2926 				callback.callback(path, callback.module, failed);
2927 
2928 			else if (typeof callback.callback === 'string')
2929 				//	load 另一個 module
2930 				_.use(callback.callback);
2931 			// TODO
2932 			// else..
2933 
2934 		} else {
2935 			/**
2936 			 * 還沒載入完成,所以再等一下。 the function it self, not 'this'.
2937 			 * @inner
2938 			 * @ignore
2939 			 */
2940 			var _s = _.include_resource.wait_to_call, _t = this, _a = arguments;
2941 			setTimeout(function() {
2942 				_s.apply(_t, _a);
2943 			}, 50);
2944 		}
2945 };
2946 
2947 //if (_.is_Function(include_resource))
2948 //	_.extend(null, include_resource, _.include_resource);
2949 
2950 
2951 
2952 /*
2953 
2954 CeL.set_run(running sequence: [commands]|[required sequence])
2955 	[commands]/動作串
2956 		[],
2957 		function_to_run
2958 			[optional] {object} function_to_run.config
2959 			執行次序:
2960 			[optional: run_first, on load required] function_to_run.run_first = function(is prepared?): [bool] time (ms) to re-check
2961 			[optional] function_to_run.require = [require sequence]
2962 			[optional: prepared, before trigger] function_to_run.before_load = function()
2963 			[optional] waiting for function_to_run.trigger =
2964 				觸發時機/trigger action time
2965 				[string] action name | number = 0
2966 				onload: 'load' (default), {number} timeout (ms)
2967 			function_to_run.send_argument = (default: auto detect)
2968 			function_to_run = function() event handler
2969 			TODO: after_load
2970 
2971 	[required sequence]/前置條件/先備條件/prerequisite/necessary
2972 		{string} library module name to import, {string} file path(image/JavaScript files/CSS), {number} timeout (ms)
2973 
2974 		.charAt(0)==='.' || .charAt(0)==='/' || .indexOf(':')!==-1
2975 			//|| .indexOf('%')!==-1
2976 			|| /\.(js|css)$/i	→URL
2977 
2978 		i=env.identifier_RegExp.source;
2979 		env.module_identifier_RegExp=new RegExp('^'+i+'(\\.'+i+')*$');	→module
2980 
2981 		else→URL
2982 
2983 		∴'path1.sub1.sub2'→'./path1.sub1.sub2'
2984 
2985 
2986 
2987 CeL.set_run.error=function(message){
2988 	;
2989 };
2990 CeL.set_run.load={resource:status};
2991 
2992 CeL.use('module_name');
2993 CeL.load('resource path');
2994 
2995 
2996 2011/6/22 17:43:50,2011/7/31 00:11:52
2997 
2998 
2999 
3000 
3001 
3002 
3003 
3004 .set_run(running sequence)
3005 
3006 
3007 //	同步 loading set: 可同時 load 的 {String|Function} module/path/function
3008 synchronous_group = {
3009 	//check: {Function},
3010 
3011 	//	.to_run 會先執行,而後 delete
3012 	to_run[]: [{Function} function],
3013 	//	to load
3014 	to_load_path{}: [{String} path],
3015 	//	有幾個 resources 需要 load
3016 	path_count: integer count of to_load_path,
3017 	to_load_module{}: [{String} module],
3018 	module_count: integer count of to_load_module,
3019 
3020 	//	可能闕如: 下一組
3021 	next_group: next synchronous_group{},
3022 
3023 	//	可能闕如: timeout 用
3024 	start_time: integer,
3025 	//	已設定之 timeout (ms)
3026 	timeout: integer,
3027 
3028 	//	可能闕如: 臨時新增用,是為了預防有 call C,但 dependency 為 A→B→C 的情況。重複使用 queue 但不檢查 require 可能造成 B 與 C 被放在同一 synchronous_group。
3029 	require: {}
3030 };
3031 
3032 
3033 
3034 
3035 臨時/後續/後來新增:
3036 
3037 原先	[C,E]
3038 發現B→C	[B,E]→[C]
3039 發現D→E	[B,D]→[E]→[C]
3040 發現A→B	[A,D]→[B]→[E]→[C]
3041 
3042 2011/8/8 00:07:06
3043 
3044 
3045 
3046 */
3047 
3048 CeL
3049 .
3050 /**
3051  * control/setup source codes to run.
3052  * 基本上使用同步(synchronous)的方式,除非所需資源已經載入,或是有辦法以 {@link XMLHttpRequest} 取得資源。
3053  * 
3054  * @example
3055  * sr = CeL.set_run;
3056  * sr('module_name', function(){
3057  * 	// ...
3058  * });
3059  * 
3060  * TODO:
3061  * sr('module_name', function(){
3062  * 	CeL.import('module_name', {module_function_1:0});
3063  * 
3064  * 	CeL.module_function_1('11') === module_function_1('11');
3065  * 
3066  * 	var instance=new CeL.module_name.module_class_1;
3067  * 	instance.print(112);
3068  * });
3069  * 
3070  * 
3071  * @param	running sequence: list of
3072  * 		{Function} function to run/欲執行之 function → change .to_run
3073  * 		| {Integer} timeout (ms): 僅能保證上次 function 執行至此次 function 一定會等超過這段時間 → change .start_time, .timeout
3074  * 		| {String} library module name to import → change .to_load_module, .module_count
3075  * 		| {String} URL/file path (image/JavaScript files/CSS) → change .to_load_path, .path_count
3076  * 		| {Array} 另一組同時 loading set: [{String|Function|Integer}, ..] → 拆開全部當作同時 loading
3077  * 		| TODO: {Object}	loading with additional config
3078  * 
3079  * @since 2011/8/4 22:31:47
3080  */
3081 set_run = function() {
3082 	//_.debug('process ' + arguments.length + ' items.', 2, '.set_run');
3083 	if (arguments.length > 0)
3084 		//Array.prototype.slice.call(arguments)
3085 		check_run(arguments, 0);
3086 };
3087 
3088 
3089 /**
3090  * main process.
3091  * 
3092  * @param {Arguments} work_queue
3093  *            sequence of set_run.arguments. 不修改 work_queue===set_run.arguments,直接以 work_queue_index 為開始值。
3094  * @param {Integer} work_queue_index
3095  *            index of work queue
3096  * @param {Object}
3097  *            [synchronous_group] 正在 running 的 set.
3098  * 
3099  * @since 2011/8/4 22:31:47
3100  * 2011/8/8 23:27:15, –2011/8/11 18:29:51	rewrite
3101  */
3102 function check_run(work_queue, work_queue_index, synchronous_group) {
3103 
3104 	var work_queue_length = work_queue.length, work_set;
3105 	// 沒有累積的 synchronous_group 時,才繼續處理指定的工作。否則先處理之。
3106 	if (!synchronous_group) {
3107 
3108 		while (!(work_set = work_queue[work_queue_index++])) {
3109 			if (work_queue_index >= work_queue_length)
3110 				_.debug('處理完畢: [' + work_queue_length + '] [' + Array.prototype.slice.call(work_queue) + ']', 2, 'check_run');
3111 				return;
3112 		}
3113 
3114 		var to_run = [], to_load_path = {}, path_count = 0, to_load_module = {}, module_count = 0, timeout = 0,
3115 		/**
3116 		 * 增加項目至當前的 synchronous_group.
3117 		 */
3118 		add_item = function(item) {
3119 			// TODO
3120 			// {Object} loading with additional config
3121 
3122 			if (_.is_Array(item)) {
3123 				// {Array} 另一組同時 loading set: [{String|Function|Integer}, ..] →
3124 				// 拆開全部當作同時 loading
3125 				for ( var i in item)
3126 					add_item(item[i]);
3127 
3128 			} else if (_.is_Function(item)) {
3129 				// {Function} function to run → to_run
3130 				if (!item.require){
3131 					//	TODO
3132 					// check if the function require something first.
3133 					to_run.push(item);
3134 				} else
3135 					to_run.push(item);
3136 
3137 			} else if (typeof item === 'string') {
3138 				if (_.request_item_maybe_module(item)){
3139 					//	TODO: 若是已 cached 則跳過。
3140 					//_.debug('treat resource [' + item + '] as module ' + module_count, 2, 'check_run');
3141 					if (!(item in to_load_module) && !_.is_loaded(item))
3142 						to_load_module[item] = 0, module_count++;
3143 				} else if (!(item in to_load_path) && !_.is_included(item))
3144 					//_.debug('treat resource [' + item + '] as URL ' + path_count, 2, 'check_run');
3145 					to_load_path[item] = 0, path_count++;
3146 
3147 			} else if ((item = Math.floor(item)) > timeout) {
3148 				// {Integer} timeout
3149 				timeout = item;
3150 
3151 			} else {
3152 				// 其他都將被忽略!
3153 				_.warn('check_run: Unknown item: [' + item + ']');
3154 			}
3155 		};
3156 
3157 		// add item to synchronous_group
3158 		add_item(work_set);
3159 
3160 		// 初始化 initialization synchronous_group
3161 		synchronous_group = {};
3162 
3163 		if (timeout)
3164 			// 設定好時間
3165 			synchronous_group.start_time = new Date(),
3166 			synchronous_group.timeout = timeout;
3167 		if (to_run.length)
3168 			synchronous_group.to_run = to_run;
3169 		if (path_count)
3170 			synchronous_group.path_count = path_count,
3171 			synchronous_group.to_load_path = to_load_path;
3172 		if (module_count)
3173 			synchronous_group.module_count = module_count,
3174 			synchronous_group.to_load_module = to_load_module;
3175 
3176 		//_.debug(module_count + '個同步載入 resource 設定完畢。', 2, 'check_run');
3177 	}
3178 
3179 
3180 	//_.debug('開始處理當前的 synchronous_group, work_queue ' + work_queue_index + '/' + work_queue_length, 2, 'check_run');
3181 
3182 	var s, index,
3183 
3184 /*
3185 
3186 臨時/後續/後來新增:
3187 如果 check 發現 _path_ dependencies 尚未 load,則把 dependencies 加入 to_load_path|to_load_module,去除 (to_load_path|to_load_module)[_path_],
3188 新增一 synchronous_group, next_group.(to_load_path|to_load_module) = _path_ 並設置 synchronous_group.require{} = dependencies
3189 
3190 原先	[C,E]
3191 發現B→C	[B,E]→[C]
3192 發現D→E	[B,D]→[E]→[C]
3193 發現A→B	[A,D]→[B]→[E]→[C]
3194 
3195 */
3196 	/**
3197 	 * 臨時/後續新增項目至當前的 synchronous_group.
3198 	 * callback 用.
3199 	 */
3200 	afterwards_add = function(item, item_is_path) {
3201 
3202 		var
3203 		require = _.is_Function(item) ?
3204 			_.parse_require(item.require, item.require_separator) :
3205 			/** module */
3206 			module_require_chain[item],
3207 
3208 		to_load_path = require.URL_to_load,
3209 		to_load_module = require.module_to_load;
3210 
3211 		if (!to_load_path && !to_load_module)
3212 			return 1;
3213 
3214 
3215 		var i, changed = false, s, n;
3216 
3217 		//	把 dependencies: URL 加入 synchronous_group
3218 		if (to_load_path) {
3219 			//	synchronous_group 可能並沒有 .path_count
3220 			if (isNaN(synchronous_group.path_count))
3221 				s = synchronous_group.to_load_path = {},
3222 				synchronous_group.path_count = 0;
3223 			else
3224 				s = synchronous_group.to_load_path;
3225 
3226 			for (i in to_load_path)
3227 				if (i = to_load_path[i]){
3228 					_.debug('URL load dependency: [' + i + ']→[' + item + ']', 2, 'check_run.afterwards_add');
3229 					if(i in s)
3230 						//	假如是同一批的 M1, M2 都需要 P0,則跑到 M2 時 P0 不需要設定第二次,但需要把 M2 移到下一批次。
3231 						if ((n = synchronous_group.next_group) && !(item in n.to_load_path))
3232 							n.to_load_path[item] = 0,
3233 							n.path_count++;
3234 						else {
3235 							if (_.is_debug() && (!n || _.is_debug(2)))
3236 								_.warn('check_run.afterwards_add: 無法把 URL [' + item + '] 移到下一批次: 下一批次' + (n ? '不存在' : '已有此 URL') + '!');
3237 						}
3238 					else
3239 						//	因為是指向 Object,因此不需要再設定 synchronous_group.to_load_path。為防節外生枝,直接改 .path_count,不 cache。
3240 						s[i] = 0, synchronous_group.path_count++, changed = true, load_URL(i);
3241 				}
3242 
3243 			//show_set('after afterwards_add URL dependency changed');
3244 		}
3245 
3246 		//	把 dependencies: module 加入 synchronous_group
3247 		if(to_load_module){
3248 			//	synchronous_group 可能並沒有 .module_count
3249 			if (isNaN(synchronous_group.module_count))
3250 				s = synchronous_group.to_load_module = {},
3251 				synchronous_group.module_count = 0;
3252 			else
3253 				//	s: 當前欲載入之 module
3254 				s = synchronous_group.to_load_module;
3255 
3256 			for (i in to_load_module)
3257 				if (i = to_load_module[i]){
3258 					_.debug('module load dependency: [' + i + ']→[' + item + ']', 2, 'check_run.afterwards_add');
3259 					if (i in s)
3260 						// 假如是同一批的 M1, M2 都需要 M0,則跑到 M2 時 M0 不需要設定第二次,但需要把 M2 移到下一批次。
3261 						if ((n = synchronous_group.next_group) && !(item in n.to_load_module))
3262 							n.to_load_module[item] = 0,
3263 							n.module_count++;
3264 						else {
3265 							if (_.is_debug() && (!n || _.is_debug(2)))
3266 								_.warn('check_run.afterwards_add: 無法把 module [' + item + '] 移到下一批次: 下一批次' + (n ? '已有此 module' : '不存在') + '!');
3267 						}
3268 					else
3269 						//	因為是指向 Object,因此不需要再設定 synchronous_group.to_load_module。為防節外生枝,直接改 .module_count,不 cache。
3270 						s[i] = 0, synchronous_group.module_count++, changed = true, load_module(i);
3271 				}
3272 
3273 			//show_set('after afterwards_add module dependency changed');
3274 		}
3275 
3276 		if (changed && item) {
3277 			//show_set('準備將 [' + item + '] 從 synchronous_group 搬到 next_group');
3278 
3279 			if (s = synchronous_group.next_group)
3280 				s = {
3281 					next_group : s
3282 				};
3283 			else {
3284 				s = {};
3285 				if ('timeout' in synchronous_group)
3286 					_.extend( {
3287 						timeout : 0,
3288 						start_time : 0
3289 					}, s, synchronous_group);
3290 			}
3291 			synchronous_group.next_group = s;
3292 
3293 			if (item_is_path) {
3294 				(s.to_load_path = {})[item] = 0;
3295 				s.path_count = 1;
3296 			} else if (typeof item === 'string') {
3297 				(s.to_load_module = {})[item] = 0;
3298 				s.module_count = 1;
3299 			} else if (_.is_Function(item)) {
3300 				(s.to_run = []).push(item);
3301 			}
3302 			//else warn();
3303 
3304 			//show_set('已將 [' + item + '] 從 synchronous_group 搬到 next_group');
3305 		} else
3306 			return 2;
3307 
3308 	},
3309 
3310 	//	debug 用
3311 	//TODO: Object.keys(obj)
3312 	//	https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
3313 	get_Object_key = function(o) {
3314 		if (_.is_Array(o))
3315 			return o;
3316 		//if (!_.is_Object(o)) return;
3317 		var i, l = [];
3318 		for(i in o)
3319 			l.push(i);
3320 		return l;
3321 	},
3322 
3323 	//	debug 用
3324 	show_set = function(from) {
3325 		if(_.is_debug(2)){
3326 			var ptr = synchronous_group, s_data = [ '預計先後載入同步載入組: ' + (from || '') ], d;
3327 			do {
3328 				d = ptr.to_load_module ? get_Object_key(ptr.to_load_module) : 0;
3329 				s_data.push(
3330 						d?
3331 								'[' + (ptr.module_count === d.length ? ptr.module_count : '<em>登記 ' + ptr.module_count + ' != 實際 ' + d.length + '</em>') + '] '
3332 										+ d.join(' <span style="color:#f00">|</span> ')
3333 								: '<span style="color:#888">(none: 此同步載入組無預計載入之 module)</span>'
3334 						);
3335 			} while (ptr = ptr.next_group);
3336 			_.debug(s_data.join('<br/>'), 1, 'check_run.show_set');
3337 		}
3338 	},
3339 
3340 	//check module_require_chain{module_name}
3341 	/**
3342 	 * 載入間執行之 function.
3343 	 * 有未載入之 dependencies,僅能從 callback 傳入此 module 所需之 dependency list 來處置。
3344 	 * TODO: 確認若是load錯誤時,會不會跳過 check_loading 不執行。
3345 	 */
3346 	check_loading,
3347 	load_module, load_URL,
3348 	move_to_next_group = false;
3349 
3350 	//	synchronous_group.to_run: 若要處理 .to_run 的 require,則 check_loading() 還是需要設定。
3351 	if (work_queue_index < work_queue_length || synchronous_group.to_run)
3352 	check_loading = function(path, module_name) {
3353 		//_.debug((module_name ? 'module [' + module_name  + ']/all ' + synchronous_group.module_count : path ? 'path [' + path + ']/all ' + synchronous_group.path_count : '沒有尚未 load 的 resource') + (synchronous_group.timeout ? ', timeout ' + synchronous_group.timeout : ''), 1, 'check_run.check_loading');
3354 		//show_set('check_loading start');
3355 
3356 		if(module_name){
3357 
3358 			//	is module
3359 			delete synchronous_group.to_load_module[module_name];
3360 			synchronous_group.module_count--;
3361 
3362 			if (!_.is_loaded(module_name))
3363 				if (module_require_chain[module_name])
3364 					afterwards_add(module_name);
3365 				else
3366 					//	若有不存在的 module,因為會以 .include_resource 載入,在 MSIE 中會 throw。
3367 					//	可以由判別 browser 改善此體驗。
3368 					_.err('check_run.check_loading: Cannot load module [' + module_name + ']!');
3369 
3370 		} else if (path) {
3371 
3372 			//	is path, 無法判別是否成功 included。
3373 			delete synchronous_group.to_load_path[path];
3374 			synchronous_group.path_count--;
3375 
3376 		}
3377 
3378 		//	可能因為循環參照(circular dependencies),這邊的 module 之前已經 load 過,因此需要再作 check。
3379 		//	.. pass
3380 		;
3381 
3382 		if (!synchronous_group.module_count
3383 					&& !synchronous_group.path_count){
3384 			var timeout = synchronous_group.timeout
3385 						- (new Date() - synchronous_group.start_time);
3386 			synchronous_group = synchronous_group.next_group;
3387 			move_to_next_group = true;
3388 
3389 			//_.debug('Move to next synchronous load group. 本同步載入組已全部載入,' + (synchronous_group ? '進入下一同步載入組。' : work_queue_index < work_queue.length ? '繼續下一組指定的工作 [' + work_queue_index + '/' + work_queue.length + ']。' : '本次指定的 ' + work_queue_index + ' 項工作已全部執行完成。') + (timeout > 4 ? 'timeout ' + timeout + ' 超過 4ms,設定 timeout。' : ''), 1, 'check_run.check_loading');
3390 			if (timeout > 4)
3391 				// TODO: setTimeout 可能不存在!
3392 				setTimeout(function() {
3393 					check_run(work_queue, work_queue_index,
3394 							synchronous_group);
3395 				}, timeout);
3396 			else
3397 				check_run(work_queue, work_queue_index,
3398 						synchronous_group);
3399 			//_.debug('設定完畢', 1, 'check_run.check_loading');
3400 		}
3401 	},
3402 
3403 	load_module = function(module_name) {
3404 		//_.debug('[' + module_name + ']', 1, 'check_run.load_module');
3405 		// .use 會先試試 .get_file()
3406 		_.use(module_name, check_loading);
3407 	},
3408 
3409 	load_URL = function(URL, encoding) {
3410 		// 準備載入 resource. ** 在已經 loaded 的情況下有可能直接就執行完 return!
3411 		//_.debug('[' + URL + ']', 1, 'check_run.load_URL');
3412 		if (/\.js$/i.test(URL))
3413 			try{
3414 				// 對 .js 先試試 .get_file()
3415 				var t = _.get_file(URL, encoding);
3416 				//_.debug('Get [' + t + ']', 2, 'check_run.load_URL');
3417 				if (t)
3418 					//	eval @ global. 這邊可能會出現 security 問題。
3419 					//	TODO: 以其他方法取代 eval 的使用。
3420 					_.eval_code(t);
3421 
3422 				check_loading(URL);
3423 				return;
3424 
3425 			}catch (e) {
3426 				//_.err(e);
3427 			}
3428 
3429 		//_.debug('需要作同步 loading resource [' + URL + ']', 1, 'check_run.load_URL');
3430 		_.include_resource(URL, check_loading);
3431 	};
3432 
3433 	// 把能處理的 .to_run function 先執行處理,而後早點 delete 以釋放空間。
3434 	if(s = synchronous_group.to_run){
3435 		for (index in s)
3436 			try {
3437 				// 已經過鑑別,這邊的都是 Function
3438 				s[index]();
3439 
3440 			} catch (e) {
3441 				_.err('check_run: ' + e.message);
3442 				_.debug('<code>'
3443 						+ ('' + s[index]).replace(/\n/g, '<br />')
3444 						+ '</code>');
3445 			}
3446 		//_.debug('把能處理的 function 先處理完了,刪除synchronous_group.to_run 的資料。', 2);
3447 		delete synchronous_group.to_run;
3448 	}
3449 
3450 
3451 	if(s = synchronous_group.to_load_module)
3452 		for (index in s)
3453 			load_module(index);
3454 
3455 	if(move_to_next_group)
3456 		//	在上一個 load_module() 呼叫 check_loading() 時,可能因為 synchronous_group = synchronous_group.next_group 使得 synchronous_group 已轉換到下一 synchronous load group。
3457 		return;
3458 
3459 	if(s = synchronous_group.to_load_path)
3460 		for (index in s)
3461 			load_URL(index);
3462 
3463 
3464 	if (!move_to_next_group && check_loading && !synchronous_group.module_count
3465 			&& !synchronous_group.path_count){
3466 		//_.debug('[' + work_queue_index + '/' + work_queue_length + '] 沒有尚未 load 的 resource (例如只輸入 timeout 或每個 resource 皆 loaded),手動執行 check_loading。', 1, 'check_run');
3467 		check_loading();
3468 	}
3469 
3470 	// 開始蟄伏, waiting for callback
3471 }
3472 
3473 
3474 
3475 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
3476 
3477 
3478 
3479 CeL
3480 .
3481 /**
3482  * module 中模擬 inherit 時使用。
3483  * 
3484  * TODO:
3485  * 同步載入功能
3486  * @param {String} parent_module_name	欲繼承的 module_name
3487  * @param initial_arguments	繼承時的 initial arguments
3488  * @returns
3489  * @see
3490  * <a href="http://fillano.blog.ithome.com.tw/post/257/17355" accessdate="2010/1/1 0:6">Fillano's Learning Notes | 物件導向Javascript - 實作繼承的效果</a>,
3491  * <a href="http://www.crockford.com/javascript/inheritance.html" accessdate="2010/1/1 0:6">Classical Inheritance in JavaScript</a>
3492  */
3493 inherit = function(parent_module_name, initial_arguments) {
3494 	if(!_.cache_code && _.cache_code !== undefined)
3495 		_.debug('inherit: cache code did not setted but try to inherit module!');
3496 
3497 	var code_for_including = loaded_module[_.to_module_name(parent_module_name)];
3498 	try {
3499 		if (_.is_Function(code_for_including))
3500 			return code_for_including.call(code_for_including, _, initial_arguments);
3501 
3502 		_.err('inherit: [' + parent_module_name + '] did not catched!');
3503 	} catch (e) {
3504 		_.err('inherit: running of [' + parent_module_name + '] error!');
3505 		return e;
3506 	}
3507 };
3508 
3509 
3510 
3511 
3512 CeL
3513 .
3514 /**
3515  * 解析 dependency list 以獲得所需之 module/path/variable name..
3516  * 
3517  * @param {Array|String}
3518  *            dependency_list
3519  *            <p>
3520  *            list of dependency function/module/variable required. module 須以
3521  *            CeL.env.module_name_separator ('.') 結尾。若輸入 String,則以 separator 或 '|' 分割。
3522  *            </p>
3523  * @returns {Object} result { variable: {variable_name: full_name}, module:
3524  *          {module name: loaded or not}, module_to_load: [], URL: {}}
3525  * @returns {Number} error_no
3526  * @since 2011/8/6 22:10:57
3527  */
3528 parse_require = function(dependency_list, separator, base_require) {
3529 
3530 	if(!dependency_list)
3531 		//	is_Object(undefined) === true!
3532 		return 0;
3533 
3534 	if (typeof dependency_list === 'string')
3535 		dependency_list = dependency_list.split(separator || '|');
3536 	else if (!_.is_Array(dependency_list) || !_.is_Object(dependency_list))
3537 		return 1;
3538 
3539 	var i, module, module_name_separator = _.env.module_name_separator,
3540 	/**
3541 	 * variable name under module
3542 	 */
3543 	var_name,
3544 	/**
3545 	 * 解析出要 extend 到 'this' 下的 variables。
3546 	 * variable_hash[variable name] = 所在 module name.
3547 	 */
3548 	//variable_hash = {},
3549 	/**
3550 	 * 解析出要 extend 到 'this' 下的 variables。
3551 	 * variable_full_name[variable name] = variable full name.
3552 	 */
3553 	variable_full_name,
3554 	/**
3555 	 * 解析出的 URL paths.
3556 	 * URL_hash[URL] = loaded or not;
3557 	 */
3558 	URL_hash,
3559 	/**
3560 	 * 解析出需要 load 的 URL paths.
3561 	 */
3562 	URL_to_load,
3563 	/**
3564 	 * dependency_list 中指定的 module。
3565 	 * module_hash[module name] = loaded or not
3566 	 */
3567 	module_hash,
3568 	/**
3569 	 * 已 load 的 module。
3570 	 */
3571 	//module_loaded = [],
3572 	/**
3573 	 * 要 load 的 module。
3574 	 */
3575 	module_to_load;
3576 
3577 	if (_.is_Object(base_require)) {
3578 		variable_full_name = base_require.variable,
3579 		URL_hash = base_require.URL,
3580 		URL_to_load = base_require.URL_to_load,
3581 		module_hash = base_require.module,
3582 		module_to_load = base_require.module_to_load;
3583 
3584 		//variable_hash = {};
3585 	} else {
3586 		variable_full_name = {},
3587 		URL_hash = {},
3588 		URL_to_load = [],
3589 		module_hash = {},
3590 		module_to_load = [];
3591 	}
3592 
3593 	//	解析 dependency_list,將所須 functions/modules 置於 variable_hash/module_hash 中。
3594 	for (i in dependency_list)
3595 		if (_.request_item_maybe_module(i = dependency_list[i])
3596 				&& (module = _.split_module_name(i))) {
3597 
3598 			// 類似 'data.split_String_to_Object' 的形式,為 function。
3599 			// 類似 'data.' 的形式,為 module。
3600 			if (var_name = module.pop())
3601 				variable_full_name[var_name] = (
3602 					//variable_hash[var_name] =
3603 					 _.to_module_name(module))
3604 						+ module_name_separator + var_name;
3605 			//_.debug('load module [' + _.to_module_name(module) + ']' + (var_name ? '.' + var_name : ''));
3606 
3607 			//_.debug('test module ['+module.join(module_name_separator)+']: '+_.get_variable(module.join(module_name_separator),_));
3608 
3609 			//	不用 _.to_module_name,因為會加油添醋。
3610 			module = module.join(module_name_separator);
3611 
3612 			//	確定是否還沒載入,必須 load。還沒載入則放在 module_to_load[] 中。
3613 			if (!(module in module_hash)) {
3614 				if (!(module_hash[module] = _.is_loaded(module)))
3615 					//_.debug('module [' + module + '] need to load first.'),
3616 					module_to_load.push(module);
3617 			}
3618 
3619 		} else if (!(i in URL_hash) && !(URL_hash[i] = _.is_included(i)))
3620 			URL_to_load.push(i);
3621 
3622 
3623 	return {
3624 		//require : dependency_list,
3625 		variable : variable_full_name,
3626 
3627 		module : module_hash,
3628 		//module_loaded : module_loaded,
3629 		module_to_load : module_to_load,
3630 
3631 		URL : URL_hash,
3632 		URL_to_load : URL_to_load
3633 	};
3634 };
3635 
3636 
3637 /*
3638 //這得要直接貼在標的 scope 內才有用。
3639 var no_strict_variable_use = (function() {
3640 	var v, i = 0;
3641 	try {
3642 		// find a undefined var_name
3643 		for (;;)
3644 			eval(v = 'tmp_' + i++);
3645 	} catch (i) {
3646 	}
3647 
3648 	eval('var ' + v + '=1;');
3649 
3650 	try {
3651 		//	OK 表示在 eval 中可以設定 var.
3652 		//	若是 'use strict'; 則不可在 eval() 中置 var.
3653 		return eval(v);
3654 	} catch (i) {
3655 	}
3656 })();
3657 */
3658 
3659 //	http://closure-compiler.appspot.com/
3660 //	這得要直接貼在標的 scope 內才有用。
3661 //var no_strict_variable_use=function(){var a,b=9;try{for(;;)eval(a="t_"+b++)}catch(c){}eval("var "+a+"=1;");try{return eval(a)}catch(d){}}();
3662 
3663 CeL
3664 .
3665 /**
3666  * module 中需要 include function/module/variable 時設定 local variables 使用。<br/>
3667  * 本函數將把所需 function include 至當前 namespace 下。
3668  * 
3669  * TODO: 輸入 function name 即可
3670  * 
3671  * @example
3672  * 
3673  * //	requires (inside module)
3674  * //	事先定義 @ 'use strict';
3675  * var split_String_to_Object;
3676  * //	之所以需要使用 eval 是因為要 extend 至當前 namespace 下。
3677  * //	若無法 load CeL.data,將會 throw
3678  * eval(library_namespace.use_function(this, 'data.split_String_to_Object'));
3679  * //	use it
3680  * split_String_to_Object();
3681  * 
3682  * //	不用 eval 的方法 1: function 預設都會 extend 至當前 library_namespace 下。
3683  * library_namespace.use_function(this, 'data.split_String_to_Object');
3684  * library_namespace.use_function(this, 'data.split_String_to_Object', false);
3685  * //	若無法 load CeL.data,將會 throw
3686  * //	use it
3687  * library_namespace.split_String_to_Object();
3688  * 
3689  * //	不用 eval 的方法 2: 設定 extend_to
3690  * var o={};
3691  * //	若無法 load CeL.data,將會 throw
3692  * library_namespace.use_function(this, 'data.split_String_to_Object', o);
3693  * //	use it
3694  * o.split_String_to_Object();
3695  * 
3696  * @param	{Function|Object} name_space	module name-space
3697  * @param	{Array|String} dependency_list	list of dependency function/module/variable required. module 須以 '.' 結尾。若輸入 String,則以 ',' 分割。
3698  * @param	{Function|Object} [extend_to]	若設定將把 variable extend 至 extend_to
3699  * 
3700  * @returns	{Number} error code
3701  * 		1: can't parse dependency_list
3702  * 
3703  * @throws	{Error}	有些 module 尚未載入。
3704  * 
3705  * @since	2009/12/26 02:36:31
3706  * 2009/12/31 22:21:23	add 類似 'data.' 的形式,為 module。
3707  * 2010/6/14 22:58:18	避免相互 require
3708  */
3709 use_function = function(name_space, extend_to, optional_use, no_strict) {
3710 
3711 	var module_name = get_module_name(name_space);
3712 
3713 	//_.debug('load function [' + dependency_list + ']' + (typeof module_name === 'string' && module_name ? ' from [' + module_name + ']' : ''));
3714 
3715 	var variable_name, value, eval_code = [],
3716 	/**
3717 	 * 要 extend 到 name_space 下的 variables。
3718 	 * variable_hash[variable name] = variable full name, 包括所在 module name.
3719 	 */
3720 	variable_hash = name_space.require_variable;
3721 
3722 	no_strict = no_strict && !extend_to ? [] : false;
3723 
3724 	//	設定 required variables
3725 	for (variable_name in variable_hash)
3726 		if ((value = _.get_variable(variable_hash[variable_name])) !== undefined) {
3727 			//_.debug('指定 [' + variable_name + ']: ' + value));
3728 			if (extend_to)
3729 				extend_to[variable_name] = value;
3730 			else {
3731 				no_strict && no_strict.push(variable_name);
3732 
3733 				eval_code.push('try{' + variable_name + '=' +
3734 						//	預防有保留字,所以用 bracket notation。例如 Chrome 中會出現 'Unexpected token native'。
3735 						//	Dot Notation and Square Bracket Notation in JavaScript	http://www.dev-archive.net/articles/js-dot-notation/
3736 						variable_hash[variable_name].replace(/\.([a-z\d_]+)/gi, '["$1"]') + ';}catch(e){}');
3737 			}
3738 
3739 		} else {
3740 			// 可能因為循環參照(circular dependencies),事實上 required 並未 loaded。
3741 			if(!(module_name in module_require_chain) || _.is_debug(2))
3742 				_.err(_.Class + '.use_function: load [' + variable_hash[variable_name] + '] @ ['
3743 						+ _.to_module_name(module_name) + '] error: The module is not included or defined? You have to load they all later.');
3744 
3745 			if (extend_to) {
3746 				extend_to[variable_name] = function() {
3747 					try {
3748 						//	稍後求值,僅對 function 有效。
3749 						return _.get_variable(variable_hash[variable_name]);
3750 					} catch (e) {
3751 					}
3752 				};
3753 			} else {
3754 				no_strict && no_strict.push(variable_name);
3755 
3756 				//	稍後求值,僅對 function 有效。
3757 				eval_code.push(variable_name + '=function(){try{return ' + variable_name + '='
3758 						+ variable_hash[variable_name].replace(/\.([a-z\d_]+)/gi, '["$1"]')
3759 						+ ';}catch(e){}};');
3760 			}
3761 
3762 
3763 			// delete it if doesn't exists
3764 			//delete variable_hash[variable_name];
3765 		}
3766 
3767 	//	應注意 module_name 為保留字之類的情況,會掛在這邊 return 後的 eval。
3768 	return extend_to
3769 		|| (no_strict ? 'var ' + no_strict.join(',') + ';' : '') + eval_code.join('');
3770 };
3771 
3772 
3773 
3774 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
3775 
3776 
3777 /**
3778  * 為一些比較舊的版本或不同瀏覽器而做調適。
3779  * @since	2010/1/14 17:58:31
3780  * @inner
3781  * @private
3782  * @ignore
3783  */
3784 function environment_adapter() {
3785 	/*
3786 	 * workaround:
3787 	 * 理論上 '.'.split(/\./).length 應該是 2,但 IE 5–8 中卻為 0!
3788 	 * 用 .split('.') 倒是 OK.
3789 	 * TODO:
3790 	 * 應該增加可以管控與回復的手段,預防有時需要回到原有行為。
3791 	 * @since	2010/1/1 19:03:40
3792 	 */
3793 	if ('.'.split(/\./).length === 0)
3794 		(function() {
3795 			var _String_split = String.prototype.split,
3796 				is_Regexp = _.object_tester('RegExp');
3797 			String.prototype.split = function(r) {
3798 				return is_Regexp(r) ?
3799 						_String_split.call(this.valueOf().replace(
3800 								r.global ? r :
3801 									// TODO: 少了 multiline
3802 									new RegExp(r.source, r.ignoreCase ? 'ig' : 'g'),
3803 							'\0'), '\0') :
3804 						_String_split.call(this, r);
3805 			};
3806 		})();
3807 }
3808 
3809 environment_adapter();
3810 
3811 }
3812 //	不用 apply(),因為比較舊的瀏覽器沒有 apply()。
3813 )(CeL);
3814 
3815 
3816 
3817 
3818 //===========================================================================================================================================================//
3819 
3820 
3821 
3822 
3823 //args=args.concat(['turnCode.js']);
3824 
3825 //	不作 initialization
3826 //CeL.no_initialization = 0;
3827 
3828 if (typeof CeL === 'function' && CeL.env.script_name === CeL.env.main_script_name
3829 		&& !CeL.no_initialization)
3830 	try {
3831 		(function() {
3832 			// WScript.Echo(CeL.env.script_name);
3833 			// CeL.debug(CeL.env.script_name);
3834 
3835 
3836 			//	將 path 寫入 registry
3837 			CeL.use('application.OS.Windows');
3838 			CeL.use('application.OS.Windows.registry');
3839 			// CeL.debug(CeL.reg);
3840 			//WScript.Echo(CeL.reg);
3841 
3842 			var path_key_name = CeL.env.registry_path_key_name,
3843 			//	此時 script 即為 main_script
3844 			library_base_path = CeL.env.script_base_path,
3845 			path_in_registry = CeL.reg.getValue(path_key_name) || '(null)';
3846 			//WScript.Echo('registry:\n' + path_in_registry + '\npath now:\n' + library_base_path);
3847 			if (path_in_registry !== library_base_path) {
3848 				WScript.Echo('Change the base path of [' + CeL.Class + '] from:\n'
3849 						+ path_in_registry + '\n to\n' + library_base_path
3850 						+ '\n\nkey name:\n' + path_key_name);
3851 				CeL.reg.setValue.cid = 1;
3852 				CeL.reg.setValue(path_key_name, library_base_path, 0, 0, 1);
3853 				CeL.reg.setValue(CeL.env.registry_base + 'main_script',
3854 						library_base_path + CeL.env.script_name, 0, 0, 1);
3855 				CeL.reg.setValue.cid = 0;
3856 			}
3857 
3858 
3859 			//	TODO
3860 			//	拖曳檔案到本檔案上面時之處置。
3861 			if (
3862 					// args instanceof Array
3863 					typeof args === 'object') {
3864 				// getEnvironment();
3865 				// alert('Get arguments ['+args.length+']\n'+args.join('\n'));
3866 				if (args.length) {
3867 					var i = 0, p, enc, f, backupDir = dBasePath('kanashimi\\www\\cgi-bin\\program\\log\\');
3868 					if (!fso.FolderExists(backupDir))
3869 						try {
3870 							fso.CreateFolder(backupDir);
3871 						} catch (e) {
3872 							backupDir = dBasePath('kanashimi\\www\\cgi-bin\\game\\log\\');
3873 						}
3874 						if (!fso.FolderExists(backupDir))
3875 							try {
3876 								fso.CreateFolder(backupDir);
3877 							} catch (e) {
3878 								if (2 === alert('無法建立備份資料夾[' + backupDir
3879 										+ ']!\n接下來的操作將不會備份!', 0, 0, 1 + 48))
3880 									WScript.Quit();
3881 								backupDir = '';
3882 							}
3883 							// addCode.report=true; // 是否加入報告
3884 							for (; i < args.length; i++)
3885 								if ((f = dealShortcut(args[i], 1))
3886 										.match(/\.(js|vbs|hta|s?html?|txt|wsf|pac)$/i)
3887 										&& isFile(f)) {
3888 									p = alert(
3889 											'是否以預設編碼['
3890 											+ ((enc = autodetectEncode(f)) == simpleFileDformat ? '內定語系('
3891 													+ simpleFileDformat + ')'
3892 													: enc) + ']處理下面檔案?\n' + f,
3893 													0, 0, 3 + 32);
3894 									if (p === 2)
3895 										break;
3896 									else if (p === 6) {
3897 										if (backupDir)
3898 											fso.CopyFile(f, backupDir + getFN(f), true);
3899 										addCode(f);
3900 									}
3901 								}
3902 				} else if (1 === alert('We will generate a reduced ['
3903 						+ CeL.env.script_name + ']\n  to [' + CeL.env.script_name
3904 						+ '.reduced.js].\nBut it takes several time.', 0, 0,
3905 						1 + 32))
3906 					reduceScript(0, CeL.env.script_name + '.reduced.js');
3907 			}// else window.onload=init;
3908 
3909 			// CeL._iF=undefined;
3910 		})();
3911 	} catch (e) {
3912 		// TODO: handle exception
3913 	}
3914 
3915 
3916 
3917 /*
3918 
3919 //test WinShell	http://msdn.microsoft.com/en-us/library/bb787810(VS.85).aspx
3920 if (0) {
3921 alert(WinShell.Windows().Item(0).FullName);
3922 
3923 var i, cmd, t = '', objFolder = WinShell.NameSpace(0xa), objFolderItem = objFolder
3924 		.Items().Item(), colVerbs = objFolderItem.Verbs(); // 假如出意外,objFolder==null
3925 for (i = 0; i < colVerbs.Count; i++) {
3926 	t += colVerbs.Item(i) + '\n';
3927 	if (('' + colVerbs.Item(i)).indexOf('&R') != -1)
3928 		cmd = colVerbs.Item(i);
3929 }
3930 objFolderItem.InvokeVerb('' + cmd);
3931 alert('Commands:\n' + t);
3932 
3933 // objShell.NameSpace(FolderFrom).CopyHere(FolderTo,0); // copy folder
3934 // objFolderItem=objShell.NameSpace(FolderFrom).ParseName("clock.avi");objFolderItem.Items().Item().InvokeVerb([動作]);
3935 // objShell.NameSpace(FolderFromPath).Items.Item(mName).InvokeVerb();
3936 
3937 // Sets or gets the date and time that a file was last modified.
3938 // http://msdn.microsoft.com/en-us/library/bb787825(VS.85).aspx
3939 // objFolderItem.ModifyDate = "01/01/1900 6:05:00 PM";
3940 // objShell.NameSpace("C:\Temp").ParseName("Test.Txt").ModifyDate =
3941 // DateAdd("d", -1, Now()) CDate("19 October 2007")
3942 
3943 // Touch displays or sets the created, access, and modified times of one or
3944 // more files. http://www.stevemiller.net/apps/
3945 }
3946 
3947 //測試可寫入的字元:0-128,最好用1-127,因為許多編輯器會將\0轉成' ',\128又不確定
3948 if (0) {
3949 var t = '', f = 'try.js', i = 0;
3950 for (; i < 128; i++)
3951 	t += String.fromCharCode(i);
3952 if (simpleWrite(f, t))
3953 	alert('Write error!\n有此local無法相容的字元?');
3954 else if (simpleRead(f) != t)
3955 	alert('內容不同!');
3956 else if (simpleWrite(f, dQuote(t) + ';'))
3957 	alert('Write error 2!\n有此local無法相容的字元?');
3958 else if (eval(simpleRead(f)) != t)
3959 	alert('eval內容不同!');
3960 else
3961 	alert('OK!');
3962 }
3963 
3964 */
3965 
3966 
3967 
3968 
3969 
3970 //}catch(e){WScript.Echo('There are some error in function.js!\n'+e.message);throw e;}
3971 
3972 
3973 
3974 //CeL.use('code.log');
3975 //CeL.warn('test_print: ' + CeL.code.log.Class);
3976 
3977 
3978 //]]>
3979 
3980