PageSourceSearch

http://www.katewed.co.kr/js/post_comment.js?1791267808

js katewed.co.kr collected 2026-10-06 20:15:54 UTC 43,139 bytes, 1,245 lines download raw bytes

1
2var POST_COMMENT = function(){
3
4	var post_code,total_count,comment_count_obj,comment_form,comment_body, comment_area,child_comment_code,use_sub_secret_comment;
5	var $comment_container;
6	var comment_img_box;
7
8	var main_comment_image, comment_image, sub_comment_image , use_secret_comment;
9
10	var commentInit = function(code){
11		post_code = code;
12		comment_count_obj = $('#comment_count');
13		total_count = Math.round(comment_count_obj.text());
14		$comment_container = $('#comment_container');
15		comment_form = $('#comment_form');
16		comment_body = $('#comment_body');
17		comment_area = $('#comment_area');
18		comment_img_box = $('#comment_img_box');
19		use_secret_comment = $('#use_secret_comment');
20		captcha_answer = $('#captcha_answer');
21		captcha_key = $('#captcha_key');
22		captcha_img = $('#captcha_img');
23
24		main_comment_image = [];
25		comment_image = {};
26		sub_comment_image = {};
27
28		$secret = comment_form.find('._secret');
29		$secret.on('click', function(){
30			if($secret.hasClass('active')){
31				$secret.removeClass('active');
32				$secret.val('N');
33				use_secret_comment.val('N');
34			}else{
35				$secret.addClass('active');
36				$secret.val('Y');
37				use_secret_comment.val('Y');
38			}
39		});
40
41
42		/*
43		comment_area.off('input keyup  paste change','._comment_textarea')
44			.on('input keyup  paste change','._comment_textarea', function (e) {
45				var input = $(this);
46				setTimeout(function(){
47					input.limitLength({max_byte:3000});
48				}, 0);
49		});
50
51		comment_area.off('keydown.enter','._comment_textarea')
52			.on('keydown.enter','._comment_textarea', function (e) {
53				if (e.keyCode == 13) {
54					var target = $('#'+$(this).data('action'));
55					target.click();
56					e.preventDefault();
57				}
58			});
59			*/
60
61		comment_area.off('input keyup keydown paste change','._comment_nick')
62			.on('input keyup keydown paste change','._comment_nick', function () {
63				var input = $(this);
64				setTimeout(function(){
65					input.limitLength({max_byte:30});
66				}, 0);
67			});
68
69		/*
70		comment_area.off('input keyup keydown paste change','._comment_password')
71			.on('input keyup keydown paste change','._comment_password', function () {
72				var input = $(this);
73				setTimeout(function(){
74					input.limitLength({max_byte:30});
75				}, 0);
76			});
77			*/
78
79
80		$("#comment_image_upload_btn").fileupload({
81			url: '/ajax/comment_image_upload.cm',
82			dataType: 'json',
83			singleFileUploads:false,
84			limitMultiFileUploads: 5,
85			dropZone: null,
86			maxFileSize : 20000000, //20mb
87			limitMultiFileUploadSize : 110000000, //110 mb
88			start: function (e, data) {},
89			progress: function (e, data) {},
90			done: function (e, data) {
91				$("#comment_image_box").show();
92				$.each(data.result.comment_images,function(i,file){
93					var url = CDN_UPLOAD_URL+file.url;
94					var html ='<span class="file-add"><input type="hidden" name="tmp_img[]" value="'+file.tmp_idx+'"><div class="file-add-bg" style="background: url('+url+') no-repeat center center;"></div><em class="del" onclick="POST_COMMENT.removeCommentImg($(this))"></em></span>';
95					$("#comment_image_box").append(html);
96
97				});
98			},
99			fail: function (e, data) {
100			}
101		});
102
103		autosize(comment_area.find('.textarea_block textarea'));
104
105		//$("#comment_image_box").sortable({
106		//	placeholder: 'ui-state-highlight'
107		//});
108	};
109
110	var removeCommentImg = function(obj){
111		var box_obj = obj.parent().parent();
112		obj.parent().remove();
113		if(box_obj.find('.file-add').length == 0)box_obj.hide();
114	};
115
116	var updateAttachToolPosition = function(form,editor){
117		var $tool = form.find('._attach_tool');
118		var scroll_top = editor.$window.scrollTop();
119		var el_offset = editor.$el.offset();
120
121		var boundingRect;
122
123		var range = editor.selection.ranges(0);
124		if (range && range.collapsed && editor.selection.inEditor()) {
125			var remove = false;
126
127			editor.markers.remove();
128			if (editor.$el.find('.fr-marker').length == 0) {
129				editor.markers.insert();
130				remove = true;
131			}
132
133			var $marker = editor.$el.find('.fr-marker:first');
134			$marker.css('line-height','inherit');
135			$marker.css('display', 'inline');
136			var offset = $marker.offset();
137			boundingRect = {};
138			boundingRect.left = offset.left;
139			boundingRect.width = 0;
140			boundingRect.height = parseInt($marker.css('line-height'), 10) || 20;
141
142			var marker_tag_name = $marker.parent().prop("tagName");
143			marker_tag_name = marker_tag_name.toLowerCase();
144			if($.inArray(marker_tag_name, ['p','span','h1','h2','h3','h4','h5','h6','h7','h8','strong','b','font','a','i'])) {
145				var outer_h = Math.round($marker.parent().outerHeight());
146				boundingRect.height = outer_h;
147			}
148			boundingRect.top = offset.top - $(editor.original_window).scrollTop();
149			boundingRect.right = 1;
150			boundingRect.bottom = 1;
151			boundingRect.ok = true;
152			$marker.css('display', 'none');
153
154			if (remove) editor.markers.remove();
155		}
156		else if (range) {
157			boundingRect = range.getBoundingClientRect();
158		}
159
160		var attach_tool_left = el_offset.left-boundingRect.left;
161		$tool[attach_tool_left ==0?'show':'hide']();
162		var attach_tool_top = scroll_top+boundingRect.top-el_offset.top + (boundingRect.height/2) - ($tool.outerHeight()/2);
163		$tool.css('top',attach_tool_top);
164	};
165
166	var hideAttachTool = function(obj){
167		obj.find('._attach_tool').removeClass('open');
168	};
169
170
171	var commentIncreaseTotalCount = function(){
172		total_count++;
173		comment_count_obj.text(total_count);
174	};
175
176	var commentDecreaseTotalCount = function(decrease_count = 1){
177		total_count -= decrease_count;
178		comment_count_obj.text(total_count);
179	};
180
181	var is_writing = false;
182
183	/**
184	 * 댓글 등록 **성공** 처리. 등록 응답에만 쓴다 — 새로고침은 이 처리를 타지 않는다
185	 * (새로고침이 저장을 부르면 화면이 "저장된 것처럼" 움직여 그대로 오해가 된다).
186	 */
187	var applyCommentAddSuccess = function(result){
188		comment_body.val('');
189		$("#comment_image_box").empty().hide();
190		commentFormHide();
191		commentIncreaseTotalCount();
192		if(result.comment_sorting_type == 'forward_new_comment'){
193			$comment_container.prepend(result.html);
194			moveToCommentListTop();
195		}else {
196			$comment_container.find('div.comment_list div.comment:last').length === 0 ? $comment_container.append(result.html) : $comment_container.find('div.comment_list div.comment:last').after(result.html);
197		}
198		autosize.update($('.comment_textarea').find('#comment_body'));
199
200		// 요구받았던 캡차는 한 번 쓰면 끝난다(키도 서버에서 소비됐다) — 블록을 걷어낸다.
201		captchaChallengeBlock(comment_form).remove();
202	};
203
204	var commentAdd = function(){
205		if(!is_writing){
206			var data = comment_form.serializeObject();
207
208			if (data.captcha_key) {
209				if (data.body.length > 0 && data.captcha_answer.length === 0) {
210					refreshCaptchaForSubmit('comment');
211					alert(getLocalizeString("설명_보안문자입력", "", "보안 문자를 입력해 주세요."));
212					return;
213				}
214			}
215
216			var menu_url = window.location.pathname;
217			data.menu_url = menu_url;
218			$.ajax({
219				type:'post',
220				data:data,
221				url:'/ajax/post_comment_add.cm',
222				dataType:'json',
223				success:function(result){
224          tokenRefresh(comment_form, result.refresh_token, result.refresh_token_key);
225					if(result.msg=='SUCCESS') {
226						if(result.qna_status_changed){ location.reload(); return; }
227						applyCommentAddSuccess(result);
228					}else {
229						// 애매한 스팸 점수면 서버가 문자 캡차를 요구한다 — 문구와 함께 캡차를 띄운다.
230						if (result.captcha_required) applyCaptchaChallenge(result, 'comment');
231						alert(result.msg);
232					}
233
234					is_writing = false;
235				},
236				complete:function(){
237					if (data.captcha_key) {
238						refreshCaptchaAfterSubmit('comment');
239					}
240				}
241			});
242			is_writing = true;
243		}
244	};
245
246	var refreshCaptcha = function(form_type = 'comment', code){
247		var sub_form_captcha_answer = $('#sub_form_captcha_answer_'+code);
248		var sub_form_captcha_key = $('#sub_form_captcha_key_'+code);
249		var sub_form_captcha_img = $('#sub_form_captcha_img_'+code);
250
251		$.ajax({
252			type:'post',
253			data:{
254				'captcha_key': form_type == 'comment' ? captcha_key.val() : sub_form_captcha_key.val(),
255				'target': 'comment',
256			},
257			url:'/ajax/refresh_captcha.cm',
258			dataType:'json',
259			success:function(result){
260				if (result.msg == 'SUCCESS') {
261					if (form_type == 'comment') {
262						captcha_answer.val('');
263						captcha_img.attr('src', result.captcha_img);
264						captcha_key.val(result.key);
265					} else if (form_type == 'sub_form') {
266						sub_form_captcha_answer.val('');
267						sub_form_captcha_img.attr('src', result.captcha_img);
268						sub_form_captcha_key.val(result.key);
269					}
270				} else {
271					alert(result.msg);
272				}
273			}
274		});
275	};
276
277	// ── 요구형 문자 캡차 — 서버가 애매한 스팸 점수(0.50 이상·임계 미만)에서 요구한다 ──────
278	// 사이트가 캡차를 켠 경우의 블록(.captcha_block·.sub_form_captcha_block)은 **서버가** 그려서
279	// 항상 폼 안에 있다. 여기서 만드는 블록은 요구받았을 때만 생기고, 입력칸 이름은 같다
280	// (captcha_key·captcha_answer) — 그래서 폼 직렬화에 그대로 실려 서버가 검증한다.
281	var CAPTCHA_CHALLENGE_ATTR = 'data-fo-captcha-challenge';
282
283	// 사이트 캡차 화면(site_ui.cls)이 쓰는 새로고침 아이콘과 같은 모양이다.
284	var CAPTCHA_CHALLENGE_REFRESH_ICON = '<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">'
285		+ '<path d="M1 0.5H27C27.2761 0.5 27.5 0.723857 27.5 1V27C27.5 27.2761 27.2761 27.5 27 27.5H1C0.723858 27.5 0.5 27.2761 0.5 27V1C0.5 0.723858 0.723857 0.5 1 0.5Z" fill="white"/>'
286		+ '<path d="M1 0.5H27C27.2761 0.5 27.5 0.723857 27.5 1V27C27.5 27.2761 27.2761 27.5 27 27.5H1C0.723858 27.5 0.5 27.2761 0.5 27V1C0.5 0.723858 0.723857 0.5 1 0.5Z" stroke="#BCC0C6"/>'
287		+ '<path d="M15.3333 7.3335C15.3333 7.3335 15.8995 7.41438 18.2426 9.75752C20.5858 12.1007 20.5858 15.8997 18.2426 18.2428C17.4125 19.073 16.3995 19.609 15.3333 19.8509M15.3333 7.3335L19.3333 7.3335M15.3333 7.3335L15.3333 11.3335M12.6667 20.6667C12.6667 20.6667 12.1005 20.5858 9.75736 18.2427C7.41421 15.8995 7.41421 12.1005 9.75736 9.75739C10.5875 8.92721 11.6005 8.39116 12.6667 8.14925M12.6667 20.6667L8.66667 20.6668M12.6667 20.6667L12.6667 16.6668" stroke="#4B515B" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>'
288		+ '</svg>';
289
290	// 그 폼의 요구 블록(없으면 빈 jQuery). 폼마다 하나만 만든다.
291	var captchaChallengeBlock = function(form){
292		return form.find('[' + CAPTCHA_CHALLENGE_ATTR + ']');
293	};
294
295	// 폼 고르기 — 일반 댓글은 #comment_form, 대댓글은 그 댓글의 답글 폼이다.
296	var captchaChallengeForm = function(form_type, code){
297		if (form_type == 'sub_form' && code) return $('#' + code).find('._add_sub_form_' + code);
298
299		return comment_form;
300	};
301
302	var createCaptchaChallengeBlock = function(){
303		var block = $('<div class="captcha_block" ' + CAPTCHA_CHALLENGE_ATTR + '="1" style="display: none;"></div>');
304		var row = $('<div style="display: flex; align-items: center;"></div>');
305		var holder = $('<div style="display: inline-flex; align-items: center; gap: 8px; margin-right: 16px;"></div>');
306		var refresh = $('<div class="_captcha_challenge_refresh" style="cursor: pointer; width: 28px; height: 28px;"></div>');
307
308		refresh.html(CAPTCHA_CHALLENGE_REFRESH_ICON);
309		holder.append($('<img width="113" height="30" alt="" />')).append(refresh);
310		row.append(holder)
311			.append('<input type="hidden" name="captcha_key" />')
312			.append('<input type="text" name="captcha_answer" class="capcha_input" />');
313		block.append(row).append('<span class="captcha_description"></span>');
314
315		// 문구는 기존 LOCALIZE 키를 그대로 쓴다(새 키를 만들지 않는다). 값은 **속성·텍스트로**
316		// 넣는다 — 문자열 조합으로 HTML 에 끼우면 현지화 문구가 마크업을 흔들 수 있다.
317		block.find('input[name="captcha_answer"]').attr('placeholder', getLocalizeString('설명_보안문자입력', '', '보안 문자를 입력해 주세요.'));
318		block.find('.captcha_description').text(getLocalizeString('설명_공백없이입력대소문자구분', '', '공백 없이 입력해 주세요. 대소문자를 구분합니다.'));
319
320		return block;
321	};
322
323	// 서버 요구 응답(captcha_required·captcha_img·key)을 그 폼에 반영한다.
324	var applyCaptchaChallenge = function(result, form_type, code){
325		var form = captchaChallengeForm(form_type, code);
326
327		// 그릴 수 없는 응답이면 문구만 남는다(등록을 막지 않는다 — 서버가 저장 여부를 정한다).
328		if (form.length === 0 || !result.captcha_img || !result.key) return;
329
330		var block = captchaChallengeBlock(form);
331
332		if (block.length === 0) {
333			block = createCaptchaChallengeBlock();
334			block.find('._captcha_challenge_refresh').on('click', function(){
335				refreshCaptchaChallenge(form_type, code);
336			});
337			form.append(block);
338		}
339
340		block.find('img').attr('src', result.captcha_img);
341		block.find('input[name="captcha_key"]').val(result.key);
342		block.find('input[name="captcha_answer"]').val('');
343		block.css('display', 'flex');
344	};
345
346	// 새로고침 — **발급 전용 엔드포인트**로 새 이미지·키만 받는다.
347	//
348	// 댓글 등록 경로(post_comment_add.cm)를 다시 태우면 안 된다: 새로고침이 판정·게이트를 다시
349	// 태우고, 그 사이 판정이 통과하면(캐시 만료·판정 실패) **실제로 댓글이 저장된다** — 사용자는
350	// 캡차만 새로 받으려 했는데 글이 올라간다. 그래서 폼을 직렬화해 보내지 않는다(본문·이미지가
351	// 실려 나가면 그 자체가 저장 요청의 재료다). 서버는 이 키의 결속 표식을 선점(DEL)한 요청에만
352	// 새 캡차를 발급하므로, 이미 쓴 키로는 발급되지 않고 문구만 돌아온다.
353	var refreshCaptchaChallenge = function(form_type, code){
354		var form = captchaChallengeForm(form_type, code);
355		var block = captchaChallengeBlock(form);
356		if (form.length === 0 || block.length === 0) return;
357
358		$.ajax({
359			type:'post',
360			data:{
361				'captcha_key': block.find('input[name="captcha_key"]').val(),
362				'target': 'comment',
363				'band_captcha': '1'
364			},
365			url:'/ajax/refresh_captcha.cm',
366			dataType:'json',
367			success:function(result){
368				if (result.msg == 'SUCCESS') {
369					// 새 이미지·새 키를 그대로 반영한다(입력칸은 비운다).
370					applyCaptchaChallenge(result, form_type, code);
371				} else {
372					alert(result.msg);
373				}
374			}
375		});
376	};
377
378	// 캡차를 다시 그리는 자리 — 요구형 캡차가 떠 있으면 그것을, 아니면 사이트 캡차를 갱신한다.
379	var refreshCaptchaForSubmit = function(form_type, code){
380		if (captchaChallengeBlock(captchaChallengeForm(form_type, code)).length > 0) {
381			refreshCaptchaChallenge(form_type, code);
382			return;
383		}
384
385		if (form_type == 'sub_form') refreshCaptcha('sub_form', code);
386		else refreshCaptcha();
387	};
388
389	/**
390	 * 등록 **시도 뒤**의 갱신 — master 와 같이 사이트 캡차만 새로 받는다.
391	 *
392	 *  - 요구형 캡차가 떠 있으면 아무것도 하지 않는다: 등록 실패 응답에 서버가 **이미 새 캡차를
393	 *    담아 줬고**(그 키의 결속 표식도 갓 발급됐다), 여기서 다시 부르면 표식만 소모된다.
394	 *  - 사이트 캡차가 없는 폼도 건드리지 않는다: 보낼 키가 없어 서버가 오류 문구를 돌려주고,
395	 *    그 문구가 **등록에 성공한 직후에** alert 로 뜬다.
396	 */
397	var refreshCaptchaAfterSubmit = function(form_type, code){
398		if (captchaChallengeBlock(captchaChallengeForm(form_type, code)).length > 0) return;
399
400		if (form_type == 'sub_form') {
401			if ($('#sub_form_captcha_key_'+code).length > 0) refreshCaptcha('sub_form', code);
402			return;
403		}
404
405		if (captcha_key.length > 0) refreshCaptcha();
406	};
407
408	var commentFormHide = function(){
409		$comment_container = $('#comment_container');
410
411		$comment_container.find('._comment_area').show();
412		$comment_container.find('._sub_comment_wrap').show();
413		$comment_container.find('._sub_form').hide();
414		$comment_container.find('._comment_edit_form').hide();
415		$comment_container.find('.write').show();
416	};
417
418	var commentShowEdit = function(code, interlock_type){
419		var obj = $('#'+code);
420		var comment_edit_body = obj.find('._comment_edit_body_'+code);
421		var comment_wrap = obj.find('._comment_wrap_'+code);
422
423		comment_image[code] = [];
424		comment_edit_body.data('org_body',comment_edit_body.val());
425		commentFormHide();
426		comment_wrap.find('._comment_area').hide();
427		comment_wrap.find('.write').hide();
428
429		$.ajax({
430			type:'post',
431			data: {'code' : code, 'board_type': interlock_type},
432			url:'/ajax/append_post_comment_html.cm',
433			dataType:'json',
434			success:function(res){
435				obj.find('._comment_edit_form_'+code).html(res.html);
436				autosize.update(obj.find('._comment_edit_body'));
437				if(comment_wrap.find("._comment_body img").length>0) $("#comment_image_modify_box_"+code).show();
438				$("#comment_image_upload_modify_btn_"+code).fileupload({
439					url: '/ajax/comment_image_upload.cm',
440					dataType: 'json',
441					singleFileUploads:false,
442					limitMultiFileUploads: 5,
443					dropZone: null,
444					maxFileSize : 20000000, //20mb
445					limitMultiFileUploadSize : 110000000, //110 mb
446					start: function (e, data) {},
447					progress: function (e, data) {},
448					done: function (e, data) {
449						$("#comment_image_modify_box_"+code).show();
450						$.each(data.result.comment_images,function(i,file){
451							var url = CDN_UPLOAD_URL+file.url;
452							var html ='<span class="file-add"><input type="hidden" name="tmp_img[]" value="'+file.tmp_idx+'"><div class="file-add-bg" style="background: url('+url+') no-repeat center center;"></div><em class="del" onclick="POST_COMMENT.removeCommentImg($(this))"></em></span>';
453							$("#comment_image_modify_box_"+code).append(html);
454
455						});
456					},
457					fail: function (e, data) {
458					}
459				});
460				autosize(comment_area.find('.textarea_block textarea'));
461			}
462		});
463
464		obj.find('._comment_edit_form_'+code).show();
465
466	};
467
468	var commentEdit = function(code){
469		var obj = $('#'+code);
470		var comment_edit_body = obj.find('._comment_edit_body_'+code);
471
472		var form = obj.find('._comment_edit_form_'+code+' ._edit_form');
473
474		var comment_body = obj.find('._comment_wrap_'+code+' ._comment_body_'+code);
475
476
477		var data = form.serializeObject();
478
479		var new_img = form.find("input[name='tmp_img[]']");
480		var org_img = form.find("input[name='org_img[]']");
481		var img_old_cnt = form.find("input[name='org_image_old_cnt']");
482		var secret_comment = form.find("input[name='secret_comment']");
483
484		if((comment_edit_body.val() == comment_edit_body.data('org_body')) && (new_img.length == 0) && (img_old_cnt.val() == org_img.length) && secret_comment.val() == secret_comment.attr('orig')) {
485			commentFormHide();
486			return;
487		}
488		$.ajax({
489			type:'post',
490			data:data,
491			url:'/ajax/post_comment_add.cm',
492			dataType:'json',
493			success:function(result){
494        tokenRefresh(form, result.refresh_token, result.refresh_token_key);
495				if(result.msg=='SUCCESS') {
496					if(result.qna_status_changed){ location.reload(); return; }
497					comment_edit_body.data('org_body', result.data.body);
498					comment_body.html('<div>'+result.data.body+'</div>');
499					comment_body.append(result.data.img_html);
500					switch(secret_comment.val()){
501						case 'Y':
502							$('#icon_' + code).show();
503							break;
504						case 'N':
505							$('#icon_' + code).hide();
506							break;
507					}
508					commentFormHide();
509					commentDestroyEdit(code);
510				}else
511					alert(result.msg);
512			}
513		});
514
515	};
516
517	var commentEditMap = function(code){
518		var obj = $('#'+code);
519		var comment_edit_body = obj.find('._comment_edit_body_'+code);
520
521		var form = obj.find('._comment_edit_form_'+code+' ._edit_form');
522
523		var comment_body = obj.find('._comment_wrap_'+code+' ._comment_body_'+code);
524
525
526		var data = form.serializeObject();
527
528		var new_img = form.find("input[name='tmp_img[]']");
529		var org_img = form.find("input[name='org_img[]']");
530		var img_old_cnt = form.find("input[name='org_image_old_cnt']");
531
532		if((comment_edit_body.val() == comment_edit_body.data('org_body')) && (new_img.length == 0) && (img_old_cnt.val() == org_img.length)) {
533			commentFormHide();
534			return;
535		}
536		$.ajax({
537			type:'post',
538			data:data,
539			url:'/ajax/map_comment_add.cm',
540			dataType:'json',
541			success:function(result){
542				if(result.msg=='SUCCESS') {
543					comment_edit_body.data('org_body', result.data.body);
544					comment_body.html(result.data.body);
545					comment_body.append(result.data.img_html);
546					commentFormHide();
547					commentDestroyEdit(code);
548				}else
549					alert(result.msg);
550			}
551		});
552	};
553
554	var commentDestroyEdit = function(code){
555		var obj = $('#'+code);
556		comment_image[code] = [];
557	};
558
559	var commentDestroyAddEditor = function(code){
560		var obj = $('._add_sub_form_'+code);
561		comment_image[code] = [];
562		var comment_edit_body = obj.find('._comment_add_body_'+code);
563		comment_edit_body.val('');
564	};
565
566	var commentCancelEdit = function(code){
567		var obj = $('#'+code);
568		var comment_edit_body = obj.find('._comment_edit_body_'+code);
569		comment_edit_body.val(comment_edit_body.data('org_body'));
570		commentFormHide();
571		commentDestroyEdit(code);
572	};
573
574	var commentShowSubForm = function(code){
575		var obj = $('#'+code);
576		var sub_form = obj.find('._sub_form_'+code);
577
578		var use_sub_secret_comment = sub_form.find('#use_sub_secret_comment');
579		$sub_secret = sub_form.find('._secret');
580		$sub_secret.on('click', function(){
581			if($sub_secret.hasClass('active')){
582				$sub_secret.removeClass('active');
583				$sub_secret.val('N');
584				use_sub_secret_comment.val('N');
585			}else{
586				$sub_secret.addClass('active');
587				$sub_secret.val('Y');
588				use_sub_secret_comment.val('Y');
589			}
590		});
591
592		commentFormHide();
593		if(sub_form.data('show')=='Y'){
594			sub_form.data('show', 'N');
595			$('body').off('mouseup.sub_comment');
596		}else {
597			sub_form.data('show', 'Y');
598			obj.find('._sub_form_' + code).show();
599			sub_comment_image[code] = [];
600			var comment_add_body = obj.find('._comment_add_body_' + code);
601
602			$('body').off('mouseup.sub_comment')
603				.on('mouseup.sub_comment', function (e) {
604					var $c_target = $(e.target);
605					var $s_form = $c_target.closest('._sub_form_' + code+', ._show_sub_form_btn_'+code);
606					if ($s_form.length == 0) {
607
608						var text = comment_add_body.val();
609						sub_form.data('show', 'N');
610						if(text == '') {
611							$('body').off('mouseup.sub_comment');
612							commentFormHide();
613						}
614					}
615				});
616		}
617		$("#comment_image_upload_btn_"+code).fileupload({
618			url: '/ajax/comment_image_upload.cm',
619			dataType: 'json',
620			singleFileUploads:false,
621			limitMultiFileUploads: 5,
622			dropZone: null,
623			maxFileSize : 20000000, //20mb
624			limitMultiFileUploadSize : 110000000, //110 mb
625			start: function (e, data) {},
626			progress: function (e, data) {},
627			done: function (e, data) {
628				$("#comment_image_box_"+code).show();
629				$.each(data.result.comment_images,function(i,file){
630					var url = CDN_UPLOAD_URL+file.url;
631					var html ='<span class="file-add"><input type="hidden" name="tmp_img[]" value="'+file.tmp_idx+'"><div class="file-add-bg" style="background: url('+url+') no-repeat center center;"></div><em class="del" onclick="POST_COMMENT.removeCommentImg($(this))"></em></span>';
632					$("#comment_image_box_"+code).append(html);
633
634				});
635			},
636			fail: function (e, data) {
637			}
638		});
639	};
640
641	/**
642	 * 대댓글 등록 성공 처리. 위 댓글 등록과 같은 이유로 분리한다(캡차 새로고침도 쓴다).
643	 */
644	var applyCommentAddSubSuccess = function(result, code){
645		var obj = $('#'+code);
646		var comment_sub_body = obj.find('._comment_add_body_'+code);
647		var $image_box = obj.find('#comment_image_box_'+code);
648
649		comment_sub_body.val('');
650		commentFormHide();
651		commentAddSubHTML(result.data.parent_code !='' ? result.data.parent_code : result.data.code,result.html);
652		commentDestroyAddEditor(code);
653		//self.location.hash=result.data.code;
654
655		$image_box.empty();
656
657		// 요구받았던 캡차는 한 번 쓰면 끝난다(키도 서버에서 소비됐다) — 블록을 걷어낸다.
658		captchaChallengeBlock(obj.find('._add_sub_form_'+code)).remove();
659	};
660
661	var commentAddSub = function(code){
662		var obj = $('#'+code);
663		var comment_sub_body = obj.find('._comment_add_body_'+code);
664		var form = obj.find('._add_sub_form_'+code);
665		var $image_box = obj.find('#comment_image_box_'+code);
666		var data = form.serializeObject();
667
668		var tmp_img = {'temp_images':sub_comment_image[code]};
669		data = $.extend(data,tmp_img);
670
671		if (data.captcha_key) {
672			if (data.body.length > 0 && data.captcha_answer.length === 0) {
673				refreshCaptchaForSubmit('sub_form', code);
674				alert(getLocalizeString('설명_보안문자입력','','보안 문자를 입력해 주세요.'));
675				return;
676			}
677		}
678
679		$.ajax({
680			type:'post',
681			data:data,
682			url:'/ajax/post_comment_add.cm',
683			dataType:'json',
684			success:function(result){
685				tokenRefresh(form, result.refresh_token, result.refresh_token_key);
686
687				if(result.msg=='SUCCESS') {
688					if(result.qna_status_changed){ location.reload(); return; }
689					applyCommentAddSubSuccess(result, code);
690				} else {
691					// 애매한 스팸 점수면 서버가 문자 캡차를 요구한다 — 문구와 함께 캡차를 띄운다.
692					if (result.captcha_required) applyCaptchaChallenge(result, 'sub_form', code);
693					alert(result.msg);
694				}
695			},
696			complete:function(){
697				if (data.captcha_key) {
698					refreshCaptchaAfterSubmit('sub_form', code);
699				}
700			}
701		});
702	};
703
704  var tokenRefresh = function(form, refresh_token, refresh_token_key){
705    form.find('input[name="comment_token"]').val(refresh_token ? refresh_token : "");
706    form.find('input[name="comment_token_key"]').val(refresh_token_key ? refresh_token_key : "");
707  };
708  
709	var commentMapAddSub = function(code){
710		var obj = $('#'+code);
711		var comment_sub_body = obj.find('._comment_add_body_'+code);
712		var form = obj.find('._add_sub_form_'+code);
713		var data = form.serializeObject();
714
715		var tmp_img = {'temp_images':sub_comment_image[code]};
716		data = $.extend(data,tmp_img);
717
718		$.ajax({
719			type:'post',
720			data:data,
721			url:'/ajax/map_comment_add.cm',
722			dataType:'json',
723			success:function(result){
724				if(result.msg=='SUCCESS') {
725					comment_sub_body.val('');
726					commentFormHide();
727					if(result.map_listing == 'map'){
728						var map_sub_comment_count = 0;
729						map_sub_comment_count = Math.round($('#list_'+result.list_idx).find('#comment_count').text());
730						map_sub_comment_count++;
731						$('#list_'+result.list_idx).find('#comment_count').text(map_sub_comment_count);
732						$('#comment_area').find('#comment_count').text(map_sub_comment_count);
733						$('#list_pop_'+result.list_idx).find('#comment_count').text(map_sub_comment_count);
734						var sub_code = result.data.parent_code !='' ? result.data.parent_code : result.data.code;
735						var comment_sub_list = $('#'+sub_code).find('._comment_sub_list');
736						comment_sub_list.append(result.html);
737						commentIncreaseTotalCount();
738					}else{
739						commentAddSubHTML(result.data.parent_code !='' ? result.data.parent_code : result.data.code,result.html);
740					}
741					commentDestroyAddEditor(code);
742					//self.location.hash=result.data.code;
743				}else
744					alert(result.msg);
745			}
746		});
747	};
748
749	var commentShowSubEdit = function(code){
750		var obj = $('#'+code);
751		var comment_edit_body = obj.find('._comment_sub_edit_body');
752		comment_edit_body.data('org_body',comment_edit_body.val());
753		comment_edit_body.focus();
754		commentFormHide();
755		obj.find('._comment_sub_wrap').hide();
756		obj.find('._comment_sub_edit_form').show();
757
758		$("#comment_image_upload_modify_btn_"+code).fileupload({
759			url: '/ajax/comment_image_upload.cm',
760			dataType: 'json',
761			singleFileUploads:false,
762			limitMultiFileUploads: 5,
763			dropZone: null,
764			maxFileSize : 20000000, //20mb
765			limitMultiFileUploadSize : 110000000, //110 mb
766			start: function (e, data) {},
767			progress: function (e, data) {},
768			done: function (e, data) {
769				$("#comment_image_modify_box_"+code).show();
770				$.each(data.result.comment_images,function(i,file){
771					var url = CDN_UPLOAD_URL+file.url;
772					var html ='<span class="file-add"><input type="hidden" name="tmp_img[]" value="'+file.tmp_idx+'"><div class="file-add-bg" style="background: url('+url+') no-repeat center center;"></div><em class="del" onclick="POST_COMMENT.removeCommentImg($(this))"></em></span>';
773					$("#comment_image_modify_box_"+code).append(html);
774
775				});
776			},
777			fail: function (e, data) {
778			}
779		});
780
781	};
782
783	var commentCancelSubEdit = function(code){
784		var obj = $('#'+code);
785		var comment_edit_body = obj.find('._comment_sub_edit_body');
786		comment_edit_body.val(comment_edit_body.data('org_body'));
787		commentFormHide();
788
789	};
790
791	var commentSubEdit = function(code){
792		var obj = $('#'+code);
793		var comment_edit_body = obj.find('._comment_sub_edit_body');
794		var comment_body = obj.find('._comment_sub_body');
795		var form = obj.find('._sub_edit_form');
796		var data = form.serializeObject();
797		if(comment_edit_body.val() == comment_edit_body.data('org_body')) {
798			commentFormHide();
799			return;
800		}
801		$.ajax({
802			type:'post',
803			data:data,
804			url:'/ajax/post_comment_add.cm',
805			dataType:'json',
806			success:function(result){
807				if(result.msg=='SUCCESS') {
808					if(result.qna_status_changed){ location.reload(); return; }
809					comment_edit_body.data('org_body', result.data.body);
810					comment_body.html($.nl2br(result.data.body));
811					commentFormHide();
812				}else
813					alert(result.msg);
814			}
815		});
816
817	};
818
819	var commentAddHTML = function(html){
820		commentIncreaseTotalCount();
821		comment_container.append(html);
822	};
823
824
825	var commentConfirmShow = function(event, code , type, interlock_type, use_interlock_board){
826		$post_secret_password = $('#post_secret_password');
827
828		if($post_secret_password.length==0){
829			$post_secret_password = $('<div class="remove-pop" id="post_secret_password" style="position:absolute; left:0;top:0;z-index:99999;"><p>' + LOCALIZE.설명_작성시등록하신비밀번호를입력해주세요() + '</p><div class="input_area"><input type="password" placeholder="' + LOCALIZE.설명_비밀번호() + '"><button class="btn btn-primary _confirm">' + LOCALIZE.버튼_확인닫기() + '</button></div></div>').hide();
830			$('body').append($post_secret_password);
831		}
832			var $post_link = $(event.target);
833
834			var top = $post_link.offset().top;
835			var left = $post_link.offset().left;
836
837			$post_secret_password.css({
838				position : 'absolute',
839				top : top,
840				left : left
841			});
842		$post_secret_password.find('input').val('');
843			$post_secret_password.show();
844			$post_secret_password.off('click','._confirm')
845				.on('click','._confirm',function(){
846					var secret_pass = $post_secret_password.find('input').val();
847					$post_secret_password.hide();
848					switch(type){
849						case 'show' : commentShow(code,secret_pass,interlock_type);
850						break;
851						case 'delete' : commentDelete(code,secret_pass,interlock_type,use_interlock_board);
852						break;
853						case 'edit' :  commentEditShow(code,secret_pass,interlock_type);
854						break;
855					}
856				});
857
858			$('body').off('mousedown.post_secret')
859				.on('mousedown.post_secret',function(e){
860					var $tmp = $(e.target).closest('#post_secret_password');
861					if($tmp.length==0) {
862						$post_secret_password.hide();
863						$('body').off('click.post_secret');
864					}
865				});
866	};
867
868	var commentMapConfirmShow = function(event, code, type, interlock_type){
869		$post_secret_password = $('#post_secret_password');
870		if($post_secret_password.length==0){
871			$post_secret_password = $('<div class="remove-pop" id="post_secret_password" style="position:absolute; left:0;top:0;z-index:99999;"><p>'+LOCALIZE.설명_작성시등록하신비밀번호를입력해주세요()+'</p><div class="input_area"><input type="password" placeholder="'+LOCALIZE.설명_비밀번호()+'"><button class="btn btn-primary _confirm">'+LOCALIZE.버튼_확인닫기()+'</button></div></div>').hide();
872			$('body').append($post_secret_password);
873		}
874		var $post_link = $(event.target);
875
876		var top = $post_link.offset().top;
877		var left = $post_link.offset().left;
878
879		$post_secret_password.css({
880			position : 'absolute',
881			top : top,
882			left : left
883		});
884
885		$post_secret_password.find('input').val('');
886		$post_secret_password.show();
887		$post_secret_password.off('click','._confirm')
888			.on('click','._confirm',function(){
889				var secret_pass = $post_secret_password.find('input').val();
890				$post_secret_password.hide();
891				switch(type){
892					case 'show'   : commentMapShow(code,secret_pass);
893					break;
894					case 'delete' : commentMapDelete(code,secret_pass);
895					break;
896					case 'edit'   : commentEditShow(code,secret_pass,interlock_type);
897					break;
898				}
899			});
900		$('body').off('mousedown.post_secret')
901			.on('mousedown.post_secret',function(e){
902				var $tmp = $(e.target).closest('#post_secret_password');
903				if($tmp.length==0) {
904					$post_secret_password.hide();
905					$('body').off('click.post_secret');
906				}
907			});
908	};
909
910	var commentDelete = function(code,secret_pass,interlock_type,use_interlock_board){
911		var obj = $('#'+code);
912		var comment_wrap = obj.find('._comment_wrap_'+code);
913		if(confirm(LOCALIZE.설명_삭제하시겠습니까())){
914			$.ajax({
915				type:'post',
916				data:{
917					code:code,
918					post_code:post_code,
919					secret_pass:secret_pass,
920					interlock_type:interlock_type,
921					use_interlock_board:use_interlock_board
922				},
923				url:'/ajax/post_comment_delete.cm',
924				dataType:'json',
925				success:function(result){
926					if(result.msg == 'SUCCESS'){
927						if(result.mode == 'delete'){
928							comment_wrap.html(LOCALIZE.설명_삭제된_댓글_입니다());
929						}else {
930							obj.remove();
931						}
932						commentDecreaseTotalCount();
933					}else{
934						alert(result.msg);
935					}
936				}
937			});
938		}
939	};
940
941	var commentShow = function(code,secret_pass,interlock_type){
942		$.ajax({
943			type : 'POST',
944			data : {code : code, post_code : post_code, secret_pass : secret_pass, show: 'Y', board_type:interlock_type},
945			url : ('/ajax/post_comment_show.cm'),
946			dataType : 'json',
947			success : function(result){
948				if(result.msg == 'SUCCESS'){
949					$("._comment_body_"+code).find("#secret_comment_text").text(result.html);
950					$("._comment_body_"+code).find($("img")).attr("src",result.img_url);
951					if(result.isSubComment){
952						for(var i in result.sub_comment){
953							var sub_data = result.sub_comment[i];
954							$('._comment_body_'+sub_data.code).html(sub_data.html);
955						}
956					}
957				}else
958					alert(result.msg);
959			}
960		});
961
962	};
963	var commentEditShow = function(code,secret_pass,interlock_type){
964		$.ajax({
965			type : 'POST',
966			data : {code : code, post_code : post_code, secret_pass : secret_pass, board_type : interlock_type},
967			url : ('/ajax/post_comment_show.cm'),
968			dataType : 'json',
969			success : function(result){
970				if(result.msg == 'SUCCESS'){
971					commentShowEdit(code,interlock_type);
972				}else
973					alert(result.msg);
974			}
975		});
976	};
977
978	var commentMapShow = function(code, secret_pass){
979		$.ajax({
980			type : 'POST',
981			data : {code : code, post_code : post_code, secret_pass : secret_pass},
982			url : ('/ajax/post_map_comment_show.cm'),
983			dataType : 'json',
984			success : function(result){
985				if(result.msg == 'SUCCESS'){
986					$("._comment_body_"+code).find("#secret_comment_text").text(result.html);
987					$("._comment_body_"+code).find($("img")).attr("src",result.img_url);
988					if(result.isSubComment){
989						for(var i in result.sub_comment){
990							var sub_data = result.sub_comment[i];
991							$('._comment_body_'+sub_data.code).html(sub_data.html);
992						}
993					}
994				}else
995					alert(result.msg);
996			}
997		});
998	};
999
1000	var commentMapDelete = function(code,secret_pass){
1001		var obj = $('#'+code);
1002		var comment_wrap = obj.find('._comment_wrap_'+code);
1003		if(confirm(LOCALIZE.설명_삭제하시겠습니까())){
1004			$.ajax({
1005				type:'post',
1006				data:{code:code,post_code :post_code,secret_pass:secret_pass},
1007				url:'/ajax/map_comment_delete.cm',
1008				dataType:'json',
1009				success:function(result){
1010					if(result.msg == 'SUCCESS'){
1011						if(result.mode == 'delete'){
1012							comment_wrap.html(LOCALIZE.설명_삭제된_댓글_입니다());
1013						}else {
1014							obj.remove();
1015						}
1016						if(result.map_listing == 'map'){
1017							var map_comment_count = 0;
1018							map_comment_count = Math.round($('#list_'+result.list_idx).find('#comment_count').text());
1019							map_comment_count--;
1020							$('#list_'+result.list_idx).find('#comment_count').text(map_comment_count);
1021							$('#comment_area').find('#comment_count').text(map_comment_count);
1022							$('#list_pop_'+result.list_idx).find('#comment_count').text(map_comment_count);
1023						}else{
1024							commentDecreaseTotalCount(result.decrease_count);
1025						}
1026					}else{
1027						alert(result.msg);
1028					}
1029				}
1030			});
1031		}
1032	};
1033
1034
1035	var commentAddSubHTML = function(code,html){
1036		var obj = $('#'+code);
1037		var comment_sub_list = obj.find('._comment_sub_list');
1038		comment_sub_list.append(html);
1039		commentIncreaseTotalCount();
1040	};
1041
1042	var commentToggleSub = function (parent_comment_id){
1043		var parent_obj = $('#'+parent_comment_id);
1044		var loaded = parent_obj.data('sub_loaded');
1045		var sub_open = parent_obj.data('sub_open');
1046		var sub_comment_wrap = parent_obj.find('._sub_comment_wrap');
1047		var sub_comment_list = parent_obj.find('._sub_comment_list');
1048		var arrow_icon = parent_obj.find('._arrow_icon');
1049		if(typeof loaded == 'undefined' || loaded == false){
1050			$.ajax({
1051				type:'post',
1052				data:{code : parent_comment_id},
1053				url:'/ajax/getChildComment.cm',
1054				dataType:'json',
1055				success:function(data){
1056					var html = $(data.html);
1057					sub_comment_list.append(html);
1058					sub_comment_wrap.show();
1059					arrow_icon.removeClass('zmdi-chevron-down').removeClass('zmdi-chevron-down').removeClass('zmdi-chevron-down');
1060					arrow_icon.addClass('zmdi-chevron-up');
1061					parent_obj.data('sub_loaded', true);
1062					parent_obj.data('sub_open', true);
1063				}
1064			});
1065		}else{
1066			if(typeof sub_open == 'undefined' || sub_open == false){
1067				sub_comment_wrap.show();
1068				arrow_icon.removeClass('zmdi-chevron-down').removeClass('zmdi-chevron-down').removeClass('zmdi-chevron-down');
1069				arrow_icon.addClass('zmdi-chevron-up');
1070				parent_obj.data('sub_loaded', true);
1071			}else{
1072				sub_comment_wrap.hide();
1073				arrow_icon.removeClass('zmdi-chevron-up').removeClass('zmdi-chevron-up').removeClass('zmdi-chevron-up');
1074				arrow_icon.addClass('zmdi-chevron-down');
1075				parent_obj.data('sub_loaded', false);
1076			}
1077		}
1078	};
1079
1080	var commentMapAdd = function(){
1081		var data = comment_form.serializeObject();
1082		$.ajax({
1083			type:'post',
1084			data:data,
1085			url:'/ajax/map_comment_add.cm',
1086			dataType:'json',
1087			success:function(result){
1088				if(result.msg=='SUCCESS') {
1089					comment_body.val('');
1090					$("#comment_image_box").empty().hide();
1091					commentFormHide();
1092					if(result.map_listing == 'map'){
1093						var map_comment_count = 0;
1094						map_comment_count = result.comment_cnt;
1095						$('#list_'+result.list_idx).find('._comment_count').text(map_comment_count);
1096						$('#comment_area').find('#comment_count').text(map_comment_count);
1097						$('#list_pop_'+result.list_idx).find('._comment_count').text(map_comment_count);
1098						if(result.map_comment_sort == 'asc' || !result.map_comment_sort){
1099							$comment_container.find('div.comment_list div.comment:last').length === 0 ? $comment_container.append(result.html) : $comment_container.find('div.comment_list div.comment:last').after(result.html);
1100						}else{
1101							$comment_container.prepend(result.html);
1102							moveToCommentListTop();
1103						}
1104						autosize.update($('.comment_textarea').find('#comment_body'));
1105					}else{
1106						commentAddHTML(result.html);
1107					}
1108				}else
1109					alert(result.msg);
1110			}
1111		});
1112	};
1113
1114	var getCommentListByCurrentPagingNum = function(current_page, is_move_to_comment_list_top){
1115		var is_loaded = false;
1116		if(is_loaded === false){ // 재호출 방지
1117			is_loaded = true;
1118			$.ajax({
1119				type:'post',
1120				data:{
1121					'board_code': comment_form.find("input[name='board_code']").val(),
1122					'post_code': post_code,
1123					'current_page':current_page
1124				},
1125				url:'/ajax/post_comment_paging.cm',
1126				dataType:'json',
1127				success:function(result){
1128					is_loaded = false;
1129					if(result.msg === 'SUCCESS') {
1130						$comment_container.html(result.html);
1131						if(is_move_to_comment_list_top) moveToCommentListTop();
1132					}else{
1133						alert(result.msg);
1134					}
1135				}
1136			});
1137		}
1138	};
1139
1140	var moveToCommentListTop = function(){
1141		var $modal_widget_fullboard = $('.modal_widget_fullboard');
1142		var $pos_comment_container = $('#comment_container');
1143
1144		// 위젯 위치 세팅
1145		if($modal_widget_fullboard.length > 0){
1146			$modal_widget_fullboard.scrollTop($('.comment-block').position().top);
1147		}else if($pos_comment_container.length > 0){
1148			// 스크롤 고정 메뉴 확인
1149			var fixed_header_section = $("._fixed_header_section");
1150			var header_height = 0;
1151
1152			if(fixed_header_section.length > 0){
1153				for(var i = 0; i < fixed_header_section.length; i++){
1154					header_height += 2 * fixed_header_section[i].offsetHeight;
1155				}
1156			}
1157			// 상단 고정 메뉴 확인
1158			var new_fixed_header = $('#doz_header_wrap').find('._new_fixed_header');
1159			if(new_fixed_header.length > 0){
1160				header_height += new_fixed_header.height();
1161			}
1162
1163			$(window).scrollTop($('.comment-block').offset().top - header_height -15);
1164		}
1165	};
1166
1167	return {
1168		init : function(code){
1169			commentInit(code);
1170		},
1171		toggleSub : function(code){
1172			commentToggleSub(code);
1173		},
1174		showEdit : function(code, board_type){
1175			commentShowEdit(code, board_type);
1176		},
1177		showSubForm : function(code){
1178			commentShowSubForm(code);
1179		},
1180		showAtForm : function(code){
1181			commentShowAtForm(code);
1182		},
1183		edit : function(code){
1184			commentEdit(code);
1185		},
1186		editMap : function(code){
1187			commentEditMap(code);
1188		},
1189		cancelEdit : function (code){
1190			commentCancelEdit(code);
1191		},
1192		addSub : function(code){
1193			commentAddSub(code);
1194		},
1195		addMapSub : function(code){
1196			commentMapAddSub(code);
1197		},
1198		addAt : function(code){
1199			commentAddAt(code);
1200		},
1201		showSubEdit : function(code){
1202			commentShowSubEdit(code);
1203		},
1204		cancelSubEdit : function (code){
1205			commentCancelSubEdit(code);
1206		},
1207		subEdit : function(code){
1208			commentSubEdit(code);
1209		},
1210		confirmShow : function(e,code,type,interlock_type,use_interlock_board){
1211			commentConfirmShow(e,code,type,interlock_type,use_interlock_board);
1212		},
1213		mapConfirmShow : function(e, code, type, interlock_type){
1214			commentMapConfirmShow(e, code , type, interlock_type)
1215		},
1216		confirmMapDelete : function(e,code){
1217			commentConfirmMapDelete(e,code);
1218		},
1219		'delete' : function(code, pass,interlock_type,use_interlock_board){
1220			commentDelete(code,pass,interlock_type,use_interlock_board);
1221		},
1222		deleteMap : function(code,pass){
1223			commentMapDelete(code,pass);
1224		},
1225		add : function(){
1226			commentAdd();
1227		},
1228		mapAdd : function(){
1229			commentMapAdd();
1230		},
1231		removeCommentImg : function(obj){
1232			removeCommentImg(obj)
1233		},
1234		getCommentListByCurrentPagingNum : function(current_page, is_move_to_comment_list_top){
1235			getCommentListByCurrentPagingNum(current_page, is_move_to_comment_list_top);
1236		},
1237		refreshCaptcha : function(){
1238			refreshCaptcha();
1239		},
1240		refreshCaptchaSubForm: function(code) {
1241			refreshCaptcha('sub_form', code);
1242		}
1243	}
1244
1245}();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.