View difference between Paste ID: qyzsVRX8 and 3EZzrsxY
SHOW: | | - or go back to the newest paste.
1
/********************************************************************/
2-
/*  gethtmldat.js :   ver.0.73   2017/10/04                         */
2+
/*  gethtmldat.js :   ver.0.33   2015/05/17                         */
3
/********************************************************************/
4
//
5
//  Jane2ch.exeでhtmlから過去ログを取得しdat形式に変換してLogsフォルダに格納する
6-
//  htmltodat-convert2.wsf+htmltodat.exeと同じような機能を果たす
6+
//  htmltodat-convert2.wsf+htmltodat.exeと同じ機能を果たす
7
//  htmltodat-convert2.wsfとGetLog.wsfからコードを盗用してます(許して)
8
//
9-
//==============================================================
9+
//--------------------------------------------------------------------
10
//  ※ 重要 ※
11-
//  なお、このスクリプトはpastbinのサイトから download するのではなく、
11+
//  なお、このスクリプトはこのサイトから DOWNLOAD するのではなく、RAW で表示したものか又はRAW Paste Data から、
12-
//  RAW( http://pastebin.com/raw.php?i=3EZzrsxY )で表示したものか 又は
12+
//  コピー&ペースト(CTRL+A,CTRL+C,CTRL+V)で、テキストエディタに貼り付け、gethtmldat.js という名前で
13-
//  下の方にある RAW Paste Data から、コピー&ペースト(CTRL+A,CTRL+C 及び CTRL+V)で、
13+
//  Shift-JISコード(メモ帳ではANSI)で保存し、Jane2ch.exe のあるフォルダに格納してください
14-
//  テキストエディタに貼り付け、gethtmldat.js という名前でShift-JISコード(メモ帳ではANSI)
14+
//  ※重要※ DOWNLOADすると、文字コードがUTF-8となり実行できなくなるので注意してください
15-
//  で保存し、Jane2ch.exe のあるフォルダに格納してください
15+
//--------------------------------------------------------------------
16-
//  ※注意※ DOWNLOADすると、文字コードがUTF-8となり実行できません
16+
17-
//           また、行番号付きでコピー&ペーストしても実行できません
17+
18-
//==============================================================
18+
19
//    コマンド内容 - wscript "$BASEPATHgethtmldat.js" $LINK$URL
20
//  を入力して、追加、OKします
21
//       ※ なお、Jane直下フォルダでは無い場合はパスをフルパスで指定してください
22
//          jane styleの下のscriptフォルダに入れた場合は、wscript "$BASEPATHscript\gethtmldat.js" $LINK$URL
23
//
24
//  コマンド登録時のパラメタに /w 又は /w:999(待ち時間) を追加するとキー送信(CTL+W)により、スレを閉じて再度開く動作をします
25-
//          jane styleの下のscriptフォルダに入れた場合は、
25+
//          wscript "$BASEPATHgethtmldat.js" $LINK$URL /w
26-
//                   wscript "$BASEPATHscript\gethtmldat.js" $LINK$URL
26+
//    ※注意※ 当該スレが開く前にキー送信がなされると現在開いている別スレが閉じてしまいます
27
//
28
//  起動オプション: 順不同
29-
//  起動オプション: 順不同 []内は省略可
29+
//    http://~      url指定
30-
//    [+]http://~   url指定
30+
31-
//                   (先頭に+を付けるとdatにURL末尾の指定範囲のレス部分だけ上書きする /aは無効)
31+
32
//    /w[:999]       スレを指定時間待って閉じ、開き直す(数値省略時 1200ms)
33
//    /-w            スレを閉じない(デフォルト)
34
//    /a[ppend]      差分のみ取得(管理人削除などで既存のログとサーバー上のデータに違いがあっても関知しない)
35-
//                   当該スレが開く前にキー送信がなされると現在開いている別スレが閉じてしまいます
35+
//    /b[ak][1]      バックアップを取る(Logs\bak\の下に既存のdatファイルをコピーする) /b1 は1回限りで上書きしない
36-
//    /a[ppend]      差分のみ取得
36+
//    /redraw[:999]  再描画 スレを開いた後、指定時間待ってからキーコード('ALT','T','G','0')を送る (数値省略時 1200ms)
37-
//                  (管理人削除などで既存のログとサーバー上のデータに違いがあっても関知しない)
37+
38-
//    /b[ak][1]      バックアップを取る(Logs\bak\の下に既存のdatファイルをコピーする)
38+
39-
//                   /b1 にするとバックアップファイルが存在しているとコピーしない
39+
//                       SQLite3 ODBC Driver : http://www.ch-werner.de/sqliteodbc/sqliteodbc.exe をダウンロード・インストール
40-
//    /redraw[:999]  再描画 スレを開いた後、指定時間待ってからキーコード('ALT','T','G','0')を送る
40+
//                                             (インストールは上記exeを実行し、Next,I Agree,Next,Install,Finishボタンで進める)
41-
//                   (数値省略時 1200ms)
41+
//                       sqlite3.exe         : http://www.sqlite.org/download.html から、sqlite-shell-win32-x86-3080900.zip 
42
//                                             をダウンロード・解凍し、本スクリプトと同じフォルダに格納する
43
//    /log[:][path]  トレースログを指定のファイルに追加書き込みします(ファイルパス名省略時は %temp%\gethtmldat.log)
44-
//                       SQLite3 ODBC Driver : http://www.ch-werner.de/sqliteodbc/sqliteodbc.exe
44+
45-
//                                             をインストール(exeを実行し、デフォルトなりで進める)
45+
46-
//                       sqlite3.exe         : http://www.sqlite.org/download.html から、
46+
//    Jane Styleで、過去ログを開いた(空白の)レス表示欄で、
47-
//                                             sqlite-shell-win32-x86-3080900.zip をダウンロード・
47+
//    又は、別スレに書かれているリンクを、
48-
//                                             解凍し、本スクリプトと同じフォルダに格納する
48+
//    又は、書き込みウィンドウ、メモ欄にURLを書き込みプレビューで現れるリンクを、
49-
//    "/log[:path]"  トレースログを指定のファイルに追加書き込みします
49+
//    右クリックして上で登録したコマンドを選択する
50-
//                   (ファイルパス名省略時は %temp%\スクリプト名.log)
50+
//    レスが表示・認識されない場合は、再描画、スレを閉じリンククリックで開き直す、>>1などのリンクをクリックなどしてください
51-
//    /keep_kako     渡された過去ログURLをそのまま処理する(したらば、next2ch、machi以外で有効)
51+
//--------------------------------------------------------------------------------
52-
//    /proxy:server:port PROXYサーバー経由でアクセスする場合に指定する
52+
53-
//    /cfg[:path]    カスタマイズ用定義ファイルの読み込み(path省略はスクリプトフォルダ\スクリプト名.cfg)
53+
54-
//                   内容は、JScriptの文法で記述する
54+
55
	@set @EnabledTest2chJSON = false; // =true で2chで最初にJSONでの取得を試みる(お遊び機能:仕様等一切不明、過去ログは無理)
56
@*/
57-
//    以下のa)~c)のいずれかで右クリックして上記登録したコマンドを選択する
57+
58-
//      a) Jane Styleで、過去ログを開いたレス表示欄
58+
59-
//         (2chでサーバーの移転があった場合は板一覧にある最新の移転先URLが受け渡されるので注意)
59+
//  "If-Modified-Since" : "Thu, 01 Jun 1970 00:00:00 GMT"
60-
//      b) 別スレに書かれているリンク
60+
//  ,"Content-Type" : "application/x-www-form-urlencoded"
61-
//      c) 書き込みウィンドウ、メモ欄にURLを書き込みプレビューで現れるリンク
61+
//  ,"User-Agent" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;)"
62
};
63-
//  TIPS :
63+
var HTTP_TIMEOUT = 10 * 1000;
64-
//    ●★「過去ログ」と表示されている場合は、メニュー(スレッド)から「強制過去ログ化」のチェック
64+
65-
//      (又はスレッドツールバーのゴミ箱アイコンをクリックして「強制過去ログ化」)
65+
var JBBS_ABN_STR = "透明あぼーん<><> <><>";
66-
//      を外すか又は、一旦ログを削除後にリンクから再取得してください
66+
67-
//    ●レスが表示されない場合は、スレッドツールバーの「表示レス数/スレの再描画」アイコンを
67+
68-
//      右クリックしてください
68+
69-
//    ●レス内容が「スレの再描画」でも変わらない場合は、
69+
70-
//        (「お気に入り」を「更新チェック」後に、その中のスレを本スクリプトで取得した場合などが相当)
70+
71-
//      スレ一覧画面の「お気に入りグループ名」タブを閉じてから「スレの再描画」をしてみてください
71+
var http; try { http = new ActiveXObject("Msxml2.ServerXMLHTTP.6.0"); } catch(e){}
72-
//      また「検索結果」「ログ一覧」「最近読込」「最近書込」「OpenThreads」の場合も同様です
72+
		  if (!http) try { http = new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e){}
