terser
terser copied to clipboard
[Feature request] Some points that can make the output smaller
Bug report or Feature request? Feature request
Version (complete output of terser -V
or specific git commit)
terser 5.18.2
Complete CLI command or minify()
options used
terser(jsstp_min,{
compress:{
unsafe:true,
computed_props:false,
unsafe_arrows:true,
unsafe_comps:true,
unsafe_Function:true,
unsafe_math:true,
unsafe_symbols:true,
unsafe_methods:true,
unsafe_proto:true,
unsafe_regexp:true,
unsafe_undefined:true
},
mangle:{
properties:{regex:/^_.*_$/}
}
);
terser
input
var jsstp = (function () {
/**
* 将字符串转换为小写
* @param {String} str 要转换的字符串
* @returns {String} 转换后的字符串
*/
var to_lower_case = str => str.toLowerCase();
/**
* 以spliter分割字符串str,只对第一个匹配的分隔符做分割
* @param {String} str 需要分割的字符串
* @param {String} spliter 分隔符
* @returns {[String,String]} 分割后的字符串数组
* @example
* var [key,value] = key_value_split("key: value",": ");
* @ignore
*/
var key_value_split = /*@__PURE__*/(str, spliter) => {
let index = str.indexOf(spliter);
return [str[substring](0, index), str[substring](index + spliter[length])];
};
/**
* 判断某一string是否符合给定的正则表达式
* @param {String} str 要判断的string
* @param {RegExp} reg 正则表达式
* @returns {Boolean} 是否符合给定的正则表达式
* @inline 这个函数使用的还不够多,以至于它带来的字节减少还没有抵消它本身的定义,我们持续inline直到未来其收益为正
* @ignore
*/
/*@__INLINE__*/var reg_test = /*@__PURE__*/(reg, str) => reg.test(str);
/**
* 判断某一string是否是事件名
* @param {String} str 要判断的string
* @returns {Boolean} 是否是事件名
* @ignore
*/
var is_event_name = /*@__PURE__*/(str) => /*@__INLINE__*/reg_test(/^On/, str);
/**
* 获取重整过的事件名
* @param {String} str 要重整的事件名
* @returns {String} 重整后的事件名
* @ignore
*/
var get_reorganized_event_name = /*@__PURE__*/(str) => str[2] == "_" ? str[substring](3) : str;
/**
* 判断一个数是否不是NaN
* @param {Number} num 要判断的数
* @returns {Boolean} 是否不是NaN
* @description 不使用Number.isNaN是为了节省压缩后字数
* @ignore
*/
var is_not_nan = /*@__PURE__*/(num) => num == num;
/**
* 将任意数据转换为字符串
* @param {*} data 任意数据
* @returns {String} 转换后的字符串
* @inline 这个函数不会带来任何压缩收益,所以我们保持其inline以节省其定义所占空间
* @ignore
*/
/*@__INLINE__*/var to_string = /*@__PURE__*/(data) => void_string + data;
/**
* 对代理的get方法进行封装,使其定义更为简单
* @param {{
* _blocker_: undefined|(target,key:String|Symbol) =>Boolean,
* _string_key_handler_:undefined|(target,key:String) =>any|undefined,
* _symbol_key_handler_:undefined|(target,key:Symbol) =>any|undefined,
* _default_handler_:undefined|(target,key:String|Symbol) =>any|undefined
* }} info 代理的get方法的信息
* @returns {(target, key:String|Symbol)=>any|undefined} 代理的get方法
* @ignore
*/
var new_get_handler = /*@__PURE__*/(info) =>
(target, key) => {
/*
the_function和the_string是为了节省压缩后字数而存在的,但是目前来说Function和String这两个东西只在这个函数有用到
反而,引入这两个变量会导致压缩后的代码变大,所以在这个函数中我们仍然使用Function和String
the_function和the_string的相关定义会作为dead code被优化掉
*/
if (info._blocker_ && info._blocker_(target, key))
return;
let result;
if (the_object(key) instanceof String)//string
result = info._string_key_handler_ && info._string_key_handler_(target, key);
else//symbol
result = info._symbol_key_handler_ && info._symbol_key_handler_(target, key);
if (result !== undefined$1)
return result;
else if (info._default_handler_)
return info._default_handler_(target, key)
return (result = target[key]) instanceof Function ? result.bind(target) : result;
};
/**
* 是否在浏览器中
* @type {Boolean}
* @ignore
*/
var in_browser = !!globalThis.window;//尽管globalThis.self也可以做到同样的事情(并且可以在压缩后的代码中节省2字节)
//但是为了避免node今后实现self,我们使用window
//node大概率不会实现window,因为多数代码都在使用windows判断是否在浏览器中
//这样做还能兼容html4!...大概?
/**
* 根据端口返回本地地址
* @param {Number|undefined} [port] 端口,默认为9801
* @returns {String} 本地地址
* @ignore
*/
var get_local_address = /*@__PURE__*/(port) => `http://localhost:${port??9801}`;
/**
* 默认的origin,在nodejs中为`http://localhost: env.PORT?? 9801`,在浏览器中为location.origin
* @type {String}
* @ignore
*/
var my_origin = in_browser ? location.origin : get_local_address(process.env.PORT);
/**
* 默认的安全等级,视origin而定,如果是本地的话为local,否则为external
* @type {String}
* @see {@link https://www.google.com/search?q=site%3Assp.shillest.net%2Fukadoc%2F+SecurityLevel}
* @ignore
*/
var my_default_security_level = /*@__INLINE__*/reg_test(/^\w+:\/\/localhost/, my_origin) ? local : external;
//一些会反复用到的常量或函数,提前定义以便在压缩时能够以短名称存在
/**
* @typename the_object
* @type {ObjectConstructor}
* @ignore
*/
var the_object = Object;
/**
* @typename the_proxy
* @type {ProxyConstructor}
* @ignore
*/
var the_proxy = Proxy;
var assign = the_object.assign;
var endline = "\r\n";
var undefined$1;// =undefined
var Get_Supported_Events = "Get_Supported_Events";
var Has_Event = "Has_Event";
var get_supported_events = to_lower_case(Get_Supported_Events);
var has_event = to_lower_case(Has_Event);
var get_simple_caller_of_event = "get_simple_caller_of_event";
var trivial_clone = "trivial_clone";
var default_info = "default_info";
var default_security_level="default_security_level";
var sstp_version_table = "sstp_version_table";
var substring = "substring";
var length = "length";
var available = "available";
var split = "split";
var entries = "entries";
var costom_text_send = "costom_text_send";
var forEach = "forEach";
var get_caller_of_method = "get_caller_of_method";
var unknown_lines = "unknown_lines";
var get_caller_of_event = "get_caller_of_event";
var sendername = "sendername";
var proxy = "proxy";
var then = "then";
var SEND = "SEND";
var get_fmo_infos = "get_fmo_infos";
var get_passthrough = "get_passthrough";
var local = "local";
var external = "external";
var void_string = "";
var _false_ = !1;
var x_sstp_passthru_head = "X-SSTP-PassThru-";
/**
* 拓展object,提供一些简单且遍历的操作
*/
class info_object {
/**
* @description 获取所有key的数组
*/
get keys() { return the_object.keys(this); }
/**
* @description 获取所有value的数组
*/
get values() { return the_object.values(this); }
/**
* @description 获取所有key-value对的数组
*/
get [entries]() { return the_object[entries](this); }
/**
* @description 获取成员数量
*/
get [length]() { return this.keys[length]; }
/**
* @description 对每个key-value对执行某个函数
* @param {(value,key?)} func 要执行的函数
*/
[forEach](func) {
return this[entries][forEach](([key, value]) => {
this[key] = func(value, key) ?? value;
});
}
/**
* @description 复制一个新的对象
* @returns {info_object} 复制的对象
*/
get [trivial_clone]() {
return assign(new_object(), this);
}
/**
* @description 遍历自身和子对象并返回一个由遍历结果构成的一维数组
* @param {(dimensions[...],value):any} func 要执行的函数,返回值将被添加到数组中
*/
flat_map(func) {
let result = [];
this[entries].map(([key, value]) =>
result.push(...(
value instanceof info_object?
value.flat_map(func.bind(func, key)):
[func(key, value)]//构建数组,因为外部有展开操作
))
);
return result;
}
/**
* @description 遍历自身并返回一个由遍历结果构成的一维数组
* @param {(value,key?):any} func 要执行的函数,返回值将被添加到数组中
*/
map(func) {
return this[entries].map(([key, value]) => func(value, key));
}
/**
* @description 对自身按照数组追加元素
* @param {[undefined|[String,String]]} array 要追加的数组
*/
push(array) {
array[forEach]((pair) => pair ? this[pair[0]] = pair[1] : undefined$1);
return this;
}
}
/**
* 生成一个新的info_object
* @returns {info_object} 生成的对象
* @ignore
*/
var new_object = () => new info_object();
/*
sstp报文格式:
SEND SSTP/1.1
Charset: UTF-8
Sender: SSTPクライアント
Script: \h\s0テストー。\u\s[10]テストやな。
Option: notranslate
由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。
*/
/**
* 基础sstp报文类
* @example
* let info = jsstp.base_sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n");
* console.log(info.head);//SSTP/1.4 200 OK
* console.log(info.Option);//notranslate
* @alias jsstp.base_sstp_info_t
*/
class base_sstp_info_t extends info_object {
#head;
/**
* 未知行的数组
* @type {Array<String>}
*/
#unknown_lines;
/**
* 自拆分好的字符串报文或对象报文构造sstp_info_t,不建议直接使用
* @param {String} info_head 报文头
* @param {Object} info_body 对象格式的报文体
* @param {Array<String>|undefined} unknown_lines 未知行的数组
* @see {@link sstp_info_t.from_string}
* @ignore
*/
constructor(info_head, info_body, unknown_lines = {}) {
super();
this.#head = /*@__INLINE__*/to_string(info_head);
if (unknown_lines[length])
this.#unknown_lines = unknown_lines;
assign(this, info_body);
}
/**
* 获取未知行的数组
* @returns {Array<String>} 未知行的数组
*/
get [unknown_lines]() { return this.#unknown_lines || []; }
/**
* 获取报文头
* @returns {String} 报文头
*/
get head() { return this.#head; }
//注入toString方法便于使用
/**
* 获取字符串报文
* @returns {String} 字符串报文
* @ignore
*/
toString() {
return [
this.#head,
...this[unknown_lines],
...this[entries].map(([key, value]) => `${key}: ${value}`),
void_string,void_string//空行结尾
].join(endline);
}
/**
* 获取字符串报文
* @returns {String} 字符串报文
*/
to_string() { return /*@__INLINE__*/to_string(this); }//兼容命名
/**
* 获取用于`JSON.stringify`的对象
* @returns {Object} 用于`JSON.stringify`的对象
* @ignore
*/
toJSON() {
return {
head: this.#head,
[unknown_lines]: this.#unknown_lines,
body: this[trivial_clone]
};
}
/**
* 获取报头返回码(若出现意外返回`NaN`)
* @returns {Number} 报头返回码(若出现意外则为`NaN`)
*/
get status_code() {
//比如:SSTP/1.4 200 OK,返回200
return +this.#head[split](" ").find(value => is_not_nan(+value));
}
}
/*
sstp报文格式:
SEND SSTP/1.1
Charset: UTF-8
Sender: SSTPクライアント
Script: \h\s0テストー。\u\s[10]テストやな。
Option: notranslate
由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。
*/
/**
* sstp报文类
* @example
* let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n");
* console.log(info.head);//SSTP/1.4 200 OK
* console.log(info.Option);//notranslate
* @alias jsstp.sstp_info_t
*/
class sstp_info_t extends base_sstp_info_t {
/**
* 自拆分好的字符串报文或对象报文构造sstp_info_t,不建议直接使用
* @param {String} info_head 报文头
* @param {Object} info_body 对象格式的报文体
* @param {Array<String>|undefined} unknown_lines 未知行的数组
* @see {@link sstp_info_t.from_string}
* @ignore
*/
constructor(info_head, info_body, unknown_lines = {}) {
super(info_head, info_body, unknown_lines);
return new the_proxy(this, {
get: new_get_handler({
_string_key_handler_: (target, key) => x_sstp_passthru_head + key in target ? target[get_passthrough](key) : undefined$1
})
});
}
/**
* 从字符串构造sstp_info_t
* @param {String} str 字符串报文
* @returns {sstp_info_t} 构造的sstp_info_t
* @example
* let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n");
*/
static from_string(str) {
let [head, ...lines] = str[split](endline);
let body = {};
let unknown_lines = [];
let last_key;
//去掉最后的空行*2
lines[length] -= 2;
for (let line of lines) {
let [key, value] = key_value_split(line, ': ');
if (!/*@__INLINE__*/reg_test(/^\w[^\s]*$/, key)) {
if (last_key)
body[last_key] += endline + line;
else
unknown_lines.push(line);
}
else
body[last_key = key] = value;
}
return new sstp_info_t(head, body, unknown_lines);
}
/**
* 获取PassThru的值
* @param {String} key 获取的PassThru名称
* @returns {String|undefined} PassThru的值
*/
[get_passthrough](key) { return this[x_sstp_passthru_head + key]; }
/**
* 用于缓存所有的PassThru
* @type {info_object}
* @private
*/
#passthroughs;
/**
* 获取所有的PassThru
* @returns {info_object} 所有的PassThru
*/
get passthroughs() {
return this.#passthroughs ??= new_object().push(
this.map((value, key) => key.startsWith(x_sstp_passthru_head) ?
[key.slice(x_sstp_passthru_head[length]), value] : undefined$1
)
);
}
/**
* 获取原始对象
* @returns {sstp_info_t} 原始对象
*/
get raw() { return this; }
}
/**
* fmo报文类
* @example
* let fmo = jsstp.get_fmo_infos();
* let kikka_uuid = fmo.get_uuid_by("name", "橘花");
* if(kikka_uuid)
* console.log(fmo[kikka_uuid].ghostpath);
* @alias jsstp.fmo_info_t
* @see {@link jsstp_t.get_fmo_infos}
* @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html}
*/
class fmo_info_t extends base_sstp_info_t {
/**
* 自字符串构造fmo_info_t,不建议直接使用
* @param {String} fmo_info
* @ignore
*/
constructor(fmo_text) {
let [head, ...lines] = fmo_text[split](endline);
super(head, {});
//fmo_info每个key的格式都是"uuid.属性名"
for (let line of lines) {
if (!line) continue;
let [key_base, value] = key_value_split(line, String.fromCharCode(1));
let [uuid, key] = key_value_split(key_base, ".");
(this[uuid] ||= new_object())[key] = value;//uuid对应的对象应是info_object以方便使用,且下方flat_map调用需要其方法
}
}
/**
* @param {String} name 要检查的属性名
* @param {String} value 期望的属性值
* @returns {String|undefined} 对应的uuid(如果有的话)
* @description 获取具有指定属性且属性值为指定值的fmo的uuid
* @example
* let kikka_uuid = fmo_info.get_uuid_by("name", "橘花");
* @description 等价于`this.uuids.find(uuid => this[uuid][name] == value)`
*/
get_uuid_by(name, value) {
return this.uuids.find(uuid => this[uuid][name] == value);
}
/**
* @param {String} name
* @returns {Array<String>}
* @description 获取所有指定属性的值
* @example
* let ghost_list = fmo_info.get_list_of("name");
* @description 等价于`this.uuids.map(uuid => this[uuid][name])`
*/
get_list_of(name) {
return this.uuids.map(uuid => this[uuid][name]);
}
/**
* @description 获取所有uuid
*/
get uuids() { return this.keys; }
/**
* @description 判断fmo是否有效
*/
get [available]() { return !!this[length]; }
//注入toString方法便于使用
/**
* 获取字符串报文
* @returns {String} 字符串报文
* @ignore
*/
toString() {
return [
this.head,
void_string,
...this.flat_map((uuid, key, value) => uuid + "." + key + String.fromCharCode(1) + value),
void_string,void_string
].join(endline);
}
/**
* 获取用于`JSON.stringify`的对象
* @returns {Object} 用于`JSON.stringify`的对象
* @ignore
*/
toJSON() {
return {
head: this.head,
fmo_infos: this[trivial_clone]
};
}
}
/**
* ghost事件查询器
* @example
* let ghost_events_queryer = jsstp.new_event_queryer();
* if(!ghost_events_queryer.available)
* console.log("当前ghost不支持事件查询");
* if(ghost_events_queryer.has_event("OnBoom"))
* jsstp.OnBoom();
* @alias jsstp.ghost_events_queryer_t
* @see {@link jsstp_t.new_event_queryer}
*/
class ghost_events_queryer_t {
/**
* 基础{@link jsstp_t}对象
* @type {jsstp_t}
*/
#base_jsstp;
/**
* 是否有`Has_Event`方法
* @type {Boolean}
*/
#ghost_has_has_event;
/**
* 是否有`Get_Supported_Events`方法
* @type {Boolean}
*/
#ghost_has_get_supported_events;
/**
* 自`Get_Supported_Events`获取的事件列表
* @type {{local:Array<String>,external:Array<String>}}
* @example
* {
* local:["On_connect","On_disconnect"],
* external:["On_connect"]
* }
*/
#ghost_event_list;
/**
* 自`Has_Event`获取的事件列表缓存
* @type {{local:{String:Boolean},external:{String:Boolean}}}
* @example
* {
* local:{On_connect:true,On_disconnect:true},
* external:{On_connect:true}
* }
* @description 仅当`#ghost_has_get_supported_events`为false时有效
*/
#ghost_event_list_cache;
/**
* 构造一个事件查询器
* @param {jsstp_t} base_jsstp
*/
constructor(base_jsstp) {
this.#base_jsstp = base_jsstp;
/**
* 查询默认的安全等级,在nodejs中为"local",在浏览器中为"external"
* @type {String}
* @see {@link https://www.google.com/search?q=site%3Assp.shillest.net%2Fukadoc%2F+SecurityLevel}
*/
this[default_security_level] = base_jsstp[default_security_level];
}
/**
* 检查事件是否存在,ghost至少需要`Has_Event`事件的支持,并可以通过提供`Get_Supported_Events`事件来提高效率
* @param {String} event_name
* @param {String} security_level
* @returns {Promise<Boolean>}
* @example
* let result = await ghost_events_queryer.check_event("On_connect");
* @see 基于 {@link jsstp_t.has_event} 和 {@link jsstp_t.get_supported_events}
*/
async check_event(event_name, security_level = this[default_security_level]) {
if (this.#ghost_has_get_supported_events)
return this.#ghost_event_list[security_level].includes(event_name);
else if (this.#ghost_has_has_event)
return this.#ghost_event_list_cache[security_level][event_name] ??= await this.#base_jsstp[has_event](event_name);
else
return _false_;
}
/**
* 检查是否能够检查事件
* @returns {Promise<Boolean>}
* @example
* if(!ghost_events_queryer.available)
* console.error("无法检查事件");
*/
get [available]() { return this.#ghost_has_has_event; }
/**
* 检查是否能够使用`Get_Supported_Events`快速获取支持的事件列表
* @returns {Promise<Boolean>}
* @example
* if(!ghost_events_queryer.fast_query_available)
* console.info("无法快速获取支持的事件列表");
* else
* console.info("好哦");
* @description 如果不支持也只是会变慢,`check_event`仍然可以使用
*/
get fast_query_available() { return this.#ghost_has_get_supported_events; }
/**
* @returns {Promise<ghost_events_queryer_t>} this
*/
reset() {
this.clear();
return this.init();
}
/**
* @returns {Promise<ghost_events_queryer_t>} this
*/
async init() {
let jsstp = this.#base_jsstp;
this.#ghost_has_has_event = await jsstp[has_event](Has_Event);
this.#ghost_has_get_supported_events = this.#ghost_has_has_event && await jsstp[has_event](Get_Supported_Events);
if (this.#ghost_has_get_supported_events)
this.#ghost_event_list = await jsstp[get_supported_events]();
return this;
}
clear() {
this.#ghost_has_has_event = this.#ghost_has_get_supported_events = _false_;
this.#ghost_event_list_cache = { [local]: {}, [external]: {} };
}
}
//构建一个包装器与http://localhost:9801/api/sstp/v1通信。
//发信方法:Content-Type: text/plain HTTP/1.1でPOST
//收信方法:HTTP/1.1 200 OKのContent-Type: text/plain
/**
* 根据方法名称获取SSTP协议头
* @param {String} type 方法名称
* @param {Object} version_table SSTP协议版本号列表
* @returns {String} SSTP协议头
* @ignore
*/
var get_sstp_header = (type,version_table) => `${type} SSTP/${version_table[type]}`;
//定义一个包装器
/**
* jsstp对象
* @see {@link jsstp}
* @alias jsstp.type
* @example
* let my_jsstp=new jsstp.type("my_coooool_jsstp",sstp_server_url);
*/
class jsstp_t /*extends Function*/ {
/**
* 对象与服务器交互时的发送者名称
* @type {String}
*/
#host;
/**
* 基础jsstp对象
* @param {String} sender_name 对象与服务器交互时的发送者名称
* @param {String} host 目标服务器地址
*/
constructor(sender_name, host) {
//super();
this.RequestHeader = {
//"Content-Type": "text/plain",//省略Content-Type并不会导致sstp无法正常工作,还能压缩dist体积。
"Origin": my_origin
};
this[default_info] = { Charset: "UTF-8" };//指定字符集,否则ssp会以本地字符集解码
this.host = host;
this[sendername] = sender_name;
/**
* SSTP协议版本号列表
*/
this[sstp_version_table] = {
[SEND]: 1.4,
NOTIFY: 1.1,
COMMUNICATE: 1.1,
EXECUTE: 1.2,
GIVE: 1.1
};
/**
* 查询默认的安全等级,在nodejs中为"local",在浏览器中为"external"
* @type {String}
* @see {@link https://www.google.com/search?q=site%3Assp.shillest.net%2Fukadoc%2F+SecurityLevel}
*/
this[default_security_level] = my_default_security_level;
return this[proxy] = new the_proxy(this, {
get: new_get_handler({
_string_key_handler_: (target, key) =>
(key in target[sstp_version_table]) ?
target[get_caller_of_method](key) :
(is_event_name(key)) ?
target[get_simple_caller_of_event](get_reorganized_event_name(key)) :
undefined$1
}),
/*
//for useage like `new jsstp()`?
apply: (target, thisArg, args) => {
if(new.target) return new target.constructor(...args);
}
*/
});
}
/**
* 修改host
* @param {string} host
*/
set host(host) { this.#host = host || get_local_address()+"/api/sstp/v1"; }
get host() { return this.#host; }
/**
* 修改sendername
* @param {String} sender_name
*/
set [sendername](sender_name) { this[default_info].Sender = sender_name || "jsstp-client"; }
get [sendername]() { return this[default_info].Sender; }
/**
* 以文本发送报文并以文本接收返信
* @param {String} info 报文体
* @returns {Promise<String|undefined>} 返回一个promise
* 若一切正常其内容为发送后得到的返回值,否则为`undefined`
*/
row_send(info) {
//使用fetch发送数据
return new Promise(
(resolve, reject) =>
fetch(this.#host, {
method: "POST",
headers: this.RequestHeader,
body: /*@__INLINE__*/to_string(info)
})[then](response =>
response.status != 200 ?
reject(response.status) :
response.text()[then](resolve),
/*catch*/reject
)
);
}
/**
* 发送报文,但是不对返回结果进行处理
* @param {String} sstphead 报文头
* @param {Object} info 报文体
* @returns {Promise<String|undefined>} 返回一个promise
* 若一切正常其内容为发送后得到的返回值,否则为`undefined`
*/
[costom_text_send](sstphead, info) {
return this.row_send(new sstp_info_t(sstphead, { ...this[default_info], ...info }));
}
/**
* 发送报文
* @param {String} sstphead 报文头
* @param {Object} info 报文体
* @returns {Promise<sstp_info_t>} 返回一个promise
*/
costom_send(sstphead, info) {
return this[costom_text_send](sstphead, info)[then](
result => sstp_info_t.from_string(result)
);
}
/**
* 获取指定方法的调用器
* @param {String} method_name 方法名称
* @returns {{
* (info: Object): Promise<sstp_info_t>,
* get_raw(info: Object): Promise<String>
* }} 调用器
*/
[get_caller_of_method](method_name) {
let header = get_sstp_header(method_name,this[sstp_version_table]);
return assign((info) => this.costom_send(header, info), {
get_raw: (info) => this[costom_text_send](header, info)
});
}
/**
* 对指定事件名的调用器进行适当的包装
* 作用1:使得调用器可以像promise一样使用then方法
* 作用2:使得调用器可以通过属性追加事件名来获取新的调用器
* @param {String} event_name 事件名称
* @param {String|undefined} method_name 方法名称
* @param {Function} value 调用器的值
* @param {{[String]:(event_name: String, method_name: String)}} caller_factory 调用器工厂
* @returns {Proxy<Function>} 调用器
*/
#warp_the_caller_of_event(event_name,method_name,value,caller_factory) {
return new the_proxy(value, {
get: (target, prop) =>
prop in target ?
target[prop] :
prop == then ?
(resolve, reject) => target()[then](resolve, reject) :
//else
this[caller_factory](event_name+"."+prop, method_name)
});
}
/**
* 获取指定事件的调用器
* @param {String} event_name 事件名称
* @param {String|undefined} method_name 方法名称
* @returns {{
* (info: Object) => Promise<sstp_info_t>
* then(
* resolve: (Function) => any,
* reject: (Boolean|any) => any
* ): Promise<any>
* }} 调用器
*/
[get_caller_of_event](event_name, method_name = SEND) {
return this.#warp_the_caller_of_event(
event_name,
method_name,
(info) => this[proxy][method_name](assign({ Event: event_name }, info)),
get_caller_of_event
);
}
/**
* 用于获取指定事件的简单调用器
* @param {String} event_name 事件名称
* @param {String|undefined} method_name 方法名称
* @returns {(...args: any[]) => Promise<sstp_info_t>} 调用器
*/
[get_simple_caller_of_event](event_name, method_name = SEND) {
return this.#warp_the_caller_of_event(
event_name,
method_name,
(...args) => {
let reference_num = 0;
let info = {};
args[forEach]((arg) =>
info[`Reference${reference_num++}`] = arg
);
return this[get_caller_of_event](event_name, method_name)(info);
},
get_simple_caller_of_event
);
}
/**
* 用于获取指定事件的简单调用器的代理
* @returns {Proxy}
* @example
* jsstp.event.OnTest("test");
*/
get event() {
return new the_proxy({}, {
get: (_target, prop) => this[get_simple_caller_of_event](prop)
});
}
/**
* 判断是否存在某个事件
* 若可能频繁调用,使用{@link ghost_events_queryer_t}(通过{@link jsstp_t.new_event_queryer}获取)来查询
* @param {String} event_name 事件名
* @param {String} security_level 安全等级
* @returns {Promise<Boolean>} 是否存在
* @example
* jsstp.has_event("OnTest").then(result => console.log(result));
* @example
* //示例代码(AYA):
* SHIORI_EV.On_Has_Event : void {
* _event_name=reference.raw[0]
* _SecurityLevel=reference.raw[1]
* if !_SecurityLevel
* _SecurityLevel=SHIORI_FW.SecurityLevel
* if SUBSTR(_event_name,0,2) != 'On'
* _event_name='On_'+_event_name
* _result=0
* if TOLOWER(_SecurityLevel) == 'external'
* _event_name='ExternalEvent.'+_event_name
* _result=ISFUNC(_event_name)
* if !_result
* _result=ISFUNC('SHIORI_EV.'+_event_name)
* SHIORI_FW.Make_X_SSTP_PassThru('Result',_result)
* }
* SHIORI_EV.ExternalEvent.On_Has_Event{
* SHIORI_EV.On_Has_Event
* }
*/
[has_event](event_name, security_level = this[default_security_level]) {
return this.event[Has_Event](event_name, security_level)[then](({ Result }) => Result == 1);
}
/**
* 以约定好的结构获取支持的事件,需要ghost支持`Get_Supported_Events`事件
* 若不确定ghost的支持情况,使用{@link ghost_events_queryer_t}(通过{@link jsstp_t.new_event_queryer}获取)来查询
* @returns {Promise<{local:string[],external:string[]}>} 包含local和external两个数组的Object
* @example
* jsstp.get_supported_events().then(result => console.log(result));
* @example
* //示例代码(AYA):
* SHIORI_EV.On_Get_Supported_Events: void {
* _L=GETFUNCLIST('On')
* _base_local_event_funcs=IARRAY
* foreach _L;_func{
* if SUBSTR(_func,2,1) == '_'
* _func=SUBSTR(_func,3,STRLEN(_func))
* _base_local_event_funcs,=_func
* }
* _L=GETFUNCLIST('SHIORI_EV.On')
* foreach _L;_func{
* if SUBSTR(_func,12,1) == '_'
* _func=SUBSTR(_func,13,STRLEN(_func))
* _base_local_event_funcs,=_func
* }
* SHIORI_FW.Make_X_SSTP_PassThru('local',ARRAYDEDUP(_base_local_event_funcs))
* _L=GETFUNCLIST('ExternalEvent.On')
* _base_external_event_funcs=IARRAY
* foreach _L;_func{
* if SUBSTR(_func,16,1) == '_'
* _func=SUBSTR(_func,17,STRLEN(_func))
* _base_external_event_funcs,=_func
* }
* _L=GETFUNCLIST('SHIORI_EV.ExternalEvent.On')
* foreach _L;_func{
* if SUBSTR(_func,26,1) == '_'
* _func=SUBSTR(_func,27,STRLEN(_func))
* _base_external_event_funcs,=_func
* }
* SHIORI_FW.Make_X_SSTP_PassThru('external',ARRAYDEDUP(_base_external_event_funcs))
* }
* SHIORI_EV.ExternalEvent.On_Get_Supported_Events{
* SHIORI_EV.On_Get_Supported_Events
* }
*/
[get_supported_events]() {
return this.event[Get_Supported_Events]()[then](({ [local]:local_evt, [external]:external_evt }) => (
{
[local]: (local_evt || void_string)[split](","),
[external]: (external_evt || void_string)[split](",")
}
));
}
/**
* 获取fmo信息
* @returns {Promise<fmo_info_t>} fmo信息
* @example
* let fmo=await jsstp.get_fmo_infos();
* if(fmo.available)
* console.log(fmo);
*/
[get_fmo_infos]() {
return this[proxy].EXECUTE.get_raw({
Command: "GetFMO"
})[then](
fmo_text => new fmo_info_t(fmo_text)
);
}
/**
* 获取当前ghost是否可用
* @returns {Promise<Boolean>} ghost是否可用
* @example
* if(await jsstp.available())
* //do something
* else
* console.error("ghost不可用,请检查ghost是否启动");
*/
[available]() {
return this[get_fmo_infos]()[then](fmo => fmo[available],/*catch*/() => _false_);
}
/**
* 获取当前ghost是否可用
* @returns {Promise} ghost是否可用
* @example
* jsstp.then(() => {
* //do something
* });
* //or
* await jsstp;
*/
[then](resolve, reject) {
return this[available]()[then](result =>
result ? resolve(this) : reject(),
/*catch*/reject
);
}
/**
* 获取一个用于查询ghost所支持事件的queryer
* @returns {Promise<ghost_events_queryer_t>} 查询支持事件的queryer
* @example
* jsstp.new_event_queryer().then(queryer =>
* queryer.check_event("OnTest").then(result =>
* console.log(result)
* )
* );
*/
new_event_queryer() { return (new ghost_events_queryer_t(this)).init(); }//省略await是合法的
}
//对定义中的所有类型补充到原型
//纯为了压缩体积(不然每个类型都要写一遍`static`)
assign(jsstp_t.prototype, {
type: jsstp_t,
base_sstp_info_t: base_sstp_info_t,
sstp_info_t: sstp_info_t,
fmo_info_t: fmo_info_t,
ghost_events_queryer_t: ghost_events_queryer_t
});
//构建一个包装器与http://localhost:9801/api/sstp/v1通信。
//发信方法:Content-Type: text/plain HTTP/1.1でPOST
//收信方法:HTTP/1.1 200 OKのContent-Type: text/plain
//定义一个包装器
/**
* sstp包装器
* @example
* jsstp.SEND({
* Event: "OnTest",
* Script: "\\s[0]Hell Wold!\\e"
* });
* @var jsstp
* @type {jsstp_t}
* @global
*/
var jsstp = new jsstp_t();
return jsstp;
})();
terser
output or error
var jsstp=function(){var t,e=t=>t.toLowerCase(),s=(t,e)=>{let s=t.indexOf(e);return[t[S](0,s),t[S](s+e[b])]},r=e=>(s,r)=>{if(e.t&&e.t(s,r))return;let i;return i=o(r)instanceof String?e.i&&e.i(s,r):e.h&&e.h(s,r),i!==t?i:e.u?e.u(s,r):(i=s[r])instanceof Function?i.bind(s):i},i=!!globalThis.window,n=t=>"http://localhost:"+(t??9801),h=i?location.origin:n(process.env.PORT),u=/^\w+:\/\/localhost/.test(h)?M:U,o=Object,a=Proxy,_=o.assign,l="\r\n",c="Get_Supported_Events",g="Has_Event",f=e(c),p=e(g),v="get_simple_caller_of_event",d="trivial_clone",w="default_info",m="default_security_level",y="sstp_version_table",S="substring",b="length",E="available",O="split",T="entries",x="costom_text_send",k="forEach",P="get_caller_of_method",C="unknown_lines",N="get_caller_of_event",$="sendername",j="proxy",F="then",q="SEND",G="get_fmo_infos",I="get_passthrough",M="local",U="external",J="",R=!1,X="X-SSTP-PassThru-";class A{get keys(){return o.keys(this)}get values(){return o.values(this)}get[T](){return o[T](this)}get[b](){return this.keys[b]}[k](t){return this[T][k]((([e,s])=>{this[e]=t(s,e)??s}))}get[d](){return _(D(),this)}flat_map(t){let e=[];return this[T].map((([s,r])=>e.push(...r instanceof A?r.flat_map(t.bind(t,s)):[t(s,r)]))),e}map(t){return this[T].map((([e,s])=>t(s,e)))}push(e){return e[k]((e=>e?this[e[0]]=e[1]:t)),this}}var D=()=>new A;class H extends A{#t;#e;constructor(t,e,s={}){super(),this.#t=J+t,s[b]&&(this.#e=s),_(this,e)}get[C](){return this.#e||[]}get head(){return this.#t}toString(){return[this.#t,...this[C],...this[T].map((([t,e])=>`${t}: ${e}`)),J,J].join(l)}to_string(){return J+this}toJSON(){return{head:this.#t,[C]:this.#e,body:this[d]}}get status_code(){return+this.#t[O](" ").find((t=>{return(e=+t)==e;var e}))}}class V extends H{constructor(e,s,i={}){return super(e,s,i),new a(this,{get:r({i:(e,s)=>X+s in e?e[I](s):t})})}static from_string(t){let e,[r,...i]=t[O](l),n={},h=[];i[b]-=2;for(let t of i){let[r,i]=s(t,": ");((t,e)=>/^\w[^\s]*$/.test(e))(0,r)?n[e=r]=i:e?n[e]+=l+t:h.push(t)}return new V(r,n,h)}[I](t){return this[X+t]}#s;get passthroughs(){return this.#s??=D().push(this.map(((e,s)=>s.startsWith(X)?[s.slice(X[b]),e]:t)))}get raw(){return this}}class Y extends H{constructor(t){let[e,...r]=t[O](l);super(e,{});for(let t of r){if(!t)continue;let[e,r]=s(t,""),[i,n]=s(e,".");(this[i]||=D())[n]=r}}get_uuid_by(t,e){return this.uuids.find((s=>this[s][t]==e))}get_list_of(t){return this.uuids.map((e=>this[e][t]))}get uuids(){return this.keys}get[E](){return!!this[b]}toString(){return[this.head,J,...this.flat_map(((t,e,s)=>t+"."+e+""+s)),J,J].join(l)}toJSON(){return{head:this.head,fmo_infos:this[d]}}}class z{#r;#i;#n;#h;#u;constructor(t){this.#r=t,this[m]=t[m]}async check_event(t,e=this[m]){return this.#n?this.#h[e].includes(t):this.#i?this.#u[e][t]??=await this.#r[p](t):R}get[E](){return this.#i}get fast_query_available(){return this.#n}reset(){return this.clear(),this.init()}async init(){let t=this.#r;return this.#i=await t[p](g),this.#n=this.#i&&await t[p](c),this.#n&&(this.#h=await t[f]()),this}clear(){this.#i=this.#n=R,this.#u={[M]:{},[U]:{}}}}class B{#o;constructor(e,s){return this.RequestHeader={Origin:h},this[w]={Charset:"UTF-8"},this.host=s,this[$]=e,this[y]={[q]:1.4,NOTIFY:1.1,COMMUNICATE:1.1,EXECUTE:1.2,GIVE:1.1},this[m]=u,this[j]=new a(this,{get:r({i:(e,s)=>s in e[y]?e[P](s):(t=>((t,e)=>/^On/.test(e))(0,t))(s)?e[v]((t=>"_"==t[2]?t[S](3):t)(s)):t})})}set host(t){this.#o=t||n()+"/api/sstp/v1"}get host(){return this.#o}set[$](t){this[w].Sender=t||"jsstp-client"}get[$](){return this[w].Sender}row_send(t){return new Promise(((e,s)=>{return fetch(this.#o,{method:"POST",headers:this.RequestHeader,body:(r=t,J+r)})[F]((t=>200!=t.status?s(t.status):t.text()[F](e)),s);var r}))}[x](t,e){return this.row_send(new V(t,{...this[w],...e}))}costom_send(t,e){return this[x](t,e)[F]((t=>V.from_string(t)))}[P](t){let e=(s=t,r=this[y],`${s} SSTP/${r[s]}`);var s,r;return _((t=>this.costom_send(e,t)),{get_raw:t=>this[x](e,t)})}#a(t,e,s,r){return new a(s,{get:(s,i)=>i in s?s[i]:i==F?(t,e)=>s()[F](t,e):this[r](t+"."+i,e)})}[N](t,e=q){return this.#a(t,e,(s=>this[j][e](_({Event:t},s))),N)}[v](t,e=q){return this.#a(t,e,((...s)=>{let r=0,i={};return s[k]((t=>i["Reference"+r++]=t)),this[N](t,e)(i)}),v)}get event(){return new a({},{get:(t,e)=>this[v](e)})}[p](t,e=this[m]){return this.event[g](t,e)[F]((({Result:t})=>1==t))}[f](){return this.event[c]()[F]((({[M]:t,[U]:e})=>({[M]:(t||J)[O](","),[U]:(e||J)[O](",")})))}[G](){return this[j].EXECUTE.get_raw({Command:"GetFMO"})[F]((t=>new Y(t)))}[E](){return this[G]()[F]((t=>t[E]),(()=>R))}[F](t,e){return this[E]()[F]((s=>s?t(this):e()),e)}new_event_queryer(){return new z(this).init()}}return _(B.prototype,{type:B,base_sstp_info_t:H,sstp_info_t:V,fmo_info_t:Y,ghost_events_queryer_t:z}),new B}();
Expected result
diff --git a/dist/jsstp.min.js b/dist/jsstp.min.js
index f3739a5..8a20505 100644
--- a/dist/jsstp.min.js
+++ b/dist/jsstp.min.js
@@ -1,13 +1,12 @@
var jsstp = function() {
var t, e = t => t.toLowerCase(),
s = (t, e) => {
- let s = t.indexOf(e);
+ var s = t.indexOf(e);
return [t[S](0, s), t[S](s + e[b])]
},
r = e => (s, r) => {
- if (e.t && e.t(s, r)) return;
- let i;
- return i = o(r) instanceof String ? e.i && e.i(s, r) : e.h && e.h(s, r), i !== t ? i : e.u ? e.u(s, r) : (i = s[r]) instanceof Function ? i.bind(s) : i
+ var i;
+ if (!e.t || !e.t(s, r)) return (i = o(r) instanceof String ? e.i && e.i(s, r) : e.h && e.h(s, r)) !== t ? i : e.u ? e.u(s, r) : (i = s[r]) instanceof Function ? i.bind(s) : i
},
i = !!globalThis.window,
n = t => "http://localhost:" + (t ?? 9801),
@@ -60,22 +59,22 @@ var jsstp = function() {
get[b]() {
return this.keys[b]
} [k](t) {
- return this[T][k]((([e, s]) => {
+ return this[T][k](([e, s]) => {
this[e] = t(s, e) ?? s
- }))
+ })
}
get[d]() {
return _(D(), this)
}
flat_map(t) {
let e = [];
- return this[T].map((([s, r]) => e.push(...r instanceof A ? r.flat_map(t.bind(t, s)) : [t(s, r)]))), e
+ return this[T].map(([s, r]) => e.push(...r instanceof A ? r.flat_map(t.bind(t, s)) : [t(s, r)])), e
}
map(t) {
- return this[T].map((([e, s]) => t(s, e)))
+ return this[T].map(([e, s]) => t(s, e))
}
push(e) {
- return e[k]((e => e ? this[e[0]] = e[1] : t)), this
+ return e[k](e => e ? this[e[0]] = e[1] : t), this
}
}
var D = () => new A;
@@ -92,7 +91,7 @@ var jsstp = function() {
return this.#t
}
toString() {
- return [this.#t, ...this[C], ...this[T].map((([t, e]) => `${t}: ${e}`)), J, J].join(l)
+ return [this.#t, ...this[C], ...this[T].map(([t, e]) => t + ": " + e), J, J].join(l)
}
to_string() {
return J + this
@@ -105,10 +104,9 @@ var jsstp = function() {
}
}
get status_code() {
- return +this.#t[O](" ").find((t => {
- return (e = +t) == e;
- var e
- }))
+ return +this.#t[O](" ").find(t => (t = +t) == t)
}
}
class V extends H {
@@ -126,7 +124,7 @@ var jsstp = function() {
i[b] -= 2;
for (let t of i) {
let [r, i] = s(t, ": ");
- ((t, e) => /^\w[^\s]*$/.test(e))(0, r) ? n[e = r] = i: e ? n[e] += l + t : h.push(t)
+ /^\w[^\s]*$/.test(r) ? n[e = r] = i : e ? n[e] += l + t : h.push(t)
}
return new V(r, n, h)
} [I](t) {
@@ -134,7 +132,7 @@ var jsstp = function() {
}
#s;
get passthroughs() {
- return this.#s ??= D().push(this.map(((e, s) => s.startsWith(X) ? [s.slice(X[b]), e] : t)))
+ return this.#s ??= D().push(this.map((e, s) => s.startsWith(X) ? [s.slice(16), e] : t))
}
get raw() {
return this
@@ -142,19 +140,19 @@ var jsstp = function() {
}
class Y extends H {
constructor(t) {
- let [e, ...r] = t[O](l);
- super(e, {});
- for (let t of r) {
- if (!t) continue;
- let [e, r] = s(t, ""), [i, n] = s(e, ".");
- (this[i] ||= D())[n] = r
- }
+ var [t, ...r] = t[O](l);
+ super(t, {});
+ for (let t of r)
+ if (t) {
+ let [e, r] = s(t, ""), [i, n] = s(e, ".");
+ (this[i] ||= D())[n] = r
+ }
}
get_uuid_by(t, e) {
- return this.uuids.find((s => this[s][t] == e))
+ return this.uuids.find(s => this[s][t] == e)
}
get_list_of(t) {
- return this.uuids.map((e => this[e][t]))
+ return this.uuids.map(e => this[e][t])
}
get uuids() {
return this.keys
@@ -163,7 +161,7 @@ var jsstp = function() {
return !!this[b]
}
toString() {
- return [this.head, J, ...this.flat_map(((t, e, s) => t + "." + e + "" + s)), J, J].join(l)
+ return [this.head, J, ...this.flat_map((t, e, s) => t + "." + e + "" + s), J, J].join(l)
}
toJSON() {
return {
@@ -182,7 +180,7 @@ var jsstp = function() {
this.#r = t, this[m] = t[m]
}
async check_event(t, e = this[m]) {
- return this.#n ? this.#h[e].includes(t) : this.#i ? this.#u[e][t] ??= await this.#r[p](t) : R
+ return this.#n ? this.#h[e].includes(t) : !!this.#i && (this.#u[e][t] ??= await this.#r[p](t))
}
get[E]() {
return this.#i
@@ -194,7 +192,7 @@ var jsstp = function() {
return this.clear(), this.init()
}
async init() {
- let t = this.#r;
+ var t = this.#r;
return this.#i = await t[p](g), this.#n = this.#i && await t[p](c), this.#n && (this.#h = await t[f]()), this
}
clear() {
@@ -219,7 +217,7 @@ var jsstp = function() {
GIVE: 1.1
}, this[m] = u, this[j] = new a(this, {
get: r({
- i: (e, s) => s in e[y] ? e[P](s) : (t => ((t, e) => /^On/.test(e))(0, t))(s) ? e[v]((t => "_" == t[2] ? t[S](3) : t)(s)) : t
+ i: (e, s) => s in e[y] ? e[P](s) : /^On/.test(s) ? e[v]((t => "_" == t[2] ? t[S](3) : t)(s)) : t
})
})
}
@@ -236,14 +234,13 @@ var jsstp = function() {
return this[w].Sender
}
row_send(t) {
- return new Promise(((e, s) => {
+ return new Promise((e, s) => {
return fetch(this.#o, {
method: "POST",
headers: this.RequestHeader,
- body: (r = t, J + r)
- })[F]((t => 200 != t.status ? s(t.status) : t.text()[F](e)), s);
- var r
- }))
+ body: J + t
+ })[F](t => 200 != t.status ? s(t.status) : t.text()[F](e), s)
+ })
} [x](t, e) {
return this.row_send(new V(t, {
...this[w],
@@ -251,11 +248,10 @@ var jsstp = function() {
}))
}
costom_send(t, e) {
- return this[x](t, e)[F]((t => V.from_string(t)))
+ return this[x](t, e)[F](t => V.from_string(t))
} [P](t) {
- let e = (s = t, r = this[y], `${s} SSTP/${r[s]}`);
- var s, r;
- return _((t => this.costom_send(e, t)), {
+ let e = t + " SSTP/" + this[y][t];
+ return _(t => this.costom_send(e, t), {
get_raw: t => this[x](e, t)
})
}
@@ -264,40 +260,40 @@ var jsstp = function() {
get: (s, i) => i in s ? s[i] : i == F ? (t, e) => s()[F](t, e) : this[r](t + "." + i, e)
})
} [N](t, e = q) {
- return this.#a(t, e, (s => this[j][e](_({
+ return this.#a(t, e, s => this[j][e](_({
Event: t
- }, s))), N)
+ }, s)), N)
} [v](t, e = q) {
- return this.#a(t, e, ((...s) => {
+ return this.#a(t, e, (...s) => {
let r = 0,
i = {};
- return s[k]((t => i["Reference" + r++] = t)), this[N](t, e)(i)
- }), v)
+ return s[k](t => i["Reference" + r++] = t), this[N](t, e)(i)
+ }, v)
}
get event() {
return new a({}, {
get: (t, e) => this[v](e)
})
} [p](t, e = this[m]) {
- return this.event[g](t, e)[F]((({
+ return this.event[g](t, e)[F](({
Result: t
- }) => 1 == t))
+ }) => 1 == t)
} [f]() {
- return this.event[c]()[F]((({
+ return this.event[c]()[F](({
[M]: t,
[U]: e
}) => ({
[M]: (t || J)[O](","),
[U]: (e || J)[O](",")
- })))
+ }))
} [G]() {
return this[j].EXECUTE.get_raw({
Command: "GetFMO"
- })[F]((t => new Y(t)))
+ })[F](t => new Y(t))
} [E]() {
- return this[G]()[F]((t => t[E]), (() => R))
+ return this[G]()[F](t => t[E], () => R)
} [F](t, e) {
- return this[E]()[F]((s => s ? t(this) : e()), e)
+ return this[E]()[F](s => s ? t(this) : e(), e)
}
new_event_queryer() {
return new z(this).init()
This diff is a further optimized version after I used UglifyJS to process terser's output, and it looks like terser still has some areas that could be improved!
You should give a short example instead of a long one.
You should give a short example instead of a long one.
That's why I've provided a diff to make the optimisable areas more visible
You should use a sample code as short as possible to describe the problem clearly.
You should use a sample code as short as possible to describe the problem clearly.
That's why I've provided a diff to make the optimisable areas more visible and I think diff is clear enough to make the point.
You should use a sample code as short as possible to describe the problem clearly.
That's why I've provided a diff to make the optimisable areas more visible and I think diff is clear enough to make the point.
You are wasting other people's time.
Personally I think the diff file speaks for itself and I think you are wasting more of your time and bombarding my inbox by commenting repeatedly. If you hate the fact that such a huge file makes you have to drag a lot of progress bars, consider installing refined github instead of complaining here.