PageSourceSearch

https://ask-us.co.kr/js/post.js?1781774629

js ask-us.co.kr collected 2026-09-29 13:52:44 UTC 27,589 bytes, 816 lines download raw bytes

1
2var POST = function(){
3	var code, post_body, body_input, is_notice,is_notice_input,is_secret,is_secret_input, post_form,post_subject,total_file_size;
4
5	var $board_container,$floara_obj;
6	var $post_img_library;
7	var $represent_img;
8	var $upload_cover_image_btn_obj, $delete_cover_image_btn_obj, $cover_image, $cover_image_tmp_no;
9	var $post_secret_password;
10	var $widget_wrap,board_code,listing_type,more_list_page;
11	var $listing_obj,type_data;
12	var option = {};
13	var category_list;
14	var board_data;
15	var sent = false;
16	var isIOS, isSafari, $fr_m_custom, $write_header, m_sticky_container_trigger_top, $toolbarContainer;
17
18	var reaction_token, reaction_token_key;
19
20	// macOS Chrome에서 게시물 본문의 '큰 이미지'를 드래그하면 즉시 취소되는(잡자마자 놓아지는) 문제 우회.
21	// 원인: macOS 크롬은 드래그 시 마우스를 따라다니는 미리보기(드래그 고스트)를 '화면에 펼친 실제 픽셀 크기'
22	//       기준으로 만드는데, 펼친 그림이 너무 크면 미리보기 생성에 실패하고 드래그 자체를 취소한다.
23	//       (Windows/Safari는 정상. 파일 용량이 아니라 가로x세로 픽셀 크기가 기준)
24	// 해결: 드래그 시작(dragstart) 시 가로 최대 120px짜리 작은 캔버스를 만들어 setDragImage로 지정 →
25	//       크롬이 무거운 원본으로 미리보기를 만들지 않게 하여 드래그가 취소되지 않는다.
26	//       (본문 원본 이미지 화질은 그대로, 드래그 중 따라다니는 미리보기만 축소)
27	var __macDragFixAttached = false;
28	var setupMacChromeImageDragFix = function(){
29		var ua = navigator.userAgent;
30		var isMacChrome = ua.indexOf('Macintosh') !== -1 && ua.indexOf('Chrome') !== -1 && ua.indexOf('Edg/') === -1 && ua.indexOf('OPR/') === -1;
31		if(!isMacChrome || __macDragFixAttached) return;
32		__macDragFixAttached = true;
33
34		document.addEventListener('dragstart', function(ev){
35			var target = ev.target;
36			if(!target || target.tagName !== 'IMG') return;
37			var dt = ev.dataTransfer;
38			if(!dt) return;
39			var maxW = 120;
40			var ratio = target.naturalWidth > 0 ? Math.min(1, maxW / target.naturalWidth) : 1;
41			var w = Math.max(1, Math.round((target.naturalWidth || target.width) * ratio));
42			var h = Math.max(1, Math.round((target.naturalHeight || target.height) * ratio));
43			var canvas = document.createElement('canvas');
44			canvas.width = w;
45			canvas.height = h;
46			var ctx = canvas.getContext('2d');
47			if(!ctx) return;
48			try {
49				ctx.drawImage(target, 0, 0, w, h);
50			} catch(e){
51				// CORS 등으로 그리기 실패 시 회색 박스로 대체 (드래그 자체는 성립시킴)
52				ctx.fillStyle = 'rgba(0,0,0,0.3)';
53				ctx.fillRect(0, 0, w, h);
54			}
55			canvas.style.position = 'fixed';
56			canvas.style.top = '-1000px';
57			canvas.style.left = '-1000px';
58			canvas.style.pointerEvents = 'none';
59			document.body.appendChild(canvas);
60			try {
61				dt.setDragImage(canvas, Math.round(w / 2), Math.round(h / 2));
62			} catch(e){ /* setDragImage 미지원 시 무시 */ }
63			setTimeout(function(){
64				if(canvas.parentNode) canvas.parentNode.removeChild(canvas);
65			}, 0);
66		}, true);
67	};
68
69	var postDeletePost = function (board_code,code,return_url,secret_pass){
70		if(confirm(LOCALIZE.설명_삭제하시겠습니까())){
71			$.ajax({
72				type		: 'post',
73				data:{'pcode':code,board_code:board_code,secret_pass:secret_pass},
74				url			: '/ajax/deletePost.cm',
75				dataType 	: 'json',
76				success		: function(result){
77					if(result.msg == 'SUCCESS'){
78						window.location.href = return_url;
79					}else{
80						alert(result.msg);
81					}
82				}
83			});
84		}
85	};
86
87
88	/***
89	 * 안드로이드앱에서 post글쓰기시 이미지 업로드 완료시 처리
90	 * @param image
91	 */
92
93	var $image_list_obj = {};
94	//이미지 임시저장 리스트 추가
95	if(!($image_list_obj.length > 0)) {
96		var image_list_html = $("<ul id='image_list' style='display: none'></ul>");
97		$("body form").append(image_list_html);
98		$image_list_obj = image_list_html;
99	}
100
101	var android_que = [];
102	var androidAppPostImageUploadComplete = function(image){
103		if(image.tmp_idx > 0){
104			android_que.push(image);
105			if(image.is_last == "Y") androidAppPostImageUploadAllComplete();
106		}
107	};
108
109	var androidAppPostImageUploadAllComplete = function(){
110		androidAppPostImageInsert(android_que[0]);
111	};
112
113	var androidAppPostImageInsert = function(image){
114			FroalaEditor('#post_body').image.insert(CDN_UPLOAD_URL + image.url, true);
115	};
116
117	var postAddImage = function(tmp_idx,size){
118		var uniq_id = makeUniq('image_');
119		var hidden_input = $('<input name="temp_images[]" value="' + tmp_idx + '" type="hidden" />');
120		var li 	= $('<li>').attr('id',uniq_id).data({'item':uniq_id,size:size});
121		li.append(hidden_input);
122		$image_list_obj.append(li);
123	};
124
125
126
127
128
129	var postInitWrite = function(key,data, str_category){
130		$("body").addClass("write_mode");
131		$board_container = $('#board_container');
132		post_body = $('#post_body');
133		post_subject = $('#post_subject');
134		body_input = $('#body_input');
135		post_form = $('#post_form');
136		$upload_cover_image_btn_obj = $('._upload_cover_image');
137		$delete_cover_image_btn_obj = $('._delete_cover_image');
138		$cover_image = $('#cover_image');
139		$cover_image_tmp_no = $('#cover_image_tmp_no');
140		code = key;
141		board_data = data;
142		total_file_size = 0;
143		category_list = categoryList(str_category);
144		if(IE_VERSION < 10){
145			CKEDITOR.replace( 'post_body',{
146				filebrowserImageUploadUrl: '/ajax/post_image_upload.cm?board_code='+key
147			});
148		}else{
149			if(android_version() == 4){
150				post_body.addClass('legacy_webview');
151			}
152			var placeholder = board_data.placeholder_edit;
153			if(placeholder == '') placeholder = getLocalizeString('설명_내용을_입력해주세요', '', '내용을 입력해주세요');
154      setFroala('#post_body', {
155        'code' : code,
156        'image_upload_url' : "/ajax/post_image_upload.cm",
157        'file_upload_url' : "/ajax/post_file_upload.cm",
158        'file_list_obj' : $("#file_list"),
159        'placeholderText' : placeholder,
160        'image_display' : 'inline',
161        'mobile_custom' : true
162      }, {
163        'image.inserted' : function($img, response){
164          if(IS_ANDROID_APP == 'Y'){
165            var img = post_body.find('img[src="' + CDN_UPLOAD_URL + image.url + '"]');
166            img.data(image);
167            postAddImage(image.tmp_idx, image.size);
168            android_que.splice(0, 1);
169            if(android_que.length > 0) androidAppPostImageUploadAllComplete();
170          }
171        }
172      });
173      setupMacChromeImageDragFix();
174		}
175
176		function dataURLtoBlob(dataurl) {
177			var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
178				bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
179			while(n--){
180				u8arr[n] = bstr.charCodeAt(n);
181			}
182			return new Blob([u8arr], {type:mime});
183		}
184
185		$delete_cover_image_btn_obj.on('click',function(){
186			POST.deleteCoverImage();
187		});
188
189		$upload_cover_image_btn_obj.setUploadImage({
190			url : '/ajax/upload_image.cm',
191			formData : {target : 'post', 'temp' : 'Y', 'param_name' : 'cover_image'}
192		}, function (msg, data,res) {
193			$.each(res.cover_image,function(i,file){
194				if(file.tmp_idx > 0){
195					$cover_image.val(CDN_UPLOAD_URL+file.url);
196					$cover_image_tmp_no.val(file.tmp_idx);
197					$delete_cover_image_btn_obj.show();
198					$board_container.toggleClass('bg_on',true);
199					$board_container.find('._cover_image').css('background-image',"url("+CDN_UPLOAD_URL+file.url+")");
200					$board_container.find('._cover_image_src').attr('src',CDN_UPLOAD_URL+file.url);
201				}
202			});
203		});
204
205		isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
206		isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
207		$fr_m_custom = $board_container.find('._fr-m-custom');
208		$write_header = $board_container.find('._write_header');
209		m_sticky_container_trigger_top = $fr_m_custom.offset().top;
210		$toolbarContainer = $fr_m_custom.find('#toolbarContainer');
211		if(isIOS && isSafari){
212			$write_header.css('position', 'absolute');
213		}
214		var timeoutTime = isIOS && isSafari ? 100 : 10;
215		var resize_time;
216		resizeStickyContainer();
217		$(window).off('scroll.mobile_write resize.mobile_write').on('scroll.mobile_write resize.mobile_write',function(){
218			var s_top = $(this).scrollTop();
219			if(isIOS && isSafari){
220				$write_header.css({'-webkit-transition': 'none', 'transition': 'none', 'top': 0});
221				if(s_top > m_sticky_container_trigger_top){
222					$toolbarContainer.css({'-webkit-transition': 'none', 'transition': 'none', 'top': 0});
223				}
224			}
225			if(resize_time) {
226				clearTimeout(resize_time);
227			}
228			resize_time = setTimeout(function() {
229				resizeStickyContainer();
230			}, timeoutTime);
231		});
232
233		// $(window).bind('beforeunload', function(){
234		// 	return LOCALIZE.설명_페이지를벗어나시겠습니까();
235		// });
236		var $_mobile_tool_bar = $('._mobile_tool_bar');
237		if($_mobile_tool_bar.find('._tool_btn:visible').length === 0){
238			$_mobile_tool_bar.hide();
239		}
240	};
241
242	function resizeStickyContainer(){
243		var s_top = $(this).scrollTop();
244		if(isIOS && isSafari){
245			$write_header.css({'-webkit-transition': 'top 100ms', 'transition': 'top 100ms', 'top': s_top + 'px'});
246			$fr_m_custom.toggleClass('m_sticky_container', s_top > m_sticky_container_trigger_top);
247			$fr_m_custom.toggleClass('m_sticky_container_ios', s_top > m_sticky_container_trigger_top);
248			if(s_top > m_sticky_container_trigger_top){
249				$toolbarContainer.css({'-webkit-transition': 'top 100ms', 'transition': 'top 100ms', 'top': s_top + 'px'});
250				post_body.css('padding-top', '50px');
251			}else{
252				$toolbarContainer.css({'-webkit-transition': 'none', 'transition': 'none', 'top': 'auto'});
253				post_body.css('padding-top', '50px');
254			}
255		}else{
256			$fr_m_custom.toggleClass('m_sticky_container', s_top > m_sticky_container_trigger_top);
257		}
258		if($(window).width() >= 768){
259			if($board_container.hasClass('bg_on'))
260				$board_container.find('#toolbarContainer').toggleClass('pc_sticky_toolbar', s_top > 487);
261			else
262				$board_container.find('#toolbarContainer').toggleClass('pc_sticky_toolbar', s_top > 180);
263		}
264	}
265
266	var deleteCoverImage = function(){
267		$cover_image.val('');
268		$cover_image_tmp_no.val('');
269		$board_container.toggleClass('bg_on',false);
270		$board_container.find('._cover_image').css('background-image','none');
271		$board_container.find('._cover_image_src').attr('src','');
272		$delete_cover_image_btn_obj.hide();
273	};
274
275
276	const setPostToken = async () => {
277		await $.ajax({
278			type: 'post',
279			url: '/set_post_client_token.cm',
280			dataType: 'json',
281			async : false
282		});
283	};
284
285	var postSubmit = async function(){
286		if(sent) return false;
287		await setPostToken(); // 토큰주입API호출
288
289		if(IE_VERSION < 10){
290			var body = CKEDITOR.instances.post_body.getData();
291			body_input.val(body);
292			post_form.submit();
293		}else{
294      if(post_body.hasClass('fr-code-view'))
295        FroalaEditor('#post_body').codeView.toggle();
296      var body = FroalaEditor('#post_body').html.get(true);
297
298			body_input.val(body);
299			post_form.submit();
300		}
301		sent = true;
302	};
303
304	var endSubmit = function(msg){
305		sent = false;
306		alert(msg);
307	};
308
309	var postCancel = function(back_url){
310		if(isIOS && isSafari){
311			var s_top = $(this).scrollTop();
312			$write_header.css({'-webkit-transition': 'none', 'transition': 'none', 'position': 'fixed', 'top': 0});
313			$fr_m_custom.toggleClass('m_sticky_container', s_top > m_sticky_container_trigger_top);
314			$fr_m_custom.toggleClass('m_sticky_container_ios', s_top > m_sticky_container_trigger_top);
315			if(s_top > m_sticky_container_trigger_top){
316				$toolbarContainer.css({'-webkit-transition': 'none', 'transition': 'none', 'position': 'fixed', 'top': $write_header.height() + 'px'});
317			}else{
318				$toolbarContainer.css({'-webkit-transition': 'none', 'transition': 'none', 'top': 'auto'});
319			}
320		}
321		document.location.href = back_url;
322	};
323
324	var is_more = true;
325	var listing_obj = {};
326
327	var postInitMoreList = function(wcode,bcode,type){
328		listing_type = type;
329		$widget_wrap = $("#"+wcode);
330		board_code = bcode;
331		more_list_page = 1;
332		is_more = true;
333		return true;
334	};
335
336	var toggleAlarmPopup = function(){
337		var $alarm_popup = $('#alarm_popup');
338		var $dLabel = $('#dLabel');
339		$alarm_popup.toggleClass('open');
340		if($alarm_popup.hasClass('open')){
341			$(window).on('click.alarm_popup',function(event){
342				var $top_closest = $(event.target).closest('a');
343				if($top_closest.attr('id')!='dLabel'){
344					var $closest = $(event.target).closest('ul');
345					if($closest != null && !$closest.hasClass('dropdown-menu')){
346						$alarm_popup.removeClass('open');
347						$(window).off('click.alarm_popup');
348						var alarm_group_list = $alarm_popup.find("input[type='checkbox']").is(":checked");
349						if(alarm_group_list) $dLabel.addClass('active');
350						else $dLabel.removeClass('active');
351					}
352				}
353			});
354		}
355	};
356	var postDeleteFile = function(id){
357		var obj = $('#'+id);
358		var size = obj.data('size');
359		total_file_size -= size;
360		obj.remove();
361	};
362	var postAddFile = function(filename,file_code,tmp_idx,size){
363		var uniq_id = makeUniq('upfile_');
364		total_file_size += size;
365		var clear_ico = $('<i class="zmdi zmdi-close"></i>').data({'item':uniq_id,size:size}).click(function(e){
366			postDeleteFile(uniq_id);
367		});
368		var hidden_input = '';
369		if(file_code.length>0) {
370			hidden_input = $('<input name="upload_files[]" value="' + file_code + '" type="hidden" />');
371		}else if(Math.round(tmp_idx) > 0){
372			hidden_input = $('<input name="temp_files[]" value="' + tmp_idx + '" type="hidden" />');
373		}
374		var li 	= $('<li>').attr('id',uniq_id).data({'item':uniq_id,size:size});
375		// XSS 방지: 파일명은 HTML로 해석되지 않도록 text로 삽입 (KVE-2025-2806)
376		var $file_name_dom = $('<span></span>');
377		$file_name_dom.text(filename);
378		$file_name_dom.append($('<em></em>').text(' ' + GetFileSize(size)));
379		li.append($file_name_dom);
380		li.append(clear_ico);
381		li.append(hidden_input);
382		$("#file_list").append(li);
383	};
384
385	var MovePostPopup = function(post_code,menu_url){
386		$.ajax({
387			type		: 'post',
388			data:{'post_code':post_code,'menu_url':menu_url},
389			url			: '/ajax/move_post_popup.cm',
390			dataType 	: 'json',
391			success		: function(result){
392				if(result.msg == 'SUCCESS'){
393					var html = $(result.html);
394					$.cocoaDialog.open({type : 'site_alert', custom_popup : html});
395				}else{
396					alert(result.msg);
397				}
398			}
399		});
400	};
401
402	/**
403	 * 설정된 카테고리 생성
404	 * @returns {Array}
405	 */
406	var categoryList = function(str_category){
407		var b_data = board_data;
408		var category_type_list_temp = [];
409		var category_list_default = {};
410		category_list_default.key = 0;
411		category_list_default.value = str_category;
412		category_type_list_temp.push(category_list_default);
413
414		if(Array.isArray(b_data.category_list)){
415			$.each(b_data.category_list, function(key, val){
416				var category_list = {};
417				var $name = val.name;
418				var $color = val.color;
419				category_list.key = key + 1;
420				category_list.value = '<span style="color:' + $color + '">' + RemoveTag($name) + '</span>';
421				category_type_list_temp.push(category_list);
422			});
423		}
424		return category_type_list_temp;
425	};
426
427	/**
428	 * 분류 리스트 출력
429	 * @param $obj
430	 * @param default_code
431	 */
432	var categoryTypeSelect = function($obj,default_code){
433		$obj.find('._category_type_list').setSelectBox({
434			option: category_list,
435			'set' : {
436				select_custom_cls:'category_select',
437				custom_cls:'category_dropdown',
438				width:180
439			},
440			'default' : default_code,
441			change: function (o) {
442				$('#category_type').val(o.key);
443			}
444		});
445	};
446
447	var viewReviewPostDetail = function(idx, board_code){
448		$(function(){
449		$.ajax({
450			type : 'POST',
451			data : {idx : idx, board_code : board_code},
452			url : ('/ajax/review_post_detail_view.cm'),
453			dataType : 'json',
454			async : false,
455			cache : false,
456			success : function(res){
457				if(res.msg === 'SUCCESS'){
458					$.cocoaDialog.open({
459						type : 'prod_detail review', custom_popup : res.html, width : 800});
460					if(history.replaceState && history.pushState){
461						// 모달 히스토리 커스텀(IE 10 이상)
462						var current_url = location.href.indexOf('#') === -1 ? location.href : location.href.substr(0, location.href.indexOf('#'));
463						var back_url = document.referrer.indexOf('#') === -1 ? document.referrer : document.referrer.substr(0, document.referrer.indexOf('#'));
464						history.pushState(null, null, current_url);
465						history.replaceState(null, null, current_url + "#prod_detail_review!/" + res.idx);
466					}else{
467						location.hash = "prod_detail_review!/" + res.idx;
468					}
469					$(window).off('hashchange').on('hashchange',function(){
470						var hash_qna_spilt = location.hash.split('!/')[1];
471						if(!hash_qna_spilt){
472							$.cocoaDialog.close();
473						}else{
474							var hash_spilt_tab = location.hash.split('!/')[0];
475							if(hash_spilt_tab === '#prod_detail_review'){
476								viewReviewPostDetail(hash_qna_spilt,board_code);
477							}else if(hash_spilt_tab === '#prod_detail_qna'){
478								viewQnaPostDetail(hash_qna_spilt,board_code);
479							}
480						}
481					});
482					$('.modal_prod_detail').off('hidden.bs.modal').on('hidden.bs.modal', function (e) {
483						removeReviewHash();
484					});
485				}else{
486					alert(res.msg);
487				}
488			}
489		});
490		});
491	};
492
493	var removeReviewHash = function(){
494		$(window).off('hashchange');
495    $('html').toggleClass('modal-scroll-control', false);
496		var hash_review_spilt = location.hash.split('!/')[1];
497		if(hash_review_spilt){
498			if(history.replaceState && history.pushState){
499				history.back();
500			}else{
501				location.href = '#prod_detail_review';
502			}
503		}
504	};
505
506	var viewQnaPostDetail = function(idx, board_code){
507		$(function(){
508			$.ajax({
509				type : 'POST',
510				data : {idx : idx, board_code : board_code},
511				url : ('/ajax/qna_post_detail_view.cm'),
512				dataType : 'json',
513				async : false,
514				cache : false,
515				success : function(res){
516					if(res.msg === 'SUCCESS'){
517						$.cocoaDialog.open({
518							type : 'prod_detail review', custom_popup : res.html, width : 800});
519						if(history.replaceState && history.pushState){
520							// 모달 히스토리 커스텀(IE 10 이상)
521							var current_url = location.href.indexOf('#') === -1 ? location.href : location.href.substr(0, location.href.indexOf('#'));
522							var back_url = document.referrer.indexOf('#') === -1 ? document.referrer : document.referrer.substr(0, document.referrer.indexOf('#'));
523							history.pushState(null, null, current_url);
524							history.replaceState(null, null, current_url + "#prod_detail_qna!/" + res.idx);
525						}else{
526							location.hash = "prod_detail_qna!!/" + res.idx;
527						}
528						$(window).off('hashchange').on('hashchange',function(){
529							var hash_qna_spilt = location.hash.split('!/')[1];
530							if(!hash_qna_spilt){
531								$.cocoaDialog.close();
532							}else{
533								var hash_spilt_tab = location.hash.split('!/')[0];
534								if(hash_spilt_tab === '#prod_detail_review'){
535									viewReviewPostDetail(hash_qna_spilt, board_code);
536								}else if(hash_spilt_tab === '#prod_detail_qna'){
537									viewQnaPostDetail(hash_qna_spilt, board_code);
538								}
539							}
540						});
541						$('.modal_prod_detail').off('hidden.bs.modal').on('hidden.bs.modal', function (e) {
542							removeQnaHash();
543						});
544					}else{
545						alert(res.msg);
546					}
547				}
548			});
549		});
550	};
551
552	var removeQnaHash = function(){
553		$(window).off('hashchange');
554    $('html').toggleClass('modal-scroll-control', false);
555		var hash_qna_spilt = location.hash.split('!/')[1];
556		if(hash_qna_spilt){
557			if(history.replaceState && history.pushState){
558				history.back();
559			}else{
560				location.href = '#prod_detail_qna';
561			}
562		}
563	};
564
565  var alertNoSale = function(){
566    $.cocoaDialog.open({
567      type: 'site_alert',
568      custom_popup: `
569        <div class="layer_pop">
570            <div class="container-fluid">
571                <p class="tw-text-center tw-mb-0">
572                    ${getLocalizeString('설명_상품페이지이동불가안내', '', '해당 상품 페이지로 이동할 수 없습니다.')}
573                </p>
574            </div>
575            <div class="btn-group-justified">
576                <a href="javascript:" class="btn" onclick="$('.modal_site_alert').modal('hide');">${getLocalizeString('버튼_확인', '', '확인')}</a>
577            </div>
578        </div>`
579    }, function(){
580      $('.modal_site_alert').css('z-index', 100002);
581    });
582  }
583
584	return {
585		'init' : function(code, data, str_category) {
586			postInitWrite(code, data, str_category);
587		},
588		'initMoreList' : function(widget_code,board_code,listing_type) {
589			return postInitMoreList(widget_code,board_code,listing_type);
590		},
591		'submit' : function(){
592			postSubmit();
593		},
594		'submit_error': function(msg){
595			endSubmit(msg);
596		},
597		'postCancel': function(back_url){
598			postCancel(back_url);
599		},
600		'addFile' : function(filename,file_code,tmp_idx,size){
601			postAddFile(filename,file_code,tmp_idx,size);
602		},
603		'androidAppPostImageUploadComplete' :function(image){
604			androidAppPostImageUploadComplete(image);
605		},
606		'androidAppPostImageUploadAllComplete' :function(){
607			androidAppPostImageUploadAllComplete();
608		},
609		'deletePost' : function (board_code,code,return_url,secret_pass) {
610			postDeletePost(board_code,code,return_url,secret_pass);
611		},
612		'moreList' : function(keyword,keyword_type,q){
613			moreList(keyword,keyword_type,q);
614		},
615		'toggleAlarmPopup' : function(){
616			toggleAlarmPopup();
617		},
618		'MovePostPopup' : function(post_code,menu_url){
619			MovePostPopup(post_code,menu_url);
620		},
621		'deleteCoverImage' : function(){
622			deleteCoverImage();
623		},
624		'deleteLibraryImage' : function(url){
625			deleteLibraryImage(url);
626		},
627		'categoryTypeSelect' : function($obj,defult_code){
628			categoryTypeSelect($obj,defult_code);
629		},
630		'categoryList' : function(str_category){
631			categoryList(str_category);
632		},
633		'viewReviewPostDetail' : function(idx, board_code){
634			viewReviewPostDetail(idx, board_code);
635		},
636		'removeReviewHash' : function(){
637			removeReviewHash();
638		},
639		'viewQnaPostDetail' : function(idx, board_code){
640			viewQnaPostDetail(idx, board_code);
641		},
642		'removeQnaHash' : function(){
643			removeQnaHash();
644		},
645    'alertNoSale' : function(){
646      alertNoSale();
647    }
648	};
649}();
650
651function POST_INIT_LIST(code,data){
652	var that 	= this;
653	that.type_data = data;
654	that.code = code;
655	that.windowWidth = $(window).width();
656	that.change_timer = setTimeout(function(){},1);
657	that.listing_obj = $('#post_card_'+that.code);
658
659	that.listing_obj.imagesLoaded().always(function(ins) {
660		that.listResize();
661	});
662
663	$('body').off('gridChange.'+that.code).on('gridChange.'+that.code,function(){
664		that.listing_obj.imagesLoaded().always(function(ins) {
665			that.listResize();
666		});
667	});
668
669	$(window).off('resize.'+that.code).on('resize.'+that.code,function(){
670		if ($(window).width() != that.windowWidth) {
671			that.windowWidth = $(window).width();
672		}else{
673			return;
674		}
675		clearTimeout(that.change_timer);
676		that.change_timer = setTimeout(function(){
677			that.listResize();
678		},1000);
679	});
680
681	this.listResize = function(){
682		that.listing_obj.imagesLoaded()
683			.always(function(){
684				var window_width = $(window).width();
685				if(!that.type_data.grid_gutter){
686					that.type_data.grid_gutter = 15;
687				}
688				if($('body').hasClass('device_type_m'))
689					window_width = 370;
690				if(window_width <= 991)
691					that.type_data.grid_gutter = that.type_data.grid_gutter/2;
692				that.listing_obj.css({'margin':'0 -'+that.type_data.grid_gutter+'px'});
693				if(that.type_data['design_type'] == 'grid' || that.type_data['design_type'] == 'masonry'){
694					that.listing_obj.css({'margin-top':'-'+that.type_data.grid_gutter+'px'});
695				}
696
697				var cnt = parseInt(that.type_data.grid_col_count);
698				var inner_width = that.listing_obj.width();
699
700				if(window_width <= 991){
701					if(typeof that.type_data.grid_mobile_col_count == "undefined")
702						cnt = 2;
703					else
704						cnt = parseInt(that.type_data.grid_mobile_col_count);
705				}else{
706					if(that.type_data.design_type == 'slide'){
707						inner_width = that.listing_obj.parent().width();
708					}else{
709						inner_width = that.listing_obj.width();
710					}
711
712					if(that.type_data.grid_extend_fix != 'Y'){
713						var s_width = (that.type_data.max_width - (that.type_data.document_margin * 2)) + that.type_data.grid_gutter * 2;
714						var item_max = s_width - ((cnt - 1) * parseInt(that.type_data.grid_gutter));
715						var grid_width = Math.floor(item_max / cnt);
716						var current_width = Math.floor((inner_width - ((cnt - 1) * parseInt(that.type_data.grid_gutter))) / cnt);
717						if(current_width > grid_width){
718							cnt = Math.floor(inner_width / grid_width);
719						}
720					}
721				}
722
723				var width = Math.floor(inner_width / cnt);
724				if(that.type_data['design_type'] == 'grid'){
725					that.listing_obj.find('._post_item_wrap').css({'padding' : that.type_data.grid_gutter + 'px'});
726					that.runColSize(cnt);
727				}else if(that.type_data['design_type'] == 'masonry'){
728					var $masonry_item = that.listing_obj.find('.ma-item');
729					var masonry_item_count = $masonry_item.length;
730					that.listing_obj.find('.ma-item').css({'width' : width,'padding' : that.type_data.grid_gutter + 'px'});
731					that.runMasonry(masonry_item_count);
732				}
733			});
734	};
735
736	this.runColSize = function(col_cnt){
737		that.listing_obj.find('._card_wrap').show();
738		var i = 1;
739		var $_row = $('<div />').addClass('_post_row post_row');
740		var is_append = false;
741		that.listing_obj.find('._dummy_item').remove();
742		var $item = that.listing_obj.find('._card_wrap');
743		var item_count = $item.length;
744
745		$item.each(function(e,$_obj){
746			$_row.append($_obj);
747			is_append = false;
748			if(i % col_cnt == 0){
749				that.listing_obj.append($_row);
750				is_append = true;
751				$_row = $('<div />').addClass('_post_row post_row');
752			}
753			i++;
754		});
755
756		if(!is_append){
757			var $tmp_item = $_row.find('._post_item_wrap');
758			if($tmp_item.length >0 ){
759				if($tmp_item.length < col_cnt){
760					var remain_cnt = col_cnt - $tmp_item.length;
761					for(var i = 0; i <remain_cnt; i++){
762						var $dummy_col = $('<div/>').addClass('dummy_col item_post _item _dummy_item list-style-card');
763						$_row.append($dummy_col);
764					}
765				}
766				that.listing_obj.append($_row);
767			}
768		}
769
770		that.listing_obj.find('._post_row').each(function(){
771			var $tmp_item = $(this).find('._post_item_wrap');
772			if($tmp_item.length ==0 ){
773				$(this).remove();
774			}
775		});
776
777		that.imgHeight();
778	};
779
780	this.imgHeight = function(){
781		if(that.type_data['design_type'] == 'grid'){
782			var height = Math.ceil(that.listing_obj.find('._post_item_wrap').eq(0).width() / (that.type_data.img_ratio / 100));
783			that.listing_obj.find('._img_wrap').height(height);
784		}
785	};
786
787	this.runMasonry = function(count){
788		if(count > 0){
789      let is_masonry_timeout;
790			that.listing_obj.off('layoutComplete').on( 'layoutComplete', function() {
791        if(that.listing_obj.css('visibility') !== 'visible'){
792          that.listing_obj.css('visibility', 'visible');
793          that.listing_obj.find('img').lazyload({
794            'effect' : 'fadeIn',
795            'effect_speed' : 50, // fadeIn 시간 단축(기본 400ms→50ms)
796            'load' : function() {
797              if(typeof is_masonry_timeout === 'number'){
798                clearTimeout(is_masonry_timeout);
799              }
800              is_masonry_timeout = setTimeout(function(){
801                /* 레이지 로드 완료 후 100ms 후에 masonry layout 재실행 */ 
802                that.listing_obj.masonry('layout');
803              }, 100);
804            },
805            'threshold': (window.innerHeight * 2)
806          });
807        }
808			});
809      that.listing_obj.masonry({
810        itemSelector: '.ma-item'
811      });
812    }else{
813      that.listing_obj.css('visibility','visible');
814    }
815	};
816}

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.