diff --git a/hwe/js/common.js b/hwe/js/common.js index e66a5b94..6f4ee66a 100644 --- a/hwe/js/common.js +++ b/hwe/js/common.js @@ -1,417 +1,2 @@ -/** - * <>& 등을 html에서도 그대로 보이도록 escape주는 함수 - * @see https://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery - * @param {string} string escape하고자 하는 문자열 - * @returns {string} - */ -var escapeHtml = (function(string) { - var entityMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/', - '`': '`', - '=': '=' - }; - - return function(string) { - return String(string).replace(/[&<>"'`=\/]/g, function(s) { - return entityMap[s]; - }); - } -})(); - -/** - * 변수가 정수인지 확인하는 함수 - * @param {*} n 정수인지 확인하기 위한 인자 - * @return {boolean} 정수인지 여부 - */ -function isInt(n) { - return +n === n && !(n % 1); -} - -; -(function(ns) { - //https://gist.github.com/demouth/3217440 - /** - * mb_strwidth - * @param String - * @return int - * @see http://php.net/manual/ja/function.mb-strwidth.php - */ - var mb_strwidth = function(str) { - var i = 0, - l = str.length, - c = '', - length = 0; - for (; i < l; i++) { - c = str.charCodeAt(i); - if (0x0000 <= c && c <= 0x0019) { - length += 0; - } else if (0x0020 <= c && c <= 0x1FFF) { - length += 1; - } else if (0x2000 <= c && c <= 0xFF60) { - length += 2; - } else if (0xFF61 <= c && c <= 0xFF9F) { - length += 1; - } else if (0xFFA0 <= c) { - length += 2; - } - } - return length; - }; - - /** - * mb_strimwidth - * @param String - * @param int - * @param int - * @param String - * @return String - * @see http://www.php.net/manual/ja/function.mb-strimwidth.php - */ - var mb_strimwidth = function(str, start, width, trimmarker) { - if (typeof trimmarker === 'undefined') trimmarker = ''; - var trimmakerWidth = mb_strwidth(trimmarker), - i = start, - l = str.length, - trimmedLength = 0, - trimmedStr = ''; - for (; i < l; i++) { - var charCode = str.charCodeAt(i), - c = str.charAt(i), - charWidth = mb_strwidth(c), - next = str.charAt(i + 1), - nextWidth = mb_strwidth(next); - trimmedLength += charWidth; - trimmedStr += c; - if (trimmedLength + trimmakerWidth + nextWidth > width) { - trimmedStr += trimmarker; - break; - } - } - return trimmedStr; - }; - ns.mb_strwidth = mb_strwidth; - ns.mb_strimwidth = mb_strimwidth; -})(window); - -/** - * object의 array를 id를 key로 삼는 object로 재 변환 - * @param {Array.{id: Object}} arr id를 가진 object의 array - * @returns {Object} - */ -function convertDictById(arr) { - var result = {}; - arr.forEach(function(v, i) { - result[v.id] = v; - }); - return result; -} - -/** - * array를 set 형태의 object로 변환 - * @param {Array} arr 값을 가진 array - * @returns {Object} - */ -function convertSet(arr) { - var result = {}; - arr.forEach(function(v) { - result[v] = true; - }); - return result; -} - - -/** - * {0}, {1}, {2}형태로 포맷해주는 함수 - */ -String.prototype.format = function() { - var args = arguments; - return this.replace(/{(\d+)}/g, function(match, number) { - return (typeof args[number] != 'undefined') ? args[number] : match; - }); -}; - - -function hexToRgb(hex) { - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } : null; -} - - -function isBrightColor(color) { - color = hexToRgb(color); - if ((color.r * 0.299 + color.g * 0.587 + color.b * 0.114) > 140) { - return true; - } else { - return false; - } -} - - -/** - * 게임내에서 지원하는 color type만 선택할 수 있도록 해주는 함수 - * @param {string} color #AAAAAA 또는 AAAAAA 형태로 작성된 RGB hex color string - * @returns {string} - */ -function convColorValue(color) { - if (color.charAt(0) == '#') { - color = color.substr(1); - } - color = color.toUpperCase(); - - var colorBase = convertSet([ - '000080', '0000FF', '008000', '008080', '00BFFF', '00FF00', '00FFFF', '20B2AA', - '2E8B57', '483D8B', '6495ED', '7B68EE', '7CFC00', '7FFFD4', '800000', '800080', - '808000', '87CEEB', 'A0522D', 'A9A9A9', 'AFEEEE', 'BA55D3', 'E0FFFF', 'F5F5DC', - 'FF0000', 'FF00FF', 'FF6347', 'FFA500', 'FFC0CB', 'FFD700', 'FFDAB9', 'FFFF00', - 'FFFFFF' - ]); - - if (!colorBase.hasOwnProperty(color)) { - return '000000'; - } - - return color; - -} - - -function numberWithCommas(x) { - return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); -} - -function linkifyStrWithOpt(text) { - return linkifyStr(text, {}); -} - -/** - * 단순한 Template 함수. <%변수명%>으로 template 가능 - * @see https://github.com/krasimir/absurd/blob/master/lib/processors/html/helpers/TemplateEngine.js - * @param {string} html - * @param {object} options - * @returns {string} - */ -var TemplateEngine = function(html, options) { - var re = /<%(.+?)%>/g, - reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g, - code = 'with(obj) { var r=[];\n', - cursor = 0, - result, - match; - var add = function(line, js) { - js ? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') : - (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : ''); - return add; - } - options.e = escapeHtml; - options.linkifyStr = linkifyStrWithOpt; - while (match = re.exec(html)) { - add(html.slice(cursor, match.index))(match[1], true); - cursor = match.index + match[0].length; - } - add(html.substr(cursor, html.length - cursor)); - code = (code + 'return r.join(""); }').replace(/[\r\t\n]/g, ' '); - try { result = new Function('obj', code).apply(options, [options]); } catch (err) { console.error("'" + err.message + "'", " in \n\nCode:\n", code, "\n"); } - return result; -} - -function getIconPath(imgsvr, picture) { - // ../d_shared/common_path.js 필요 - if (!imgsvr) { - return pathConfig.sharedIcon + '/' + picture; - } else { - return pathConfig.root + '/d_pic/' + picture; - } -} - -function activeFlip($obj) { - var $result; - if ($obj === undefined) { - $result = $('img[data-flip]'); - } else { - $result = $obj.find('img[data-flip]'); - } - - $result.each(function() { - activeFlipItem($(this)); - }); - -} - -function combineObject(item, columnList) { - var newItem = {}; - for (var columnIdx in columnList) { - var columnName = columnList[columnIdx]; - newItem[columnName] = item[columnIdx]; - } - return newItem; -} - -function combineArray(array, columnList) { - var result = []; - for (var key in array) { - var item = array[key]; - result[key] = combineObject(item, columnList); - } - return result; -} - -function activeFlipItem($img) { - var imageList = []; - imageList.push($img.attr('src')); - $.each($img.data('flip').split(','), function(idx, value) { - var value = $.trim(value); - if (!value) { - return true; - } - imageList.push(value); - }); - if (imageList.length <= 1) { - return; - } - $img.data('computed_flip_array', imageList); - $img.data('computed_flip_idx', 0); - - $img.click(function() { - var arr = $img.data('computed_flip_array'); - var idx = $img.data('computed_flip_idx'); - idx = (idx + 1) % (arr.length); - $img.attr('src', arr[idx]); - $img.data('computed_flip_idx', idx); - }); - $img.css('cursor', 'pointer'); -} - -jQuery(function($) { - $('.obj_tooltip').mouseover(function() { - var $objTooltip = $(this); - if ($objTooltip.data('setObjTooltip')) { - return true; - } - - var tooltipClassText = $objTooltip.data('tooltip-class'); - if (!tooltipClassText) { - tooltipClassText = ''; - } - var template = '' - .format(tooltipClassText); - - $objTooltip.tooltip({ - title: function() { - return $.trim($(this).find('.tooltiptext').html()); - }, - template: template, - html: true - }).tooltip('show'); - - $objTooltip.data('setObjTooltip', true); - }); - /*each(function(){ - var $objTooltip = $(this); - - - });*/ - - activeFlip(); - - var customCSS = localStorage.getItem('sam_customCSS'); - if (customCSS) { - var $style = $(''); - $style.text(customCSS); - $style.appendTo($('head')); - } - - -}); - - -function errUnknown() { - alert('작업을 실패했습니다.'); -} - -function errUnknownToast() { - $.toast({ - title: '에러!', - content: '작업을 실패했습니다.', - type: 'danger', - delay: 5000 - }); -} - -function quickReject(errMsg) { - if (errMsg === undefined) { - errMsg = '작업을 실패했습니다.'; - } - var deferred = $.Deferred(); - deferred.reject(errMsg); - return deferred.promise(); -} - -function nl2br(text) { - return text.replace(/\n/g, "
"); -} -/* -function br2nl (text) { - return text.replace(/<\s*\/?br\s*[\/]?>/gi, '\n'); -} -*/ - -function getNpcColor(npcType) { - if (npcType >= 2) { - return 'cyan'; - } - if (npcType == 1) { - return 'skyblue'; - } - return null; -} - -function initTooltip($obj) { - if ($obj === undefined) { - $obj = $('.obj_tooltip'); - } else if (!$obj.hasClass('obj_tooltip')) { - $obj = $obj.find('.obj_tooltip'); - } - console.log($obj); - - $obj.each(function() { - $target = $(this); - - if ($target.data('installHandler')) { - return true; - } - $target.data('installHandler', true); - - $target.mouseover(function() { - var $objTooltip = $(this); - if ($objTooltip.data('setObjTooltip')) { - return true; - } - - var tooltipClassText = $objTooltip.data('tooltip-class'); - if (!tooltipClassText) { - tooltipClassText = ''; - } - var template = '' - .format(tooltipClassText); - - $objTooltip.tooltip({ - title: function() { - return $.trim($(this).find('.tooltiptext').html()); - }, - template: template, - html: true - }).tooltip('show'); - - $objTooltip.data('setObjTooltip', true); - }); - }); -} \ No newline at end of file +(()=>{"use strict";function t(n){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(n)}function n(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}function r(t,n){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:"";return n(this,l),p(a(t=c.call(this,r)),"name","RuntimeError"),t.message=r,t}return i=l,(u=[{key:"toString",value:function(){return this.message?this.name+": "+this.message:this.name}}])&&r(i.prototype,u),l}(u(Error)));function v(t,n){(null==n||n>t.length)&&(n=t.length);for(var r=0,e=new Array(n);r":">",'"':""","'":"'","/":"/","`":"`","=":"="},function(t){return String(t).replace(/[&<>"'`=/]/g,(function(t){return h[t]}))});function y(t){for(var n=t.length,r=0,e=0;e');r.text(n),r.appendTo(t("head"))}})),window.escapeHtml=w,window.isInt=function(t){return+t===t&&!(t%1)},window.mb_strwidth=y,window.mb_strimwidth=function(t,n,r){for(var e=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=y(e),i=t.length,a=0,u=[],c=n;cr){u.push(e);break}}return u.join("")},window.convertDictById=function(t){for(var n={},r=0,e=Object.values(t);r140},window.convColorValue=function(t){return"#"==t.charAt(0)&&(t=t.substr(1)),t=t.toUpperCase(),new Set(["000080","0000FF","008000","008080","00BFFF","00FF00","00FFFF","20B2AA","2E8B57","483D8B","6495ED","7B68EE","7CFC00","7FFFD4","800000","800080","808000","87CEEB","A0522D","A9A9A9","AFEEEE","BA55D3","E0FFFF","F5F5DC","FF0000","FF00FF","FF6347","FFA500","FFC0CB","FFD700","FFDAB9","FFFF00","FFFFFF"]).has(t)?t:"000000"},window.numberWithCommas=function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},window.linkifyStrWithOpt=m,window.TemplateEngine=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=/<%(.+?)%>/g,e=/(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g,o=0,i=function t(n,r){return u+=r?n.match(e)?n+"\n":"r.push("+n+");\n":""!=n?'r.push("'+n.replace(/"/g,'\\"')+'");\n':"",t};for(n.e=w,n.linkifyStr=m;;){var a=r.exec(t);if(!a)break;i(t.slice(o,a.index))(a[1],!0),o=a.index+a[0].length}i(t.substr(o,t.length-o));var u="with(obj) { var r=[];\n";u=(u+'return r.join(""); }').replace(/[\r\t\n]/g," ");try{return new Function("obj",u).apply(n,[n])}catch(t){throw console.error("'"+t.message+"'"," in \n\nCode:\n",u,"\n"),t}},window.getIconPath=function(t,n){return t?window.pathConfig.root+"/d_pic/"+n:window.pathConfig.sharedIcon+"/"+n},window.activeFlip=g,window.combineObject=F,window.combineArray=function(t,n){var r,e=[],o=function(t,n){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,n){if(t){if("string"==typeof t)return v(t,n);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?v(t,n):void 0}}(t))||n&&t&&"number"==typeof t.length){r&&(t=r);var e=0,o=function(){};return{s:o,n:function(){return e>=t.length?{done:!0}:{done:!1,value:t[e++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return a=t.done,t},e:function(t){u=!0,i=t},f:function(){try{a||null==r.return||r.return()}finally{if(u)throw i}}}}(t.keys());try{for(o.s();!(r=o.n()).done;){var i=r.value,a=t[i];e[i]=F(a,n)}}catch(t){o.e(t)}finally{o.f()}return e},window.activeFlipItem=j,window.errUnknown=function(){alert("작업을 실패했습니다.")},window.errUnknownToast=function(){jQuery.toast({title:"에러!",content:"작업을 실패했습니다.",type:"danger",delay:5e3})},window.quickReject=function(t){void 0===t&&(t="작업을 실패했습니다.");var n=$.Deferred();return n.reject(t),n.promise()},window.nl2br=function(t){return t.replace(/\n/g,"
")},window.getNpcColor=function(t){return t>=2?"cyan":1==t?"skyblue":null},window.initTooltip=function(t){void 0===t?t=$(".obj_tooltip"):t.hasClass("obj_tooltip")||(t=t.find(".obj_tooltip")),console.log(t),t.each((function(){var t=$(this);t.data("installHandler")||(t.data("installHandler",!0),t.mouseover((function(){var t=$(this);if(!t.data("setObjTooltip")){var n=t.data("tooltip-class");n||(n="");var r=''.format(n);t.tooltip({title:function(){return $.trim($(this).find(".tooltiptext").html())},template:r,html:!0}).tooltip("show"),t.data("setObjTooltip",!0)}})))}))}})(); +//# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/hwe/js/common.js.map b/hwe/js/common.js.map new file mode 100644 index 00000000..f5a4e125 --- /dev/null +++ b/hwe/js/common.js.map @@ -0,0 +1 @@ +{"version":3,"file":"common.js","mappings":"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","sources":["webpack://hidche_lib/./hwe/ts/util.ts","webpack://hidche_lib/./hwe/ts/common_legacy.ts"],"sourcesContent":["type ErrType = { new(msg?: string): T }\ntype Nullable = T | null | undefined\n\nexport class RuntimeError extends Error {\n public name = 'RuntimeError';\n constructor(public message: string = '') {\n super(message);\n }\n toString(): string {\n if (this.message) {\n return this.name + ': ' + this.message;\n }\n else {\n return this.name;\n }\n }\n}\n\nexport class NotNullExpected extends RuntimeError {\n public name = 'NotNullExpected';\n}\n\nexport function unwrap(result: Nullable): T {\n if (result === null || result === undefined) {\n throw new NotNullExpected();\n }\n return result;\n}\n\nexport function unwrap_err(result: Nullable, errType: ErrType, errMsg?: string): T {\n if (result === null || result === undefined) {\n throw new errType(errMsg);\n }\n return result;\n}","import { unwrap } from \"./util\";\n\ndeclare const jQuery: JQueryStatic;\n\n\n/** \n * <>& 등을 html에서도 그대로 보이도록 escape주는 함수\n * @see https://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery\n */\nexport const escapeHtml = (() => {\n const entityMap: { [v: string]: string } = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '='\n };\n\n return function (string: string) {\n return String(string).replace(/[&<>\"'`=/]/g, function (s: string) {\n return entityMap[s];\n });\n }\n})();\n\n/**\n * 변수가 정수인지 확인하는 함수\n * @param {*} n 정수인지 확인하기 위한 인자\n * @return {boolean} 정수인지 여부\n */\nexport function isInt(n: unknown): n is number {\n const v = n as number;\n return +v === v && !(v % 1);\n}\n\n\n//https://gist.github.com/demouth/3217440\n/**\n * mb_strwidth\n * @see http://php.net/manual/function.mb-strwidth.php\n */\nexport function mb_strwidth(str: string): number {\n const l = str.length;\n let length = 0;\n for (let i = 0; i < l; i++) {\n const c = str.charCodeAt(i);\n if (0x0000 <= c && c <= 0x0019) {\n length += 0;\n } else if (0x0020 <= c && c <= 0x1FFF) {\n length += 1;\n } else if (0x2000 <= c && c <= 0xFF60) {\n length += 2;\n } else if (0xFF61 <= c && c <= 0xFF9F) {\n length += 1;\n } else if (0xFFA0 <= c) {\n length += 2;\n }\n }\n return length;\n}\n\n\n/**\n * mb_strimwidth\n * @param String\n * @param int\n * @param int\n * @param String\n * @return String\n * @see http://www.php.net/manual/function.mb-strimwidth.php\n */\nexport function mb_strimwidth(str: string, start: number, width: number, trimmarker = ''): string {\n const trimmakerWidth = mb_strwidth(trimmarker);\n const l = str.length;\n let trimmedLength = 0;\n const trimmedStr: string[] = [];\n for (let i = start; i < l; i++) {\n const c = str.charAt(i);\n const charWidth = mb_strwidth(c);\n const next = str.charAt(i + 1);\n const nextWidth = mb_strwidth(next);\n\n trimmedLength += charWidth;\n trimmedStr.push(c);\n if (trimmedLength + trimmakerWidth + nextWidth > width) {\n trimmedStr.push(trimmarker);\n break;\n }\n }\n return trimmedStr.join('');\n}\n\n/**\n * object의 array를 id를 key로 삼는 object로 재 변환\n */\nexport function convertDictById(arr: ArrayLike): Record {\n const result: Record = {};\n for (const v of Object.values(arr)) {\n result[v.id] = v;\n }\n return result;\n}\n\n/**\n * array를 set 형태의 object로 변환\n */\nexport function convertSet(arr: ArrayLike): Record {\n const result: Record = {};\n for (const v of Object.values(arr)) {\n result[v] = true;\n }\n return result;\n}\n\n\n/** \n * {0}, {1}, {2}형태로 포맷해주는 함수\n */\n\ndeclare global {\n interface String {\n format(...args: string[]): string;\n }\n}\nString.prototype.format = function (...args: string[]) {\n return this.replace(/{(\\d+)}/g, function (match, number) {\n return (typeof args[number] != 'undefined') ? args[number] : match;\n });\n};\n\n\nexport function hexToRgb(hex: string): { r: number, g: number, b: number } | null {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n}\n\nexport function isBrightColor(color: string): boolean {\n const cv = unwrap(hexToRgb(color));\n if ((cv.r * 0.299 + cv.g * 0.587 + cv.b * 0.114) > 140) {\n return true;\n } else {\n return false;\n }\n}\n\n/**\n * 게임내에서 지원하는 color type만 선택할 수 있도록 해주는 함수\n * @param {string} color #AAAAAA 또는 AAAAAA 형태로 작성된 RGB hex color string\n * @returns {string}\n */\nexport function convColorValue(color: string): string {\n if (color.charAt(0) == '#') {\n color = color.substr(1);\n }\n color = color.toUpperCase();\n\n const colorBase = new Set([\n '000080', '0000FF', '008000', '008080', '00BFFF', '00FF00', '00FFFF', '20B2AA',\n '2E8B57', '483D8B', '6495ED', '7B68EE', '7CFC00', '7FFFD4', '800000', '800080',\n '808000', '87CEEB', 'A0522D', 'A9A9A9', 'AFEEEE', 'BA55D3', 'E0FFFF', 'F5F5DC',\n 'FF0000', 'FF00FF', 'FF6347', 'FFA500', 'FFC0CB', 'FFD700', 'FFDAB9', 'FFFF00',\n 'FFFFFF'\n ]);\n\n if (!colorBase.has(color)) {\n return '000000';\n }\n\n return color;\n}\n\n\nexport function numberWithCommas(x: number): string {\n return x.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n}\n\n//linkify가 불러와 있어야함\ndeclare global {\n interface Window {\n linkifyStr: (v: string, k?: Record) => string;\n }\n}\nexport function linkifyStrWithOpt(text: string): string {\n return window.linkifyStr(text, {});\n}\n\n/**\n * 단순한 Template 함수. <%변수명%>으로 template 가능\n * @see https://github.com/krasimir/absurd/blob/master/lib/processors/html/helpers/TemplateEngine.js\n * @param {string} html \n * @param {object} options \n * @returns {string}\n */\nexport function TemplateEngine(html: string, options: Record = {}): string {\n const re = /<%(.+?)%>/g;\n const reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g;\n let cursor = 0;\n const add = function (line: string, js?: boolean) {\n js ? (code += line.match(reExp) ? line + '\\n' : 'r.push(' + line + ');\\n') :\n (code += line != '' ? 'r.push(\"' + line.replace(/\"/g, '\\\\\"') + '\");\\n' : '');\n return add;\n }\n options.e = escapeHtml;\n options.linkifyStr = linkifyStrWithOpt;\n for (; ;) {\n const match = re.exec(html);\n if (!match) {\n break;\n }\n add(html.slice(cursor, match.index))(match[1], true);\n cursor = match.index + match[0].length;\n }\n add(html.substr(cursor, html.length - cursor));\n\n let code = 'with(obj) { var r=[];\\n';\n code = (code + 'return r.join(\"\"); }').replace(/[\\r\\t\\n]/g, ' ');\n try {\n return new Function('obj', code).apply(options, [options]);\n } catch (err) {\n console.error(\"'\" + err.message + \"'\", \" in \\n\\nCode:\\n\", code, \"\\n\");\n throw err;\n }\n}\n\nexport function getIconPath(imgsvr: boolean | 1 | 0, picture: string): string {\n // ../d_shared/common_path.js 필요\n if (!imgsvr) {\n return window.pathConfig.sharedIcon + '/' + picture;\n } else {\n return window.pathConfig.root + '/d_pic/' + picture;\n }\n}\n\nexport function activeFlip($obj?: JQuery): void {\n let $result: JQuery;\n if ($obj === undefined) {\n $result = $('img[data-flip]');\n } else {\n $result = $obj.find('img[data-flip]');\n }\n\n $result.each(function () {\n activeFlipItem($(this));\n });\n\n}\n\nexport function combineObject(item: V[], columnList: K[]): Record {\n const newItem: Record = {};\n for (const columnIdx in columnList) {\n const columnName = columnList[columnIdx];\n newItem[columnName] = item[columnIdx];\n }\n return newItem;\n}\n\nexport function combineArray(array: V[][], columnList: K[]): Record[] {\n const result: Record[] = [];\n for (const key of array.keys()) {\n const item = array[key];\n result[key] = combineObject(item, columnList);\n }\n return result;\n}\n\nexport function activeFlipItem($img: JQuery): void {\n const imageList = [];\n imageList.push($img.attr('src'));\n $.each($img.data('flip').split(','), function (idx, value) {\n value = $.trim(value);\n if (!value) {\n return true;\n }\n imageList.push(value);\n });\n if (imageList.length <= 1) {\n return;\n }\n $img.data('computed_flip_array', imageList);\n $img.data('computed_flip_idx', 0);\n\n $img.click(function () {\n const arr = $img.data('computed_flip_array');\n let idx = $img.data('computed_flip_idx');\n idx = (idx + 1) % (arr.length);\n $img.attr('src', arr[idx]);\n $img.data('computed_flip_idx', idx);\n });\n $img.css('cursor', 'pointer');\n}\n\njQuery(function ($) {\n $('.obj_tooltip').mouseover(function () {\n const $objTooltip = $(this);\n if ($objTooltip.data('setObjTooltip')) {\n return true;\n }\n\n let tooltipClassText = $objTooltip.data('tooltip-class');\n if (!tooltipClassText) {\n tooltipClassText = '';\n }\n const template = '
'\n .format(tooltipClassText);\n\n $objTooltip.tooltip({\n title: function () {\n return $.trim($(this).find('.tooltiptext').html());\n },\n template: template,\n html: true\n }).tooltip('show');\n\n $objTooltip.data('setObjTooltip', true);\n });\n /*each(function(){\n var $objTooltip = $(this);\n \n \n });*/\n\n activeFlip();\n\n const customCSS = localStorage.getItem('sam_customCSS');\n if (customCSS) {\n const $style = $('');\n $style.text(customCSS);\n $style.appendTo($('head'));\n }\n});\n\n\nexport function errUnknown(): void {\n alert('작업을 실패했습니다.');\n}\n\n\n\nexport function errUnknownToast(): void {\n jQuery.toast({\n title: '에러!',\n content: '작업을 실패했습니다.',\n type: 'danger',\n delay: 5000\n });\n}\n\nexport function quickReject(errMsg: string): JQuery.Promise {\n if (errMsg === undefined) {\n errMsg = '작업을 실패했습니다.';\n }\n const deferred = $.Deferred();\n void deferred.reject(errMsg);\n return deferred.promise();\n}\n\nexport function nl2br(text: string): string {\n return text.replace(/\\n/g, \"
\");\n}\n/*\nfunction br2nl (text) { \n return text.replace(/<\\s*\\/?br\\s*[\\/]?>/gi, '\\n');\n}\n*/\n\nexport function getNpcColor(npcType: number): 'cyan' | 'skyblue' | null {\n if (npcType >= 2) {\n return 'cyan';\n }\n if (npcType == 1) {\n return 'skyblue';\n }\n return null;\n}\n\nexport function initTooltip($obj: JQuery): void {\n if ($obj === undefined) {\n $obj = $('.obj_tooltip');\n } else if (!$obj.hasClass('obj_tooltip')) {\n $obj = $obj.find('.obj_tooltip');\n }\n console.log($obj);\n\n $obj.each(function () {\n const $target = $(this);\n\n if ($target.data('installHandler')) {\n return;\n }\n $target.data('installHandler', true);\n\n $target.mouseover(function () {\n const $objTooltip = $(this);\n if ($objTooltip.data('setObjTooltip')) {\n return;\n }\n\n let tooltipClassText = $objTooltip.data('tooltip-class');\n if (!tooltipClassText) {\n tooltipClassText = '';\n }\n const template = '
'\n .format(tooltipClassText);\n\n $objTooltip.tooltip({\n title: function () {\n return $.trim($(this).find('.tooltiptext').html());\n },\n template: template,\n html: true\n }).tooltip('show');\n\n $objTooltip.data('setObjTooltip', true);\n });\n });\n}\n\ndeclare global {\n interface Window {\n /** @deprecated Module 사용할 것 */\n escapeHtml: typeof escapeHtml;\n /** @deprecated Module 사용할 것 */\n isInt: typeof isInt;\n /** @deprecated Module 사용할 것 */\n mb_strwidth: typeof mb_strwidth;\n /** @deprecated Module 사용할 것 */\n mb_strimwidth: typeof mb_strimwidth;\n /** @deprecated Module 사용할 것 */\n convertDictById: typeof convertDictById;\n /** @deprecated Module 사용할 것 */\n convertSet: typeof convertSet;\n /** @deprecated Module 사용할 것 */\n hexToRgb: typeof hexToRgb;\n /** @deprecated Module 사용할 것 */\n isBrightColor: typeof isBrightColor;\n /** @deprecated Module 사용할 것 */\n convColorValue: typeof convColorValue;\n /** @deprecated Module 사용할 것 */\n numberWithCommas: typeof numberWithCommas;\n /** @deprecated Module 사용할 것 */\n linkifyStrWithOpt: typeof linkifyStrWithOpt;\n /** @deprecated Module 사용할 것 */\n TemplateEngine: typeof TemplateEngine;\n /** @deprecated Module 사용할 것 */\n getIconPath: typeof getIconPath;\n /** @deprecated Module 사용할 것 */\n activeFlip: typeof activeFlip;\n /** @deprecated Module 사용할 것 */\n combineObject: typeof combineObject;\n /** @deprecated Module 사용할 것 */\n combineArray: typeof combineArray;\n /** @deprecated Module 사용할 것 */\n activeFlipItem: typeof activeFlipItem;\n /** @deprecated Module 사용할 것 */\n errUnknown: typeof errUnknown;\n /** @deprecated Module 사용할 것 */\n errUnknownToast: typeof errUnknownToast;\n /** @deprecated Module 사용할 것 */\n quickReject: typeof quickReject;\n /** @deprecated Module 사용할 것 */\n nl2br: typeof nl2br;\n /** @deprecated Module 사용할 것 */\n getNpcColor: typeof getNpcColor;\n /** @deprecated Module 사용할 것 */\n initTooltip: typeof initTooltip;\n }\n}\n\nwindow.escapeHtml = escapeHtml;\nwindow.isInt = isInt;\nwindow.mb_strwidth = mb_strwidth;\nwindow.mb_strimwidth = mb_strimwidth;\nwindow.convertDictById = convertDictById;\nwindow.convertSet = convertSet;\nwindow.hexToRgb = hexToRgb;\nwindow.isBrightColor = isBrightColor;\nwindow.convColorValue = convColorValue;\nwindow.numberWithCommas = numberWithCommas;\nwindow.linkifyStrWithOpt = linkifyStrWithOpt;\nwindow.TemplateEngine = TemplateEngine;\nwindow.getIconPath = getIconPath;\nwindow.activeFlip = activeFlip;\nwindow.combineObject = combineObject;\nwindow.combineArray = combineArray;\nwindow.activeFlipItem = activeFlipItem;\nwindow.errUnknown = errUnknown;\nwindow.errUnknownToast = errUnknownToast;\nwindow.quickReject = quickReject;\nwindow.nl2br = nl2br;\nwindow.getNpcColor = getNpcColor;\nwindow.initTooltip = initTooltip;"],"names":["NotNullExpected","message","this","name","Error","entityMap","escapeHtml","string","String","replace","s","mb_strwidth","str","l","length","i","c","charCodeAt","hexToRgb","hex","result","exec","r","parseInt","g","b","linkifyStrWithOpt","text","window","linkifyStr","activeFlip","$obj","undefined","$","find","each","activeFlipItem","combineObject","item","columnList","newItem","columnIdx","$img","imageList","push","attr","data","split","idx","value","trim","click","arr","css","prototype","format","args","match","number","jQuery","mouseover","$objTooltip","tooltipClassText","template","tooltip","title","html","customCSS","localStorage","getItem","$style","appendTo","isInt","n","mb_strimwidth","start","width","trimmarker","trimmakerWidth","trimmedLength","trimmedStr","charAt","charWidth","next","nextWidth","join","convertDictById","Object","values","v","id","convertSet","isBrightColor","color","cv","unwrap","convColorValue","substr","toUpperCase","Set","has","numberWithCommas","x","toString","TemplateEngine","options","re","reExp","cursor","add","line","js","code","e","slice","index","Function","apply","err","console","error","getIconPath","imgsvr","picture","pathConfig","root","sharedIcon","combineArray","array","keys","key","errUnknown","alert","errUnknownToast","toast","content","type","delay","quickReject","errMsg","deferred","Deferred","reject","promise","nl2br","getNpcColor","npcType","initTooltip","hasClass","log","$target"],"sourceRoot":""} \ No newline at end of file diff --git a/hwe/ts/common_legacy.ts b/hwe/ts/common_legacy.ts new file mode 100644 index 00000000..b905383a --- /dev/null +++ b/hwe/ts/common_legacy.ts @@ -0,0 +1,498 @@ +import { unwrap } from "./util"; + +declare const jQuery: JQueryStatic; + + +/** + * <>& 등을 html에서도 그대로 보이도록 escape주는 함수 + * @see https://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery + */ +export const escapeHtml = (() => { + const entityMap: { [v: string]: string } = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + '`': '`', + '=': '=' + }; + + return function (string: string) { + return String(string).replace(/[&<>"'`=/]/g, function (s: string) { + return entityMap[s]; + }); + } +})(); + +/** + * 변수가 정수인지 확인하는 함수 + * @param {*} n 정수인지 확인하기 위한 인자 + * @return {boolean} 정수인지 여부 + */ +export function isInt(n: unknown): n is number { + const v = n as number; + return +v === v && !(v % 1); +} + + +//https://gist.github.com/demouth/3217440 +/** + * mb_strwidth + * @see http://php.net/manual/function.mb-strwidth.php + */ +export function mb_strwidth(str: string): number { + const l = str.length; + let length = 0; + for (let i = 0; i < l; i++) { + const c = str.charCodeAt(i); + if (0x0000 <= c && c <= 0x0019) { + length += 0; + } else if (0x0020 <= c && c <= 0x1FFF) { + length += 1; + } else if (0x2000 <= c && c <= 0xFF60) { + length += 2; + } else if (0xFF61 <= c && c <= 0xFF9F) { + length += 1; + } else if (0xFFA0 <= c) { + length += 2; + } + } + return length; +} + + +/** + * mb_strimwidth + * @param String + * @param int + * @param int + * @param String + * @return String + * @see http://www.php.net/manual/function.mb-strimwidth.php + */ +export function mb_strimwidth(str: string, start: number, width: number, trimmarker = ''): string { + const trimmakerWidth = mb_strwidth(trimmarker); + const l = str.length; + let trimmedLength = 0; + const trimmedStr: string[] = []; + for (let i = start; i < l; i++) { + const c = str.charAt(i); + const charWidth = mb_strwidth(c); + const next = str.charAt(i + 1); + const nextWidth = mb_strwidth(next); + + trimmedLength += charWidth; + trimmedStr.push(c); + if (trimmedLength + trimmakerWidth + nextWidth > width) { + trimmedStr.push(trimmarker); + break; + } + } + return trimmedStr.join(''); +} + +/** + * object의 array를 id를 key로 삼는 object로 재 변환 + */ +export function convertDictById(arr: ArrayLike): Record { + const result: Record = {}; + for (const v of Object.values(arr)) { + result[v.id] = v; + } + return result; +} + +/** + * array를 set 형태의 object로 변환 + */ +export function convertSet(arr: ArrayLike): Record { + const result: Record = {}; + for (const v of Object.values(arr)) { + result[v] = true; + } + return result; +} + + +/** + * {0}, {1}, {2}형태로 포맷해주는 함수 + */ + +declare global { + interface String { + format(...args: string[]): string; + } +} +String.prototype.format = function (...args: string[]) { + return this.replace(/{(\d+)}/g, function (match, number) { + return (typeof args[number] != 'undefined') ? args[number] : match; + }); +}; + + +export function hexToRgb(hex: string): { r: number, g: number, b: number } | null { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; +} + +export function isBrightColor(color: string): boolean { + const cv = unwrap(hexToRgb(color)); + if ((cv.r * 0.299 + cv.g * 0.587 + cv.b * 0.114) > 140) { + return true; + } else { + return false; + } +} + +/** + * 게임내에서 지원하는 color type만 선택할 수 있도록 해주는 함수 + * @param {string} color #AAAAAA 또는 AAAAAA 형태로 작성된 RGB hex color string + * @returns {string} + */ +export function convColorValue(color: string): string { + if (color.charAt(0) == '#') { + color = color.substr(1); + } + color = color.toUpperCase(); + + const colorBase = new Set([ + '000080', '0000FF', '008000', '008080', '00BFFF', '00FF00', '00FFFF', '20B2AA', + '2E8B57', '483D8B', '6495ED', '7B68EE', '7CFC00', '7FFFD4', '800000', '800080', + '808000', '87CEEB', 'A0522D', 'A9A9A9', 'AFEEEE', 'BA55D3', 'E0FFFF', 'F5F5DC', + 'FF0000', 'FF00FF', 'FF6347', 'FFA500', 'FFC0CB', 'FFD700', 'FFDAB9', 'FFFF00', + 'FFFFFF' + ]); + + if (!colorBase.has(color)) { + return '000000'; + } + + return color; +} + + +export function numberWithCommas(x: number): string { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); +} + +//linkify가 불러와 있어야함 +declare global { + interface Window { + linkifyStr: (v: string, k?: Record) => string; + } +} +export function linkifyStrWithOpt(text: string): string { + return window.linkifyStr(text, {}); +} + +/** + * 단순한 Template 함수. <%변수명%>으로 template 가능 + * @see https://github.com/krasimir/absurd/blob/master/lib/processors/html/helpers/TemplateEngine.js + * @param {string} html + * @param {object} options + * @returns {string} + */ +export function TemplateEngine(html: string, options: Record = {}): string { + const re = /<%(.+?)%>/g; + const reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g; + let cursor = 0; + const add = function (line: string, js?: boolean) { + js ? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') : + (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : ''); + return add; + } + options.e = escapeHtml; + options.linkifyStr = linkifyStrWithOpt; + for (; ;) { + const match = re.exec(html); + if (!match) { + break; + } + add(html.slice(cursor, match.index))(match[1], true); + cursor = match.index + match[0].length; + } + add(html.substr(cursor, html.length - cursor)); + + let code = 'with(obj) { var r=[];\n'; + code = (code + 'return r.join(""); }').replace(/[\r\t\n]/g, ' '); + try { + return new Function('obj', code).apply(options, [options]); + } catch (err) { + console.error("'" + err.message + "'", " in \n\nCode:\n", code, "\n"); + throw err; + } +} + +export function getIconPath(imgsvr: boolean | 1 | 0, picture: string): string { + // ../d_shared/common_path.js 필요 + if (!imgsvr) { + return window.pathConfig.sharedIcon + '/' + picture; + } else { + return window.pathConfig.root + '/d_pic/' + picture; + } +} + +export function activeFlip($obj?: JQuery): void { + let $result: JQuery; + if ($obj === undefined) { + $result = $('img[data-flip]'); + } else { + $result = $obj.find('img[data-flip]'); + } + + $result.each(function () { + activeFlipItem($(this)); + }); + +} + +export function combineObject(item: V[], columnList: K[]): Record { + const newItem: Record = {}; + for (const columnIdx in columnList) { + const columnName = columnList[columnIdx]; + newItem[columnName] = item[columnIdx]; + } + return newItem; +} + +export function combineArray(array: V[][], columnList: K[]): Record[] { + const result: Record[] = []; + for (const key of array.keys()) { + const item = array[key]; + result[key] = combineObject(item, columnList); + } + return result; +} + +export function activeFlipItem($img: JQuery): void { + const imageList = []; + imageList.push($img.attr('src')); + $.each($img.data('flip').split(','), function (idx, value) { + value = $.trim(value); + if (!value) { + return true; + } + imageList.push(value); + }); + if (imageList.length <= 1) { + return; + } + $img.data('computed_flip_array', imageList); + $img.data('computed_flip_idx', 0); + + $img.click(function () { + const arr = $img.data('computed_flip_array'); + let idx = $img.data('computed_flip_idx'); + idx = (idx + 1) % (arr.length); + $img.attr('src', arr[idx]); + $img.data('computed_flip_idx', idx); + }); + $img.css('cursor', 'pointer'); +} + +jQuery(function ($) { + $('.obj_tooltip').mouseover(function () { + const $objTooltip = $(this); + if ($objTooltip.data('setObjTooltip')) { + return true; + } + + let tooltipClassText = $objTooltip.data('tooltip-class'); + if (!tooltipClassText) { + tooltipClassText = ''; + } + const template = '' + .format(tooltipClassText); + + $objTooltip.tooltip({ + title: function () { + return $.trim($(this).find('.tooltiptext').html()); + }, + template: template, + html: true + }).tooltip('show'); + + $objTooltip.data('setObjTooltip', true); + }); + /*each(function(){ + var $objTooltip = $(this); + + + });*/ + + activeFlip(); + + const customCSS = localStorage.getItem('sam_customCSS'); + if (customCSS) { + const $style = $(''); + $style.text(customCSS); + $style.appendTo($('head')); + } +}); + + +export function errUnknown(): void { + alert('작업을 실패했습니다.'); +} + + + +export function errUnknownToast(): void { + jQuery.toast({ + title: '에러!', + content: '작업을 실패했습니다.', + type: 'danger', + delay: 5000 + }); +} + +export function quickReject(errMsg: string): JQuery.Promise { + if (errMsg === undefined) { + errMsg = '작업을 실패했습니다.'; + } + const deferred = $.Deferred(); + void deferred.reject(errMsg); + return deferred.promise(); +} + +export function nl2br(text: string): string { + return text.replace(/\n/g, "
"); +} +/* +function br2nl (text) { + return text.replace(/<\s*\/?br\s*[\/]?>/gi, '\n'); +} +*/ + +export function getNpcColor(npcType: number): 'cyan' | 'skyblue' | null { + if (npcType >= 2) { + return 'cyan'; + } + if (npcType == 1) { + return 'skyblue'; + } + return null; +} + +export function initTooltip($obj: JQuery): void { + if ($obj === undefined) { + $obj = $('.obj_tooltip'); + } else if (!$obj.hasClass('obj_tooltip')) { + $obj = $obj.find('.obj_tooltip'); + } + console.log($obj); + + $obj.each(function () { + const $target = $(this); + + if ($target.data('installHandler')) { + return; + } + $target.data('installHandler', true); + + $target.mouseover(function () { + const $objTooltip = $(this); + if ($objTooltip.data('setObjTooltip')) { + return; + } + + let tooltipClassText = $objTooltip.data('tooltip-class'); + if (!tooltipClassText) { + tooltipClassText = ''; + } + const template = '' + .format(tooltipClassText); + + $objTooltip.tooltip({ + title: function () { + return $.trim($(this).find('.tooltiptext').html()); + }, + template: template, + html: true + }).tooltip('show'); + + $objTooltip.data('setObjTooltip', true); + }); + }); +} + +declare global { + interface Window { + /** @deprecated Module 사용할 것 */ + escapeHtml: typeof escapeHtml; + /** @deprecated Module 사용할 것 */ + isInt: typeof isInt; + /** @deprecated Module 사용할 것 */ + mb_strwidth: typeof mb_strwidth; + /** @deprecated Module 사용할 것 */ + mb_strimwidth: typeof mb_strimwidth; + /** @deprecated Module 사용할 것 */ + convertDictById: typeof convertDictById; + /** @deprecated Module 사용할 것 */ + convertSet: typeof convertSet; + /** @deprecated Module 사용할 것 */ + hexToRgb: typeof hexToRgb; + /** @deprecated Module 사용할 것 */ + isBrightColor: typeof isBrightColor; + /** @deprecated Module 사용할 것 */ + convColorValue: typeof convColorValue; + /** @deprecated Module 사용할 것 */ + numberWithCommas: typeof numberWithCommas; + /** @deprecated Module 사용할 것 */ + linkifyStrWithOpt: typeof linkifyStrWithOpt; + /** @deprecated Module 사용할 것 */ + TemplateEngine: typeof TemplateEngine; + /** @deprecated Module 사용할 것 */ + getIconPath: typeof getIconPath; + /** @deprecated Module 사용할 것 */ + activeFlip: typeof activeFlip; + /** @deprecated Module 사용할 것 */ + combineObject: typeof combineObject; + /** @deprecated Module 사용할 것 */ + combineArray: typeof combineArray; + /** @deprecated Module 사용할 것 */ + activeFlipItem: typeof activeFlipItem; + /** @deprecated Module 사용할 것 */ + errUnknown: typeof errUnknown; + /** @deprecated Module 사용할 것 */ + errUnknownToast: typeof errUnknownToast; + /** @deprecated Module 사용할 것 */ + quickReject: typeof quickReject; + /** @deprecated Module 사용할 것 */ + nl2br: typeof nl2br; + /** @deprecated Module 사용할 것 */ + getNpcColor: typeof getNpcColor; + /** @deprecated Module 사용할 것 */ + initTooltip: typeof initTooltip; + } +} + +window.escapeHtml = escapeHtml; +window.isInt = isInt; +window.mb_strwidth = mb_strwidth; +window.mb_strimwidth = mb_strimwidth; +window.convertDictById = convertDictById; +window.convertSet = convertSet; +window.hexToRgb = hexToRgb; +window.isBrightColor = isBrightColor; +window.convColorValue = convColorValue; +window.numberWithCommas = numberWithCommas; +window.linkifyStrWithOpt = linkifyStrWithOpt; +window.TemplateEngine = TemplateEngine; +window.getIconPath = getIconPath; +window.activeFlip = activeFlip; +window.combineObject = combineObject; +window.combineArray = combineArray; +window.activeFlipItem = activeFlipItem; +window.errUnknown = errUnknown; +window.errUnknownToast = errUnknownToast; +window.quickReject = quickReject; +window.nl2br = nl2br; +window.getNpcColor = getNpcColor; +window.initTooltip = initTooltip; \ No newline at end of file diff --git a/hwe/ts/jquery-toast.d.ts b/hwe/ts/jquery-toast.d.ts new file mode 100644 index 00000000..bed348a5 --- /dev/null +++ b/hwe/ts/jquery-toast.d.ts @@ -0,0 +1,15 @@ +type JQueryBootstrapToast = { + container?: JQuery, + position?: 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center', + title?: string, + subtitle?: string, + content?: string, + type?: 'info'|'success'|'warning'|'danger'|'error', + delay?: number, + img?: string, + pause_on_hover?: boolean, +} + +interface JQueryStatic { + toast(opt: JQueryBootstrapToast): void; +} \ No newline at end of file diff --git a/package.json b/package.json index 8f94c49c..b5dcaea4 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,8 @@ "@babel/core": "^7.15.0", "@babel/preset-env": "^7.15.0", "@babel/preset-typescript": "^7.15.0", + "@types/bootstrap": "^4.6.1", + "@types/jquery": "^3.5.6", "@types/lodash": "^4.14.172", "@typescript-eslint/eslint-plugin": "^4.29.1", "@typescript-eslint/parser": "^4.29.1", diff --git a/webpack.config.js b/webpack.config.js index 2ebf3f26..4918cf53 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -10,6 +10,7 @@ module.exports = [ }, entry: { inheritPoint: './hwe/ts/inheritPoint.ts', + common: './hwe/ts/common_legacy.ts', }, output: { filename: '[name].js',