1//ie8ì´í start 2if(!Array.indexOf){ 3 Array.prototype.indexOf = function(obj){ 4 for(var i=0; i<this.length; i++){ 5 if(this[i]==obj){ 6 return i; 7 } 8 } 9 return -1; 10 } 11} 12 13if (!Object.keys) Object.keys = function(o) { 14 if (o !== Object(o)) 15 throw new TypeError('Object.keys called on a non-object'); 16 var k=[],p; 17 for (p in o) if (Object.prototype.hasOwnProperty.call(o,p)) k.push(p); 18 return k; 19} 20 21if(typeof String.prototype.trim !== 'function') { 22 String.prototype.trim = function() { 23 return this.replace(/^\s+|\s+$/g, ''); 24 } 25} 26//ie8ì´í end 27 28if (typeof L10n != 'object') 29 document.write('<script type="text/javascript" src="/data/js/language/L10n_KR.js"></script>'); 30 31// í¨ìë¶ë§ ë°ë¡ í¸ì¶ 32document.write('<script type="text/javascript" src="/app/javascript/js/common-function.js?v=191205"></script>'); 33 34$(function(){ 35 /* ì¤íì¼ì ì© */ 36 apply_input_style(); 37 38 //ìíëì¤íë ì´ì ëììí´ë¦ì -> ëìììëì¤íì¤ì ëì´ìì´ì¼í¨ 39 $(".goodsDisplayVideoWrap").bind("click",function(e){ 40 $(this).find("img").addClass("hide"); 41 $(this).find(".thumbnailvideo").hide(); 42 $(this).find(".mobilethumbnailvideo").hide(); 43 $(this).find("iframe").removeClass("hide"); 44 $(this).find("embed").removeClass("hide"); 45 }); 46 47 //ëììë£ê¸°ì ëììí´ë¦ì-> ëìììëì¤íì¤ì ëì´ìì´ì¼í¨ 48 $(".DisplayVideoWrap").bind("click",function(e){ 49 $(this).find("img").addClass("hide"); 50 $(this).find(".thumbnailvideo").hide(); 51 $(this).find(".mobilethumbnailvideo").hide(); 52 $(this).find("iframe").removeClass("hide"); 53 $(this).find("embed").removeClass("hide"); 54 }); 55 56 /* ëììë£ê¸°/ìíëì¤íë ì´ ëììì´ë¯¸ì§ì²´í¬ */ 57 $(".thumbnailvideo").each(function(){ 58 var width = ($(this).attr("width"))?$(this).attr("width"):400; 59 var height = ($(this).attr("height"))?$(this).attr("height"):200; 60 $(this).css({'width':width}); 61 $(this).css({'height':height}); 62 }); 63 64 $(".mobilethumbnailvideo").each(function(){ 65 var width = ($(this).attr("width"))?$(this).attr("width"):150; 66 var height = ($(this).attr("height"))?$(this).attr("height"):50; 67 $(this).css({'width':width}); 68 $(this).css({'height':height}); 69 }); 70}); 71 72$(window).load(function() { 73 /* ì¤íì¼ì ì© */ 74 chk_small_goods_image(); 75 /* 76 $('img.small_goods_image').each(function() { 77 if (!this.complete ) {// image was broken, replace with your new image 78 this.src = '/data/icon/goods/error/noimage_list.gif'; 79 } 80 }); 81 */ 82 83 /* ëììë£ê¸°/ìíëì¤íë ì´ ëììì´ë¯¸ì§ì²´í¬ */ 84 $(".thumbnailvideo").each(function(){ 85 var width = ($(this).attr("width"))?$(this).attr("width"):400; 86 var height = ($(this).attr("height"))?$(this).attr("height"):200; 87 $(this).css({'width':width}); 88 $(this).css({'height':height}); 89 }); 90 91 $(".mobilethumbnailvideo").each(function(){ 92 var width = ($(this).attr("width"))?$(this).attr("width"):150; 93 var height = ($(this).attr("height"))?$(this).attr("height"):50; 94 $(this).css({'width':width}); 95 $(this).css({'height':height}); 96 }); 97 98}); 99 100String.prototype.replaceAll = function (str1,str2){ 101 var str = this; 102 var result = str.replace(eval("/"+str1+"/gi"),str2); 103 return result; 104} 105 106//íµê³ìë²ë¡ íµê³ë°ì´í° ì ë¬ 107function statistics_firstmall(act,goods_seq,order_seq,review_point) 108{ 109 var url = '/_firstmallplus/statistics'; 110 var allFormValues = "act="+act+"&goods_seq="+goods_seq; 111 if( order_seq ) allFormValues += "&order_seq="+order_seq; 112 if( review_point ) allFormValues += "&review_point="+review_point; 113 114 if(act == 'order' && !order_seq) return false; 115 if(act == 'review' && !review_point) return false; 116 if(!goods_seq) return false; 117 $.ajax({ 118 cache:false, 119 timeout:1000, 120 type:"POST", 121 url:url, 122 data:allFormValues, 123 error:function(){}, 124 success:function(response){} 125 }); 126 return true; 127} 128 129// ì¬ìí ì§ê¸ ì¡°ê±´ ìì¸ 2015-05-14 pjm 130$(".gift_log").bind('click', function(){ 131 $.ajax({ 132 type: "post", 133 url: "./gift_use_log", 134 data: "order_seq="+$(this).attr('order_seq')+"&item_seq="+$(this).attr('item_seq'), 135 success: function(result){ 136 if (result){ 137 $("#gift_use_lay").html(result); 138 //ì¬ìí ì´ë²¤í¸ ì ë³´ 139 openDialog(getAlert('mo023'), "gift_use_lay", {"width":"450","height":"250"}); 140 } 141 } 142 }); 143}); 144 145 146//문ìì´ ë°ì´í¸ ì²´í¬(utf-8ë ê°ë¥) 147String.prototype.byteLength = function(mode){ 148 mode = (!mode) ? 'euc-kr' : mode; 149 text = this; 150 byte = 0; 151 switch(mode){ 152 case 'utf-8' : 153 for(byte=i=0;char=text.charCodeAt(i++);byte+=char>>11?3:char>>7?2:1); 154 break; 155 156 default : 157 for(byte=i=0;char=text.charCodeAt(i++);byte+=char>>7?2:1); 158 159 } 160 return byte 161}; 162 163//############################## 2019-10-16 [gcs] sdh : #3406 무ë£ë
163³´ìí¨ì¹ ############################## 164/* 165 * form RSA ìí¸í íë¡ì¸ì¤ 166 * - form ë´ì fileì´ ìì ê²½ì° ê¸°ì¡´ íë¡ì¸ì¤ììë file ë°ì´í° ì ì¡ì ëìíì§ ììì. 167 * íì¸ë submit ìì¸ ì¬í 168 * - front script ë 벨ìì formì ìì±í í bodyì ì¶ê°íì§ ìê³ submit 169 * -> ì´ ê²½ì°ë https://www.w3.org/TR/html5/forms.html#constraints 4.10.22.3 를 ìë°íì¬ ì¼ë¶ ë¸ë¼ì°ì ìì submitì´ ë°ìíì§ ìì. 170 * - ajaxë iframeì íµí´ ìë¡ì´ íì´ì§ë¥¼ ìì±í í document.sslForm.submit() 를 íµí´ submit 171 * -> DOM ê°ì²´ë¡ submit í¸ì¶ê³¼ ëì¼ 172 * - ì¤í¬ë¦½í¸ í¸ì¶ê³¼ ë°ì¸ë©ì´ ì´ë£¨ì´ì§ê¸° ì $(document).ready() ì ëìì submit 173 */ 174// RSA ì ì ë³ì ì ì¸ 175var getPublicKeyUrl = ["/ssl/getRSAPublicKey","/RSA/ssl/getRSAPublicKey"]; 176var handshakeUrl = ["/ssl/getRSAHandShake","/RSA/ssl/getRSAHandShake"]; 177var arrCheckActions = ["/ssl/relayRsa?action=", "/RSA/ssl/setRSAReturnPost/"]; 178var jcryptionReloadDelayTime = 500; // 0.5 ì´ í ë¤ì 리ë¡ë, ì§ì° ë°ì ì 1ì´ì© ì¦ê° 179var sGlAction = ''; 180// ëì ì¤í¬ë¦½í¸ í¸ì¶ 181$.loadScript = function (url, callback) {$.ajax({url: url,dataType: 'script',success: callback,async: true});} 182$(document).ready(function(){ 183 // order_price_calculate 주문ì ê³ì° í¨ììì ssl íµì ì ì´ì©íê³ ìì§ ìê³ íì¬ íì´ì§ê° 주문ì ìì± íì´ì§ë¼ë©´ ssl_urlë¡ ì¹í 184 if( window.location.pathname.indexOf('/order/settle') > -1 185 && order_price_calculate.toString().indexOf("/common/ssl_action")==-1){ 186 console.log("order_price_calculate convert"); 187 order_price_calculate = function () { 188 var f = $("form#orderFrm"); 189 action = "/order/calculate?mode="+gl_mode; 190 // ssl ì ì© 191 $.ajax({ 192 async: false, 193 'url' : '/common/ssl_action', 194 'data' : {'action':action}, 195 'type' : 'get', 196 'dataType' : 'html', 197 'success' : function(res) { 198 action = res; 199 } 200 }); 201 f.attr("action",action); 202 f.attr("target","actionFrame"); 203 // jCryption ì¬ì ì© ì¤í¨ì orderFrm ì ssl ë§í¬ê° ì기ì js ìììì ì¬ì ì¸ 204 moduleJcryption.resetJcryptionSubmit(f[0]); 205 f.submit(); 206 }; 207 } 208
209 // jquery ë²ì ì´ 1.7 ì´í ì¼ê²½ì° ê´ë¦¬ììì ì¬ì©ì¤ì´ë¯ë¡ https ê°í를 ì ì¸íë¤. 210 if($().jquery >= "1.7"){ 211 $.loadScript("/app/javascript/plugin/jcryption/jquery.jcryption.3.1.0_custom.js", function(){ 212 initJcryption(); 213 }); 214 } 215 // ajax í¸ì¶ í ìë¡ ìì±ë formìë ì ì© 216 $(document).ajaxComplete(function() { 217 // 모ë í¼ ì리먼í¸ì ì´ë²¤í¸ë¥¼ ë°ì¸ë© íë¤ 218 $("body form").each(function (){ 219 var domEl = this; 220 moduleJcryption.convertJcryptionSubmit(domEl); 221 }); 222 }); 223}); 224// ìí¸í ì ì© ê¸°ë¥ ëª¨ëí 225var moduleJcryption = { 226 // í¼ìì íë¡í ì½ì í¬í¨í host nameì ì»ëë¤. 227 getHostNameFromForm : function (formObj) { 228 var formActionUrl = formObj.attr("action"); 229 return moduleJcryption.getHostNameFromUrl(formActionUrl); 230 } 231 , getHostNameFromUrl : function (url){ 232 var arr = url.split("/"); 233 var result = arr[0]+"//"+arr[2]; 234 return result; 235 } 236 // SSL ì ì© í¼ì¸ì§ ì¬ë¶ íì¸ 237 , checkSSLForm : function (formObj){ 238 var formActionUrl = formObj.attr("action"); 239 if(formActionUrl){ 240 for(var i in arrCheckActions){ 241 if(formActionUrl.indexOf(arrCheckActions[i])>-1){ 242 return i; 243 } 244 } 245 } 246 return -1; 247 } 248 // ì´ë²¤í¸ê° ë°ì¸ë ë í¼ì¸ì§ íì¸ 249 , checkBindEventForm : function (formObj){ 250 var data = (formObj.data("jCryptionInit") === true); 251 if(data){ 252 return true; 253 } 254 return false; 255 } 256 // ì´ë²¤í¸ê° ì¹íë ë í¼ì¸ì§ íì¸ 257 , checkBindEventJcryptionForm : function (formObj){ 258 var data = (formObj.data("jCryptionAlready") === true); 259 if(data){ 260 return true; 261 } 262 return false; 263 } 264 // ìì±ì íì¸íë¤ 265 , getAttributes : function ( $node ) { 266 var attrs = {}; 267 $.each( $node[0].attributes, function ( index, attribute ) { 268 attrs[attribute.name] = attribute.value; 269 } ); 270 271 return attrs; 272 } 273 , destroyJcryptionSubmit : function(domEl){ 274 $(domEl).data("jCryptionInit",false); 275 $(domEl).data("jCryptionAlready",false); 276 $(domEl).off("submit"); 277 } 278 , resetJcryptionSubmit : function(domEl){ 279 moduleJcryption.destroyJcryptionSubmit(domEl); 280 moduleJcryption.convertJcryptionSubmit(domEl); 281 } 282 , convertJcryptionSubmit : function(domEl){ 283 // ì´ë¯¸ ì¹íë í¼ì ì¤ë³µ ì¹ííì§ ìì. 284 if(moduleJcryption.checkBindEventJcryptionForm($(domEl))){ 285 // console.log("already submit convert ", $(domEl));
286 }else{ 287 // console.log("submit convert event binding!", $(domEl)); 288 $(domEl).data("jCryptionAlready",true); 289 // URL ì´ SSL ì ì© í¼ì¸ì§ íì¸ 290 // console.log($(domEl),$(domEl).attr("action"),moduleJcryption.checkSSLForm($(domEl))); 291 if(moduleJcryption.checkSSLForm($(domEl))>-1){ 292 // 기본 dom ê°ì²´ë¥¼ ì°ì ì¹íí í jquery ê°ì²´ submit ì´ë²¤í¸ ë°ì¸ë©. 293 // jqueryê°ì²´ ìë¸ë°ì´ ë°ìíë¤ë©´ preventDefault ë¡ ì¸í´ domê°ì²´ì ìë¸ë°ì ë°ìíì§ ìì. 294 domEl.submit = function (event){ 295 // console.log("DOM el submit"); 296 moduleJcryption.convertSubmit(domEl); 297 }; 298 // validate íë¬ê·¸ì¸ì´ ì ì©ëì´ ìì ì ë³ëì submithandle를 ì´ì©íë¯ë¡ jquery ê°ì²´ ë°ì¸ë© ì ì¸ 299 if(typeof $(domEl).data("validator") !== "undefined"){ 300 }else{ 301 $(domEl).on("submit", function(event){ 302 // console.log("jquery el submit"); 303 event.preventDefault(); 304 moduleJcryption.convertSubmit(domEl); 305 }); 306 } 307 } 308 } 309 } 310 // ì¸ì í¤ ì ì§ë¥¼ ìí action url ì¶ê° 311 , convertActionUrl : function ($formEl){ 312 // console.log("convertActionUrl!", $formEl); 313 var action = $formEl.attr("action"); 314 var sessionKey = $.jCryption.getAESSessionKey($formEl); 315 var actionDomain = moduleJcryption.getHostNameFromForm($formEl); 316 var domain = window.location.hostname; 317 if(domain.indexOf("m.")==0){ 318 domain = domain.replace("m.",""); 319 } 320 if(domain.indexOf("www.")==0){ 321 domain = domain.replace("www.",""); 322 } 323 if(actionDomain.indexOf(domain)==-1 && moduleJcryption.checkSSLForm($formEl)>-1 && action.indexOf(sessionKey)==-1){ 324 action = action+"/"+sessionKey; 325 } 326 327 // firstmall ssl ì¬ì©ì 328 var thisRegex = new RegExp('gabiafreemall'); 329 if( thisRegex.test(action) ){ 330 var aPath = action.split("/"); 331 sGlAction = aPath[6].replace("-", "+"); 332 sGlAction = sGlAction.replace("_", "/"); 333 sGlAction = window.atob(sGlAction); 334 action = sGlAction; 335 }else{ 336 sGlAction = ''; 337 } 338 339 $formEl.attr("action",action); 340 } 341 // ìí¸í ìë¸ë° ì²ë¦¬ 342 , convertSubmit : function(thisDom){ 343 var $formEl = $(thisDom); 344 // submit ì ì© í¼ì¸ì§ ì²´í¬ 345 if(moduleJcryption.checkBindEventForm($formEl)){ 346 // console.log("already!", $formEl); 347 moduleJcryption.convertActionUrl($formEl); 348 return true; 349 }else{ 350 // SSL ì ì©í¼ì¸ì§ ì²´í¬ 351 if(moduleJcryption.checkSSLForm($formEl)>-1){ 352 // ì¤í¬ë¦½í¸ê° ë¡ëëìëì§ ì²´í¬ 353 if(typeof $.jCryption === "function"){ 354 // rsa í¼ ìì 355 $(".rsaForm").remove(); 356 357 // ìí¸í ì ì© 358 var AESEncryptionKey = $.jCryption.getAESEncryptionKey($formEl); 359 // console.log(AESEncryptionKey); 360 var hostName = moduleJcryption.getHostNameFromForm($formEl); 361 362 var $submitElement = $formEl.find(":input:submit"); 363 var $encryptedElement = $("<input />",{ 364 type:'hidden', 365 name:'jCryption' 366 }); 367 368 // ìí¸í submit ì ì© form 369 var $submitRSAForm = $("<form class='rsaForm'/>"); 370 var formAttrs = moduleJcryption.getAttributes($formEl); 371 for (var i in formAttrs){ 372 if(i!="id" && i!="name"){ 373 $submitRSAForm.attr(i,formAttrs[i]); 374 } 375 } 376 var remakeHandshakeUrl = handshakeUrl[moduleJcryption.checkSSLForm($formEl)]; 377 if(moduleJcryption.checkSSLForm($formEl)!=0){ 378 remakeHandshakeUrl = remakeHandshakeUrl+"/"+$.jCryption.getAESSessionKey($submitRSAForm); 379 } 380 381 $.jCryption.authenticate( 382 AESEncryptionKey, 383 hostName+getPublicKeyUrl[moduleJcryption.checkSSLForm($formEl)], 384 hostName+remakeHandshakeUrl, 385 function(AESEncryptionKey) { 386 var toEncrypt = $formEl.serialize(); 387 // console.log(toEncrypt); 388 // console.log($formEl); 389 if ($submitElement.is(":submit")) { 390 toEncrypt = toEncrypt + "&" + $submitElement.attr("name") + "=" + $submitElement.val(); 391 } 392 $encryptedElement.val($.jCryption.encrypt
392(toEncrypt, AESEncryptionKey)); 393 // console.log($submitRSAForm); 394 $submitRSAForm.append($encryptedElement); 395 $("body").append($submitRSAForm); 396 $submitRSAForm.data("jCryptionInit",true); 397 moduleJcryption.convertActionUrl($submitRSAForm); 398 if(sGlAction){ 399 var $encryptionKeyElement = $("<input />",{ 400 type:'hidden', 401 name:'encryptionKey', 402 value:AESEncryptionKey 403 }); 404 $submitRSAForm.append($encryptionKeyElement); 405 } 406 $submitRSAForm.submit(); 407 }, 408 function() { 409 // Authentication with AES Failed ... sending form without protection 410 confirm("Authentication with Server failed, are you sure you want to submit this form unencrypted?", function() { 411 $formEl.submit(); 412 }); 413 } 414 ); 415 }else{ 416 var delayTime = jcryptionReloadDelayTime; 417 console.log("íì ì¤í¬ë¦½í¸ê° ë¡ëëì§ ìììµëë¤. "+(delayTime/1000)+"ì´ í ë¤ì ìëí©ëë¤."); 418 setTimeout(function(){ 419 console.log($formEl,"리ë¡ë"+delayTime); 420 moduleJcryption.resetJcryptionSubmit(thisDom); 421 $formEl.submit(); 422 }, delayTime); 423 jcryptionReloadDelayTime += 1000; // 1ì´ì© ì¦ê° 424 // $formEl.submit(); 425 } 426 return false; 427 }else{ 428 return true; 429 } 430 } 431 } 432}; 433 434// ìí¸í ì ì© 435var initJcryption = function(){ 436 // 모ë í¼ ì리먼í¸ì ì´ë²¤í¸ë¥¼ ë°ì¸ë© íë¤ 437 $("body form").each(function (){ 438 var domEl = this; 439 moduleJcryption.convertJcryptionSubmit(domEl); 440 }); 441 442 // ìì´ë ì²´í¬ì ê²½ì° SSL íµì ì´ ììì¼ë¯ë¡ ê°ì ë¡ ì ì© 443 function setupJoinMemberPageCheckId(){ 444 var url = location.href; 445 var tmp_url = url.split("?"); 446 var domain = moduleJcryption.getHostNameFromUrl(tmp_url[0]); 447 var sub_url = tmp_url[0].replace(domain,""); 448 449 // íìê°ì íì´ì§ ì¼ ê²½ì° 450 if(sub_url=="/member/register"){ 451 452 // íì¬ íìê°ì í¼ì action ì íµí´ ì ë£/ë¬´ë£ SSLì íì¸íë¤. 453 var registFrmAction = $("#registFrm").attr("action"); 454 var registFrmHost = moduleJcryption.getHostNameFromUrl(registFrmAction); 455 if(registFrmHost.indexOf("http")>-1){ 456 var sslSubUrlIndex = 0; 457 if(registFrmHost == "https://ssl.gabiafreemall.com"){ 458 sslSubUrlIndex = 1; 459 } 460 var idCheckFormUrl = registFrmHost+arrCheckActions[sslSubUrlIndex]; 461 462 var idCheckCallbackUrl = domain+"/member/"+"../member_process/id_chk"; 463 var encodeIdCheckCallbackUrl = Base64.encode(idCheckCallbackUrl); 464 encodeIdCheckCallbackUrl = encodeIdCheckCallbackUrl.replace(/[\+]/g,"-"); 465 encodeIdCheckCallbackUrl = encodeIdCheckCallbackUrl.replace(/[\/]/g,"_"); 466 var idCheckFormAction = idCheckFormUrl+encodeIdCheckCallbackUrl; 467 468 $("input[name='userid']").unbind("blur"); 469 $("input[name='userid']").blur(function() { 470 471 if($(this).val()){ 472 // rsa í¼ ìì 473 $("#idchkform").remove(); 474 $(".rsaForm").remove(); 475 $formEl = $("<form id='idchkform' method='post' target='actionFrame' action='"+idCheckFormAction+"'/>"); 476 var idval = $("<input type='hidden' name='userid' value='"+$(this).val()+"'>"); 477 $formEl.append(idval); 478 $("body").append($formEl); 479 480 // ìí¸í ì ì© 481 var AESEncryptionKey = $.jCryption.getAESEncryptionKey($formEl); 482 // console.log(AESEncryptionKey); 483 var hostName = moduleJcryption.getHostNameFromForm($formEl); 484 485 var $submitElement = $formEl.find(":input:submit"); 486 var $encryptedElement = $("<input />",{ 487 type:'hidden', 488 name:'jCryption' 489 }); 490 491 // ìí¸í submit ì ì© form 492 var $submitRSAForm = $("<form class='rsaForm'/>"); 493 var formAttrs = moduleJcryption.getAttributes($formEl); 494 for (var i in formAttrs){ 495 if(i!="id" && i!="name"){ 496 $submitRSAForm.attr(i,formAttrs[i]); 497 } 498 } 499 var remakeHandshakeUrl = handshakeUrl[moduleJcryption.checkSSLForm($formEl)]; 500 if(moduleJcryption.checkSSLForm($formEl)!=0){ 501 remakeHandshakeUrl = remakeHandshakeUrl+"/"+$.jCryption.getAESSessionKey($submitRSAForm); 502 } 503 504 $.jCryption.authenticate( 505 AESEncryptionKey, 506 hostName+getPublicKeyUrl[moduleJcryption.checkSSLForm($formEl)], 507 hostName+remakeHandshakeUrl, 508 function(AESEncryptionKey) { 509 var toEncrypt = $formEl.serialize(); 510 // console.log(toEncrypt); 511 // console.log($formEl); 512 if ($submitElement.is(":submit")) { 513 toEncrypt = toEncrypt + "&" + $submitElement.attr("name") + "=" + $submitElement.val(); 514 } 515 $encryptedElement.val($.jCryption.encrypt
515(toEncrypt, AESEncryptionKey)); 516 // console.log($submitRSAForm); 517 $submitRSAForm.append($encryptedElement); 518 $("body").append($submitRSAForm); 519 $submitRSAForm.data("jCryptionInit",true); 520 moduleJcryption.convertActionUrl($submitRSAForm); 521 $submitRSAForm.submit(); 522 }, 523 function() { 524 // Authentication with AES Failed ... sending form without protection 525 confirm("Authentication with Server failed, are you sure you want to submit this form unencrypted?", function() { 526 $formEl.submit(); 527 }); 528 } 529 ); 530 531 } 532 }); 533 } 534 } 535 } 536 setupJoinMemberPageCheckId(); 537} 538function callbackIdChk(json){ 539 var response = $.parseJSON(json); 540 var text = response.return_result; 541 var userid = response.userid; 542 $("#id_info").html(text); 543 $("input[name='userid']").val(userid); 544} 545//############################## 2019-10-16 [gcs] sdh : #3406 무ë£ë³´ìí¨ì¹ ##############################
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.