73-
//    ●未読状態が既読状態にならない場合やレス番リンクのポップアップが表示されなかったり
73+
		  if (!http) { http  = new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
74-
//      ID抽出回数が0回になる場合は
74+
75-
//      1)ステータスが過去ログ以外の時、所属する板を開いてスレ一覧更新をして、
75+
76-
//        又は、スレを開きなおして、最新レス末尾までスクロールさせる
76+
77-
//      2)過去ログの場合、上記「強制過去ログ化」のチェックを外した後、
77+
shell.CurrentDirectory = JANE_PATH;
78-
//        又は、>>999 などの未読状態のレスを指すリンクをクリックする
78+
79-
//        又は、名前欄1001をクリックする
79+
80-
//        又はアドレスバーに「スレURL/999」のようなレス番付きで入力する
80+
81-
//        「最後までスクロールしたスレを既読にする」「再描画する」の場合は、末尾までスクロールさせる
81+
82-
//      ★なお、新着チェックができる(ボタンが押せる)のなら新着チェックでよい
82+
83-
//    ●2ch.netでftp://問題により520エラー又はデータが途切れてしまう場合の部分的な救済方法
83+
84-
//        webブラウザで問題となるレス番をtrial and errorで目星をつけて、それを避けるように
84+
85-
//        範囲指定してデータを取得する
85+
86-
//        例えば、レス番50が引っ掛かっている場合は、-49 と 51- の2回に分けて取得する
86+
87-
//        コマンド登録時には、+$LINK$URLとし、URL末尾に範囲指定付きのリンクから使うか
87+
//--------------------------------------------------------------------------------
88-
//        /f も追加して、実行時にURL末尾にレス番範囲を追加で入力する
88+
89
String.prototype.convDontUseStr = function() {
90-
//  修正履歴:
90+
91-
//    http://pastebin.com/my14uCkr を参照
91+
92-
//==============================================================
92+
	var s = this;
93
	for(var i in tbl0) { s=s.replace( new RegExp("^"+i+"$","i") , tbl0[i]); }
94
	return s.replace(/[\\/:*?]/g, function (w){return tbl1[w];});
95
}
96-
// 以下をtrueにすると2chで最初にJSONでの取得を試みる(お遊び機能:仕様等一切不明)
96+
function Err(s,t) { s=ErrMsg(s,t); trace("---- "+s+" ----",2); throw new Error(s); }
97-
	@set @EnabledTest2chJSON = false;
97+
98-
//漢字コード変換にbasp21.dllを使う
98+
99-
// http://www.hi-ho.ne.jp/babaq/basp21.htmlのBASP21-2003-0211.exeのインストールが必要
99+
100-
	@set @EnabledBASP21 = false;
100+
101
102
var ERROR_MSG = {
103
	 "E_already_there" : "このスレは既に取得しています"
104-
  "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
104+
105
	,"E_remained_garbage" : "レスデータのみの抽出に失敗しました"
106-
var HTTP_TIMEOUT = 120 * 1000;
106+
107
	,"E_title_not_found" : "スレタイトルが見つかりません"
108-
var ABN_MSG = "透明あぼ~ん<>透明あぼ~ん<>透明あぼ~ん ID:DELETED<>透明あぼ~ん<>透明あぼ~ん";
108+
109-
var ABN_MSG_PINK = "うふ~ん<>うふ~ん<>うふ~ん ID:DELETED<>うふ~ん<>うふ~ん";
109+
110-
var NOT_GET_MSG = "未取得<>未取得<>未取得 ID:NONE<>未取得<>";
110+
	,"E_stop" : "処理を中止しました"
111
	,"E_no_data" : "取得データはありません"
112
	,"E_http_timeout" : "受信タイムアウト"
113
	,"E_http_recieve" : "http受信エラー"
114
	,"E_bbs_not_found" : "掲示板番号が不正です"
115
	,"E_key_not_found" :"スレッド番号が不正です"
116-
var http;
116+
117-
var USED_WINHTTP = true;
117+
118-
try { http = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); } catch(e){}
118+
	,"E_unmatched_res_count" : "抽出したレス数が合いません"
119-
if (!http) try { http = new ActiveXObject("Msxml2.ServerXMLHTTP.6.0"); } catch(e){}
119+
120-
if (!http) try { http = new ActiveXObject("Msxml2.ServerXMLHTTP.3.0"); } catch(e){}
120+
121-
if (!http) var USED_WINHTTP = false;
121+
122-
if (!http) try { http = new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e){}
122+
123-
if (!http) { http  = new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
123+
124-
var basp; /*@if (@EnabledBASP21) try { basp = new ActiveXObject("basp21"); } catch(e){} @end @*/
124+
125
	f.prototype = o;
126
	n = new f;
127
	for (i=1, len=arguments.length; i<len; ++i) for (prop in arguments[i]) n[prop] = arguments[i][prop];
128-
//shell.CurrentDirectory = JANE_PATH;
128+
129
}
130
object.f = function(){};
131
//--- http://with-love-from-siberia.blogspot.jp/2009/12/msgbox-inputbox-in-jscript.html -----------
132
var vb = {};
133
vb.Function = function(func) { return function() { return vb.Function.eval.call(this, func, arguments); }; };
134
vb.Function.eval = function(func) {
135
	var args = Array.prototype.slice.call(arguments[1]);
136
	for (var i = 0; i < args.length; i++) {
137
		if ( typeof args[i] != 'string' ) { continue; }
138-
//カスタマイズ用定義ファイル指定(この指定より引数/cfg:での指定の方が優先される)
138+
139-
var CFG_FILE = SCRIPT_PATH + MY_NAME + ".cfg";
139+
140
	var vbe;
141-
//欠落しているレス番をあぼーんメッセージで補う(2ch互換BBSのみ)
141+
142-
//   +URL指定時は無効で元のレスのままかあるいは未取得メッセージで穴埋めされる
142+
143-
var FILL_ABONE = 0; //0:問い合わせる 1:常に穴埋めする 2:常に詰める
143+
144-
//既存のdatファイルよりレス数が大きくない場合にdatファイルを上書きするかどうか(差分/aの場合は無効)
144+
145-
var REWRITE_DAT = 0; //0:問い合わせる 1:上書きする 2:一致の場合は中止する 3:常に中止する
145+
146
var MsgBox = vb.Function('MsgBox');
147-
//BEアイコン以外の<img>タグ(現状はお絵かきのみ)を変換するときのスキームを指定する ("http" or "sssp")
147+
//--------------------------------------------------------------------------------
148-
var IMG_TO = "sssp:";
148+
149
var args = parmParse(WScript.Arguments);
150-
//bakusai用
150+
151-
var OPT_BBS = {
151+
var WMI = (function () {
152-
	"//bakusai.com": [thread_bakusai, "【仮想板:爆サイ】", /\/\/(bakusai\.com[^\/]*)/ ]
152+
153
	var services = locator.ConnectServer(null, "root\\CIMV2");
154-
var MAX_READ_PAGES_OF_THREAD_LIST_CREATE = 3; //subject.txt作成時
154+
155-
var MAX_READ_PAGES_OF_THREAD_LIST_UPDATE = 1; //subject.txt更新時
155+
156-
var BROWSER_PATH = "";
156+
157
				var query = "SELECT * FROM Win32_Process WHERE name='"+pName+"'";
158-
//==============================================================
158+
159
				for (var i=0, status=false; i<props.length; i++) { if(props[i].ExecutablePath == pPath) {status = true;} }
160
				return status;
161
			}
162
		,wmiProps :
163
			function (query) {
164
				var result = [];
165
				try {
166-
	var s = this.replace(/[. ]+$/,"");
166+
167
					var e = new Enumerator(set);
168
					while (!e.atEnd()) { result.push(e.item()); e.moveNext(); }
169
				} catch (e) { throw e; }
170-
var trace = function(){};
170+
171-
function Err(s,t) {s=ErrMsg(s,t); trace("---- "+s+" ----",2); throw new Error(s);}
171+
172
		 ,getProcessID :
173
			function (pName, pPath) {
174-
var ERROR_MSG_STOP = "処理を中止しました";
174+
175
				do {
176
					var props = this.wmiProps(query);
177
					for (var i=0,c=0,pid; i<props.length; i++) {
178
						if (props[i].ExecutablePath == pPath) { c++; pid=props[i].ProcessID; }
179
					}
180
				} while (c>1);
181
				return pid;
182
			}
183-
	,"E_stop" : ERROR_MSG_STOP
183+
184
})();
185
186
var URL_2ch = {
187
  RE_SITE : new RegExp("^http://\\w+\\.(?:2ch\\.net|bbspink\\.com|2ch\\.sc)/")	//この定義は未使用
188
 ,RE_URL  : new RegExp("^http://((\\w+)(\\.(\\w+).+?))/(?:test/.+?/)?(\\w+)/(?:kako/.+?/)?(((\\d+)\\d)\\d{5})(/|\\.html|\\.dat(?:\\.gz)?)?")
189
 ,setInfo : function(url) {
190
				this.kako = /\/kako\//.test(url);
191
				this.prm  = url.match(this.RE_URL) || Err("E_illegal_url");
192
				this.url  = this.prm[0];
193-
	,"E_not_suported_proxy" : "PROXY指定はできません(IEの設定が使われます)"
193+
194-
	,"E_data_error" : "レスデータの抽出で異常を検出しました"
194+
				if (!this.kako) { this.url2 += (args.opt_n) ? args.opt_n : (url.match(/\/n?(\d+)[^\/]*$/)||[])[1]||"";}
195-
	,"E_data_not_found" : "データがみつかりません"
195+
				else	{ delete args.append; }
196-
	,"E_no_support" : "この機能はサポートしません"
196+
				this.site     = this.prm[1];
197
				this.category = "";
198
				this.brdID    = this.prm[5];
199
				this.thrID    = this.prm[6];
200
			}
201
}
202
var URL_jbbs = {
203
  RE_SITE : new RegExp("^http://jbbs\\.(?:shitaraba|livedoor)\\.(?:net|jp|com)/")
204
 ,RE_URL  : new RegExp("^http://(jbbs\\.shitaraba\\.net)/bbs/\\w+\\.cgi/(\\w+)/(\\d+)/(\\d+)/?")
205
 ,setInfo : function(url) {
206
				// this.kako = /\/(storage|read_archive\.cgi)\//.test(url);
207
				this.prm  = url.match(this.RE_URL) || Err("E_illegal_url");
208
				this.url  = this.prm[0];
209
				this.url2 = this.prm[0] + (args.opt_n || (url.match(/\/n?(\d+)[^\/]*$/)||[])[1]||"");
210
				this.site     = this.prm[1];
211
				this.category = this.prm[2];
212
				this.brdID    = this.prm[3];
213
				this.thrID    = this.prm[4];
214
			}
215
}
216
var URL = URL_2ch;
217
218
var Jane_2ch = {
219
 ini          : loadFile(JANE_INI)
220
 ,brd         : ""
221
 ,LogBasePath : ""
222
 ,init        : function() { this._setLogBasePath(); this._loadBRD(); }
223
 ,getINI      : function(p) { var m=this._search(this.ini, this._re_ini, p); return m && m[1] || p[3]; }
224-
//==============================================================
224+
225
					var m = this._search(this.brd, this._re_brd, p);
226
					return (m) ? m[1].convDontUseStr()+"\\"+m[2].convDontUseStr()+"\\" : null;
227
				}
228
 ,_re_ini     : "^\\[$1\\]\\r\\n(?:.*\\r\\n)*?(?:$2=(.*)|\\[.*\\])\\r\\n"
229-
  RE_HOST : new RegExp("^http://\\w+\\.(?:[25]ch\\.net|bbspink\\.com)/")	//この定義はdat取得できないサイトの判別に使う
229+
 ,_re_brd     : "^(\\S+).*\\r\\n(?:\\t.*\\r\\n)*?\\t\\w+$3\\t$5\\t(\\S+)\\r\\n"
230-
 ,RE_URL  : new RegExp("^http://((\\w+(?=\\.\\w+\\.))?(\\.?(\\w+)[^\\/]+?))/(?:(?:test|bbs)/.+?/)?(\\w+)/(?:kako/.+?/)?(((\\d+)\\d)\\d{5})(/|\\.html|\\.dat(?:\\.gz)?)?")
230+
 ,_search     : function(f,s,p) { var re,x,y; re=new RegExp(this._expand(s,p),"img"); while(x=re.exec(f)) {y=x;} return y; }
231-
 ,range   : ""
231+
232-
 ,set_prm : function(url) { this._set_prm(url, 1, null, 5, 6); this.kako = /\/kako\//.test(url) && delete args.append; }
232+
 ,_setLogBasePath : function() { this.LogBasePath = this.getINI([,"PATH","LogBasePath",""]); }
233-
 ,otherURLType : 0
233+
 ,_loadBRD     : function() { this.brd = loadFile(this.LogBasePath + JANE_BRD); }
234-
 ,otherURL : ""
234+
235-
 ,_set_prm: function(url,p1,p2,p3,p4) {
235+
236-
 				var r;
236+
  _re_brd : "^(\\S+).*\\r\\n(?:\\t.*\\r\\n)*?\\t$1/$2\\t$3\\t(\\S+)\\r\\n"
237
});
238-
				if(/\d$/.test(this.prm[0])) this.prm[0] += "/";
238+
239
Jane.init();
240
241-
				switch(this.otherURLType) {
241+
242-
					case 1: this.url = this.otherURL+this.url; break;
242+
243-
					case 2: this.url = this.otherURL; break;
243+
244-
					default: break;
244+
245
				this.dat = dat;
246-
				this._setRange(url);
246+
247-
				this.site     = this.prm[p1];
247+
248-
				this.category = (p2) ? this.prm[p2] : "";
248+
249-
				this.brdID    = this.prm[p3];
249+
					var s = loadFile2(dat);
250-
				this.thrID    = this.prm[p4];
250+
					this.cnt  = s.replace(/^.*$/mg,"").length;
251
					this.title = (s.match(/<>((?:(?!<>).)*)$/m)||[])[1];
252-
 ,_setRange :	function(url) {
252+
253-
					var range;
253+
254-
					if(this.prm[0].slice(-1)=="/") {
254+
255-
						range = url.match(/\/n?((\d*)n?(-?)[^\/]*)$/)||[];
255+
256-
						this.url2 += (args.opt_n||range[2]||"");
256+
257-
						if(range[3]) this.range = ((range[2]?"":"1")+range[1]||"").replace(/n/ig,"");
257+
258-
						else if(range[2]) this.range = range[2] + "-" + range[2];
258+
259
				}
260-
 				}
260+
261-
 ,appendRange : function(top) {
261+
262-
					if (args.overwrite) this.url += this.range;
262+
263-
					else                this.url += ((args.append && top) ? top+"-n" : "");
263+
264
				  }
265-
 ,getUrl2 : function() { return this.url2; }
265+
266-
 ,entryCheck : function(url) {
266+
267-
 				var r,i;
267+
var Trace = function() {
268-
 				
268+
269-
 				var ptn=[
269+
270-
 				  [ /^https?((?::\/\/www\.google\.co\.jp\/url\?q=https?)?:\/\/webcache\.googleusercontent\.com\/search(?:\?q=|%3Fq%3D)cache:.+?:.*https?:\/\/([^+&%]+).*=(?:(?!http).)+)/ , 1]
270+
271-
 				  ,[ /^https?(:\/\/webcache\.googleusercontent\.com\/search\?q=cache:.+?:([^+&%]+).*=(?:(?!http).)+)/ ,2 ]
271+
272-
 				  ,[ /^https?(:\/\/cache\.yahoofs\.jp\/search\/cache\?.*&u=([^&]+)(?:&.*=(?:(?!http).)+)?)/ ,2 ]
272+
273-
 				  ,[ /http:(\/\/(bakusai\.com(?:\.[^\/]+)?\/thr_(?:res|tl)\/acode=\d+\/ctgid=\d+(?:\/test\/read\.cgi)?(?:\/(?:\w+=)?[\d-]+)+\/))/ , 3 ]
273+
274-
 				];
274+
	var env = new ENV();
275-
 				
275+
276-
				for(i=0;i<ptn.length;i++) {
276+
		var f = fso.CreateTextFile(logfile);
277-
 					r = url.match(ptn[i][0]);
277+
		f.WriteLine("["+MY_NAME+"]");
278-
 					if(r) {
278+
		f.WriteLine("Jane Type = "+chkJaneProg()+"\t"+fso.GetFileVersion(JANE_PATH+JANE_EXE));
279-
 						this.otherURLType=ptn[i][1];
279+
		f.WriteLine("current path = "+JANE_PATH);
280-
						switch(this.otherURLType) {
280+
		f.WriteLine("Logs path = "+Jane.LogBasePath+JANE_LOGS);
281-
							case 1: this.otherURL = r[1]; return "http"+r[2];
281+
		f.WriteLine("script path = "+SCRIPT_PATH);
282-
							case 2: this.otherURL = "http"+r[1]; return "http://"+r[2].replace(/%2F/ig,"/");
282+
		f.WriteLine("UAC = "+env.UAC);
283-
							case 3: this.otherURL = r[0]; return "http://"+r[2];
283+
		f.WriteLine("64bit? = "+env.PROCESSOR_ARCHITECTURE+"\t"+env.PROCESSOR_ARCHITEW6432);
284
		f.WriteLine("----------------------------------------------------------------------");
285-
 					}
285+
		f.Close();
286-
 				}
286+
	} catch(e) {flag=false; if(f) f.Close();}
287-
 				return url.replace(/^https?(:.+?)(?:http.+)?$/,"http$1");
287+
	env = null;
288-
 			}
288+
289-
 ,isOPT_BBS : function(url) {
289+
290-
 				var i,r;
290+
291-
 				for(i in OPT_BBS) { if(url.indexOf(i)>0) r=i; }
291+
292-
				this.optItem = r;
292+
293-
 				return r;
293+
294-
 			}
294+
295
			if(!s) { t[n] = new Date();}
296-
var URL_jbbs = object(URL_2ch,{
296+
297-
  RE_HOST : new RegExp("^http://jbbs\\.(?:shitaraba|livedoor)\\.(?:net|jp|com)/")
297+
298
		} catch(e) {if(f) f.Close();}
299-
 ,set_prm : function(url) { this._set_prm(url,1,2,3,4); }
299+
300
}
301-
var URL_machi = object(URL_2ch,{
301+
302-
  RE_HOST : new RegExp("^http://(?:\\w+\\.)?machi\\.to/")
302+
303-
 ,RE_URL  : new RegExp("^http://((?:\\w+\\.)?machi\\.to)/bbs/\\w+\\.cgi/2/(\\w+)/(\\d+)/?")
303+
304-
 ,set_prm : function(url) { this._set_prm(url,1,null,2,3); }
304+
305-
 ,getUrl2 : function() { return this.url2.replace(/\/offlaw\.cgi\/2\//,"/read.cgi/"); }
305+
306
			, "/"  , ("0"+d.getDate()).slice(-2)
307
			, "("  , "日月火水木金土".substr(d.getDay(),1)
308
			, ") " , ("0"+d.getHours()).slice(-2)
309
			, ":"  , ("0"+d.getMinutes()).slice(-2)
310-
 ini          : loadFile2(JANE_INI)
310+
311
			, "."  , ("00"+parseInt(d.getMilliseconds(),10)+" ").slice(-4,n-4)
312
		  ].join("");
313
}
314-
 ,getINI      : function(p) { var m=this._search(this.ini, this._re_ini, p); return m && RegExp.$1 || p[3]; }
314+
315
	return ("        "+d).slice(-n);
316-
					var m = this._search(this.brd
316+
317-
					                     , (/\.[25]ch\.net/.test(p[3]))?this._re_brd2:this._re_brd
317+
318-
					                     , p);
318+
319-
					var b1=RegExp.$1, b2=RegExp.$4;
319+
320-
					var host2=RegExp.$3, host1=RegExp.$2;
320+
321-
					return (m) ? [b1.convDontUseStr()+"\\"+b2.convDontUseStr()+"\\",host1,host2] : null;
321+
322
	 return this;
323
}
324-
 ,_re_brd     : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*\\t(\\w*)($3)\\t$5\\t([^\\t\\r\\n]+?) *\\r\\n"
324+
if (args.trace !== void 0) { trace = new Trace(); } else { trace = function(){}; }
325-
 ,_re_brd2    : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*\\t(\\w+)\\.([25]ch\\.net)\\t$5\\t([^\\t\\r\\n]+?) *\\r\\n"
325+
326-
 ,_search     : function(f,s,p) { return f.match(new RegExp(this._expand(s,p),"img")); }
326+
//--------------------------------------------------------------------------------
327
328-
 ,_setLogBasePath : function() { this.LogBasePath = this.getINI([,"PATH","LogBasePath",""]).replace(/[^\\]$/,"$&\\");}
328+
329-
 ,_loadBRD     : function() { this.brd = loadFile2(this.LogBasePath + JANE_BRD); }
329+
  re_thr      : /^[\s\S]*?<dl[^>]*>\s*(?:<font[^>]*>.*<\/font>.*\s*)?((?:<dt>.+?<dd>.+\n?)+)(\s*<\/dl>)?/i
330
 ,re_msg      : /<dt.*?>([0-9]+).+?(?:"mailto:(.+?)">)?<b[^>]*>(.*?)<\/b>(?:<\/font>|<\/a>)?(?: ?投稿日)? ?:(.*?)<dd>(.*?)(?:<br>)*(?=<dt.*?>|$)/img
331
 ,msg         : ""
332-
  _re_brd : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*?\\t(($1/$2))\\t$3\\t([^\\t\\r\\n]+?) *\\r\\n"
332+
 ,isExistAbn  : false
333
 ,init        : function() {}
334-
var Jane_machi = object(Jane_2ch,{
334+
335-
  _re_brd : "^([ \\S]+).*\\r\\n(?:\\t.*\\r\\n)*?\\t(($1))\\t$2\\t([^\\t\\r\\n]+?) *\\r\\n"
335+
336
 ,mainReplace : function() { this.msg = this.msg.replace(this.re_msg, "$3<>$2<>$4<>$5<>"); }
337
 ,postReplace : function() {}
338
 ,createBrdFolder : function() { return null;}
339
 ,urlAppendFirstNum : function(u) { return u + ((args.append && DatInfo.cnt) ? DatInfo.cnt + "n-" : ""); }
340
 ,getTBlock   : function() { this.msg = (this.msg.match(this.re_thr,"$1")||[])[1]; }
341-
if (args.trace !== void 0) { trace = new Trace(); }
341+
 ,getTitle    : function(s) { this.title = (s.match(/<title>(.*?)<\/title>/i)||[])[1]; }
342-
trace("--- start ---   "+args.url,1);trace("",1)
342+
 ,readHTTP    : function(url) { this.msg = readHTTP(url); this.getTitle(this.msg); this.getTBlock(); return true; }
343
 ,getFirst    : function() { return parseInt((this.msg.match(/^<dt[^>]*>(\d+)/i)||[])[1],10); }
344-
//----------------------
344+
 ,getLast     : function() { return parseInt((this.msg.match(/<dt[^>]*>(\d+).*<dd>.*\n$/i)||[])[1],10); }
345
 ,delContents : function(s) { return s.replace(/^(?:(?:(?!<>).)*<>){4}.*$/mg, ""); }
346
 ,checkData   : function(s) {
347
					var ln = this.checkData0(s);
348-
 ,offset   : 0
348+
					if (this.last-this.first+1 != ln.length)
349
						{Err("E_unmatched_res_count"," 先頭=$1 末尾=$2 レス数=$3".expand([,this.first,this.last,ln.length]));}
350-
 ,msg      : (args.overwrite) ? [] : ""
350+
351
 ,checkData0  : function(s) {
352
					var ln = this.delContents(s);
353
					if (ln.replace(/\n/g,"").length > 0) Err("E_remained_garbage");
354
					return ln;
355
				}
356-
					trace();
356+
357-
					var msg = loadFile(dat);
357+
358-
					this.cnt  = msg.split("\n").length-1;
358+
					if ((this.msg.match(/^<dt[^>]*>(\d+)/i)||[])[1] == DatInfo.cnt) { this.msg = this.msg.replace(/^.*\n/m, ""); }
359-
					this.title = (msg.match(/^(?:(?:(?:(?!<>).)*)<>|(?:[^,]*),){4}(.*)$/m)||[])[1];
359+
360-
					if (args.overwrite) { this.msg = msg.slice(0,-1).split("\n"); }
360+
 ,delBeforeFirstData : function() {}
361-
					else this.msg="";
361+
 ,insertAbn   : function() {}
362-
					trace("load file "+dat.replace(/^.*\\(\d+\.dat)/,"$1")+" : "+this.title+" lines="+this.cnt);
362+
363
					trace("--- start ---   "+args.url,1);trace("",1)
364
					this.init();
365
					URL.setInfo(this.urlReplace(args.url));
366
					var brd = Jane.getBRD(URL.prm);
367
					if (!brd) brd = this.createBrdFolder();
368
					if (!brd) Err("E_brditem_not_found");
369
					var dat = Jane.LogBasePath + JANE_LOGS + brd + URL.thrID + ".dat";
370
					var bak = Jane.LogBasePath + JANE_BAK + brd + URL.thrID + ".dat";
371
					DatInfo.setInfo(dat, bak, brd);
372
					URL.url = this.urlAppendFirstNum(URL.url);
373
					if (trace()|this.readHTTP(URL.url)|trace("HTTP total read time")) {
374
						if (!this.msg) Err("E_block_not_found");
375
						if (!this.title) Err("E_title_not_found");
376-
 ,update :	function(msgs) {
376+
						this.preReplace();
377-
				this.msg = msgs;
377+
378-
				this.cnt = this.msg.length;
378+
379
							if(this.msg=="") Err("E_already_there");
380
						}
381
						this.first = this.getFirst();
382-
//================================================================================
382+
383
						trace(); this.mainReplace(); trace("html->dat main replace time");
384
						this.checkData(this.msg);
385
						if (this.first==1) { this.addTitle(); }
386-
  re_sel      : -1
386+
						if(this.isExistAbn) { trace(); this.insertAbn(); trace("透明abnレス挿入"); }
387-
 ,REG_PATTERN : [ {} ]
387+
						this.postReplace();
388
					}
389-
 ,bin         : null
389+
					trace("スレタイトル:"+this.title+"\tレス数:"+this.last+"\tサイズ:"+this.msg.length,9);
390-
 ,resNo       : []
390+
					saveDat(dat, this.msg);
391-
 ,resNo_offset : 0
391+
392-
 ,requireFillAbn  : false
392+
393-
 ,prepare     : function() {}
393+
					invokeJaneStyle(URL.url2);
394
					trace("---- end ----",1);
395
				}
396-
 ,mainReplace : function() { this.msg = this.msg.replace(this.REG_PATTERN[this.re_sel].msg, this.REG_PATTERN[this.re_sel].rep); }
396+
397
398
var Thread_2ch = object(Thread,{
399-
 ,testTBlock : function() {
399+
  preReplace  : function() { this.msg = this.msg.replace(/(<a href=)"\/cdn-cgi\/l\/(email-protection\#.*?">)/ig,'$1"mailto:$2'); }
400-
				 var i,rc,ss;
400+
 ,postReplace : function() {
401-
				 for(i=0; i<this.REG_PATTERN.length; i++) {
401+
					this.msg = this.msg.replace(/<a href="http.*?>(.*?)<\/a>/ig, "$1")
402-
					if(ss=this.msg.match(this.REG_PATTERN[i].thr)) {this.re_sel =i; break;}
402+
								.replace(/<a href="javascript:be\((\d+?)\)[^>]*>\?(.*?)<\/a>/ig, "BE:$1-$2")
403-
				 }
403+
								.replace(/<img src="http:\/\/(img\.2ch\.net\/.+?)">/ig, "sssp://$1");
404-
				 rc = ss ? true : false;
404+
405-
				 return rc;
405+
406-
 			   }
406+
407-
 ,setTBlock : function() {
407+
408-
				var s;
408+
409-
				if(this.re_sel>=0) {
409+
410-
					s=this.msg.match(this.REG_PATTERN[this.re_sel].thr);
410+
411-
					if(s) { this.msg=s[1]||""; s=s[2]; }
411+
412
		return url;
413-
				return s;
413+
414-
			  }
414+
415-
 ,getTitle    : function(s) { this.title = (s.match(/<title>(.*?)\n*<\/title>/i)||[])[1]; }
415+
416-
 ,readHTTP    : function(url) {
416+
		/*@if (@EnabledTest2chJSON)
417-
	trace("try URL="+url,9);
417+
			o("1st try json");
418-
	this.msg = readHTTP(url)[0];
418+
			this.msg = get2chJSON();
419-
	this.testTBlock(); //re_selの設定
419+
			if(this.msg=="") Err("E_already_there");
420-
	this.preReplace();
420+
			if(this.msg) return false;
421-
	this.getTitle(this.msg);
421+
			o("2nd try html");
422-
	if (this.re_sel<0) Err("E_block_not_found","\n\nTITLE="+this.title+"\n文字数="+this.msg.length);
422+
		@end @*/
423-
	this.setTBlock();
423+
		this.kakoUrl = this._getKakoUrl();
424-
	return true;
424+
		if(URL.kako) if(!this.readHTTP2(this.kakoUrl)) return false;
425-
  }
425+
426-
 ,getFirst    : function() { return (args.overwrite) ? parseInt(URL.range,10) : (args.append) ? DatInfo.cnt + 1 : 1; }
426+
		this.msg = readHTTP(url);
427-
 ,getLast     : function() { return parseInt((this.msg.match(/(?:^|\n)(\d+).+\n$/i)||[])[1],10)-this.resNo_offset; }
427+
		var ss = this.msg.match(this.re_thr,"$1");
428-
 ,delContents : function(s) { return s.replace(/^(?:(?:(?!<>).)*<>|(?:[^,]*,)){4}.*$/mg, ""); }
428+
429
			var u = this.kakoUrl.replace(/\.dat\.gz$/,".html");
430
			if (u!=url) {
431-
					if(FILL_ABONE==2) return;
431+
				switch(this.readHTTP3(u)) {
432-
					var resTbl=this.msg.match(/^(\d+)/mg)||[];
432+
					case 0: return false;
433-
					for(var i=1; i<resTbl.length; i++) {
433+
					case 1: url=u;  ss=this.msg.match(this.re_thr,"$1"); break;
434-
						if(args.overwrite && i==1
434+
					default: break // case -1
435-
							&& parseInt(resTbl[1],10)==this.first && parseInt(resTbl[0],10)==1) continue;
435+
436-
						if(parseInt(resTbl[i],10)!=parseInt(resTbl[i-1],10)+1) {
436+
437-
							this.requireFillAbn = true;
437+
438-
							break;
438+
439
		if(!ss) {
440
			ss = "<URL>="+url+"\n<TITLE>="+this.title+"\n<メッセージ長>="+this.msg.length+"\n\n";
441-
					if (FILL_ABONE==0 && this.requireFillAbn) {
441+
442-
						switch(shell.Popup("抽出したレス数が合いません。"
442+
443-
											+"(先頭="+this.first+" 末尾="+this.last+" レス数="+ln.length+")"
443+
444-
											+"\n抜けているレス番を穴埋めしますか? [はい] [いいえ]"
444+
					|| "不明";
445-
											+"\n又は、ここで処理を中断するなら [キャンセル]"
445+
446-
											+"\nを選択してください。", 0, MY_NAME, 3+48)) {
446+
447-
							case 6: this.requireFillAbn = true; break;
447+
		if (!ss[2]) {
448-
							case 7: this.requireFillAbn = false; break;
448+
			if (MsgBox("途中でデータが途切れているようですが続行しますか?",4+48,MY_NAME)!=6) Err("E_stop");
449-
							default: Err("E_stop"); //case 2
449+
450
		var s = ss[1] || "";
451
		if (s.substr(s.length-1)!="\n") s += "\n";
452
		this.msg = s;
453
		return true;
454
	}
455
 ,readHTTP2 :
456
	function(url) {
457
		var re = /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(.*)\s*$/m;
458
		trace("try URL="+url,9);
459
		var s = readHTTP(url); //9999999999.dat.gz
460-
					if ((this.msg.match(/^(\d+)/i)||[])[1] == DatInfo.cnt) { this.msg = this.msg.replace(/^.*\n/m, ""); }
460+
		var r = s.match(re);
461
		if(!r) {url=url.replace(/\.gz$/,""); trace("try URL="+url,9); s=readHTTP(url); r=s.match(re); }
462-
 ,fillAbn     : function() {
462+
463-
					// 透明あぼーんレスを挿入する
463+
			this.msg = s;
464-
					var d = [], n = this.first, m;
464+
			this.last = this.checkData0(s).replace(/^.*$/m,"").length;
465-
					var s = this.msg.split("\n");
465+
466-
					for (var i=0; i<s.length; i++) {
466+
467-
						m = parseInt(s[i].replace(/^(\d+).+$/, "$1"),10);
467+
468-
						if(n>m) continue; //レス番重複または逆転時はスキップ
468+
469-
						for (var j=n; j<m; j++) {
469+
470-
							d.push(j+"<>"+(/\.bbspink\.com$/.test(URL.site)?ABN_MSG_PINK:ABN_MSG));
470+
471-
							n++;
471+
472
 ,readHTTP3 :
473-
						d.push(s[i]); n++;
473+
474
		var title=((this.msg.match(/<title>(.*)<\/title>/im)||[])[1]||"");
475-
					this.msg = d.join("\n");
475+
476
		if (/error/i.test(title)) {
477-
 ,delResNo    : function() { this.msg = this.msg.replace(/^\d+<>/mg, ""); }
477+
			if(!this.readHTTP2(this.kakoUrl)) return 0; //最初に/kako/.../9999999999.dat.gzを試す
478-
 ,overwriteMsg : function() {
478+
479-
 					var data = this.msg.split("\n");
479+
			var s = readHTTP(url);  //9999999999.html
480-
 					var msg = DatInfo.msg;
480+
481-
 					var i;
481+
482-
 					for (i=0; i<data.length; i++) msg[parseInt(data[i],10)-1] = data[i].replace(/^\d+<>/,"");
482+
483-
 					for (i=0; i<msg.length; i++) if(!msg[i]) msg[i] = NOT_GET_MSG;
483+
484-
 					this.msg = msg.join("\n");
484+
485-
 					if(this.msg.slice(-1)!="\n") this.msg += "\n";
485+
486-
 				 }
486+
487-
 ,rebuildSubject : function() { Err("E_no_support"); }
487+
488
	}
489-
					this.prepare();
489+
490-
					URL.set_prm(this.urlReplace(args.url));
490+
491-
					var brd, m = Jane.getBRD(URL.prm);
491+
492-
					if(/^(\w+)\.[25]ch\.net/.test(URL.site)) {
492+
  init        : function() { Jane=Jane_jbbs; URL=URL_jbbs; }
493-
						// URLをbrdの登録されているHOST名に置換する(2ch/5ch対策)
493+
 ,re_thr      : {}
494-
						if(RegExp.$1=="itest") { URL.set_prm(URL.url.replace(/\w+\.[25]ch\.net/,m[1]+"."+m[2])); }
494+
 ,re_msg      : /<DT><A.*?>([0-9]+).+?(?:<A HREF="mailto:(.+?)">)?<B> ?(?:<font color.*?>)?(.*?)(?:<\/font>)? ?<\/B>(?:<\/A>|<\/FONT>)(?: 投稿日)?: ?(.*?)(?:<BR>)?<DD>(.*) ?<BR><BR>/img
495-
						else                   { URL.set_prm(URL.url.replace(/[25]ch\.net/,m[2])); }
495+
496
					//したらばの事前URL変換:旧site名、/storage/ URLを現在のURLに置換
497-
					if (m) brd = m[0];
497+
					return  u.replace(URL.RE_SITE,"http://jbbs.shitaraba.net/")
498
							 .replace( /\/\w+\.cgi\//, "/read.cgi/")
499
							 .replace(/^(http:\/\/[^\/]+\/)([^\/]+\/)([^\/]+\/)storage\/(\d+).*$/,"$1bbs/read.cgi/$2$3$4/");
500
				}
501
// ,preReplace : function() {
502
//					s = s.replace(/^\s*$/mg,"");
503-
					if (args.subject) { this.rebuildSubject(); return; }
503+
//					s = s.replace(/\n\n/g,"\n");
504-
					if (args.browser) { invokeBrowser(URL.url); return; }
504+
//					s = s.replace(/\s*<div[^>]+>(?:(?!<\/div>)[\s\S])*<\/div>\s*/ig,"\n"); //100レス毎に入る公告を除去
505-
					URL.appendRange(DatInfo.cnt);
505+
//				 }
506
 ,delDupData  : function() { //わざと重複して要求した先頭レス番データ削除
507-
						if(!this.msg) Err("E_block_not_found","\n\nTITLE="+this.title);
507+
					if ((this.msg.match(/^(\d+)/)||[])[1] == DatInfo.cnt) { this.msg = this.msg.replace(/^.*\n/m, ""); }
508-
						if (!this.noChkTitle && !this.title) Err("E_title_not_found");
508+
509-
						trace(); this.mainReplace(); trace("html->dat main Replace");
509+
510
	function() {
511
		this.msg = this.msg.replace(/^(\d+<>.*?<>.*?<>.*?)(<>.*<>)((?:(?!<>).)*)$/mg, function($0,$1,$2,$3) {return ($3)?$1+" ID:"+$3+$2:$0;});
512
	}
513
 ,createBrdFolder :
514
	function() {
515
		var s = readHTTP( URL.url.replace( /\/\w+\.cgi(\/\w+\/\w+\/).*$/, "/api/setting.cgi$1") );
516
		var bbs_title = (s.match(/^BBS_TITLE=(.*)$/m)||[])[1];
517
		var category = (s.match(/^CATEGORY=(.*)$/m)||[])[1];
518-
						if(this.requireFillAbn) { trace(); this.fillAbn(); trace("透明abnレス挿入"); }
518+
519-
						trace(); this.postReplace(); trace("post Replace");
519+
520-
						if(args.overwrite) this.overwriteMsg();
520+
521-
						else               this.delResNo();
521+
522
	}
523-
					trace("スレタイトル:"+this.title+"\tレス数:"+this.last,9);
523+
 ,getFirst    : function() { return (args.append) ? DatInfo.cnt + 1 : 1; }
524-
					saveDat(dat, this.msg, this.bin);
524+
 ,getLast     : function() { return parseInt((this.msg.match(/(\d+).*\n$/)||[])[1],10); }
525
 ,checkData   :
526
	function(s) {
527-
					invokeJaneStyle(URL.getUrl2());
527+
528
			this.isExistAbn = true;
529
			// 末尾のIDを削除
530
			this.msg = s.replace(/^(.*?)<>((?!<>).)*$/mg, "$1");
531
		} else {
532
			// 先頭のレス番と末尾のIDを削除
533-
  read_cgi_ver : ""
533+
			this.msg = s.replace(/^\d+<>(.*?)<>((?!<>).)*$/mg, "$1");
534-
 ,REG_PATTERN : [
534+
535-
   // ver 07.0.0 / ver.07.0.1
535+
536-
   { "thr" : /<div class="thread">(<div class="post"[^>]*><div class="meta">[\s\S]+<\/span><\/div><\/div>)((?:<br>)?<\/div>|[\s\S]*?$)/i
536+
537-
     ,"msg" : /[\s\S]*?<div class="post"[^>]*>(?:<[^>]*?>)*<span class="number">(\d+).+?<span class="name"><b>(?:<a href="mailto:(.+?)">)?(.*?)(?:<\/a>)?<\/b><\/span><span class="date">(.*?)<\/span>(<span class="be[^>]*><a[^>]*>[^<]*<\/a><\/span>)?<\/div><div class="message"><span class="escaped">(.*?)<\/span><\/div><\/div>/ig
537+
538-
     ,"rep" : "$1<>$3<>$2<>$4$5<>$6<>\n"
538+
539-
     ,"preReplace" : [ [/(?:<div class="post"[^>]* id="0"|<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<div class="post"|(?:<br>)?<\/div><div class="push">|$)/ig,""]
539+
540-
                      ,[/<a href="(?:https?:)?\/\/(?!be\.[25]ch\.net\/).*?>([^<]*)<\/a>/ig, "$1"] ]
540+
541-
     ,"postReplace" : [ [/<span class="be[^>]*><a href="[^"]+\/(\d+)"[^>]*>\?(.*?)<\/a><\/span>/ig," BE:$1-$2"]
541+
 ,insertAbn   :
542-
                       ,[/^(\d+<>.*?<>.*?<>.*? BE:\d+-[^ <]+) BE:\d+-[^ <]+/mg,"$1"]
542+
543-
                       ,[/<\/span><span class="uid"[^>]*>/ig, " "]
543+
		// 透明あぼーんレスを挿入する
544-
                       ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"]
544+
		var d = [];
545-
                       ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ]
545+
		n = this.first;
546-
    }
546+
		var s = this.msg.split("\n");
547
		for (var i=0; i<s.length; i++) {
548-
   // ver 06.0.0
548+
			for (var j=n; j<parseInt(s[i].replace(/^(\d+).+$/, "$1"),10); j++) { d.push(JBBS_ABN_STR); n++; }
549-
   ,{ "thr" : /<div class="thread"[^>]*>((?:<div class="post".+?<\/div><\/div>)+)(<\/div>)?/i
549+
			d.push(s[i].replace(/^\d+<>(.+)$/, "$1")); n++;
550-
     ,"msg" : /.*?<div class="number">(\d+).+?<\/div><div class="name"><b>(?:<a href="mailto:(.+?)">)?(.*?)(?:<\/a>)?<\/b><\/div><div class="date">(.*?)<\/div><div class="message">(.*?)<\/div><\/div>(?=<div class="post"|$)/ig
550+
551-
     ,"rep" : "$1<>$3<>$2<>$4<>$5<>\n"
551+
		this.msg = d.join("\n");
552-
     ,"preReplace" : [ [/(?:<div class="post"[^>]* id="0"|<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<div class="post"|<\/div><div class="cLength"|$)/ig,""]
552+
553-
                      ,[/<a href="(?:https?:)?\/\/(?!be\.[25]ch\.net\/).*?>([^<]*)<\/a>/ig, "$1"] ]
553+
554-
     ,"postReplace" : [ [/<\/div><div class="be[^>]*><a href="[^"]+\/(\d+)"[^>]*>\?(.*?)<\/a>/ig," BE:$1-$2"]
554+
555-
                       ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"]
555+
556-
                       ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ]
556+
557-
    }
557+
558
		var s = readHTTP( raw_url, true);
559-
   // ver 06.0.0 ppspink
559+
560-
   ,{ "thr" : /(<section class="thread"[\s\S]+<\/dd><\/dl>)(<\/section>)/i
560+
561-
     ,"msg" : /[\s\S]*?<dl class="post"[^>]*>(?:<[^>]*?>)*<span class="number">(\d+).+?<span class="name"><b>.*?(?:<a href="mailto:(.+?)">)?(.*?)(?:<\/a>)?<\/b><\/span><span class="date">(.*?)<\/span>(<div class="be[^>]*><a[^>]*>[^<]*<\/a><\/div>)?<\/dt><dd class="thread_in">(.*?)(?:<\/dd><\/dl>|$)/ig
561+
562-
     ,"rep" : "$1<>$3<>$2<>$4$5<>$6<>\n"
562+
563-
     ,"preReplace" : [ [/(?:<dl class="post"[^>]* id="0"|<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<section|<dl class="post"|$)/ig,""]
563+
564-
                      ,[/<a href="(?:https?:)?\/\/(?!be\.[25]ch\.net\/).*?>([^<]*)<\/a>/ig, "$1"] ]
564+
565-
     ,"postReplace" : [ [/<div class="be[^>]*><a href="[^"]+\/(\d+)"[^>]*>\?(.*?)<\/a><\/div>/ig," BE:$1-$2"]
565+
				this.getLast = this.getLast2;
566-
                       ,[/^(\d+<>)<font color="green">(.*?)<\/font>(?=<>)/img, "$1$2"]
566+
567-
                       ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"]
567+
				this.mainReplace = this.mainReplace2;
568-
                       ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ]
568+
569-
    }
569+
				this.readHTTP2(URL.prm[0]);
570
				delete this.addTitle;
571-
   // ver 05.02.02
571+
572-
   ,{ "thr" : /^[\s\S]*?<dl[^>]*>\s*(?:<font[^>]*>.*<\/font>.*\s*)?((?:\s*<dt[^>]*>.+?<dd>.+\r?\n?)+)(\s*<)?/i
572+
573-
     ,"msg" : /[ \t]*<dt.*?>([0-9]+).+?(?:"mailto:(.+?)">)?<b[^>]*>(.*?)<\/b>(?:<\/font>|<\/a>)?(?: ?投稿日)? ?:(.*?)<dd>(.*?)(?:<br>)*(?=<dt.*?>|$)/img
573+
574-
     ,"rep" : "$1<>$3<>$2<>$4<>$5<>"
574+
575-
     ,"preReplace" : [ [/(?:<div (?:class|id)=[^>]*banner)[\s\S]*?(?=<dt|<\/dl>|$)/ig,""]
575+
576-
                      ,[/<a href="(?:https?:)?\/\/.*?>([^<]*)<\/a>/ig, "$1"]
576+
577-
                      ,[/(<a href=)"\/cdn-cgi\/l\/(email-protection\#.*?">)/ig,'$1"mailto:$2'] ]
577+
578-
     ,"postReplace" : [ [/<a href="javascript:be\(([^\)]+?)\)[^>]*>\?(.*?)<\/a>/ig, "BE:$1-$2"]
578+
579-
                       ,[/<img src="(?:https?:)?(\/\/img\.[25]ch\.net\/.+?)">/ig, "sssp:$1"]
579+
580-
                       ,[/<img src="(?:https?:)?(.*?)">/ig, IMG_TO+"$1"] ]
580+
581-
     ,"ln_terminate" : true
581+
582-
    }
582+
583-
  ]
583+
584-
,urlReplace  :
584+
		//-- 2nd try : read html text --
585
		trace("try URL="+url,9);
586-
	    url = url.replace(/^http:\/\/(?:mattari\.plusvip\.jp|jane\.s28\.xrea\.com)\/test\/\w+\.cgi\/(?:jane2ch|bbs)\//, "http://jane2ch.net/test/read.cgi/community/")
586+
		this.msg = readHTTP(url); //途中からデータを取ることができない
587-
		         .replace(/^(http:\/\/next2ch\.net\/)(\w+\/)(?:kako\/\d{3,4}\/(?:\d{5}\/)?)?(\d+)(?:\/|\.html)?$/,"$1test/read.cgi/$2$3/")
587+
588-
				 .replace(/\/read\.cgi\?(?=.*?bbs=(\w+))(?=.*?key=(\d+))(?=.*?st=(\d+))?(?=.*?to=(\d+))?.*$/i, "/read.cgi/$1/$2/$3-$4").replace(/\/-$/,"/")
588+
		var re_thr1 = /^[\s\S]*?<dl\s+(?:class|id)="thread[^>]*?>\s*(<dt>(?:(?!<\/dl>)[\s\S])*?\s*)<\/dl>[\s\S]*$/i
589-
				 .replace(/^(.*?)itest(\.[25]ch\.net)\/(\w+)(?=\/test\/read\.cgi\/)/,"$1$3$2");
589+
		var re_thr2 = /^[\s\S]*?<dl[^>]*?>(?:(?!<dt>)[\s\S])*(<dt>(?:(?!<\/dl>)[\s\S])*)<\/dl>[\s\S]*$/i
590-
		if(!args.keep_kako)
590+
		if (re_thr1.test(this.msg) != 0) { this.re_thr = re_thr1 }
591-
			url=url.replace(/^(.*?\/)(\w+\/)kako\/\d{3,4}\/(?:\d{5}\/)?(\d+)\.html$/,"$1test/read.cgi/$2$3/");
591+
		else if (re_thr2.test(this.msg) != 0) { this.re_thr = re_thr2; }
592
		this.getTBlock();
593
	}
594-
 ,preReplace  :
594+
 ,getLast2    : function() { return parseInt((this.msg.match(/<dt><a[^>]*?>(\d+).*<dd>.*\n$/i)||[])[1],10); }
595-
 	function() {
595+
 ,getTitle2   : function(s) {
596-
		var i,list;
596+
					this.title = (s.match(/<h1 class="thread-title">(.*?)<\/h1>/i)||[])[1]
597-
		if(this.re_sel==-1) this.testTBlock(); //re_selの設定
597+
								 || (s.match(/<title>(.*?)<\/title>/i)||[])[1] || "";
598-
		if(this.re_sel>=0) {
598+
599-
			trace("");
599+
 ,delDupData2 :
600-
			list = this.REG_PATTERN[this.re_sel].preReplace;
600+
601-
			for(i=0;i<list.length; i++) {
601+
		//append時、既存のレス数分データを読み飛ばす
602-
				this.msg = this.msg.replace(list[i][0],list[i][1]);
602+
		while( (this.msg.match(/^<dt><a[^>]*?>(\d+)/i)||[])[1] < DatInfo.cnt+1) { this.msg = this.msg.replace(/^.*\n/m,""); }
603
	}
604-
			trace("pre Replace");
604+
 ,mainReplace2 : function() { this.msg = this.msg.replace(this.re_msg, "$1<>$3<>$2<>$4<>$5<>"); }
605
 ,checkData2   :
606
	function(s) {
607-
 ,postReplace :
607+
		var ln = this.checkData0(s);
608-
 	function() {
608+
		if (this.last-this.first+1 != ln.length) {
609-
		var i,list;
609+
			this.isExistAbn = true;
610-
		list = this.REG_PATTERN[this.re_sel].postReplace;
610+
		} else {
611-
		for(i=0;i<list.length; i++) {
611+
			// 先頭のレス番を削除
612-
			this.msg = this.msg.replace(list[i][0],list[i][1]);
612+
			this.msg = s.replace(/^\d+<>/mg, "");
613
		}
614
	}
615
});
616
617
//-------------------------------------------------------------------------------
618
function loadFile(f) {
619
	var s;
620
	try {
621
		strm.Type = 2;
622
		strm.Charset = 'shift_jis';
623
		strm.Open();
624
		strm.loadFromFile(f);
625
		s = strm.ReadText(-1);
626-
		var s,ss,u,msgLength;
626+
627-
		if(!URL.otherURLType) {
627+
628-
			if(!URL.kako && !URL.RE_HOST.test(url)) {
628+
629-
				if(!this.readHTTP0(url)) return false; //dat取得
629+
630
function loadFile2(f) {
631-
			/*@if (@EnabledTest2chJSON)
631+
	var s;
632-
				o("1st try json");
632+
633-
				this.msg = get2chJSON();
633+
634-
				if(this.msg=="") Err("E_already_there");
634+
635-
				if(this.msg) return false;
635+
636-
				o("2nd try html");
636+
	} catch(e) { if(file) file.close(); Err("E_loadfile", "\n"+e.message+"\ncurrent="+shell.CurrentDirectory+"\nfile="+f); }
637-
			@end @*/
637+
638-
			this.kakoUrl = this._getKakoUrl();
638+
639-
			// keep_kakoオプションによるkako形式のURIが受け渡される場合には最初に .dat.gz/.dat のアクセスを試行する
639+
640-
			if(URL.kako) if(!this.readHTTP2(this.kakoUrl)) return false;
640+
function saveFile(f,s) {
641
	strm.Type = 2;
642
	strm.Charset = 'shift_jis';
643-
		this.msg = readHTTP(url)[0];
643+
644-
		this.read_cgi_ver = (this.msg.match(/>read\.cgi ver ([\d.]+)/)||[])[1];
644+
	if (args.append) { try {strm.loadFromFile(f); strm.Position = strm.Size;} catch(e){} }
645-
		this.preReplace();
645+
646
	try { strm.Savetofile(f, 2); }
647-
		msgLength = this.msg.length;
647+
648-
		ss = this.setTBlock();
648+
649-
		if (ss==null && !URL.otherURLType) {
649+
650-
			u = this.kakoUrl.replace(/\.dat\.gz$/,".html");
650+
function saveFile2(f,s) {
651-
			switch(this.readHTTP3(u)) {
651+
652-
				case 0: return false;
652+
		var file = fso.OpenTextFile( f, (args.append)?8:2 , true, 0);
653-
				case 1: url=u;  ss=this.setTBlock(); break;
653+
654-
				default: break // case -1
654+
655
	} catch(e) { if(file) file.Close(); Err("E_savefile", "\n"+e.message+"\ncurrent="+shell.CurrentDirectory+"\nfile="+f); }
656
}
657-
		if(ss==null) {
657+
658-
			ss = "<URL>="+url+"\n<TITLE>="+this.title+"\n<文字数>="+msgLength+"\n\n";
658+
function readHTTP(u, withHeaders) {
659
	var s="", r="";
660
	http.open("GET", u, true);
661
	for(var i in HTTP_HEADERS) { http.setRequestHeader(i, HTTP_HEADERS[i]); }
662-
					|| this.msg.substr(0,(msgLength>100)?100:msgLength-1).replace(/<br.*?>/g,"\n");
662+
663
	for (var t0=new Date(); http.readyState<4; ) {
664
		if (new Date() - t0 > HTTP_TIMEOUT) { http.abort(); Err("E_http_timeout"); }
665
		WScript.Sleep(50);
666-
			if (shell.Popup("途中でデータが途切れているようですが続行しますか?",0,MY_NAME,4+48)!=6) Err("E_stop");
666+
667
	if (http.status != 200 && !http.status==0) Err("E_http_recieve", " status="+http.status);
668-
		if(this.REG_PATTERN[this.re_sel].ln_terminate && this.msg && this.msg.slice(-1)!='\n') this.msg += '\n';
668+
669
	if (withHeaders) r = http.getAllResponseHeaders();
670
	s = http.responseText;
671
	if (!/charset=/i.test(header)) {
672
		if(http.responseBody !== void 0) {
673-
		var re1 = /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>((?:(?!<>).)*).*\s*$/m;
673+
			trace("HTTP文字コード変換開始",9);
674-
		var re2 = /^(?:[^,]*),(?:[^,]*),(?:[^,]*),(?:[^,]*),(.*)$/m;
674+
675
			strm.Type = 1;
676-
		var s="",r="";
676+
			strm.Open();
677-
		try { s=readHTTP(url); r=s[0].match(re1); if(!r) r=s[0].match(re2); }catch(e){} //9999999999.dat.gz
677+
			strm.Write(http.responseBody);
678-
		if(!r) {
678+
			strm.Position = 0;
679-
			url=url.replace(/\.gz$/,"");
679+
			strm.Type = 2;
680
			strm.Charset = cs;
681-
			try{ s=readHTTP(url); r=s[0].match(re1); if(!r) r=s[0].match(re2); }catch(e){} //9999999999.dat
681+
			s = strm.ReadText(-1);
682
			strm.Close();
683
		}
684-
			this.msg = s[0];
684+
685-
			this.bin = s[2];
685+
686-
			this.last = this.checkData0(s[0]).replace(/^.*$/m,"").length;
686+
687
	return withHeaders ? [s,r] : s;
688
}
689
690
function saveDat(dat,s) {
691
	if (args.append) {
692
		if(s=="") Err("E_already_there");
693
	} else {
694
		if(s.match(/\n/g)==null) Err("E_no_data");
695
		if(DatInfo.cnt>=s.match(/\n/g).length) {
696
			if (MsgBox("既存のスレデータの方が同じか又は大きいですが、置換を続行しますか?",4+32+256,MY_NAME) != 6){
697
				Err("E_stop");
698-
		if (/error|隊長|過去ログ倉庫/i.test(title)) {
698+
699-
			if(!URL.kako && !this.readHTTP2(this.kakoUrl)) return 0; //最初に/kako/.../9999999999.dat.gzを試す
699+
700
	}
701-
			var s = ""; try{ s=readHTTP(url)[0]; }catch(e){}  //9999999999.html
701+
702
	trace(); saveFile2(path(dat), s); trace("save file:"+dat);
703-
				this.title = (s.match(/<title>(.*)<\/title>/im)||[])[1]||"";
703+
704
705-
				this.preReplace();
705+
706
	shell.Exec(JANE_EXE + " " + url);
707
	if(args.sendkey && args.sendkey > 0) {
708
		WScript.Sleep(args.sendkey);
709
		shell.SendKeys('^(w)');
710
		WScript.Sleep(200);
711
		shell.Exec(JANE_EXE + " " + url);
712
	}
713
	if(args.redraw) {
714-
 ,readHTTP0 :
714+
715
		shell.SendKeys('%');
716-
		var re = /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>((?:(?!<>).)*).*\s*$/m;
716+
717-
		var s;
717+
718-
		url = "http://"+URL.site+"/"+URL.brdID+"/dat/"+URL.thrID+".dat";
718+
719
		shell.SendKeys('G');
720-
		try { s=readHTTP(url); } catch(e) {}
720+
721-
		if(s) {
721+
722-
			this.msg = s[0];
722+
723-
			this.title = (s[0].match(re)||[])[1];
723+
724-
			if(this.title===void 0||/[25]ちゃんねる専用ブラウザをご利用の皆さまへ/.test(this.title)) return true;
724+
725-
			this.bin = s[2];
725+
726-
			this.last = this.checkData0(s[0]).replace(/^.*$/m,"").length;
726+
727
	WScript.Sleep(200);
728
	shell.SendKeys("%({F4})");
729
	do {
730
		var cnt=20;
731
		while(cnt && WMI.isAliveProcess(JANE_EXE, JANE_PATH+JANE_EXE)) { WScript.Sleep(100); cnt--;}
732
		if(!cnt) { WScript.Echo(JANE_EXE+"を終了させてください"); }
733
	} while(!cnt);
734
}
735-
  prepare     : function() { Jane=Jane_jbbs; URL=URL_jbbs; }
735+
736-
 ,REG_PATTERN : [
736+
function saveIdx(boardUrl) {
737-
    { "thr" : /^[\s\S]*?<dl\s+(?:class|id)="thread[^>]*?>\s*(<dt>(?:(?!<\/dl>)[\s\S])*?\s*)<\/dl>[\s\S]*$/i
737+
	var i,s,r;
738-
     ,"msg" : /<DT><A.*?>([0-9]+).+?(?:<A HREF="mailto:(.+?)">)?<B> ?(?:<font color.*?>)?(.*?)(?:<\/font>)? ?<\/B>(.*?)(?:<\/A>|<\/FONT>)(?: 投稿日)?: ?(.*?)(?:<BR>)?<DD>(.*) ?<BR><BR>/img
738+
739-
     ,"rep" : "$1<>$3$4<>$2<>$5<>$6<>"
739+
740-
    }
740+
741-
   ,{ "thr" : /^[\s\S]*?<dl[^>]*?>(?:(?!<dt>)[\s\S])*(<dt>(?:(?!<\/dl>)[\s\S])*)<\/dl>[\s\S]*$/i
741+
742-
     ,"msg" : /<DT><A.*?>([0-9]+).+?(?:<A HREF="mailto:(.+?)">)?<B> ?(?:<font color.*?>)?(.*?)(?:<\/font>)? ?<\/B>(.*?)(?:<\/A>|<\/FONT>)(?: 投稿日)?: ?(.*?)(?:<BR>)?<DD>(.*) ?<BR><BR>/img
742+
743-
     ,"rep" : "$1<>$3$4<>$2<>$5<>$6<>"
743+
744-
    }
744+
745-
  ]
745+
	var state = (DatInfo.lines>=maxRes) ? 0 : IDX_STATE[ (URL===URL_2ch) ? "2ch" : "jbbs" ];
746
	if (URL.kako) state = 10;
747
	
748-
					return  u.replace(URL.RE_HOST,"http://jbbs.shitaraba.net/")
748+
749-
							 .replace(/\/bbs\/lite\//,"/bbs/")
749+
	var idx = [ datName,DatInfo.title,'',DatInfo.lines,'0','',boardUrl,state,DatInfo.lines,'','','0',last_got,'0','0' ];
750-
							 .replace(/\/\w+\.cgi\//, "/read.cgi/")
750+
751-
							 .replace(/^(http:\/\/[^\/]+\/)([^\/]+\/)([^\/]+\/)storage\/(\d+).*$/,"$1bbs/read.cgi/$2$3$4/")
751+
752-
							 .replace(/\/([^\/]+)\/bbs\/read\.cgi\?(?=.*?bbs=(\d+))(?=.*?key=(\d+))(?=.*?start=(\d+))?(?=.*?end=(\d+))?.*$/i, "/bbs/read.cgi/$1/$2/$3/$4-$5").replace(/\/-$/,"/");
752+
753
					+ 'INSERT OR IGNORE INTO "tableversion" VALUES(' + "'board_db','00000001');"
754-
 ,preReplace : 	function() {
754+
755-
					if(URL.otherURLType==1) { // archive.org
755+
756-
						this.msg = this.msg.replace(/<a href="\/web\/\d+\//g,'<a href="');
756+
757
					+ " uri TEXT, state TEXT,new_lines TEXT, write_name TEXT, write_mail TEXT,"
758-
					if(URL.otherURLType && /<dl.*?>\s+<dt>\s+<a/.test(this.msg)) {
758+
759-
						//1と100レス毎に入る公告を除去
759+
760-
						this.msg = this.msg.replace(/^\s*(.*?)\s*\n/mg,"$1")
760+
761-
						                   .replace(/<!--.*?-->/g,"")
761+
	var SQL_CMD_3 = "update idxlist set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,DatInfo.lines]);
762-
						                   .replace(/<br>(?:<\/dd>)?<div[^>]*>.*?<\/div>(?=<dt>|<\/dl>)/ig,"")
762+
763-
						                   .replace(/<table.*?>(?:(?!<dt>).)*?<\/table>(?=<dt>|<\/dl>)/ig,"")
763+
764-
						                   .replace(/<br>\s*<br>(?:<\/dd>)?(?=<dt>|<\/dl>)/ig,"<br><br>\n")
764+
765-
						                   ;
765+
766
		var sql = new Sql();
767-
			 	}
767+
768
		sql.isSqlite_ODBC || sql.isSqlite_exe || Err("E_require_sqlite");
769
	}
770
	if(args.restart) terminateJaneExe();
771
	
772
	if (use_db && args.restart) {
773
	switch(chkJaneProg()) {
774-
		var s = readHTTP( URL.url.replace( /\/\w+\.cgi(\/\w+\/\w+\/).*$/, "/api/setting.cgi$1") )[0];
774+
775
		case 'Style?':
776
			shell.CurrentDirectory = dir;
777
			r=sql.exec("BoardDB.db",SQL_CMD_1+SQL_CMD_2+SQL_CMD_3+SQL_CMD_4);
778
			break;
779
		case 'Xeno':
780
		case 'Xeno?':
781
			var qmerge3 = Jane.LogBasePath+JANE_LOGS+"qmerge3.db";
782
			if(!fso.FileExists(qmerge3)) break;
783
			idx.splice(14,1,last_got);
784
			idxText = [];
785-
			this.requireFillAbn = true;
785+
786
			var brd=DatInfo.brd.slice(0,-1);
787-
		// 末尾のIDを削除
787+
788-
		this.msg = s.replace(/^(.*?)<>((?!<>).)*$/mg, "$1");
788+
789
			var SQL_CMD_XENO3 = "select board_id from thread where board_id=$1 and datname='"+datName+"';";
790
			var SQL_CMD_XENO4 = "insert into thread values($1,"+idxText.join(",")+");";
791
			var SQL_CMD_XENO5 = "update thread set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,DatInfo.lines]);
792
			var SQL_CMD_XENO6 = "update thread set lines=" + idxText[3] + ",uri=" + idxText[6] + ",title=" + idxText[1]
793
								+ ",state=" + idxText[7] + ",last_got=" + idxText[12] + " where datname=" + idxText[0] + ";";
794
			var board_id = sql.select(qmerge3,SQL_CMD_XENO1);
795
			board_id = (board_id[0].match(/^(\d+)/)||[])[1];
796
			if (!board_id) { sql.exec(qmerge3, SQL_CMD_XENO2); board_id=((sql.select(qmerge3,SQL_CMD_XENO1))[0].match(/^(\d+)/)||[])[1]; }
797-
		// web.archive/google cacheからの取得
797+
798-
		if(URL.otherURLType) {
798+
799-
			this.getTitle = this.getTitle2;
799+
800-
			this.delDupData = this.delDupData2
800+
801-
			this.checkData = this.checkData2;
801+
802-
			Thread.readHTTP.call(this, url);
802+
803-
			delete this.mainReplace;
803+
804-
			delete this.addTitle;
804+
805-
			return true;
805+
806
	}
807
	
808
	// idxファイルの更新
809
	shell.CurrentDirectory = dir;
810-
		var s = readHTTP(raw_url);
810+
811
	if(fso.FileExists(datName+".idx")) {
812
		s = loadFile(datName+".idx").replace(/\r/g,"").split("\n");
813
		if(s.length>=12) {
814
			isExistIdx = true;
815
			s[7]  = "" + (parseInt(s[7],10) + DatInfo.lines - parseInt(s[2],10));
816
			s[2]  = "" + idx[3];
817
			s[5]  = idx[6];
818
			s[6]  = "" + idx[7];
819-
				Thread.readHTTP.call(this, URL.prm[0]);
819+
820-
				delete this.mainReplace;
820+
821
		}
822
	}
823
	if(!isExistIdx) {
824
		s = idx;
825
		s.splice(0,1);
826
		s.push("");
827
	}
828
	s = s.join("\r\n");
829
	try { saveFile(datName+".idx", s); } catch(e) {}
830
	
831
	// subject.txtの更新
832
	if(fso.FileExists("subject.txt")) {
833-
 ,getTitle2   :
833+
		var re = new RegExp("^"+datName+"\\..*\\((\\d+)\\)(\\s*)$", "m");
834-
	function(s) { this.title = (s.match(/<h1 class="thread-title">(.*?)<\/h1>/i)||[])[1]
834+
		s = loadFile("subject.txt");
835-
				  || (s.match(/<title>(.*?)<\/title>/i)||[])[1] || "";
835+
836
		if(r) {
837-
 ,delDupData2 : //append時、既存のレス数分データを読み飛ばす
837+
			s = s.replace(re, r[0].replace(/\((\d+)\)(\s*)$/,"("+DatInfo.lines+")$2"));
838-
	function() { while( (this.msg.match(/^(\d+)/i)||[])[1] < DatInfo.cnt+1)
838+
839-
					{ this.msg = this.msg.replace(/^.*\n/m,""); }
839+
840-
			   }
840+
841
	shell.CurrentDirectory = basedir;
842-
	function(s) { var ln = this.checkData0(s);
842+
843-
				  if (this.last-this.first+1 != ln.length) { this.requireFillAbn = true; }
843+
844
function Sql(){
845
	var DRIVER = "DRIVER=SQLite3 ODBC Driver;";
846
	var db = new ActiveXObject("ADODB.Connection");
847-
var Thread_machi = object(Thread,{
847+
848-
  prepare     : function() { Jane=Jane_machi; URL=URL_machi; }
848+
849-
 ,noChkTitle  : true
849+
850-
 ,REG_PATTERN : [
850+
851-
    { "thr" : /^(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>((?:(?!<>).)*)<>((?:(?!<>).)*).*\s*$/m
851+
852-
     ,"msg" : /^((?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*<>(?:(?!<>).)*)(<>(?:(?!<>).)*<>(?:(?!<>).)*)<>((?:(?!<>).)*)(?:<>)?(.*\s*)$/mg
852+
853-
     ,"rep" : "$1 [ $3 ]$2$4"
853+
854-
    }
854+
855-
  ]
855+
856
			db.Open(DRIVER+"Database="+dbFile);
857-
 					if(URL.otherURLType) Err("E_illegal_url");
857+
858-
 					u=u.replace(/\/test\/(?=read)/,"/bbs/")
858+
859-
 					   .replace(/\/read\.cgi\//,"/offlaw.cgi/2/");
859+
860-
 					trace("replace url="+u,9);
860+
861-
 					return u;
861+
862-
 				}
862+
863-
 ,getTitle    : function(s) { this.title = (s.match(this.REG_PATTERN[this.re_sel].thr)||[])[1] || DatInfo.title; }
863+
864
		var rs = new ActiveXObject("ADODB.Recordset");
865-
 					if(!/^\d+<>.*?<>.+?<>.*?<>.*$/m.test(s)) Err("E_remained_garbage");
865+
866-
					if (this.last-this.first+1 != s.replace(/^.*$/mg,"").length) { this.requireFillAbn = true; }
866+
867
			rs.Open(sql,db);
868-
 ,delDupData  : function() {}
868+
869
				var rr=[];
870-
 ,setTBlock   : function() {}
870+
871
				r += rr.join("|")+"\n";
872
				rs.MoveNext();
873-
//==============================================================
873+
874
		} catch(e) { s = e.message; }
875-
	var s="";
875+
876
		try { db.Close(); } catch(e) { s += " | Connection Close:"+e.message; }
877
		rs = null;
878
		return [r, s];
879
	}
880
	function exec_exe(dbFile,sql) { return select_exe(dbFile, sql); }
881
	function select_exe(dbFile, sql) {
882
		var sqlite = shell.Exec(SCRIPT_PATH + "sqlite3.exe");
883
		sqlite.StdIn.WriteLine(".open '"+ dbFile+ "'");
884
		sqlite.StdIn.WriteLine(sql);
885
		sqlite.StdIn.WriteLine(".quit");
886
		return [ sqlite.StdOut.ReadAll(), sqlite.StdErr.ReadAll() ];
887-
	var s="";
887+
888
}
889
890
function getBrdCustomizeIni(brdurl) {
891
	if(!fso.FileExists(JANE_BRDCUSTOMIZE_INI)) return null;
892-
	} catch(e) {
892+
893-
		if(file) file.close();
893+
894-
		s = loadFile(f);
894+
895
		if (r = s.match(new RegExp("^\\[$1/?\\]\\s+MaxResNum=(\\d+)".expand([,"http://"+brdurl]),"im"))) break;
896
		u = brdurl.split(/\/(?=[^\/]+$)/);
897
		brdurl =u[0];
898
	} while(u[1])
899-
function saveFile(f,s,add) {
899+
900
}
901
902
function chkJaneProg() {
903-
	if (add) { try {strm.loadFromFile(f); strm.Position = strm.Size;} catch(e){} }
903+
	var i,n1=0,n2=0;
904
	var folder=sha.Namespace(JANE_PATH);
905
	var items=folder.Items();
906
	for(i=0; i<items.Count-1;i++) {
907
		if(folder.GetDetailsOf(items, i) == '説明') { n1=i; }
908
		if(folder.GetDetailsOf(items, i) == '製品名') { n2=i; }
909-
function saveFile2(f,s,add) {
909+
910
	if(n1>0)  var description = folder.GetDetailsOf(folder.ParseName("Jane2ch.exe"),n1);
911-
		var file = fso.OpenTextFile( f, (add)?8:2 , true, 0);
911+
	if(n2>0)  var productname = folder.GetDetailsOf(folder.ParseName("Jane2ch.exe"),n2);
912
	if (description=="JaneXeno") return "Xeno";
913
	if (description=="JaneView") return "View";
914-
	} catch(e) {
914+
915-
		if(file) file.Close();
915+
916-
		saveFile(f,s,add);
916+
917
	if (fileversion<1.0) return "Xeno?";
918
	return "Unknown";
919
}
920-
function saveBinaryFile(f,b) {
920+
//--------------------------------------------------------------------------------
921-
	strm.Type = 1;
921+
922
	var d = p.match(/[^\\]+\\/g), e = "";
923-
	strm.Write(b);
923+
	for (var i = 0; d[i]; i++) fso.FolderExists(e += d[i]) || fso.CreateFolder(e);
924
	return p;
925-
	catch(e) { strm.Close(); Err("E_savefile", "\n"+e.message+"\ncurrent="+shell.CurrentDirectory+"\nfile="+f+" (binary)"); }
925+
926
927
function parmParse(args) {
928
	var ptn = [ "^(?:/n:)?(\\d+)", "^/f", "^http://", "^/w:?(-?\\d+)?$", "^/-w", "^/a(?:ppend)?"
929-
function readHTTP(u) {
929+
				, "^/b(?:ak)?(1)?", "^/z", "^/redraw:?(\\d+)?$", "/log:?(.*)$" ];
930-
	var s="", r="", b;
930+
	var p = {};
931-
	if(args.proxy) {
931+
	for (var i=0; i<args.length; i++) {
932-
		if(USED_WINHTTP) { http.setProxy(2, args.proxy, ""); }
932+
	for (var j=0,n=-1; j<ptn.length;j++) {if ((new RegExp(ptn[j],"i")).test(args(i))) { n=j; break;} }
933-
		else Err("E_not_suported_proxy");
933+
	switch (n) {
934
		case 0: p["opt_n"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||"");
935
				break;
936
		case 1: p["url"] = InputBox("URLを指定してください",MY_NAME) || "";
937
				break;
938
		case 2: p["url"] = args(i);
939-
	var t0=new Date();
939+
940-
	while( (USED_WINHTTP) ? !http.waitForResponse(0) : http.readyState<4 ) {
940+
		case 3: p["sendkey"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||1200);
941
				break;
942
		case 4: p["sendkey"] = -1;
943
				break;
944-
//	if (http.status != 200 && !http.status==0) Err("E_http_recieve", " status="+http.status);
944+
		case 5: p["append"] = true;
945
				break;
946-
	b = http.responseBody;
946+
		case 6: p["bak"] = -1;
947-
	r = http.getAllResponseHeaders();
947+
				if ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]) { p["bak"] = 1; }
948-
	try {s = http.responseText;} catch(e) {}
948+
949
		case 7: p["restart"] = true;
950-
		if(b !== void 0) {
950+
951
		case 8: p["redraw"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||1200);
952-
			if(cs=="x-sjis") cs="shift-jis";
952+
953-
			if(basp) {
953+
		case 9: p["trace"] = ((args(i).match(new RegExp(ptn[n],"i"))||[])[1]||"");
954-
				trace("文字コード変換開始 with basp21",9);
954+
955-
				s = basp.Kconv(b,4,cs=="shift-jis"?1:0);
955+
		default: break;
956
	}
957-
				trace("文字コード変換開始",9);
957+
958-
				strm.Type = 1;
958+
	if (!("url" in p)) p["url"] = InputBox("URLを指定してください",MY_NAME) || "";
959-
				strm.Open();
959+
	p.url = p.url.replace(/^(http:\/\/.*?)http:\/\/.*$/, "$1")
960-
				strm.Write(b);
960+
961-
				strm.Position = 0;
961+
962-
				strm.Type = 2;
962+
963-
				strm.Charset = cs;
963+
//--------------------------------------------------------------------------------
964-
				s = strm.ReadText(-1);
964+
965-
				strm.Close();
965+
966
	if (URL_jbbs.RE_SITE.test(args.url)) Thread_jbbs.proc();
967
	else Thread_2ch.proc();
968
}
969
970
/*@if (@DEBUG)
971-
	return [s,r,b];
971+
972
	@else @*/
973
	try {main();} catch (e) {WScript.Echo(e.message);}
974-
function saveDat(dat,s,b,add,latest) {
974+
975-
	var cnt;
975+
976
//--------------------------------------------------------------------------------
977
/*@if (@EnabledTest2chJSON)
978
function get2chJSON() {
979
	var urlJSON = "http://itest.2ch.net/public/newapi/client.php?subdomain=$2&board=$5&dat=$6".expand(URL.prm);
980-
		cnt = s.match(/\n/g).length+DatInfo.offset;
980+
981-
		if(!args.overwrite) {
981+
	var s = readHTTP(urlJSON);
982-
			if(DatInfo.cnt>=cnt && (latest==null || latest==true)) {
982+
983-
				if(REWRITE_DAT==3 || (REWRITE_DAT==2 && DatInfo.cnt==cnt)) Err("E_stop");
983+
984-
				if (REWRITE_DAT==0
984+
	var thread      = s.match(/"thread":\[(\d+),(\d+),("[^"]*"),("[^"]*"),("[^"]*"),("[^"]*")\]/);
985-
						&& shell.Popup("新規のレスが無いようですが置換を続行しますか? ("
985+
	var comments    = (s.match(/"comments":\[((?:\[(\d+),("[^"]*"),("[^"]*"),(\d+),("[^"]*"),("[^"]*"),("[^"]*")\],?)+)\]/)||[])[1];
986-
					 					+DatInfo.cnt+" -->"+cnt+")",0,MY_NAME,4+32+256) != 6){
986+
987-
					Err("E_stop");
987+
988
	comments = comments.replace(/(\[(?:\d+),(?:"[^"]*"),(?:"[^"]*"),(?:\d+),(?:"[^"]*"),(?:"[^"]*"),(?:"[^"]*")\]),/g,"$1\n").split("\n");
989
	Thread_2ch.title = title;
990
	Thread_2ch.last = comments.length;
991
	if(args.append && DatInfo.cnt>0) { comments.splice(0,DatInfo.cnt); }
992
	for(var i=0; i<comments.length; i++) {
993-
//	if((!args.append&&add==0)||args.overwrite) {
993+
994-
//		saveFile(path(dat),""); trace("create file:"+dat,9); //既存のdatを削除
994+
995-
//	}
995+
		res = res.match(/^(\d+),("[^"]*"),("[^"]*"),(\d+),("[^"]*"),("[^"]*"),("[^"]*")$/);
996-
	if(b===null) { trace(); saveFile2(path(dat), s, args.append||(!args.overwrite&&add) ); trace("save file:"+dat); }
996+
		var name = eval(res[2]).replace(/(◆.+)$/,"</b>$1<b>").replace(/(転載ダメ&copy;2ch\.net)/,"<small>$1</small>");
997-
	else         { trace(); saveBinaryFile(path(dat), b); trace("save binary file:"+dat); }
997+
		
998
		d = new Date( (res[4]<365*24*60*60*1000) ? res[4]*1000 : res[4] );
999
		d = formatDate(d,2);
1000
		if (res[5]!='""')  id = " ID:" + eval(res[5]);
1001
		if (res[6]!='""')  be = " BE:" + eval(res[6]);
1002
		comments[i] = [ name, eval(res[3]), d + id + be, eval(res[7]), ].join("<>");
1003
	}
1004
	s = "";
1005
	if(comments.length>0) {
1006
		if(!args.append || !DatInfo.cnt) { comments[0] += title; }
1007
		s = comments.join("\n") + "\n";
1008
	}
1009
	return s;
1010
}
1011
@end @*/
1012
1013
//--------------------------------------------------------------------
1014
// History :
1015
//	v.0.1 2015/03/26 created
1016
//	v.0.2 2015/03/27 fixed
1017
//			email-protection から mailto: へ置換を追加
1018
//	v.0.3 2015/03/27 fixed
1019
//			スレッドデータ抽出判定を変更
1020
//	v.0.4 2015/03/27 added
1021-
	var wmi; try { wmi = new WMI(); } catch(e) { wmi=null; }
1021+
//			スレッドデータ抽出できなかった場合のエラーチェックを追加
1022
//	v.0.5 2015/03/28
1023
//			試験的に「したらば」の過去ログ取得をサポート(ほぼ未検証)
1024
//			通信が非同期になってなかったのを修正
1025-
	if(!wmi) { WScript.Sleep(4000);}
1025+
//			bbspink.comの場合も2ch.netの処理に飛ぶようにした
1026-
	else {
1026+
//			スレッドデータからレスを正常に抽出できない場合のチェックを追加
1027-
		do {
1027+
//			既存のdatがあった場合に、レス数が大きくない場合は置換するかどうか問い合わせするようにした
1028-
			var cnt=40;
1028+
//	v.0.6 2015/03/28
1029-
			while(cnt && wmi.isAliveProcess(JANE_EXE, JANE_PATH+JANE_EXE)) { WScript.Sleep(100); cnt--;}
1029+
//			dat格納場所が見つからない場合のチェックを追加
1030-
			if(!cnt) { WScript.Echo(JANE_EXE+"を終了させてください"); }
1030+
//			URLにレス番の指定が無い場合レス番1をURLに追加し、スレの先頭から表示されるようにした
1031-
		} while(!cnt);
1031+
//			一度スレを閉じるための"ALT","T","C","C"のキーを送る時に適当にウェイトを入れた
1032
//	v.0.7 2015/03/29
1033
//			キー送信のウェイトを再度調整 300ms->600ms
1034
//			(メニューが残るのは最初の起動で開く処理がキー操作の途中にくるタイミングなのでキー送信を全体に遅らせた)
1035-
function saveIdx(boardUrl,force) {
1035+
//			既存のdatが存在した場合は、現在のレス位置とし、再度開く時にスレの先頭に移動しないようにした
1036-
	var i,s,r,lines=Math.max(DatInfo.cnt,DatInfo.lines);
1036+
//	v.0.8 2015/03/29
1037
//			LogsファイルをJane Style直下のフォルダ以外に移動している場合、brdファイル読み込みエラーになるのを修正
1038
//			起動パラメタ(オプション指定)を追加しました
1039
//			パラメタなし : urlを問い合わせる(対話型)
1040
//			第1パラメタ  : URL
1041
//			第2パラメタ以降  :
1042
//				http://~  第1パラメタを無視してこちらをurlとして優先する
1043
//				/f         第1パラメタのurlを無視してurlを問い合わせる
1044-
	var state = (lines>=maxRes) ? 0 : IDX_STATE[ (URL===URL_jbbs) ? "jbbs" : "2ch" ];
1044+
//				/n:999     レス番を指定(そのレス番に飛ぶ)
1045
//			コマンド登録時に、wscript "$BASEPATHgethttpdat.js" "$LINK$URL" $INPUT としておくと動的にオプションを指定できます
1046
//	v.0.9 2015/03/30
1047
//			【したらば】の過去ログ取得を拡張
1048-
	var idx = [ datName,DatInfo.title,'',lines,'0','',boardUrl,state,lines,'','','0',last_got,'0','0' ];
1048+
//				・/bbs/read.cgi/ 以外、/bbs/read_archive.cgi/ でも取得する
1049
//				・まず rawmode.cgi での取得を試みる
1050
//				・事前にカテゴリ/板を開いたことが無いスレでも取得できるようにした(スレ一覧も開きます)
1051
//			パラメタのレス番指定は、/n:を省略可能 数字のみでよい
1052
//	v.0.10 2015/03/30
1053
//			【したらば】のスレデータ受信時予期せぬエラーの場合正常としていたのを修正
1054
//	v.0.11 2015/03/31
1055
//			板一覧(Jane2ch.brd)に複数の板識別子が存在する場合、最後のものを採用するように変更
1056
//			【したらば】過去ログで、
1057
//				透明あぼーん(番号が飛んでいる)の場合に「透明あぼーん」を追加しレス番ずれを防止
1058
//				スレデータを抽出できない場合があったのを修正
1059
//	v.0.12 2015/03/31
1060-
	var SQL_CMD_3 = "update idxlist set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,lines]);
1060+
//			2chのデータの中に<a href="mailto:xxx"></a>が無い場合や最後に<br><br>が付いてない場合も抽出できるようにした
1061
//				( [ここ壊れてます]のようなデータのこと)
1062
//			スレ抽出できない場合サーバーメッセージらしきものをエラーメッセージに追加?(datが存在しません/人大杉)
1063
//			したらばのrawmodeで取得したデータでの透明あぼーん処理を追加
1064
//			引数追加とデフォルト動作変更
1065
//				/w      スレを閉じて開きなおす(600ms)
1066
//				/w:999  スレを閉じて開きなおす(wait指定)
1067
//				/-w     スレを閉じない(デフォルト)
1068
//	v.0.13 2015/04/03
1069
//			2chのデータの中に名前が無い(<font.*><b></b></font>)場合に抽出できなかったのを修正
1070
//			引数の指定を順不同にし、以下を追加
1071
//				/a, /append  既存のデータに追加する(差分のみ取得)
1072
//				/b, /bak     保存前に既存のdatファイルが存在した場合は、Logs\bak\フォルダにバックアップコピーする
1073
//			したらばの透明あぼーん補正処理は必要のない場合スキップする
1074
//			2chのサーバーエラーメッセージで"LoadAverage ="が抜けていたのを修正
1075
//	v.0.14 2015/04/04
1076
//			/a 指定時、したらばの過去ログを正常に追加できていなかったのを修正(したらばは過去ログの部分取得が無理なため)
1077
//	v.0.15 2015/04/12
1078
//			レス数を正しく認識できない場合があった(レス番抽出正規表現の間違い)のを修正
1079
//			/a 指定時、2chのdatが無い場合、先頭レス番1が消えるのを修正
1080
//	v.0.16 2015/04/16
1081
//			2chでデータが途中で途切れている場合のチェックを追加
1082
//			(ftp:// のようなデータがある場合、現状では、エラーにならず途切れていることがある)
1083
//	v.0.17 2015/04/17
1084
//			考えを変えて、データが途中で途切れている場合も取得したところまでで処理を続行するように変更した
1085
//			オプションに、/b1, /bak1 を追加(bakupは1回限りでファイルが存在していたら上書きしない)
1086
//	v.0.18 2015/04/21
1087
//			オプション /z を追加(Jane2ch.exeを終了させて、db、idx、subject.txtに情報を設定し、再起動する)
1088
//			 (なお、高速Merge有効時にはsqlite3.exeが必要)
1089
//			 (stateは=3(dat落ち)に設定) ※本来の処理としては、レス数1000(10000)以上では=0のままで良く、未満時は=10(過去ログ)?
1090-
			var SQL_CMD_XENO5 = "update thread set new_lines=new_lines+$2-lines where datname='$1';".expand([,datName,lines]);
1090+
//	v.0.19 2015/04/21
1091
//			引数にurlが含まれていない場合、url入力ボックスが出ずにエラーになってたのを修正
1092
//	v.0.20 2015/04/27
1093
//			したらばの旧過去ログURL(http://[したらばsite]/[カテゴリ]/[掲示板番号]/storage/[スレッド番号].html)もサポート
1094
//			/z オプション時、高速Merge無効時の処理を修正
1095
//			                 高速Merge有効時、sqlite3.exeに加えてSQLite3 ODBC Driverもサポート(どちらか一方があればよい)
1096
//			db,idxのstate値は、=0(brdcustomize.iniの設定値又は1000以上の時)、それ以外は =3(dat落ち) にする
1097
//	v.0.21 2015/04/27
1098
//			/z オプション時、高速Merge有効時、sqlite3.exeとSQLite3 ODBC Driverの両方とも無い場合エラーになってたのを修正
1099
//	v.0.22 2015/04/29
1100
//			2chの過去ログURL形式(/[板識別子]/kako/[スレID(3or4)桁]/([スレID5桁]/)[スレID].html 又は.dat)をサポート
1101
//			ただし、サーバー移転等でURLのサーバー名と過去ログ倉庫が不一致の場合は不可
1102
//			kako形式の場合には/nオプションや/aオプションは無効となる
1103
//			/z 時のdb,idxのstate値は=10に設定される
1104
//			それと関連して、通常URLでメッセージ「error 4002」が返ってきた場合は、URLをkako形式に変えて再トライする
1105
//			また、「error 3001」(datが無い)が返ってきた場合はkako形式のURLに変えて実行すると取得できるかもしれない
1106
//	v.0.23 2015/04/29
1107
//			2chでURLにレス番指定(/l50,/-n10)がくっ付いている場合、正常に処理できなくなっていたのを修正
1108
//	v.0.24 2015/04/29
1109
//			2chで/a指定時、既存のdatファイルが存在していると正常に処理できなくなっていたのを修正
1110
//	v.0.25 2015/04/29
1111
//			したらばで、カテゴリ名に / が含まれている場合に正常に処理できなくなってたのを修正
1112
//	v.0.26 2015/05/04
1113
//			/b オプションが正常に処理できなくなっていたのを修正
1114-
			s[7]  = "" + (parseInt(s[7],10) + lines - parseInt(s[2],10));
1114+
//			(また、Logsフォルダを指定してない場合 /b を付けて無くてもバックアップされてしまっていた)
1115
//			Jane2ch.exeに送るキーコードを変更(/wの時 CTL+w でスレを閉じる, /z の時 ALT+F4 で終了する)
1116
//	v.0.27 2015/05/04
1117
//			ファイル読み書きエラー時、付随情報としてカレントパス、ファイル名を正常に出力するするように修正
1118
//			/redraw (/redraw:999) オプション追加 (スレを開いた後キーコード('T','G','0')を送る)
1119
//			Xenoでは/zオプション時sqlite3.exeは弾くようにした(dbがutf16の場合、日本語が化けるため)、またタイトルも書き換える
1120
//	v.0.28 2015/05/04
1121
//			/redraw 'ALT'を送るのが抜けていたのを修正
1122
//	v.0.29 2015/05/07
1123
//			brdファイル検索時の正規表現文字列の生成(ピリオドが曖昧にマッチしていた)を修正
1124
//			(具体的には、xxx.2ch.netとnext2ch.netの両方が存在していると、後ろのnext2chの方にdatファイルが作成されていた)
1125
//	v.0.30 2015/05/17
1126
//			オプション /log[:][path] を追加 path名の指定には環境変数が使えます(path省略時 %temp%\gethtmldat.log)
1127
//			/w, /redraw のデフォルトのwaitを1200msに変更
1128
//			2ch  - .dat.gz/.dat read追加,URL変換は「error 4002」に限定しない 
1129
//			jbbs - board_info.cgi->/api/setting.cgiに変更
1130
//	v.0.31 2015/05/17
1131-
	var re = new RegExp("^"+datName+"\\..*\\((\\d+)\\)(\\s*)$", "m");
1131+
//			一部のエラーメッセージがきちんと表示されないのを修正
1132-
	s="";
1132+
//			jbbs - 現役のスレ(rawmode.cgi)でスレタイトルとIDが異常になるのを修正、dat落ち扱いしないように修正
1133-
	r=0;
1133+
//			ファイルアクセスを、ADODB StreamからFileSystemObjectに変更(read速度が大幅に改善)
1134-
	if(fso.FileExists("subject.txt")) try{s=loadFile("subject.txt"); r=1;} catch(e){r=-1;}
1134+
//	v.0.32 2015/05/17
1135-
	if(force) {
1135+
//			2ch - URL変換再試行時もエラーの場合、最初のエラー内容を表示するように修正
1136-
		s = s.replace(re,"");
1136+
//	v.0.33 2015/05/17
1137-
		s = datName+".dat<>"+DatInfo.title+"("+lines+")\r\n" + s;
1137+
//			2ch - URL変換再試行は「error」に限定(人大杉/LoadAverageは除外)
1138-
		try {saveSubjectTxt("subject.txt", s, force);}
1138+
//--------------------------------------------------------------------