1 
  2 /**
  3  * @name	CeL code reorganize function
  4  * @fileoverview
  5  * 本檔案包含了程式碼重整重構用的 functions。
  6  * @since	
  7  */
  8 
  9 /*
 10 parse code
 11 use ISO-14977: Extended Backus–Naur Form (EBNF)
 12 http://zh.wikipedia.org/wiki/%E6%89%A9%E5%B1%95%E5%B7%B4%E7%A7%91%E6%96%AF%E8%8C%83%E5%BC%8F
 13 
 14 http://blog.zhaojie.me/2010/11/narcissus-javascript-parser.html
 15 Narcissus是一個JavaScript引擎,完全使用JavaScript編寫,不過利用了SpiderMonkey的一些擴展,因此無法直接在僅僅實現了ECMAScript 3的引擎上執行(例如各瀏覽器)。
 16 http://en.wikipedia.org/wiki/Narcissus_%28JavaScript_engine%29
 17 http://hax.iteye.com/blog/181358
 18 
 19 */
 20 
 21 if (typeof CeL === 'function'){
 22 
 23 /**
 24  * 本 module 之 name(id),<span style="text-decoration:line-through;">不設定時會從呼叫時之 path 取得</span>。
 25  * @type	String
 26  * @constant
 27  * @inner
 28  * @ignore
 29  */
 30 var module_name = 'code.reorganize';
 31 
 32 //===================================================
 33 /**
 34  * 若欲 include 整個 module 時,需囊括之 code。
 35  * @type	Function
 36  * @param	{Function} library_namespace	namespace of library
 37  * @param	load_arguments	呼叫時之 argument(s)
 38  * @return
 39  * @name	CeL.code.reorganize
 40  * @constant
 41  * @inner
 42  * @ignore
 43  */
 44 var code_for_including = function (library_namespace, load_arguments) {
 45 
 46 
 47 var 
 48 /**
 49  * null module constructor
 50  * @class 程式碼重整重構相關之 functions。
 51  * @constructor
 52  */
 53 CeL.code.reorganize
 54 = function () {
 55 	//	null module constructor
 56 };
 57 
 58 /**
 59  * for JSDT: 有 prototype 才會將之當作 Class
 60  */
 61 CeL.code.reorganize
 62 .prototype = {};
 63 
 64 
 65 
 66 
 67 //class public interface	---------------------------
 68 
 69 CeL.code.reorganize
 70 .
 71 /**
 72  * 取得[script_filename].wsf中不包括自己([script_filename].js),其餘所有 .js 的code。
 73  * @param {String} script_filename	script filename
 74  * @return
 75  * @requires ScriptName,simpleRead
 76  * @deprecated	若想在低版本中利用eval(get_all_functions(ScriptName))來補足,有時會出現奇怪的現象,還是別用好了。
 77  * @memberOf CeL.code.reorganize
 78  */
 79 get_all_functions = function (script_filename) {
 80 	if (!script_filename)
 81 		script_filename = ScriptName;
 82 	var t = '', i, a = simpleRead(script_filename + '.wsf'), l = a ? a
 83 			.match(/[^\\\/:*?"<>|'\r\n]+\.js/gi) : [script_filename + '.js'];
 84 
 85 	for (i in l)
 86 		if (l[i] != script_filename + '.js' && (a = simpleRead(l[i])))
 87 			t += a;
 88 	return t;
 89 };
 90 
 91 
 92 var JS_reserved_word = {
 93 		Keyword : 'break,do,instanceof,typeof,case,else,new,var,catch,finally,return,void,continue,for,switch,while,debugger,function,this,with,default,if,throw,delete,in,try',
 94 		FutureReservedWord : 'class,enum,extends,super,const,export,import',
 95 		NullLiteral : 'null',
 96 		BooleanLiteral : 'true,false'
 97 };
 98 
 99 
100 //var OK = add_code('alert,simpleWrite', ['alert', 'NewLine', 'get_all_functions']);if (typeof OK == 'string') simpleWrite('try.js', OK), alert('done'); else alert('OK:' + OK);
101 /*
102 {
103 	var ss = [23, 23.456, undefined, Attribute, null, Array, '567', 'abc'], l = 80, repF = 'tmp.txt', sa = ss, st = add_code('', ['ss']), t;
104 	ss = '(reseted)'; try { eval(st); } catch (e) { } t = (sa === ss) + ': ' + typeof sa + '→' + typeof ss + '\n';
105 	simpleWrite(repF, t + sa + '\n→\n' + ss + '\n\n◎eval:\n' + st);
106 	alert(t + (sa = '' + sa, sa.length < l ? sa : sa.slice(0, l / 2) + '\n..' + sa.slice(sa.length - l / 2)) + '\n→\n' + (ss = '' + ss, ss.length < l ? ss : ss.slice(0, l / 2) + '\n..' + ss.slice(ss.length - l / 2)) + '\n\n' + (ss = '' + st, ss.length < l ? ss : ss.slice(0, 200) + '\n..\n' + ss.slice(ss.length - 200)));
107 }
108 */
109 
110 /*
111 加入識別格式之方法:
112 
113 //	from function.js	-------------------------------------------------------------------
114 
115 //e.g.,
116 //	[function.js](f1,f2,'string'	//	'string'或"string"中包含的需要是完整的敘述句
117 //	number var,string var,object var,date var,undefined  var)
118 
119 //e.g.,
120 //	[function.js](OS,NewLine,dirSp,dirSpR,'var ScriptName=getScriptName();',ForReading,ForWriting,ForAppending,TristateUseDefault,TristateTrue,TristateFalse,WshShell,fso,args,'initWScriptObj();',initWScriptObj,setTool,JSalert,Str2Date,Date2Str,decplaces,dQuote,set_obj_value,getScriptFullName,getScriptName,'setTool();',WinEnvironment,SpecialFolder,Network,NetDrive,NetPrinter,getEnvironment,'getEnvironment();',dateUTCdiff,gDate)
121 //e.g.,
122 //	[function.js]("var NewLine='\n',OS='unix',dirSp=dirSpR='/';",dQuote,setTool,product,decplaces,countS,getText,turnUnicode,trimStr_,trimStr,StrToDate,DateToStr,reducePath,getPathOnly,getFN,getFP,dBasePath,trigger,setTopP,setAstatusOS,setAstatus,setAstatusOver,setAstatusOut,doAlertResize,doAlertInit,doAlert,doAlertAccess,doAlertScroll,setCookie,getCookie,scrollTo,disableKM,setCookieS,*disabledKM=0;,scrollToXY,scrollToInterval,scrollToOK,doAlertDivName,doAlertOldScrollLocation,parse_Function,dealPopup,sPopP,sPopF,sPopInit,sPopInit,sPop,setTextT,setText)
123 
124 ..(inclide code)
125 //	[function.js]End	-------------------------------------------------------------------
126 //	↑from function.js	-------------------------------------------------------------------
127 
128 
129 TODO:
130 .htm 加入 .replace(/\//g,'\\/')
131 */
132 CeL.code.reorganize
133 .
134 /**
135  * 將各 function 加入檔案中,可做成 HTML 亦可用之格式。
136  * @example
137  * add_code('複製 -backup.js');
138  * @param file_name	file name (list)
139  * @param Vlist	多加添的 function/various list
140  * @param {String} start_string	start string
141  * @param {String} end_string	ending string
142  * @returns
143  * @request	NewLine,is_file,simpleRead,autodetectEncode,generate_code,JSalert,setTool,*setTool();
144  * @memberOf	CeL.code.reorganize
145  */
146 add_code = function (file_name, Vlist, start_string, end_string) {
147 	if (!start_string)
148 		start_string = '//	[' + library_namespace.Class + ']';
149 	if (!end_string)
150 		end_string = start_string + 'End';
151 	//alert(is_file(FN)+'\n'+start_string+'\n'+end_string);
152 
153 	if (typeof file_name == 'string')
154 		file_name = [ is_file(file_name) ? file_name : start_string
155 				+ (file_name ? '(' + file_name + ')' : '') + NewLine
156 				+ end_string + NewLine ];
157 	if (typeof Vlist == 'string')
158 		Vlist = [ Vlist ];
159 	else if (typeof Vlist != 'object')
160 		Vlist = [];
161 
162 	var i, j, F, a, A, start, end, code_head, b, c, d, f, m, OK = 0, new_line,
163 	// 「」『』【】〈〉《》〔〕{}︵︶︹︺︷︸︻︼︿﹀︽︾﹁﹂﹃﹄()「」『』‘’“”〝〞‵′
164 	s = '()[]{}<>\u300c\u300d\u300e\u300f\u3010\u3011\u3008\u3009\u300a\u300b\u3014\u3015\uff5b\uff5d\ufe35\ufe36\ufe39\ufe3a\ufe37\ufe38\ufe3b\ufe3c\ufe3f\ufe40\ufe3d\ufe3e\ufe41\ufe42\ufe43\ufe44\uff08\uff09\u300c\u300d\u300e\u300f\u2018\u2019\u201c\u201d\u301d\u301e\u2035\u2032',
165 	end_char, req, direct_input = '*', tmpExt = '.tmp', encoding, oriC;
166 
167 
168 	for (i in file_name) try {
169 		if (a = oriC = is_file(file_name[i]) ? simpleRead(file_name[i],
170 				encoding = autodetectEncode(file_name[i])) : file_name[i], !a)
171 			continue;
172 		A = '', dones = [], doneS = 0;
173 		//sl(a.slice(0,200));
174 
175 /*	判斷 new_line 這段,將三種資料作比較就能知道為何這麼搞。
176 
177 ~\r:
178 
179 \r	123
180 \n	1
181 \r\n	2
182 \n-\r	-120
183 
184 
185 ~\n:
186 
187 \r	1
188 \n	123
189 \r\n	2
190 \n-\r	120
191 
192 
193 ~\r\n:
194 
195 \r	123
196 \n	123
197 \r\n	123
198 \n-\r	-2~2
199 */
200 		new_line = a.replace(/[^\n]+/g, '').length;
201 		b = a.replace(/[^\r]+/g, '').length;
202 		if (new_line != b && new_line && b) {
203 			alert("There're some encoding problems in the file:\n"
204 					+ file_name[i] + '\n\\n: ' + new_line + '\n\\r: ' + b);
205 			new_line = Math.max(new_line, b) > 10 * Math.abs(new_line - b) ? '\r\n'
206 					: new_line > b ? '\n' : '\r';
207 		} else
208 			new_line = new_line ? b ? '\r\n' : '\n' : '\r';
209 
210 		//sl(a.indexOf(start_string)+'\n'+start_string+'\n'+a.slice(0,200));
211 		// TODO: a=a.replace(/(startReg)(.*?)(endReg)/g,function($0,$1,$2,$3){.. return $1+~+$3;});
212 		while ((start = a.indexOf(start_string)) != -1
213 				// &&(end=a.indexOf(end_string,start+start_string.length))!=-1
214 				) {
215 			//	initial reset
216 			code_head = codeText = end_char = '';
217 			req = [];
218 			j = 0;
219 			//	判斷 end index
220 			if ((end = a.indexOf(end_string, start + start_string.length)) == -1) {
221 				alert('add_code: There is start mark without end mark!\nend_string:\n'
222 						+ end_string);
223 				//	未找到格式則 skip
224 				break;
225 			}
226 			//	b=inner text
227 			b = a.slice(start + start_string.length, end);
228 			b = b.split(new_line); //b=b.split(new_line=b.indexOf('\r\n')!=-1?'\r\n':b.indexOf('\n')!=-1?'\n':'\r');	//	test檔案型式:DOS or UNIX.最後一位元已被split掉
229 			if (c = b[0].match(/^\s*([^\w])/)) {
230 				code_head += b[0].slice(0, RegExp.lastIndex);
231 				b[0] = b[0].slice(RegExp.lastIndex);
232 				if (s.indexOf(c = c[1]) % 2 == 0)
233 					end_char = s.charAt(s.indexOf(c) + 1);
234 				else
235 					end_char = c;
236 			}
237 			//new_line=b[0].slice(-1)=='\r'?'\r\n':'\n';	//	移到前面:因為需要以new_line作split	test檔案型式:DOS or UNIX.最後一位元已被split掉
238 			//alert('end_char='+end_char+',j='+j+',d='+d+'\n'+b[0]+'\nNewLine:'+(new_line=='\n'?'\\n':new_line=='\r\n'?'\\r\\n':'\\r')+'\ncode_head:\n'+code_head);
239 
240 			do {
241 				// 不需要d>=b[j].length
242 				//if(d==b[j].length)continue;	
243 				if (!j)
244 					d = 0;
245 				else if (b[j].slice(0, 2) != '//')
246 					continue;
247 				else
248 					d = 2;
249 
250 				for (;;) {
251 					//alert('search '+b[j].slice(d));
252 					if ((c = b[j].slice(d).match(/^[,\s]*([\'\"])/))
253 							&& (f = d + RegExp.lastIndex) <= b[j].length &&
254 							// (c=c[1], f<b[j].length)
255 							(c = c[1]) && f < b[j].length) { // .search(
256 						// alert(b[j].charAt(f)+'\n'+c+'\n^(.*[^\\\\])['+c+']');
257 						if (b[j].charAt(f) == c) {
258 							// '',""等
259 							alert('add_code: 包含[' + c + c + ']:\n'
260 									+ b[j].slice(f));
261 							continue;
262 						}
263 						if (c = b[j].slice(f).match(
264 								new RegExp('^(.+?[^\\\\])[' + c + ']'))) {
265 							d = f + RegExp.lastIndex;
266 							req.push(direct_input/* +b[j].charAt(f-1) 改進後不需要了 */
267 									+ c[1]);
268 							continue;
269 						}
270 						alert('add_code: Can not find end quota:\n' + b[j].slice(f));
271 					}
272 					//alert(d+','+b[j].length+'\nsearch to '+b[j].slice(d));
273 
274 					//	出現奇怪現象請加"()"
275 					//if((c=b[j].slice(d).match(/([^,\s]+)([,\s]*)/))&& ( (d+=RegExp.lastIndex)==b[j].length || /[,\n]/.test(c[2])&&d<b[j].length ) ){	//	不需要\s\r
276 					if ((c = b[j].slice(d).match(/([^,\s]+)[,\s]*/)) && (d += RegExp.lastIndex) <= b[j].length) {	//	不需要\s\r
277 						//if(!/[,\n]/.test(c[2])&&d<b[j].length)break;
278 						//alert(RegExp.index+','+d+','+b[j].length+','+end_char+'\n['+c[1]+']\n['+c[2]+']\n'+b[j].slice(d));
279 						if (!end_char || (m = c[1].indexOf(end_char)) == -1) req.push(c[1]);
280 						else { if (m) req.push(c[1].slice(0, m)); end_char = ''; break; }
281 					} else break;
282 				}
283 				code_head += b[j] + new_line;
284 				//alert('output start_string:\n'+start_string+'\ncode_head:\n'+code_head);
285 			} while (end_char && ++j < b.length);
286 			//for(j=0,b=[];j<req.length;j++)b.push(req[j]);	//	不能用b=req:object是用參考的,這樣會改到req本身!
287 			//for(j=0;j<Vlist.length;j++)b.push(Vlist[j]);	//	加入附加的變數
288 
289 			b = _.generate_code(req.concat(Vlist), new_line, direct_input);
290 			codeText = code_head + (arguments.callee.report ? '/*	add_code @ ' + gDate('', 1)	//	report
291 					+ (req.length ? new_line + '	request variables [' + req.length + ']:	' + req : '')
292 					+ (Vlist.length ? new_line + '	addition lists [' + Vlist.length + ']:	' + Vlist : '')
293 					+ (req.length && Vlist.length && b[2].length < req.length + Vlist.length ? new_line + '	Total request [' + b[2].length + ']:	' + b[2] : '')
294 					+ (b[4].length ? new_line + '	really done [' + b[4].length + ']:	' + b[4] : '')
295 					+ (b[5].length ? new_line + '	cannot found [' + b[5].length + ']:	' + b[5] : '')
296 					+ (b[6].length ? new_line + '	all listed [' + b[6].length + ']:	' + b[6] : '')
297 					//+(b[3].length?new_line+'	included function ['+b[3].length+']:	'+b[3]:'')
298 					+ new_line + '	*/' : '') + new_line + _.reduce_code(b[0]).replace(/([};])function(\s)/g, '$1' + new_line + 'function$2').replace(/}var(\s)/g, '}' + new_line + 'var$1')/*.replace(/([;}])([a-z\._\d]+=)/ig,'$1'+new_line+'$2')*/ + new_line + b[1] + new_line;
299 			//alert(start+','+end+'\n'+a.length+','+end+','+end_string.length+','+(end+end_string.length)+'\n------------\n'+codeText);//+a.slice(end+end_string.length)
300 			A += a.slice(0, start + start_string.length)
301 					+ codeText
302 					+ a.substr(end, end_string.length);
303 			a = a.substr(end + end_string.length);
304 		}
305 
306 		if (file_name.length == 1 && !is_file(file_name[i]))
307 			return A;
308 
309 		if (A && oriC != A + a)	//	有變化才寫入
310 			if (!simpleWrite(file_name[i] + tmpExt, A + a, encoding))
311 				try {
312 					fso.DeleteFile(file_name[i]);
313 					fso.MoveFile(file_name[i] + tmpExt, file_name[i]);
314 					OK++;
315 				} catch (e) {
316 					// popErr(e);
317 				}
318 			else
319 				try {
320 					fso.DeleteFile(file_name[i] + tmpExt);
321 				} catch (e) {
322 					// popErr(simpleFileErr);popErr(e);
323 				}
324 		//else{alert('add_code error:\n'+e.message);continue;}
325 	} catch (e) {
326 		//popErr(e);
327 		throw e;
328 	}
329 
330 	//	A:成功的最後一個檔之內容
331 	return file_name.length == 1 && OK == 1 ? A : OK;
332 };
333 
334 /**
335  * 是否加入報告
336  * @type	Boolean
337  */
338 _.add_code.report = false;
339 
340 
341 CeL.code.reorganize
342 .
343 /**
344  * add libary use
345  * @param	{String} code	script code
346  * @returns 
347  * @memberOf	CeL.code.reorganize
348  */
349 add_use = function (code) {
350 	//	TODO: 去除 comments 中的 .use()
351 	var _s = _.add_use, i, m = code.match(_s.pattern);
352 
353 	library_namespace.err('TODO');
354 };
355 _.add_use.pattern = new RegExp(library_namespace.Class
356 		+ '\\s*.\\s*use\\((.+)\\)');
357 
358 /*
359 try.wsf
360 <package><job id="try"><script type="text/javascript" language="JScript" src="function.js"></script><script type="text/javascript" language="JScript" src="try.js"></script></job></package>
361 try.js
362 destory_script('WshShell=WScript.CreateObject("WScript.Shell");'+NewLine+NewLine+alert+NewLine+NewLine+'alert("資料讀取錯誤!\\n請檢查設定是否有錯!");');
363 */
364 CeL.code.reorganize
365 .
366 /**
367  * script 終結者…
368  * @param	{String} code	script code
369  * @param	addFN
370  * @returns	error no. 
371  * @memberOf	CeL.code.reorganize
372  */
373 destory_script = function (code, addFN) {
374 	try {
375 		//	input indepent code, additional files
376 		var SN = getScriptName(), F, a, listJs, i, len, self = SN + '.js';
377 		if (!code)
378 			code = ''; //SN='try';
379 		a = simpleRead(SN + '.wsf');
380 		if (!a) a = '';
381 		//	一網打盡
382 		listJs = a.match(/[^\\\/:*?"<>|'\r\n]+\.(js|vbs|hta|s?html?|txt|wsf|pac)/gi);
383 		//,listWsf=(SN+'.wsf\n'+a).match(/[^\\\/:*?"<>|'\r\n]+\.wsf/gi);
384 
385 		for (i = 0, F = {}; i < listJs.length; i++)
386 			F[listJs[i]] = 1;
387 		if (typeof addFN == 'object')
388 			for (i in addFN)
389 				F[addFN[i]] = 1;
390 		else if (addFN)
391 			F[addFN] = 1;
392 
393 		listJs = [];
394 		//	避免重複
395 		for (i in F)
396 			listJs[listJs.length] = i; 
397 		//alert(listJs.join('\n'));
398 
399 		//done all .js @ .wsf & files @ additional list without self
400 		for (i = 0; i < listJs.length; i++)
401 			//	除了self外殺無赦
402 			if (listJs[i] != self) try {
403 				if (!listJs[i].match(/\.js$/i) && listJs[i] != SN + '.wsf') { try { fso.DeleteFile(listJs[i], true); } catch (e) { } continue; } //	非.js就讓他死
404 				if (changeAttributes(F = fso.GetFile(listJs[i]), '-ReadOnly')) throw 0; //	取消唯讀
405 				a = add_null_code(F.size); //a=listJs[i].match(/\.js$/i)?add_null_code(F.size):'';	先確認檔案存在,再幹掉他
406 				//alert('done '+listJs[i]+'('+F.size+')\n'+(a.length<500?a:a.slice(0,500)+'..'));
407 				simpleWrite(listJs[i], a);
408 			} catch (e) {
409 				//popErr(e);
410 			}
411 
412 		//done .wsf
413 		try {
414 			if (changeAttributes(F = fso.GetFile(SN + '.wsf'), '-ReadOnly'))
415 				throw 0;
416 			a = '<package><job id="' + SN + '"><script type="text/javascript" src="' + SN + '.js"><\/script><\/job><\/package>';
417 			//alert('done '+SN+'.wsf'+'('+F.size+')\n'+a);
418 			//a='<package><job id="'+SN+'"><script type="text/javascript" src="function.js"><\/script><script type="text/javascript" src="'+SN+'.js"><\/script><\/job><\/package>';
419 			simpleWrite(SN + '.wsf', a);
420 		} catch (e) {
421 			//popErr(e);
422 		}
423 
424 		//	done self
425 		if (listJs.length) try {
426 			if (changeAttributes(F = fso.GetFile(self), '-ReadOnly') < 0)
427 				throw 0;
428 			a = (F.size - code.length) / 2;
429 			a = add_null_code(a) + code + add_null_code(a);
430 			if (F.Attributes % 2)
431 				//	取消唯讀
432 				F.Attributes--;
433 			//alert('done '+self+'('+F.size+')\n'+(a.length<500?a:a.slice(0,500)+'..'));
434 			//a='setTool(),destory_script();';
435 			simpleWrite(self, a);
436 		} catch (e) {
437 			//popErr(e);
438 		}
439 
440 		//run self & WScript.Quit()
441 		//return WshShell.Run('"'+getScriptFullName()+'"');
442 		return 0;
443 	} catch (e) {
444 		return 1;
445 	}
446 };
447 
448 /*	for version<5.1:因為不能用.wsf,所以需要合併成一個檔。
449 請將以下函數copy至.js主檔後做適當之變更
450 getScriptName(),merge_script(FN),preCheck(ver)
451 */
452 //	將script所需之檔案合併
453 //	因為常由preCheck()呼叫,所以所有功能亦需內含。
454 function merge_script(FN) {
455 	var i, n, t, SN = getScriptName(), NewLine, fso, ForReading, ForWriting, ForAppending;
456 	if (!NewLine)
457 		NewLine = '\r\n';
458 	if (!fso)
459 		fso = WScript.CreateObject("Scripting.FileSystemObject");
460 	if (!ForReading)
461 		ForReading = 1, ForWriting = 2, ForAppending = 8;
462 	try {
463 
464 		//	from .wsf
465 		/*var F=fso.OpenTextFile(SN+'.wsf',ForReading)
466 		//,R=new RegExp('src\s*=\s*["\']?(.+\.js)["\']?\s*','gi')
467 		,a=F.ReadAll();F.Close();*/
468 		a = simpleRead(SN + '.wsf');
469 		S = fso.OpenTextFile(FN, ForWriting, true/* create */);
470 
471 		try {
472 			//t=a.match(/<\s*resource\s+id=(['"].*['"])\s*>((.|\r\n)*?)<\/\s*resource\s*>/gi);
473 			//	5.1版以下果然還是不能成功實行,因為改變regexp不能達到目的:沒能找到t。所以在下面第一次test失敗後即放棄;改用.ini設定。
474 			var r = new RegExp("<\\s*resource\\s+id=(['\"].*['\"])\\s*>((.|\\r\\n)*?)<\\/\\s*resource\\s*>", "ig");
475 			t = a.match(r);
476 			S.WriteLine('//	merge_script: from ' + SN + '.wsf');
477 			S.WriteLine("function getResource(id){");
478 			if (!t || !t.length) S.WriteLine(" return ''");
479 			else for (i = 0; i < t.length; i++) {
480 				//alert(i+':'+t[i]);
481 				//n=t[i].match(/<\s*resource\s+id=(['"].*['"])\s*>((.|\r\n)*?)<\/\s*resource\s*>/i);
482 				r = new RegExp("<\\s*resource\\s+id=(['\"].*['\"])\\s*>((.|\\r\\n)*?)<\\/\\s*resource\\s*>", "i");
483 				n = t[i].match(r);
484 				S.WriteLine(" " + (i ? ":" : "return ") + "id=="
485 						+ n[1] + "?'"
486 						+ n[2].replace(/\r?\n/g, '\\n') + "'");
487 			}
488 			S.WriteLine(" :'';" + NewLine + "}" + NewLine);
489 		} catch (e) {
490 		}
491 
492 		//	from .js
493 		t = a.match(/src\s*=\s*["']?(.+\.js)["']?\s*/gi);
494 		for (i = 0; i < t.length; i++) {
495 			//alert(i+':'+t[i].match(/src\s*=\s*["']?(.+\.js)["']?\s*/i)[1]);
496 			//try{F=fso.OpenTextFile(n=t[i].match(/src\s*=\s*["']?(.+\.js)["']?\s*/i)[1],ForReading);}
497 			//catch(e){continue;}
498 			//S.WriteLine('//	merge_script: from script	'+n);S.WriteBlankLines(1);S.WriteLine(F.ReadAll());
499 			//S.WriteLine('//	merge_script: from script	'+n+NewLine+NewLine+F.ReadAll());
500 			//F.Close();
501 			S.WriteLine('//	merge_script: from script	'
502 					+ (n = t[i]
503 					.match(/src\s*=\s*["']?(.+\.js)["']?\s*/i)[1])
504 					+ NewLine + NewLine + simpleRead(n));
505 		}
506 		S.Close();
507 	} catch (e) {
508 		return 1;
509 	}
510 	return 0;
511 };
512 
513 
514 
515 
516 
517 //var fa=function(a,s){return '"'+a+k+"'";},fb=function kk(a,t){return a;},fc=new Function('return b+b;'),Locale2=fa,Locale3=fb,Locale4=fc,r=generate_code(['fa','fb','fc','Locale2','Locale3','Locale4','kk']);alert(r.join('\n★'));try{eval(r[0]);alert(fa);}catch(e){alert('error!');}
518 /*	use for JSON (JavaScript Object Notation)
519 directly input:	[directInput]string
520 輸出string1(可reduce_code),輸出string2(主要為object definition,不需reduce_code,以.replace(/\r\n/g,'')即可reduce),總共要求的變數(去掉重複),包含的函數(可能因參考而有添加),包含的變數(可能因參考而有添加),未包含的變數
521 
522 未來:對Array與Object能確實設定之	尚未對應:Object遞迴/special Object(WScript,Excel.Application,內建Object等)/special function(內建函數如Math.floor與其他如WScript.CreateObject等)
523 JScript中對應資料型態,應考慮到內建(intrinsic 或 built-in)物件(Boolean/Date/Function/Number/Array/Object(需注意遞迴:Object之值可為Object))/Time/Error/RegExp/Regular Expression/String/Math)/string/integer/Byte/number(float/\d[de]+-\d/Number.MAX_VALUE/Number.MIN_VALUE)/special number(NaN/正無限值:Number.POSITIVE_INFINITY/負無限值:Number.NEGATIVE_INFINITY/正零/負零)/date/Boolean/undefined(尚未設定值)/undcleared(尚未宣告)/Null/normal Array/normal Object/special Object(WScript,Automation物件如Excel.Application,內建Object等)/function(實體/參考/anonymous)/special function(內建函數如isNaN,Math之屬性&方法Math[.{property|method}]與其他如WScript.CreateObject等)/unknown(others)
524 
525 **	需同步更改 json()
526 
527 
528 TODO:
529 Object.toSource()
530 Array.toSource()
531 json	http://www.json.org/json.js
532 UglifyJS	https://github.com/mishoo/UglifyJS
533 
534 
535 XML Object
536 
537 bug:
538 函數定義 .toString() 時無法使用。
539 
540 
541 使用 \uXXXX 使.js跨語系
542 含中文行
543544 //turnBy	含中文行
545 \x..
546 考慮註解&執行時語系
547 
548 to top BEFORE ANY FUNCTIONS:
549 generate_code.dLK='dependencyList';	//	dependency List Key
550 */
551 CeL.code.reorganize
552 .
553 /**
554  * 利用[*現有的環境*]及變數設定生成code,因此並不能完全重現所有設定,也無法判別函數間的相依關係。
555  * @param {Array} Vlist	變數 list
556  * @param {String} new_line	new line
557  * @param {String} direct_input	直接輸入用辨識碼
558  * @requires	set_obj_value,dQuote
559  * @memberOf	CeL.code.reorganize
560  */
561 generate_code = function (Vlist, new_line, direct_input) {
562 	//	vars:處理過的variables(不論是合法或非合法),c:陳述是否已完結
563 	var _s = _.generate_code, codeText = '', afterCode = '', vars = [], vari = [], func = [], done = [], undone = [], t, i = 0, c = 0, val, vName, vType;
564 	if (!new_line)
565 		new_line = '\n';
566 	if (!direct_input)
567 		direct_input = _s.ddI;
568 	if (typeof Vlist === 'string')
569 		Vlist = Vlist.split(_s.dsp);
570 
571 	for (; i < Vlist.length; i++) if (!((vName = '' + Vlist[i]) in vars)) {
572 		//	c(continue)=1:var未截止,vName:要加添的變數內容
573 		vars[vName] = vari.length, vari.push(vName); //	避免重複
574 
575 		//	不加入的
576 		if (vName.charAt(0) == '-') {
577 			vars[vName.slice(1)] = -1;
578 			continue;
579 		}
580 
581 		//	直接輸出
582 		if (vName.slice(0, direct_input.length) == direct_input) {
583 			if (c)
584 				codeText += ';' + new_line, c = 0;
585 			codeText += val = vName.substr(direct_input.length);
586 			done.push('(directly input)' + val);
587 			continue;
588 		}
589 		try {
590 			// void
591 			eval('vType=typeof(val=' + vName + ');');
592 		} catch (e) {
593 			//	b:type,c:已起始[var ];catch b:語法錯誤等,m:未定義
594 			//	e.constructor
595 			undone.push((vType ? '(' + vType + ')' : '') + vName
596 					+ '(error ' + (e.number & 0xFFFF) + ':'
597 					+ e.description + ')');
598 			continue;
599 		}
600 
601 
602 		//	or use switch-case
603 		if (vType === 'function') {
604 			//	加入function object成員,.prototype可用with()。加入函數相依性(dependency)
605 			try {
606 				eval("var j,k;for(j in "
607 						+ vName
608 						+ ")if(j=='"
609 						+ _s.dLK
610 						+ "'&&(k=typeof "
611 						+ vName
612 						+ "."
613 						+ _s.dLK
614 						+ ",k=='string'||"
615 						+ vName
616 						+ "."
617 						+ _s.dLK
618 						+ " instanceof Array)){j="
619 						+ vName
620 						+ "."
621 						+ _s.dLK
622 						+ ";if(k=='string')j=j.split(',');for(k in j)if(j[k])Vlist.push(j[k]);}else Vlist.push('"
623 						+ vName + ".'+j);for(j in " + vName
624 						+ ".prototype)Vlist.push('" + vName
625 						+ ".prototype.'+j);");
626 			} catch (e) {
627 				undone.push('(' + vType + ')' + vName + '.[child]'
628 						+ '(error ' + (e.number & 0xFFFF) + ':'
629 						+ e.description + ')');
630 			}
631 
632 			val = ('' + val).replace(/[\r\n]/g, new_line); //	function 才會產生 \r\n 問題,所以先處理掉
633 			if ((t = val.match(/^\s*function\s*\(/)) || val.match(/^\s*function\s+([\w_]*)([^(]*)\(/))	//	這種判別法不好!
634 				if (t || (t = RegExp.$1) == 'anonymous') {
635 					func.push(vName); vType = (typeof t == 'string' ? t : 'no named') + ' ' + vType;
636 					if (t === 'anonymous') {
637 						//	忠於原味(笑)
638 						//	anonymous 是從new Function(文字列を使って)來的
639 						var m = val.match(/\(([^)]*)\)\s*{/), l = RegExp.lastIndex, q = val.match(/[^}]*$/); q = RegExp.index;
640 						if (!m) { undone.push('(anonymous function error:' + val + ')' + vName); continue; }
641 						if (t = m[1].replace(/,/g, "','")) t = "'" + t + "',"; t = 'new Function(' + t + dQuote(_.reduce_code(val.slice(l, q - 1))) + ')';
642 					} else t = val;
643 				} else if (t == vName) {
644 					//	関数(function): http://www.interq.or.jp/student/exeal/dss/ejs/1/2.html
645 					if (c) codeText += ';' + new_line, c = 0; func.push(vName), codeText += val + new_line; continue;
646 				} else if (val.indexOf('[native code]') != -1) { undone.push('(native code function error:' + val + ')' + vName); continue; } //	內建(intrinsic 或 built-in)函數:這種判別法不好!
647 				else if (t in vars) done.push('(' + vType + ')' + vName), func.push(vName); //	已經登錄過了,所以就這麼下去..
648 				else {
649 					if (c)
650 						codeText += ';' + new_line;
651 					codeText += val + new_line;
652 					vars[t] = vari.length;
653 					done.push('(' + vType + ')' + t);
654 					func.push(t, vName);
655 					c = 0;
656 				}
657 			else {
658 				// unknown error
659 				undone.push('(function error:' + val + ')' + vName);
660 				continue;
661 			}
662 		} else if (vType == 'number') {
663 			//	http://msdn2.microsoft.com/zh-tw/library/y382995a(VS.80).aspx
664 			var k = 0, m = 'MAX_VALUE,MIN_VALUE,NEGATIVE_INFINITY,POSITIVE_INFINITY,NaN'.split(',');
665 			if (val === NaN || val === Infinity || val === -Infinity) t = '' + val;
666 			else for (t = 0; k < m.length; k++) if (val === Number[m[k]]) { t = 'Number.' + m[k]; break; }
667 			if (!t) {
668 				//	http://msdn2.microsoft.com/zh-tw/library/shydc6ax(VS.80).aspx
669 				for (k = 0, m = 'E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2'.split(','); k < m.length; k++) if (val === Math[m[k]]) { t = 'Math.' + m[k]; break; }
670 				if (!t) t = (t = Math.floor(val)) == val && ('' + t).length > (t = '0x' + val.toString(16)).length ? t : val;
671 			}
672 		} else if (vType == 'boolean' || val === null) t = val; //String(val)//val.toString()	//	typeof null is 'object'
673 		else if (vType == 'string') t = dQuote(val);
674 		else if (vType == 'object' && typeof val.getTime == 'function' || vType == 'date') t = 'new Date(' + ((val - new Date) > 999 ? val.getTime() : '') + ')'; //	date被當作object
675 		//	http://msdn2.microsoft.com/en-us/library/dww52sbt.aspx
676 		else if (vType == 'object' && /*val.constructor==Error  "[object Error]" */('' + val.constructor).indexOf('Error') != -1)
677 			t = 'new Error' + (val.number || val.description ? '(' + (val.number || '') + (val.description ? (val.number ? ',' : '') + dQuote(val.description) : '') + ')' : '');
678 		/*
679 		else if(vName=='set_obj_value.F'){	//	明白宣示在這裡就插入依存函數:不如用 set_obj_value.F,'set_obj_value();'
680 		if(!vars['set_obj_value']||!vars['dQuote'])Vlist=Vlist.slice(0,i).concat('set_obj_value','dQuote',Vlist.slice(i));
681 		Vlist[i--]=directInput+'var set_obj_value.F;';continue;
682 		}
683 		*/
684 		else if (vType == 'object' && (val.constructor == Object || val.constructor == Array)) {// instanceof
685 			var k, T = '', T_ = '', T_2 = '', _i = 0, cmC = '\\u002c', eqC = '\\u003d', NL_ = "'" + new_line + "+'", maxLen = 300 - NL_.length; //	type;loop用,Text,間距,integer?
686 			if (val.constructor == Object) {
687 				t = '';
688 				//	http://fillano.blog.ithome.com.tw/post/257/59403
689 				//	** 一些內建的物件,他的屬性可能會是[[DontEnum]],也就是不可列舉的,而自訂的物件在下一版的ECMA-262中,也可以這樣設定他的屬性。
690 				for (k in val)
691 					if (typeof val[k] == 'object' || typeof val[k] == 'function')
692 						Vlist.push(vName + '.' + k); //	簡單的Object遞迴
693 					else {
694 						T_2 = k.replace(/,/g, cmC).replace(/=/g, eqC) + '=' + ('' + val[k]).replace(/,/g, cmC).replace(/=/g, eqC) + ',';
695 						if (T_.length + T_2.length > maxLen) T += T_ + NL_, T_ = T_2; else T_ += T_2;
696 						if (!_i && parseInt(val[k]) == val[k]) _i = 1; else if (_i < 2 && parseFloat(val[k]) == val[k] && parseInt(val[k]) != val[k]) _i = 2;
697 					}
698 				T += T_;
699 			} else {// if(val.constructor==Array)
700 				var base = 16, d_, d = -1, k_, kA = [];
701 				for (k in val)
702 					if (typeof val[k] == 'object' || typeof val[k] == 'function')
703 						Vlist.push(vName + '.' + k); //	簡單的Object遞迴
704 					else kA.push(parseInt(k) == k ? parseInt(k) : k); //	因為Array中仍有可能存在非數字index
705 				kA.sort(), vType = 'Array', t = ',' + base;
706 				for (k_ = 0; k_ < kA.length; k_++) {
707 					if (!((k = kA[k_]) in val)) {
708 						if (d_ != '*')
709 							if (k - d == 1)
710 								d_ += ',';
711 							else
712 								d_ = '*';
713 					} else {
714 						T_2 = (k - d == 1 ? ''
715 								: d_ != '*' && k - d < 3/* k.toString(base).length-1 */? d_
716 										: (isNaN(k) ? k.replace(/,/g, cmC)
717 														.replace(/=/g, eqC)
718 													: k.toString(base))
719 								+ '=')
720 							+ ('' + val[k]).replace(/,/g, cmC).replace(/=/g, eqC)
721 							+ ',';
722 						d_ = '';
723 						if (T_.length + T_2.length > maxLen)
724 							T += T_ + NL_, T_ = T_2;
725 						else
726 							T_ += T_2;
727 					}
728 					d = k;
729 					if (!_i && parseInt(val[k]) == val[k])
730 						_i = 1;
731 					else if (_i < 2 && parseFloat(val[k]) == val[k]
732 					&& parseInt(val[k]) != val[k])
733 						_i = 2;
734 				}
735 				T += T_;
736 			}
737 			if (T) {
738 				if (!vars['set_obj_value'] || !vars['dQuote']) {
739 					Vlist.push('set_obj_value', 'dQuote'); //	假如沒有set_obj_value則須將之與其所依存之函數(dQuote)一同加入
740 					if (!vars['set_obj_value.F'])
741 						Vlist.push(direct_input + 'var set_obj_value.F;');
742 				}
743 				afterCode += "set_obj_value('"
744 					+ vName
745 					+ "','"
746 					+ T.slice(0, -1)
747 					+ "'"
748 					+ (_i ? _i == 1 ? ",1" : ",.1" : t ? ",1"
749 							: '') + t + ");" + new_line;
750 				t = 1;
751 			} else
752 				t = vType == 'Object' ? '{}' : '[]'; //new Object(), new Array()
753 		} else if (vType == 'object' && val.constructor == RegExp)
754 			t = val;
755 		else if (vType == 'undefined')
756 			//	有定義(var)但沒設定值,可計算undefined數目
757 			t = 1;
758 		else if (t = 1, vType != 'unknown')
759 			if (('' + val).match(/^\s*\[[Oo]bject\s*(\w+)\]\s*$/)) t = RegExp.$1; //	僅對Math有效?
760 			else vType = 'unknown type: ' + vType + ' (constructor: ' + val.constructor + ')', alert(vName + ': ' + vType + ', please contract me!\n' + val); //	未知
761 		else alert('The type of ' + vName + ' is "' + vType + '"!'); //	unknown
762 		if (typeof t != 'undefined') {
763 			if (vName.indexOf('.') == -1)
764 				codeText += (c ? ',' : 'var ') + vName + (t === 1 && vType != 'number' ? '' : '=' + t), c = 1; //alert(codeText.substr(codeText.length-200));
765 			else if (t !== 1 || vType == 'number')
766 				codeText += (c ? ';' : '') + vName + '=' + t + ';',
767 				c = 0;
768 		}
769 		done.push('(' + vType + ')' + vName);
770 	}
771 	if (c)
772 		codeText += ';' + new_line; //,c=0;//alert(codeText.substr(codeText.length-200));//alert(afterCode);
773 	return [ codeText, afterCode, vari, func, done, undone, Vlist ];
774 };
775 /**
776  * default direct input symbol
777  * @type	String
778  * @memberOf	CeL.code.reorganize
779  */
780 _.generate_code.ddI = '*';
781 /**
782  * default separator
783  * @type	String
784  * @memberOf	CeL.code.reorganize
785  */
786 _.generate_code.dsp = ',';	
787 
788 
789 
790 
791 //	null code series
792 //simpleWrite('try.js',add_null_code(50000));
793 var null_code_data, null_code_data_length, add_null_codeD; //	處理null_code的變數暫存,null_code_data[變數名]=變數值,null_code_data_length=length,add_null_codeD:add_null_code data,因為每次都重新執行null_code()很費時間
794 function add_null_code(len, type) {	//	為了基底才能加入function而作
795 	var s = '', t, l, i, j; if (typeof add_null_codeD != 'object') add_null_codeD = []; qq = 0;
796 	while (s.length < len) {
797 		/*  t=Math.random()<.5?'function':'';
798 		s+=len-s.length>9?null_code((len/2>999?999:len/2)+'-'+len,t):null_code(len,t);*/
799 		l = len - s.length > 9 ? len > 2e3 ? 999 : len / 2 : len;
800 		j = 0; for (i in add_null_codeD) if (i > l) break; else j = i;
801 		if (j && j > 99) { if (len - s.length > 99) t = null_code(null_code(99, 0)), s += (add_null_codeD[t.length] = t); while (len - s.length > j) s += add_null_codeD[j]; }
802 		s += j && len - s.length - j < 50 ? add_null_codeD[j]
803 		//	:(t=null_code(l),add_null_codeD[t.length]=t);
804                                     : (t = null_code(l) ? add_null_codeD[t.length] = t : '');
805 	}
806 	return s;
807 }
808 function null_code_data_add(vari, val) {	//	variables,value
809 	if (vari) {
810 		if (typeof null_code_data != 'object') null_code_data = {}, null_code_dataI = [], null_code_data_length = 0;
811 		if (!(vari in null_code_data)) null_code_dataI.push(vari), null_code_data_length++;
812 		null_code_data[vari] = val;
813 	}
814 }
815 //var t=null_code('230-513','function');alert(t.length+'\n'+t);
816 //	
817 //	其他方法(有閒情逸致時再加):/**/,//,var vari=num+-*/num,str+-str,if(typeof vari=='~'){},try{eval('~');}catch(e){},eval('try{}catch(e){}');if()WScript.Echo();
818 CeL.code.reorganize
819 .
820 /**
821  * 產生無用的垃圾碼
822  * @param length	\d || \d-\d
823  * @returns	{String}	無用的垃圾碼
824  * @see
825  * @memberOf	CeL.code.reorganize
826  */
827 null_code = function (length, type) {
828 	//	variables;up,down:長度上下限
829 	var t = '', vari = [], u, d;
830 	if (typeof null_code_data != 'object')
831 		null_code_data = {}, null_code_dataI = [],
832 		null_code_data_length = 0;
833 	if (typeof length == 'number')
834 		u = d = Math.floor(length);
835 	else if (length = '' + length, (i = length.indexOf('-')) != -1)
836 		d = parseInt(length.slice(0, i)), u = parseInt(length
837 				.substr(i + 1));
838 	if (u < d) {
839 		var a = d;
840 		d = u, u = a;
841 	}
842 	if (!length || !u || length < 0)
843 		return '';
844 	if (typeof type != 'string')
845 		type = typeof type;
846 
847 	//if(type=='boolean'){return Math.random()<.5?1:0;}
848 	if (type == 'number') {
849 		return Math.floor(Math.random() * (u - d) + d);
850 	}
851 	if (type == 'n2') {
852 		if (u < 9 && d < 9)
853 			d = Math.pow(10, d), u = Math.pow(10, u);
854 		return Math.floor(Math.random() * (u - d) + d);
855 	}
856 	if (type == 'string') {
857 		// if(d<0&&(d=0,u<0))
858 		if (d < 0 && u < (d = 0))
859 			return '';
860 		for ( var i = 0, l = null_code(d + '-' + u, 0), t = []; i < l; i++)
861 			t.push(null_code('32-128', 0));
862 		return fromCharCode(t);
863 	}
864 	if (type == 'vari') {
865 		//	變數variables
866 		if (d) d--; u--; if (u > 32) u = 32; else if (u < 1) u = 1; //	最長變數:32
867 		var a, i, l, c = 0;
868 		do {
869 			t = [], a = null_code('65-123', 0), i = 0, l = null_code(d + '-' + u, 0);
870 			if (a > 90 && a < 97) a = 95; t.push(a);
871 			for (; i < l; i++) { a = null_code('55-123', 0); if (a > 90 && a < 97) a = 95; else if (a < 65) a -= 7; t.push(a); } //	code:48-57,65-90,95,97-122;
872 			t = fromCharCode(t); try { eval('a=typeof ' + t + '!="undefined";'); } catch (e) { } //	確保是新的變數
873 			if (c % 9 == 0 && d < u) ++d;
874 		} while (++c < 99 && (a || (t in null_code_data))); //	不能確保是新變數的話,給個新的:繼續作。★此作法可能導致長時間的迴圈delay!因此限制最多99次。
875 		//if(c==99){alert('重複:['+a+']'+t);WScript.Quit();}
876 		return t;
877 	}
878 	if (type == 'function') {
879 		var i = 0, l = null_code('0-9', 0), fN = null_code('2-30', 'vari'), a = NewLine + 'function ' + fN + '(', b = NewLine + '}' + NewLine, v, D = []; //	fN:函數名
880 		//	只加入函數名
881 		null_code_data_add(fN, 'function');
882 		if (l) {
883 			for (; i < l; i++)
884 				v = null_code('2-30', 'vari'), a += v + ',', D.push(v);
885 			a = a.slice(0, -1);
886 		}
887 		a += '){';
888 		l = (a + b).length + NewLine.length;
889 		if (u < l)
890 			return null_code(length);
891 		return a + (NewLine + null_code((d < l ? 0 : d - l) + '-'
892 				+ (u - l))).replace(/\n/g, '\n	') + b;
893 	}
894 	//	others:type=='code'
895 	var l = null_code(length, 0);
896 	while (t.length < l) {
897 		var a, v, va = (Math.random() < .5 ? (va = null_code('1-6', 0))
898 				: dQuote(va = null_code('5-'
899 						+ (u - t.length > 50 ? 50 : u - t.length),
900 				'string')));
901 		if (u - t.length > 20 && Math.random() < .9) {
902 			if (Math.random() < .7 && null_code_data_length > 9)
903 				v = null_code_dataI[null_code(0 + '-'
904 						+ null_code_data_length, 0)], a = v + '=' + va;
905 			else
906 				v = null_code('1-9', 'vari'), a = 'var ' + v
907 				+ (Math.random() < .3 ? '' : '=' + va);
908 			a += ';' + (Math.random() < .4 ? NewLine : '');
909 			null_code_data_add(v, va);
910 		} else {
911 			a = Math.floor(Math.random() * 4);
912 			a = a == 1 ? '	' : a || u < t.length + NewLine.length ? ' '
913 					: NewLine;
914 		}
915 		if (t.length + a.length <= u)
916 			t += a;
917 	}
918 	return t;
919 };
920 //	↑null code series
921 
922 
923 
924 /*
925 bug:
926 當每一行都去除\n也可時方能使用!否則會出現「需要;」的錯誤!
927 可能會lose條件式編譯(@cc_on等)的資訊或判別錯誤!另外,尚不保證不會lose或更改程式碼!
928 
929 http://www.dreamprojections.com/syntaxhighlighter/Default.aspx
930 
931 TODO:
932 將 local various 甚至 global 依頻率縮短,合併以字串組合代替。	selectable
933 safer cut '\r\n'
934 {_exp1_;_exp2_;}	→	_exp1_,_exp2_;
935 safer cut ';'	;}	→	}
936 compress: eval("~")
937 
938 (function(~){~})(~);
939 
940 var fascii2ascii = (function(){
941 var cclass
942 = '['+String.fromCharCode(0xff01)+'-'+String.fromCharCode(0xff5e)+']';
943 var re_fullwidth = new RegExp(cclass, 'g');
944 var substitution = function(m){
945 return String.fromCharCode(m.charCodeAt(0) - 0xfee0); // 0xff00 - 0x20
946 };
947 return function(s){ return s.replace(re_fullwidth, substitution) };
948 })();
949 
950 
951 
952 
953 /*@cc_on	OK
954 /*@ cc_on	error
955 /* @cc_on	無效
956 
957 
958 JSlint 可以協助您檢查出有問題的程式碼。
959 http://www.jslint.com/
960 
961 Javascript compressor
962 http://dean.edwards.name/packer/
963 http://javascriptcompressor.com/
964 http://www.creativyst.com/Prod/3/
965 http://www.radok.com/javascript-compression.html
966 http://alex.dojotoolkit.org/shrinksafe/
967 http://www.saltstorm.net/depo/esc/introduction.wbm
968 */
969 
970 CeL.code.reorganize
971 .
972 /**
973  * 精簡程式碼:去掉註解與\s\n。
974  * use for JSON (JavaScript Object Notation)
975  * @param code	欲精簡之程式碼
976  * @param mode	mode=1:''中unicode轉\uHHHH
977  * @returns	{String}	精簡後之程式碼
978  * @example
979  * CeL.use('code.reorganize');
980  * CeL.reduce_code('a + v  = ddd;');
981  * @see
982  * @requires	
983  * @memberOf	CeL.code.reorganize
984  */
985 reduce_code = function (code, mode) {
986 	if (!code)
987 		return ''; //sss=0,mmm=90;
988 	var _s = _.reduce_code, reduce_space = _s.reduce_space, A = '', a = '' + code, m, b, q, c, Begin, End;
989 	//reduce_codeM=[''];
990 	while (a.match(/['"\/]/)) {
991 		with (RegExp)
992 			Begin = index, End = lastIndex, m = lastMatch;
993 		//alert(a);
994 		//	RegExp.$'等
995 		if (Begin && a.charAt(Begin - 1) == '$') {
996 			A += reduce_space(a.slice(0, Begin)) + m;
997 			a = a.substr(End);
998 			continue;
999 		}
1000 
1001 		if (m == '/') if (m = a.charAt(RegExp.lastIndex), m == '*' || m == '/') {	//	comment
1002 			//if(++sss>mmm-2&&alert('sss='+sss+NewLine+a),sss>mmm){alert('comment');break;}
1003 			//A+=reduce_space(a.slice(0,Begin)),b=m=='*'?'*/':'\n',m=a.indexOf(b,End+1);//A+=a.slice(0,RegExp.index),b=m=='*'?'*/':'\n',m=a.substr(RegExp.lastIndex).indexOf(b);//
1004 			A += reduce_space(a.slice(0, Begin));
1005 			b = m == '*' ? '*/' : '\n';
1006 			m = End + 1;
1007 			do {
1008 				//	預防「\*/」…其實其他地方(如["'])也需要預防,但沒那精力了。
1009 				m = a.indexOf(b, m);
1010 				if (a.charAt(m - 1) == '\\')
1011 					m += 2;
1012 				else
1013 					break;
1014 			} while (m != -1);
1015 			//reduce_codeM.push('find comment:	Begin='+Begin+',End='+End+',m='+m+',b='+b.replace(/\n/g,'\\n')+NewLine+(m-End>200||m==-1?a.substr(Begin,200)+'..':a.slice(Begin,m))+NewLine+NewLine+'continue:'+NewLine+a.substr(m+b.length,200)+'..');
1016 			if (m == -1)
1017 				if (b == '\n') { a = ''; break; /*return A;*/ }
1018 				else throw new Error(1, '[/*] without [*/]!\n' + a.substr(Begin, 200));
1019 			else if (
1020 					//	7: 最起碼應該有這麼多 char 的 comment 才列入查核
1021 					7 + End < m &&
1022 					//a.substring(End+1,m-5).indexOf('@cc_on')==0	不一定只有 cc_on
1023 					/^@[cei][a-z_]+/.test(a.substring(End + 1, m - 5))
1024 				)
1025 				//alert('There is conditional compilation detected,\n you may need pay attention to:\n'+a.substring(End+1,m-5)),
1026 				//	對條件式編譯全選,預防資訊lose。僅有'/*@cc_on'才列入,\/*\s+@\s+cc_on不可!
1027 				A += a.slice(End - 1, m + b.length).replace(/\s*(\/\/[^\r\n]*)?(\r?\n)\s*/g, '$2'), a = a.slice(m + b.length);
1028 			else if (a = a.substr(m + b.length), A.match(/\w$/) && a.match(/^\s*\w/))
1029 				//	預防return /*~*/a被轉為returna
1030 				A += ' ';
1031 		} else {
1032 			//	RegExp
1033 			//reduce_codeM.push('find RegExp:	Begin='+Begin+NewLine+a.substr(Begin,200)+NewLine+'-'.x(20)+NewLine+A.substr(A.length-200)+'..');
1034 			b = a.slice(0, Begin), m = 1; //c=Begin,q=End
1035 
1036 			if (b.match(/(^|[(;+=!{}&|:\\\?,])\s*$/))
1037 				//	RegExp:以起頭的'/'前面的字元作判別,前面是這些則為RegExp
1038 				m = 1;
1039 			else if (b.match(/[\w)\]]\s*$/))
1040 				//	前面是這些則為op
1041 				m = 0;
1042 			else
1043 				//	需再加強前兩項判別之處
1044 				throw new Error(1,
1045 						'Unknown [/]! Please check it and add rules!\n'
1046 						+ b + '\n-------------\n'
1047 						+ a.slice(0, End + 80)
1048 						//+'\n-------------\n'+A
1049 				);
1050 
1051 			if (!m)
1052 				//if(!m)A+=a.slice(0,q),a=a.substr(q);//	應該是op之類//
1053 				A += reduce_space(a.slice(0, End)),
1054 				a = a.substr(End);
1055 			else {
1056 				A += reduce_space(a.slice(0, Begin)), a = a.substr(Begin), c = 0; //else{A+=a.slice(0,c),a=a.substr(c),c=0;//
1057 				//if(++sss>mmm-2&&alert('sss='+sss+'\n'+a),sss>mmm){alert('reg');break;}
1058 				while (m = a.substr(c).match(/([^\\]|[\\]{2,})([[\/\n])/)) {	//	去掉[]
1059 					//reduce_codeM.push('find RegExp [ or / or \\n :'+NewLine+a.substr(c+RegExp.index+1,20));
1060 					if (m[1].length > 1 && m[1].length % 2 == 1) { c += RegExp.lastIndex - 1; continue; } //	奇數個[\]後
1061 					else if (m = m[2], m == '/') break;
1062 					if (m == '[')
1063 						while ((m = a.substr(c += RegExp.lastIndex).match(/([^\\]|[\\]{2,})\]/))) {	//	不用c+=RegExp.index+1是因[]中一定得有字元
1064 							if (m[1].length > 1 && m[1].length % 2 == 1) { c += RegExp.lastIndex - 1; continue; } //	奇數個[\]後
1065 							c += RegExp.lastIndex - 1; m = 1; break; //	-1:因為偵測'['時需要前一個字元
1066 							//if(++sss>mmm-2&&alert('sss='+sss+'\nc='+c+'\n'+a.substr(c)),sss>mmm){alert('reg 2');break;}
1067 						}
1068 					if (m != 1) throw new Error(1, 'RegExp error!\nbegin with:\n' + a.substr(Begin, 200));
1069 				}
1070 				//reduce_codeM.push('find RegExp 2:'+NewLine+a.slice(0,c+RegExp.lastIndex));
1071 				A += a.slice(0, c += RegExp.lastIndex), a = a.substr(c); //q=RegExp.lastIndex,alert('reg:'+Begin+','+c+','+q+'\n'+a.slice(0,Begin)+'\n-------\n'+a.slice(Begin,c+q)+'\n-------\n'+a.substr(c+q,200));return A;
1072 				//q=RegExp.lastIndex,A+=reduce_space(a.slice(0,Begin))+a.slice(Begin,c+=q),a=a.substr(c);//A+=a.slice(0,c+=RegExp.lastIndex),a=a.substr(c);//
1073 			}
1074 		} else {
1075 			//	quotation
1076 			//alert('quotation:\n'+a)
1077 			//reduce_codeM.push('find quotation:'+NewLine+a.substr(RegExp.index,200));
1078 			//if(++sss>mmm-2&&alert('sss='+sss+'\n'+a),sss>mmm){alert('quo');break;}
1079 			//c=RegExp.index,b=a.substr(RegExp.lastIndex-1).match(new RegExp('[^\\\\]('+(q=m)+'|\\n)'));	較正式
1080 
1081 
1082 
1083 /*
1084 
1085    q=m;	//	2009/8/16 15:59:02 FAILED
1086 
1087 function test_quotation(){
1088 '\';		//	Error
1089 '\\\';		//	Error
1090 '\\\\\';	//	Error
1091 '';
1092 'n';
1093 '\\';
1094 'nn';
1095 '\\n';
1096 'n\\';
1097 'n\\n';
1098 '\\\\';
1099 '\\\\n';
1100 'n\\\\';
1101 'n\\\\n';
1102 'nn\\\\';
1103 'nn\\\\n';
1104 'nnn\\\\';
1105 'nnn\\\\n';
1106 }
1107 alert(reduceCode(test_quotation));
1108 
1109 alert(reduceCode(reduceCode));
1110 */
1111 
1112 /*
1113 			//	找到 '\n' 為止,考慮 [\\\\]\\r?\\n
1114 			c = Begin + 1, b = '';
1115 			while ((c = a.indexOf('\n', c)) != -1) {
1116 				q = a.charAt(c - 1);
1117 				if (q == '\\' || q == '\r' && a.charAt(c - 2) == '\\') {
1118 					c++;
1119 					continue;
1120 				}
1121 
1122 			};
1123 			if (a.charAt(c - 1))
1124 
1125 				// alert('use RegExp: '+new
1126 				// RegExp('^([^\\\\\\r\\n]*|[\\\\][^\\r\\n]|[\\\\]\\r?\\n)*('+q+'|\\n)'));
1127 				b = a.slice(Begin + 1).match(
1128 						new RegExp('^([^\\\\\\r\\n]*|[\\\\][^\\r\\n]|[\\\\]\\r?\\n)*(' + q
1129 								+ '|\\n)')); // too slow!
1130 			alert('test string:\n' + a.slice(Begin + 1))
1131 			if (!b || b[2] == '\n')
1132 				throw new Error(1, 'There is a start quotation mark [' + q
1133 						+ '] without a end quotation mark!\nbegin with:\n'
1134 						+ a.substr(Begin, 200)); // 語法錯誤?
1135 			q = RegExp.lastIndex + 1;
1136 */
1137 
1138 			//	未考慮 '\n' (不能 check error!)
1139 			c = Begin;
1140 			q = m;
1141 			//	考慮 [\\\\]\\r?\\n
1142 			while (b = a.substr(c).match(new RegExp('([^\\\\\\r]|\\\\{2,})(' + q + '|\\r?\\n)')))
1143 				if (b[1].length > 1 && b[1].length % 2 == 1)
1144 					c = RegExp.lastIndex - 1;
1145 				else
1146 					break;
1147 
1148 			if (!b || b[2] == '\n')
1149 				//	語法錯誤?
1150 				throw new Error(1, 'There is a start quotation mark ['
1151 						+ q + '] without a end quotation mark!\nget:['
1152 						+ b + ']\nbegin with:\n' + a.substr(Begin, 200));
1153 			//reduce_codeM.push('find quota ['+q+']:'+NewLine+a.substr(c,RegExp.lastIndex)+NewLine+'continue:'+NewLine+a.substr(c+RegExp.lastIndex,99));
1154 
1155 			q = RegExp.lastIndex;
1156 
1157 
1158 
1159 			//alert('q='+q+',['+b[0]+']');
1160 			//alert(b[1]);
1161 			//alert(b[2]);
1162 
1163 			b = a.substr(Begin, q).replace(/\\\r?\n/g, '');
1164 			//alert('mode='+mode);
1165 			if (mode == 1) {
1166 				m = '';
1167 				for ( var i = 0; i <= q; i++)
1168 					m += b.charCodeAt(i) > 127 ? '\\u'
1169 							+ b.charCodeAt(i).toString(16) : b
1170 							.charAt(i);
1171 			}
1172 			else m = b;
1173 
1174 			//A+=a.slice(0,c+=RegExp.lastIndex),a=a.substr(c);
1175 			A += reduce_space(a.slice(0, Begin)) + m, a = a.substr(Begin + q);
1176 
1177 			//alert('A='+A);
1178 			//alert('a='+a);
1179 
1180 			//	對於 ~';{ → ~'{ 或  ~';if → ~'if  不被接受。
1181 			//if(!/^[\s\r\n]*\}/.test(a))A+=';';
1182 		}
1183 	}
1184 
1185 	//	後續處理
1186 	A += reduce_space(a);
1187 	//	這兩行在 reduce_space() 中已處理
1188 	//A=A.replace(/([^;])\s*\n+\s*/g,'$1;');
1189 	//A=A.replace(/\s*\n+\s*/g,'');//while(A.match(/\s*\n\s*/))A=A.replace(/\s*\n\s*/g,'');//
1190 
1191 	return A;
1192 };
1193 
1194 /*	tech. data:
1195 
1196 string:
1197 ['"]~$1
1198 
1199 RegExp:
1200 [/]~$1[a-z]*
1201 [/]~$1[gim]*
1202 =RegExp.[source|test(|exec(]
1203 
1204 .match(RegExp)
1205 .replace(RegExp,)
1206 .search(RegExp)
1207 
1208 op[/]:
1209 word/word
1210 word/=word
1211 
1212 ~:
1213 /\\{0,2,4,6,..}$/
1214 
1215 註解comment:
1216 /*~* /
1217 //~\n
1218 
1219 符號denotation:/[+-*=/()&^,<>|!~%\[\]?:{};]+/
1220 +-
1221 word:/[\w]+/
1222 
1223 program:
1224 ((denotation|word|comment)+(string|RegExp)*)+
1225 
1226 test:
1227 i++ +
1228 a+=++i+4
1229 ++a+i++==++j+ ++e
1230 a++ += ++d
1231 a++ + ++b
1232 
1233 for(.*;;)
1234 
1235 
1236 */
1237 CeL.code.reorganize
1238 .
1239 /**
1240  * 精簡程式碼部分:去掉\n,;前後的空白等,應由 reduce_code() 呼叫。
1241  * @param code	輸入欲精簡之程式碼
1242  * @returns	{String}	精簡後之程式碼
1243  * @see
1244  * http://dean.edwards.name/packer/
1245  * @memberOf	CeL.code.reorganize
1246  */
1247 reduce_code.reduce_space = function (code) {
1248 	//	比下一行快很多,但為了正確性而放棄。
1249 	//code=code.replace(/\s*\n+\s/g,'');
1250 	//	當每一行都去除\n也可時方能使用!否則會出現「需要;」的錯誤!
1251 	code = code
1252 		.replace(
1253 			/([^\s]?)\s*\n+\s*([^\s]?)/g,
1254 			function($0, $1, $2) {
1255 				var a = $1, b = $2;
1256 				return a
1257 					+ (a && b && a.match(/\w/) && b.match(/\w/) ? ' ' : '')
1258 					+ b;
1259 			})
1260 		.replace(/\s+$|^\s+/g, '');
1261 
1262 	//if(code.match(/\s+$/))code=code.slice(0,RegExp.index);
1263 	//if(code.match(/^\s+/))code=code.substr(RegExp.lastIndex);
1264 
1265 	//	對喜歡將\n當作;的,請使用下面的;但這可能造成失誤,例如[a=(b+c)\nif(~)]與[if(~)\nif(~)]
1266 	/*
1267 	var m, a;
1268 	while (m = code.match(/\s*\n+\s*(.?)/))
1269 		a = RegExp.lastIndex, code = code.slice(0, RegExp.index)
1270 				+ (m[1].match(/\w/) ? ';' : '')
1271 				+ code.substr(a - (m[1] ? 1 : 0));
1272 	if (m = code.match(/\s+$/))
1273 		code = code.slice(0, RegExp.index);
1274 	if (m = code.match(/^\s+(.?)/)) {
1275 		code = code.substr(RegExp.lastIndex - 1);
1276 		if ((m[0].indexOf('\n') != -1 && m[1].match(/\w/)))
1277 			code = ';' + code;
1278 	}
1279 	*/
1280 
1281 	code = code
1282 	//	最後再作
1283 	//.replace(/([^;])\s*\n+\s*/g,'$1;').replace(/\s*\n+\s*/g,'')
1284 
1285 	//	因為直接執行下行敘述會將for(~;;也變成for(~;,所以需先作處理。
1286 	//.replace(/for\s*\(([^;]*);\s*;/g,'for;#$1#')
1287 	//	在''等之中執行此行可能出問題,因此另外置此函數。
1288 	//.replace(/\s*;+\s*/g,';')
1289 
1290 	//.replace(/for;#([^#]*)#/g,'for($1;;')
1291 
1292 
1293 	//.replace(/(.)\s+([+\-]+)/g,function($0,$1,$2){return $1+($1=='+'||$1=='-'?' ':'')+$2;}).replace(/([+-]+)\s+(.)/g,function($0,$1,$2){return $1+($2=='+'||$2=='-'?' ':'')+$2;})	//	+ ++ +
1294 	.replace(/([+\-])\s+([+\-])/g, '$1 $2').replace(/([^+\-])\s+([+-])/g, '$1$2').replace(/([+\-])\s+([^+\-])/g, '$1$2') // + ++ +
1295 
1296 	.replace(/\s*([()\[\]&|^{*\/%<>,~!?:.]+)\s*/g, '$1')	//	.replace(/\s*([()\[\]&|{}/%,!]+)\s*/g,'$1')	//	去掉'}',因為可能是=function(){};或={'ucC':1};
1297 	.replace(/([a-zA-Z])\s+([=+\-])/g, '$1$2').replace(/([=+\-])\s+([a-zA-Z])/g, '$1$2')
1298 
1299 	.replace(/\s*([+\-*\/%=!&^<>]+=)\s*/g, '$1')
1300 	//.replace(/\s*([{}+\-*/%,!]|[+\-*\/=!<>]?=|++|--)\s*/g,'$1')
1301 
1302 
1303 	//	因為直接執行下行敘述會將for(~;;也變成for(~;,所以需先作處理。
1304 	.replace(/for\(([^;]*);;/g, 'for;#$1#')
1305 	//.replace(/};+/g,'}')	/*.replace(/;{2,}{/g,'{')*/.replace(/{;+/g,'{')//.replace(/;*{;*/g,'{')//在quotation作修正成效不彰
1306 	//	去掉'}',因為可能是=function(){};或={'ucC':1};
1307 	.replace(/\s*([{;]);+\s*/g, '$1')//.replace(/\s*([{};]);+\s*/g,'$1')
1308 	.replace(/for;#([^#]*)#/g, 'for($1;;')
1309 
1310 	.replace(/\s{2,}/g, ' ')
1311 	.replace(/([^)]);}/g, '$1}')	//	~;while(~);}	but: ~;i=(~);} , {a.b();}
1312 	;
1313 	//if(code.charAt(0)=="'")code=(code.charAt(1)=='}'?'}':code.charAt(1)==';'?'':code.charAt(1))+code.substr(2);
1314 
1315 	return code;
1316 };
1317 
1318 
1319 
1320 CeL.code.reorganize
1321 .
1322 /**
1323  * 精簡整個檔的程式碼
1324  * …and test程式是否有語法不全處(例如沒加';')
1325  * @param original_ScriptFileName	origin javascript file name
1326  * @param output_ScriptFileName	target javascript file name
1327  * @param flag
1328  * 	flag={doTest:bool,doReport:bool,outEnc:(enc),copyOnFailed:bool,startFrom:// | '',addBefore:'',runBefore:function}
1329  * 	startFrom 若為 // 則應為 startAfter!!
1330  * @requires	autodetectEncode,simpleRead,simpleWrite,reduce_code,is_file
1331  * @deprecated use <a href="http://closure-compiler.appspot.com/" accessdate="2009/12/3 12:13">Closure Compiler Service</a>
1332  * @memberOf	CeL.code.reorganize
1333  */
1334 reduce_script = function (original_ScriptFileName, output_ScriptFileName, flag) {
1335 	if (!original_ScriptFileName)
1336 		original_ScriptFileName = WScript.ScriptFullName;
1337 
1338 	if (!output_ScriptFileName)
1339 		output_ScriptFileName =
1340 			//	getFP(original_ScriptFileName.replace(/\.ori/,''),1);
1341 			original_ScriptFileName +
1342 				//.compressed.js
1343 				'.reduced.js';
1344 
1345 	if (!flag)
1346 		flag = {};
1347 
1348 	if (!fso)
1349 		fso = new ActiveXObject("Scripting.FileSystemObject");
1350 
1351 	// 同檔名偵測(若自行把 .ori 改成標的檔等,把標的檔先 copy 成原來檔案。)
1352 	if (original_ScriptFileName == output_ScriptFileName) {
1353 		if (2 == WshShell.Popup('origin file and output file is the same!'
1354 				+ (flag.originFile ? "\nI'll try to copy it back." : ''), 0,
1355 				'Copy target as origin file', 1 + 48))
1356 			return;
1357 		if (!flag.originFile)
1358 			return;
1359 		if (is_file(original_ScriptFileName = flag.originFile)) {
1360 			alert('origin file is exist! Please rename the file!');
1361 			return;
1362 		}
1363 		try {
1364 			fso.CopyFile(output_ScriptFileName, original_ScriptFileName);
1365 		} catch (e) {
1366 			alert('Failed to copy file!');
1367 			return;
1368 		}
1369 	}
1370 
1371 	if (!is_file(original_ScriptFileName)) {
1372 		alert("Doesn't found original javascript file!\n" + original_ScriptFileName);
1373 		return;
1374 	}
1375 
1376 	var sp = '='.x(80) + NewLine, reduce_codeM = [], enc = autodetectEncode(original_ScriptFileName), i, outenc = autodetectEncode(output_ScriptFileName);
1377 
1378 	if (!flag.outEnc)
1379 		flag.outEnc = outenc || enc || TristateTrue;
1380 
1381 	try {
1382 		var f = simpleRead(original_ScriptFileName, enc),
1383 		ot = simpleRead(output_ScriptFileName, flag.outEnc), r = '';
1384 		if (typeof f != 'string')
1385 			throw new Error(1, "Can't read file [" + original_ScriptFileName + "]!");
1386 		t = flag.runBefore ? flag.runBefore(f) || f : f;
1387 		if (flag.startFrom)
1388 			if (typeof flag.startFrom == 'string') {
1389 				if ((i = t.indexOf(flag.startFrom)) != -1)
1390 					t = t.slice(i);
1391 			} else if (flag.startFrom instanceof RegExp)
1392 				t = t.replace(flag.startFrom, '');
1393 		t = reduce_code(t);
1394 		t = (flag.addBefore || '')
1395 				+ t.replace(/([};])function(\s)/g, '$1\nfunction$2').replace(
1396 						/}var(\s)/g, '}\nvar$1')/* .replace(/([;}])([a-z\._\d]+=)/ig,'$1\n$2') */
1397 				+ reduce_codeM.join(NewLine + sp);
1398 		// 不相同才 run
1399 		if (t)
1400 			if (t != ot || outenc != flag.outEnc)
1401 				simpleWrite(output_ScriptFileName, t, flag.outEnc);
1402 			else
1403 				r = '* 欲寫入之內容(' + t.length + ' chars)與標的檔相同。檔案並未變更。\n';
1404 
1405 		if (flag.doTest)
1406 			// void //should use windows.eval
1407 			// //if(WScript.ScriptName!=output_ScriptFileName)eval(t);
1408 			eval('if(0){if(0){if(0){' + t + '}}}');
1409 		if (flag.doReport)
1410 			alert('OK!\n' + r + '\n' + f.length + '→' + t.length
1411 					+ '(origin output: ' + ot.length + ') ('
1412 					+ (100 * t.length / f.length).decp(2) + '%)\n\n[' + enc
1413 					+ '] ' + original_ScriptFileName + '\n→\n[' + flag.outEnc
1414 					+ '] ' + output_ScriptFileName);
1415 	} catch (e) {
1416 		if (6 == alert(
1417 				'reduce_script: Error occured!\nDo you want to write error message to target file?\n'
1418 						+ output_ScriptFileName, 0, 0, 3 + 32))
1419 			simpleWrite(output_ScriptFileName, popErr(e) + NewLine + NewLine
1420 					+ reduce_codeM.join(NewLine + sp), TristateTrue/* enc */, 0,
1421 					true);
1422 		if (flag.copyOnFailed)
1423 			try {
1424 				fso.CopyFile(original_ScriptFileName, output_ScriptFileName);
1425 			} catch (e) {
1426 				alert('Failed to copy file!');
1427 				return;
1428 			}
1429 	}
1430 };
1431 
1432 
1433 
1434 
1435 /*
1436 !! arguments unfinished !!
1437 
1438 usage: include code in front:
1439 //	[function.js]_iF,rJS
1440 //	[function.js]End
1441 
1442 rJS({add:'/*\nCopyright 2008 kanashimi\n欲使用此工具功能者,請聯絡作者。\n*\/\n'});
1443 
1444 //	code start
1445 
1446 (main code)..
1447 
1448 */
1449 CeL.code.reorganize
1450 .
1451 /**
1452  * 縮減 HTML 用 .js大小+自動判別。
1453  * TODO:
1454  * 自動選擇 target 之模式(不一定是 .ori)
1455  * @param flag	flag
1456  * @requires	reduce_script
1457  * @since	2008/7/31 17:40:40
1458  * @memberOf	CeL.code.reorganize
1459  */
1460 rJS = function (flag) {
1461 	if (typeof WScript == 'object') {
1462 		var o = WScript, t, n;
1463 
1464 		if (typeof reduce_script != 'function')
1465 			o.Echo('Please include function reduce_script() to generate code.');
1466 		else
1467 			flag = flag || {},
1468 			n = o.ScriptFullName,
1469 			t = n.replace(/\.ori/, ''),
1470 			reduce_script(n, t, {
1471 				doReport : 1,
1472 				outEnc : 'UTF-8',
1473 				startFrom : flag.cut || /^(.|\n)+code\s+start\r?\n/,
1474 				addBefore : flag.add,
1475 				originFile : t.replace(flag.ori || /(\.[^.]+)$/, '.ori$1')
1476 			});
1477 
1478 		o.Quit();
1479 	}
1480 };
1481 
1482 
1483 /*
1484 try{var o;try{o=new ActiveXObject('Microsoft.XMLHTTP')}catch(e){o=new XMLHttpRequest()}with(o)open('GET',(new ActiveXObject("WScript.Shell")).RegRead('HKCU\\Software\\Colorless echo\\CeL.path'),false),send(null),eval(responseText)}catch(e){}
1485 
1486 */
1487 //(''+CeL.library_loader).replace(/^\s*function\s*\(\s*\)\s*{\s*/,'').replace(/\s*}\s*;\s*$/,'');
1488 CeL.code.reorganize
1489 .
1490 /**
1491 * for 引用: include library 自 registry 中的 path
1492 * @since	2009/11/25 22:59:02
1493 * @_memberOf	_module_
1494 */
1495 library_loader_by_registry = function () {
1496 	//if (typeof WScript == "object")
1497 	try {
1498 		var o;
1499 		try {
1500 			o = new ActiveXObject('Microsoft.XMLHTTP');
1501 		} catch (e) {
1502 			o = new XMLHttpRequest();
1503 		}
1504 		with (o)
1505 			open('GET', (new ActiveXObject("WScript.Shell")).RegRead(library_namespace.env.registry_key), false),
1506 				send(null),
1507 				eval(responseText);
1508 	} catch (e) {
1509 	}
1510 };
1511 
1512 
1513 CeL.code.reorganize
1514 .
1515 /**
1516 * get various from code
1517 * @param {String} code	程式碼
1518 * @param {Boolean} fill_code	(TODO) 不只是定義,在 .code 填入程式碼。
1519 * @return	{Object}	root namespace
1520 * @since	2009/12/5 15:04:42, 2009/12/20 14:33:30, 2010/7/7 10:58:22
1521 * @_memberOf	_module_
1522 */
1523 get_various_from_code = function (code, fill_code) {
1524 	//library_namespace.log(''+code.slice(0, 100));
1525 
1526 	//	使用 .split(/\r?\n/) 應注意:這實際上等於 .split(/(\r?\n)+/) (??)
1527 	code = code.split(/\r?\n/);
1528 
1529 	var i, m, last_code = [],
1530 	/**
1531 	 * 現在所處之 line
1532 	 * 
1533 	 * @inner
1534 	 * @ignore
1535 	 */
1536 	line = '',
1537 	/**
1538 	 * code.length, 加快速度用
1539 	 * 
1540 	 * @constant
1541 	 * @inner
1542 	 * @ignore
1543 	 */
1544 	l = code.length,
1545 	/**
1546 	 * root namespace
1547 	 * 
1548 	 * @inner
1549 	 * @ignore
1550 	 */
1551 	ns = {},
1552 	/**
1553 	 * 暫存 code(變數定義)
1554 	 * 
1555 	 * @inner
1556 	 * @ignore
1557 	 */
1558 	tmp_code,
1559 	/**
1560 	 * 名稱暫存變數
1561 	 * 
1562 	 * @inner
1563 	 * @ignore
1564 	 */
1565 	name,
1566 	/**
1567 	 * arguments 暫存變數<br/>
1568 	 * e.g., 變數 name
1569 	 * 
1570 	 * @inner
1571 	 * @ignore
1572 	 */
1573 	various,
1574 	/**
1575 	 * 本變數之 properties。<br/>
1576 	 * properties = { property: text contents of this property }
1577 	 * 
1578 	 * @inner
1579 	 * @ignore
1580 	 */
1581 	properties,
1582 	/**
1583 	 * 最後一次定義的變數名,用於之後若有變數需要繼承 namespace 時。
1584 	 * 
1585 	 * @inner
1586 	 * @ignore
1587 	 */
1588 	latest_name,
1589 	/**
1590 	 * 紀錄有意義的註解所在行號.
1591 	 * 預防需要把註解之前的也讀進來。有 bug!
1592 	 * 
1593 	 * @inner
1594 	 * @ignore
1595 	 */
1596 	origin_index,
1597 	new_line=library_namespace.env.new_line,
1598 	/**
1599 	 * 將 jsdoc properties 轉換成 VSdoc(JScript IntelliSense in Visual Studio)
1600 	 * 
1601 	 * @inner
1602 	 * @ignore
1603 	 * @see
1604 	 * http://weblogs.asp.net/bleroy/archive/2007/04/23/the-format-for-javascript-doc-comments.aspx,
1605 	 * http://msdn.microsoft.com/zh-tw/library/bb385682.aspx,
1606 	 * http://www.codeproject.com/Articles/60661/Visual-Studio-JavaScript-Intellisense-Revisited.aspx
1607 	 */
1608 	jsdoc_to_vsdoc = function() {
1609 		var p = [ '' ], n, V, a, i, l, t_p = function(v) {	
1610 			//CeL.log(n + ':\n' + properties[n]);
1611 			v = typeof v === 'string' ? v
1612 					.replace(/^[\s\n]+|[\s\n]+$/g, '')
1613 					.replace(/\r?\n\s+|\s+\r?\n/g, new_line)
1614 					//.replace(/</g,'<')
1615 					: '';
1616 			a = '';
1617 
1618 			switch (n) {
1619 
1620 			case 'description':
1621 			case 'summary':
1622 				if (!v || /^[\s\n]*$/.test(v))
1623 					return;
1624 				n = 'summary';
1625 				break;
1626 
1627 			case 'param':
1628 				if (a = v.match(/^({([a-zA-Z_\d.$\|\s]+)}\s*)?([a-zA-Z_\d$]+|\[([a-zA-Z_\d.$]+)\])\s*(.*?)$/)){
1629 					var t = a[2].replace(/\s+/g, '');
1630 					v = a[5], a = ' name="' + (a[4] || a[3]) + '" type="' + t + '" optional="' + (!!a[4]) + '"';
1631 
1632 					if (/integer/i.test(t))
1633 						a += ' integer="true"';
1634 					//	from CeL.net.web
1635 					if (/HTML([A-U][A-Za-z]{1,15})?Element/i.test(t))
1636 						a += ' domElement="true"';
1637 				}else
1638 					a = '';
1639 				break;
1640 
1641 			case 'type':
1642 				return;
1643 
1644 			case 'return':
1645 				n += 's';
1646 			case 'returns':
1647 				if (a = v.match(/^({([a-zA-Z_\d$.\|\s]+)})?(.*)$/)){
1648 					v = a[3].replace(/^[\s\n]+/g, '');
1649 					a = a[2].replace(/\s+/g, '') || properties.type;
1650 
1651 					a = a ? ' type="' + a + '"' : '';
1652 
1653 					if (/integer/i.test(t))
1654 						a += ' integer="true"';
1655 					//	from CeL.net.web
1656 					if (/HTML([A-U][A-Za-z]{1,15})?Element/i.test(t))
1657 						a += ' domElement="true"';
1658 				}else
1659 					a = '';
1660 				break;
1661 
1662 			default:
1663 			}
1664 
1665 			if (v.indexOf(new_line) === -1 && a.indexOf(new_line) === -1)
1666 				p.push('<' + n + a + (v ? '>' + v + '</' + n + '>' : '/>'));
1667 			else{
1668 				p.push('<' + n + a + '>');
1669 				p = p.concat(v.split(new_line));
1670 				p.push('</' + n + '>');
1671 			}
1672 		};
1673 
1674 		for (n in properties)
1675 			if (library_namespace.is_Array(V = properties[n]))
1676 				for (i = 0, l = V.length; i < l; i++)
1677 					t_p(V[i]);
1678 			else
1679 				t_p(V);
1680 
1681 		return p.length>1 ? p.join(new_line + '	///	') + new_line
1682 						+ new_line : '';
1683 	},
1684 	/**
1685 	 * 從變數定義取得變數名。
1686 	 * 
1687 	 * @param {String} _
1688 	 *            變數定義
1689 	 * @inner
1690 	 * @ignore
1691 	 */
1692 	set_name = function(_) {
1693 		name = properties.name;
1694 		if (!name) {
1695 			name = [];
1696 			var i = origin_index, l;
1697 			while (i > 0)
1698 				if (/[;{})]\s*$/.test(l = code[--i].replace(/\/\/.*$/, '')))
1699 					if ((name = name.join(' ')
1700 							// 除去註解後
1701 							.replace(/\/\*(.*?)\*\//g, ' '))
1702 							// 已無註解的話
1703 							.indexOf('*/') === -1){
1704 						_ = name.replace(/^\s*var(\s+|$)/, '') + _;
1705 						break;
1706 					} else
1707 						name = [ l, name ];
1708 				else if(l)
1709 					name.unshift(l);
1710 
1711 			//if(!i):	Error!
1712 			//if(_.match(/var/)) library_namespace.warn(name+'\n'+_);
1713 
1714 			name = properties.memberOf ?
1715 							(_.replace(/[\s\n]+/g, '').indexOf(properties.memberOf + '.') === -1 ?
1716 									properties.memberOf + '.' : '')
1717 							+ _ /* .replace(/^(.+)\./,'') */
1718 					: 'property' in properties ?
1719 							latest_name ? latest_name + '.prototype.' + _.replace(/^(.+)\./, '') : ''
1720 					: _;
1721 		}
1722 
1723 		// 除去 space
1724 		name = name.replace(/[\s\n]+/g, '');
1725 	},
1726 	handle_name = function() {
1727 		var m = name
1728 		.match(/^([a-zA-Z_$\d]+)\.[^.].+[^.]\.([a-zA-Z_$\d]+)$/);
1729 		return m && m[1] === library_namespace.Class ? m[1] + '.'
1730 				+ m[2] + '=' + name : name;
1731 	};
1732 
1733 	for (i = 0; i < l; i++) {
1734 		//	一行一行判斷
1735 		//	TODO: 提升效率
1736 		line = code[origin_index = i];
1737 
1738 		if (/^\s*\/\*\*/.test(line)) {
1739 			//	處理 '/**' 之註解(這些是有意義的)
1740 			properties = {};
1741 			//	都沒有 '@' 時,預設為 @description
1742 			name = 'description';
1743 			tmp_code = [];
1744 			various=[];
1745 			//library_namespace.log('' + line);
1746 			while (i < l) {
1747 				//library_namespace.log('' + line);
1748 				tmp_code.push(line);
1749 
1750 				//	判別
1751 				if (line.indexOf('*/') !== -1 || (m = line.match(/^\s+\*\s+@([_a-zA-Z\d\$.]+)(\s+([^\s].*)?\s*)?$/))) {
1752 					//	設定 name = various
1753 					various = various.join(new_line);
1754 					if (name in properties)
1755 						if (library_namespace.is_Array(properties[name]))
1756 							properties[name].push(various);
1757 						else
1758 							properties[name] = [ properties[name], various ];
1759 					else
1760 						properties[name] = various;
1761 
1762 					if (line.indexOf('*/') !== -1)
1763 						break;
1764 
1765 					name = m[1], various = [ m[3] ];
1766 
1767 				} else
1768 					various.push((m = line.match(/^\s+\*\s+([^\s].+)$/)) ? m[1] : line.replace(/^(.*)\/\*\*/, ''));
1769 
1770 				line = code[++i];
1771 			}
1772 
1773 			//library_namespace.log('[' + i + ']' + '\n' + tmp_code.join('\n') + '\n' + line);
1774 			if (m = line.match(/(.*?\*\/)/)) {
1775 				line = line.replace(/(.*?)\*\//, '');
1776 				while (i < l
1777 						&& !/=\s*[^\s]|{/.test(line = line.replace(
1778 								/\s*\/\/[^\n]*/g, '').replace(
1779 										/\/\*((.|\n)*?)\*\//g, '')))
1780 					line += code[++i];
1781 
1782 				//	初始化函式名
1783 				name = '';
1784 
1785 				/*
1786 				* 註解處理完了,接下來是變數。先把整個定義區放到 line。
1787 				* 這邊處理幾種定義法:
1788 				* function name() {};
1789 				* var name = function(){};
1790 				* var name = new Function();
1791 				* var name = 123;
1792 				*/
1793 				while (!/^\s*function\s$/.test(line) && !/[=;,]/.test(line))
1794 					line += ' ' + code[++i];
1795 
1796 				if (m = line.match(/^\s*function\s+([_a-zA-Z\d\$.]*)\s*\((.*)/)) {
1797 					// function name() {};
1798 					set_name(m[1]);
1799 					various = m[2];
1800 					while (i < l && various.indexOf(')') === -1)
1801 						various += code[++i];
1802 					m = various.match(/^[^)]*/);
1803 					tmp_code.push(handle_name() + '=function(' + m[0] + '){'
1804 									+ jsdoc_to_vsdoc() + '};');
1805 
1806 				} else if (m = line
1807 						.match(/^\s*(var\s+)?([_a-zA-Z\d\$.]+)\s*=\s*(.+)/)) {
1808 					set_name(m[2]);
1809 					various = m[3];
1810 					if (/^\s*function(\s+[_a-zA-Z\d\$]+)?\s*\(/.test(various)) {
1811 						// var name = function(){};
1812 						while (i < l && various.indexOf(')') === -1)
1813 							various += code[++i];
1814 						m = various.match(/^[^)]+\)/);
1815 						tmp_code.push(handle_name() + '=' + m[0] + '{' + jsdoc_to_vsdoc() + '};');
1816 
1817 					} else if (/^\s*new\s+Function\s*\(/.test(various)) {
1818 						// var name = new Function();
1819 						if (m = various.match(/^\s*new\s+Function\s*\(.+\)\s*;?\s*$/)) {
1820 							//	TODO
1821 							tmp_code.push(handle_name() + '=new Function("");');
1822 						} else
1823 							tmp_code.push(handle_name() + '=new Function();');
1824 
1825 					} else {
1826 						// var name = 123;
1827 						if (!properties.type)
1828 							if (/^['"]/.test(various)) {
1829 								properties.type = 'String';
1830 							} else if (!isNaN(various)) {
1831 								properties.type = 'number';
1832 							} else if (/^(true|false)([\s;,]|$)/.test(various)) {
1833 								properties.type = 'bool';
1834 							} else if (various.charAt(0) === '[') {
1835 								properties.type = 'array';
1836 							} else if (various.charAt(0) === '{') {
1837 								properties.type = 'object';
1838 							} else if (various.charAt(0) === '/') {
1839 								properties.type = 'regexp';
1840 							} else if (/^regexp obj(ect)?$/.test(properties.type)) {
1841 								properties.type = 'regexp';
1842 							}
1843 
1844 						//if (name === 'module_name');
1845 
1846 						switch ((properties.type || '').toLowerCase()) {
1847 							case 'string':
1848 								m = various.replace(/\s*[,;]*\s*$/, '');
1849 								//library_namespace.log('['+m+']');
1850 								if (/^'[^\\']*'$/.test(m)
1851 									|| /^"[^\\"]*"$/.test(m)) {
1852 									various = '=' + m + ';';
1853 								} else {
1854 									various = '="";	//	' + various;
1855 								}
1856 								properties.type='String';
1857 								break;
1858 
1859 							case 'bool':
1860 							case 'boolean':
1861 								if (m = various.toLowerCase().match(
1862 									/^(true|false)([\s,;]|$)/i)) {
1863 									various = '=' + m[1] + ';';
1864 								} else {
1865 									various = '=true;	//	' + various;
1866 								}
1867 								properties.type='Boolean';
1868 								break;
1869 
1870 							case 'number':
1871 								properties.type = 'Number';
1872 							case 'int':
1873 							case 'integer':
1874 								if (/int(eger)?/i.test(properties.type))
1875 									properties.type = 'Integer';
1876 
1877 								if (!isNaN(various)) {
1878 									various = '=' + various + ';';
1879 								} else {
1880 									various = '=0;	//	' + various;
1881 								}
1882 								break;
1883 
1884 							case 'array':
1885 								various = '=' + '[];';
1886 								properties.type = 'Array';
1887 								break;
1888 
1889 							case 'object':
1890 								if (various.charAt(0) === '{') {
1891 									while (i < l) {
1892 										if (various.lastIndexOf('}') !== -1) {
1893 											m = various.slice(1, various.lastIndexOf('}'));
1894 											if (m.lastIndexOf('/*') === -1
1895 												|| m.lastIndexOf('/*') < m
1896 														.lastIndexOf('*/'))
1897 												break;
1898 										}
1899 										various += '\n' + code[++i];
1900 									}
1901 									m = various
1902 										.replace(/\s*\/\/[^\n]*/g, '')
1903 										.replace(/\/\*((.|\n)*?)\*\//g, '')
1904 										.replace(/}(.*)$/,'}');
1905 									if (0 && m.length > 3)
1906 										library_namespace.log(name + '\n' + m
1907 									// + '\n'+v
1908 									);
1909 									if (/^{([\s\n]*(('[^']*'|"[^"]*"|[_a-zA-Z\d\$.]+))[\s\n]*:('[^']*'|"[^"]*"|[\s\n\d+\-*\/()\^]+|true|false|null)+|,)*}/
1910 										.test(m))
1911 										various = '=' + various.replace(/}(.*)$/, '}') + ';';
1912 									else
1913 										various = '=' + '{};';
1914 								} else
1915 									various = '=' + '{};';
1916 								properties.type = 'Object';
1917 								break;
1918 
1919 							case 'regexp':
1920 								if (/^\/.+\/$/.test(various))
1921 									various = '=' + various + ';';
1922 								else {
1923 									various = '=' + '/^regexp$/;	//	' + various;
1924 								}
1925 								properties.type = 'RegExp';
1926 								break;
1927 
1928 							default:
1929 								//	TODO: T1|T2|..
1930 								if (/^[_a-zA-Z\d\$.]/.test(various)) {
1931 									// reference
1932 									various = ';//' + (properties.type ? '[' + properties.type + ']' : '')
1933 										+ various;
1934 								} else {
1935 									// unknown code
1936 									various = ';	//	'
1937 										+ (properties.type ? '[' + properties.type + ']' : '')
1938 										+ various;
1939 								}
1940 						}
1941 
1942 						tmp_code.push((/^=/.test(various) ? '' : '//') + handle_name() + various);
1943 					}
1944 				}
1945 
1946 				if (name && !('ignore' in properties) && !('inner' in properties) && !('private' in properties)) {
1947 					if (!('property' in properties))
1948 						//	定義最後一次變數名
1949 						latest_name = name;
1950 
1951 					name = name.split(library_namespace.env.module_name_separator);
1952 
1953 					//	對可能的錯誤發出警告
1954 					if (name[0] !== library_namespace.Class && !('deprecated' in properties))
1955 						library_namespace.warn(i + ': line [' + name.join(library_namespace.env.module_name_separator) + '] NOT initial as '+library_namespace.Class+'\n'
1956 								+ code.slice(i - 6, i + 6).join('\n'));
1957 
1958 					//	將變數定義設置到 ns
1959 					var np = ns, nl = name.length - 1, n;
1960 					for (m = 0; m < nl; m++) {
1961 						n = name[m];
1962 						if (!(n in np))
1963 							// 初始設定 namespace
1964 							np[n] = {
1965 								'this': ''
1966 							};
1967 						else if (!library_namespace.is_Object(np[n]))
1968 							np[n] = {
1969 								'this': np[n]
1970 							};
1971 						np = np[n];
1972 					}
1973 
1974 					n = name[nl];
1975 					//if (n in np) library_namespace.log('get_various_from_code: get duplicate various: [' + name.join(library_namespace.env.module_name_separator) + ']');
1976 
1977 					np[n] = tmp_code.join(new_line);
1978 				}
1979 			}
1980 		}
1981 	}
1982 
1983 	return ns;
1984 };
1985 
1986 
1987 CeL.code.reorganize
1988 .
1989 /**
1990 * 把 get_various_from_code 生成的 namespace 轉成 code
1991 * @param	{Object} ns	root namespace
1992 * @param	{String} [prefix]	(TODO) prefix of root namespace
1993 * @param	{Array}	[code_array]	inner use, please don't specify this value.
1994 * @return	{String}	code
1995 * @since	2009/12/20 14:51:52
1996 * @_memberOf	_module_
1997 */
1998 get_code_from_generated_various = function (ns, prefix, code_array) {
1999 	var _s = _.get_code_from_generated_various, i, return_text = 0;
2000 
2001 	if (!code_array)
2002 		code_array = [],
2003 		return_text = 1;
2004 
2005 	//	先處理 'this'
2006 	if (prefix) {
2007 		if (!/\.prototype$/.test(prefix))
2008 			if (i = ns['this']) {
2009 				code_array.push(i);
2010 				delete ns['this'];
2011 			} else
2012 				code_array.push('',
2013 						'//	null constructor for [' + prefix + ']',
2014 						prefix + '=function(){};',
2015 						prefix + '.prototype={};');
2016 		prefix += '.';
2017 	} else
2018 		prefix = '';
2019 
2020 
2021 	for (i in ns)
2022 		if (typeof ns[i] === 'string')
2023 			code_array.push(ns[i]);
2024 		else
2025 			_s(ns[i], prefix + i, code_array);
2026 
2027 	return return_text ?
2028 			code_array.join(library_namespace.env.new_line)
2029 					//.replace(/[\r\n]+/g,library_namespace.env.new_line)
2030 			: code_array;
2031 };
2032 
2033 
2034 
2035 return (
2036 	CeL.code.reorganize
2037 );
2038 };
2039 
2040 //===================================================
2041 
2042 CeL.setup_module(module_name, code_for_including);
2043 
2044 };
2045