support clash type (proxy&rule provider)

This commit is contained in:
Shawn
2020-08-23 21:08:11 +08:00
parent 79dde69759
commit 064454dcef

View File

@@ -1,17 +1,17 @@
/** /**
☑️ 资源解析器 ©𝐒𝐡𝐚𝐰𝐧 ⟦2020-08-20 13:29⟧ ☑️ 资源解析器 ©𝐒𝐡𝐚𝐰𝐧 ⟦2020-08-23 22:29⟧
---------------------------------------------------------- ----------------------------------------------------------
🛠 发现 𝐁𝐔𝐆 请反馈: @Shawn_KOP_bot 🛠 发现 𝐁𝐔𝐆 请反馈: @Shawn_KOP_bot
⛳️ 关注 🆃🅶 相关频道: https://t.me/QuanX_API ⛳️ 关注 🆃🅶 相关频道: https://t.me/QuanX_API
🗣 🆃🄷🄰🄽🄺🅂 🆃🄾 @Jamie CHIEN, @M**F**, @c0lada, @Peng-YM 🗣 🆃🄷🄰🄽🄺🅂 🆃🄾 @Jamie CHIEN, @M**F**, @c0lada, @Peng-YM
🤖 主要功能: 🤖 主要功能:
❶ 将格式的服务器订阅解析成 𝐐𝐮𝐚𝐧𝐭𝐮𝐦𝐮𝐥𝐭 𝐗 格式 ❶ 将其它格式的服务器订阅解析成 𝐐𝐮𝐚𝐧𝐭𝐮𝐦𝐮𝐥𝐭 𝐗 格式
☑︎ 支持 𝗩𝗺𝗲𝘀𝘀/𝗦𝗦(𝗥/𝗗)/𝗧𝗿𝗼𝗷𝗮𝗻/𝗤𝘂𝗮𝗻𝘁𝘂𝗺𝘂𝗹𝘁(𝗫)/𝗦𝘂𝗿𝗴𝗲/𝗛𝗧𝗧𝗣(𝗦) ☑︎ 支持 𝗩𝗺𝗲𝘀𝘀/𝗦𝗦(𝗥/𝗗)/𝗧𝗿𝗼𝗷𝗮𝗻/𝗤𝘂𝗮𝗻𝘁𝘂𝗺𝘂𝗹𝘁(𝗫)/𝗦𝘂𝗿𝗴𝗲/𝐂𝐥𝐚𝐬𝐡/𝗛𝗧𝗧𝗣(𝗦) 格式
☑︎ 提供说明 1⃣ 中的可选个性化参数(筛选、重命名 等) ☑︎ 提供说明 1⃣ 中的可选个性化参数(筛选、重命名 等)
𝗿𝗲𝘄𝗿𝗶𝘁𝗲(重写) & 𝗳𝗶𝗹𝘁𝗲𝗿(分流) 的 转换&筛选 𝗿𝗲𝘄𝗿𝗶𝘁𝗲(重写) & 𝗳𝗶𝗹𝘁𝗲𝗿(分流) 的 转换&筛选
☑︎ 用于禁用远程引用中某(几)项 𝗿𝗲𝘄𝗿𝗶𝘁𝗲/𝗵𝗼𝘀𝘁𝗻𝗮𝗺𝗲/𝗳𝗶𝗹𝘁𝗲𝗿 ☑︎ 用于禁用远程引用中某(几)项 𝗿𝗲𝘄𝗿𝗶𝘁𝗲/𝗵𝗼𝘀𝘁𝗻𝗮𝗺𝗲/𝗳𝗶𝗹𝘁𝗲𝗿
☑︎ 𝐒𝐮𝐫𝐠𝐞 类型规则 𝗹𝗶𝘀𝘁 与 模块 𝐦𝐨𝐝𝐮𝐥𝐞 的解析使用 ☑︎ 𝐒𝐮𝐫𝐠𝐞/𝐂𝐥𝐚𝐬𝐡 类型规则 𝗹𝗶𝘀𝘁 与 模块 𝐦𝐨𝐝𝐮𝐥𝐞 的解析使用
---------------------------------------------------------- ----------------------------------------------------------
0⃣ ⟦原始链接⟧ 后加 "#" 使用, 不同参数用 "&" 连接: 0⃣ ⟦原始链接⟧ 后加 "#" 使用, 不同参数用 "&" 连接:
⚠️ ☞ 𝐡𝐭𝐭𝐩𝐬://𝐦𝐲𝐬𝐮𝐛.𝐜𝐨𝐦#𝙚𝙢𝙤𝙟𝙞=1&𝙩𝙛𝙤=1&𝙞𝙣=香港+台湾 ⚠️ ☞ 𝐡𝐭𝐭𝐩𝐬://𝐦𝐲𝐬𝐮𝐛.𝐜𝐨𝐦#𝙚𝙢𝙤𝙟𝙞=1&𝙩𝙛𝙤=1&𝙞𝙣=香港+台湾
@@ -138,6 +138,7 @@ var pfi = Pin0 ? "in=" + Pin0.join(", ") + ", " : ""
var pfo = Pout0 ? "out=" + Pout0.join(", ") : "" var pfo = Pout0 ? "out=" + Pout0.join(", ") : ""
var pfihn = Phin0 ? "inhn=" + Phin0.join(", ") + ", " : "" var pfihn = Phin0 ? "inhn=" + Phin0.join(", ") + ", " : ""
var pfohn = Phout0 ? "outhn=" + Phout0.join(", ") : "" var pfohn = Phout0 ? "outhn=" + Phout0.join(", ") : ""
var Pcnt = para1.indexOf("cnt=") != -1 ? para1.split("cnt=")[1].split("&")[0] : 0;
var flow = ""; var flow = "";
var exptime = ""; var exptime = "";
//$notify(type0) //$notify(type0)
@@ -170,7 +171,7 @@ if (type0 == "Subs-B64Encode") {
total = SubsEd2QX(content0, Pudp0, Ptfo0, Pcert0, PTls13); total = SubsEd2QX(content0, Pudp0, Ptfo0, Pcert0, PTls13);
} else if (type0 == "Subs") { } else if (type0 == "Subs") {
total = Subs2QX(content0, Pudp0, Ptfo0, Pcert0, PTls13); total = Subs2QX(content0, Pudp0, Ptfo0, Pcert0, PTls13);
} else if (type0 == "QuanX") { } else if (type0 == "QuanX" || type0 == "Clash") {
total = isQuanX(content0); total = isQuanX(content0);
} else if (type0 == "Surge") { } else if (type0 == "Surge") {
total = Surge2QX(content0); total = Surge2QX(content0);
@@ -236,6 +237,7 @@ if (flag == 1) { //server 类型统一处理
total = QXSort(total, Psort0); total = QXSort(total, Psort0);
} }
total = TagCheck_QX(total) //节点名检查 total = TagCheck_QX(total) //节点名检查
if (Pcnt == 1) {$notify("final content" , "Nodes", total)}
if (flag == 1) { total = Base64.encode(total.join("\n")) } //强制节点类型 base64 加密后再导入 Quantumult X if (flag == 1) { total = Base64.encode(total.join("\n")) } //强制节点类型 base64 加密后再导入 Quantumult X
$done({ content: total }); $done({ content: total });
} else { $done({ content: total });} } else { $done({ content: total });}
@@ -276,6 +278,7 @@ function Type_Check(subs) {
var DomainK = ["domain-set,"] var DomainK = ["domain-set,"]
var QuanXK = ["shadowsocks=", "trojan=", "vmess=", "http="]; var QuanXK = ["shadowsocks=", "trojan=", "vmess=", "http="];
var SurgeK = ["=ss,", "=vmess,", "=trojan,", "=http,", "=custom,", "=https,", "=shadowsocks", "=shadowsocksr"]; var SurgeK = ["=ss,", "=vmess,", "=trojan,", "=http,", "=custom,", "=https,", "=shadowsocks", "=shadowsocksr"];
var ClashK = ["proxies:"]
var SubK = ["dm1lc3M", "c3NyOi8v", "dHJvamFu", "c3M6Ly", "c3NkOi8v", "c2hhZG93"]; var SubK = ["dm1lc3M", "c3NyOi8v", "dHJvamFu", "c3M6Ly", "c3NkOi8v", "c2hhZG93"];
var RewriteK = [" url "] var RewriteK = [" url "]
var SubK2 = ["ss://", "vmess://", "ssr://", "trojan://", "ssd://"]; var SubK2 = ["ss://", "vmess://", "ssr://", "trojan://", "ssd://"];
@@ -298,6 +301,11 @@ function Type_Check(subs) {
type = "Surge"; // Surge Profiles type = "Surge"; // Surge Profiles
} else if (SurgeK.some(NodeCheck)) { } else if (SurgeK.some(NodeCheck)) {
type = "Subs" // Surge proxy list type = "Subs" // Surge proxy list
} else if (ClashK.some(NodeCheck)){ // Clash 类型节点转换
type = "Clash";
console.log(type)
content0 = Clash2QX(subs)
console.log("waht"+content0)
} else if (subi.indexOf("[Script]") != -1 || subi.indexOf("[Rule]") != -1 || subs.indexOf("[URL Rewrite]") != -1 || subs.indexOf("[Map Local]") != -1 || para1.indexOf("dst=regex") != -1) { // Surge module /rule-set(url-regex) 类型 } else if (subi.indexOf("[Script]") != -1 || subi.indexOf("[Rule]") != -1 || subs.indexOf("[URL Rewrite]") != -1 || subs.indexOf("[Map Local]") != -1 || para1.indexOf("dst=regex") != -1) { // Surge module /rule-set(url-regex) 类型
type = "sgmodule" type = "sgmodule"
} else if (subi.indexOf("hostname=") != -1 || RewriteK.some(RewriteCheck)) { } else if (subi.indexOf("hostname=") != -1 || RewriteK.some(RewriteCheck)) {
@@ -547,11 +555,11 @@ function Rule_Handle(subs, Pout, Pin) {
if (Tout != "" && Tout != null) { // 有 out 参数时 if (Tout != "" && Tout != null) { // 有 out 参数时
var dlist = []; var dlist = [];
for (var i = 0; i < cnt.length; i++) { for (var i = 0; i < cnt.length; i++) {
cc = cnt[i] cc = cnt[i].indexOf(" - ") != -1? cnt[i].split(" - ")[1].trim() : cnt[i].trim()
const exclude = (item) => cc.indexOf(item) != -1; // 删除项 const exclude = (item) => cc.indexOf(item) != -1; // 删除项
const RuleCheck = (item) => cc.indexOf(item) != -1; //无视注释行 const RuleCheck = (item) => cc.indexOf(item) != -1; //无视注释行
if (Tout.some(exclude) && !RuleK.some(RuleCheck)) { if (Tout.some(exclude) && !RuleK.some(RuleCheck)) {
dlist.push(Rule_Policy("-" + cnt[i])) dlist.push(Rule_Policy("-" + cc))
} else if (!RuleK.some(RuleCheck) && cc) { //if Pout.some, 不操作注释项 } else if (!RuleK.some(RuleCheck) && cc) { //if Pout.some, 不操作注释项
dd = Rule_Policy(cc); dd = Rule_Policy(cc);
if (Tin != "" && Tin != null) { if (Tin != "" && Tin != null) {
@@ -586,7 +594,7 @@ function Rule_Handle(subs, Pout, Pin) {
} else if (Tin != "" && Tin != null) { //if Tout } else if (Tin != "" && Tin != null) { //if Tout
var dlist = []; var dlist = [];
for (var i = 0; i < cnt.length; i++) { for (var i = 0; i < cnt.length; i++) {
cc = cnt[i] cc = cnt[i].indexOf(" - ") != -1? cnt[i].split(" - ")[1].trim() : cnt[i].trim()
const RuleCheck = (item) => cc.indexOf(item) != -1; //无视注释行 const RuleCheck = (item) => cc.indexOf(item) != -1; //无视注释行
if (!RuleK.some(RuleCheck) && cc) { //if Pout.some, 不操作注释项 if (!RuleK.some(RuleCheck) && cc) { //if Pout.some, 不操作注释项
dd = Rule_Policy(cc); dd = Rule_Policy(cc);
@@ -609,7 +617,7 @@ function Rule_Handle(subs, Pout, Pin) {
} }
function Rule_Policy(content) { //增加、替换 policy function Rule_Policy(content) { //增加、替换 policy
var cnt = content.split(","); var cnt = content.replace(/ - /g,"").trim().split(",");
var RuleK = ["//", "#", ";"]; var RuleK = ["//", "#", ";"];
var RuleK1 = ["host", "domain", "ip-cidr", "geoip", "user-agent", "ip6-cidr"]; var RuleK1 = ["host", "domain", "ip-cidr", "geoip", "user-agent", "ip6-cidr"];
const RuleCheck = (item) => cnt[0].toLowerCase().indexOf(item) != -1; //无视注释行 const RuleCheck = (item) => cnt[0].toLowerCase().indexOf(item) != -1; //无视注释行
@@ -1449,6 +1457,99 @@ function LoonSSR2QX(cnt) {
return node return node
} }
// Clash parser
function Clash2QX(cnt) {
const yaml = new YAML()
var aa = JSON.stringify(yaml.parse(cnt))
var bb = JSON.parse(aa).proxies
console.log(bb)
var nl = bb.length
var nodelist=[]
var node=""
for (i=0; i<nl; i++){
node=bb[i]
typec = node.type
if (typec == "ss") {
node = CSS2QX(node,1,1)
} else if (typec == "vmess"){
node = CV2QX(node,1,1)
} else if (typec == "trojan"){
node = CT2QX(node,1,1)
} else if (typec == "http"){
node = CH2QX(node)
}
nodelist.push(node)
}
return nodelist.join("\n")
}
//Clash ss type server
function CSS2QX(cnt,pudp,ptfo) {
tag = "tag="+cnt.name.replace(/\\U.+?\s{1}/gi,"")
ipt = cnt.server+":"+cnt.port
pwd = "password=" + cnt.password
mtd = "method="+ cnt.cipher
udp = cnt.udp ? "udp-relay=true" : "udp-relay=false"
tfo = cnt.tfo ? "fast-open=true" : "fast-open=false"
obfs = cnt.plugin == "obfs"? "obfs=" + cnt["plugin-opts"].mode : ""
ohost = cnt.plugin == "obfs"? "obfs-host=" + cnt["plugin-opts"].host : ""
node = "shadowsocks="+[ipt, pwd, mtd, udp, tfo, obfs, ohost, tag].filter(Boolean).join(", ")
console.log(node)
return node
}
//Clash vmess type server
function CV2QX(cnt,pudp,ptfo) {
tag = "tag="+cnt.name.replace(/\\U.+?\s{1}/gi," ")
ipt = cnt.server+":"+cnt.port
pwd = "password=" + cnt.uuid
mtd = "method="+ "aes-128-gcm" //cnt.cipher
udp = cnt.udp ? "udp-relay=true" : "udp-relay=false"
tfo = cnt.tfo ? "fast-open=true" : "fast-open=false"
obfs = ""
if (cnt.network == "ws" && cnt.tls) {
obfs = "obfs=wss"
} else if (cnt.network == "ws"){
obfs = "obfs=ws"
} else if (cnt.tls){
obfs = "obfs=over-tls"
}
ohost = cnt["ws-headers"]? "obfs-host=" + cnt["ws-headers"]["Host"] : ""
ouri = cnt["ws-path"]? "obfs-uri="+cnt["ws-path"] : ""
cert = cnt["skip-cert-verify"] && cnt.tls ? "tls-verification=false" : ""
node = "vmess="+[ipt, pwd, mtd, udp, tfo, obfs, ohost, ouri, cert, tag].filter(Boolean).join(", ")
console.log(node)
return node
}
//Clash Trojan
function CT2QX(cnt,pudp,ptfo) {
tag = "tag="+cnt.name.replace(/\\U.+?\s{1}/gi," ")
ipt = cnt.server+":"+cnt.port
pwd = "password=" + cnt.password
otls = "over-tls=true"
cert = cnt["skip-cert-verify"] ? "tls-verification=false" : "tls-verification=true"
udp = cnt.udp ? "udp-relay=true" : "udp-relay=false"
tfo = cnt.tfo ? "fast-open=true" : "fast-open=false"
node = "trojan="+[ipt, pwd, otls, cert, udp, tfo, tag].filter(Boolean).join(", ")
console.log(node)
return node
}
// Clash http
function CH2QX(cnt){
tag = "tag="+cnt.name.replace(/\\U.+?\s{1}/gi," ")
ipt = cnt.server+":"+cnt.port
uname = cnt.username ? "username=" + cnt.username : ""
pwd = cnt.password ? "password=" + cnt.password : ""
tls = cnt.tls ? "over-tls=true" : ""
cert = cnt["skip-cert-verify"] && cnt.tls ? "tls-verification=false" : ""
node = "http="+[ipt, uname, pwd, tls, cert, tag].filter(Boolean).join(", ")
console.log(node)
return node
}
// UDP/TFO 参数 (强制 surge/quanx 类型转换) // UDP/TFO 参数 (强制 surge/quanx 类型转换)
function XUDP(cnt,pudp) { function XUDP(cnt,pudp) {
var udp = pudp == 1? "udp-relay=true, " : "udp-relay=false, " var udp = pudp == 1? "udp-relay=true, " : "udp-relay=false, "
@@ -1621,6 +1722,441 @@ function Base64Code() {
} }
/*
YAML parser for Javascript
Author: Diogo Costa
This program is released under the MIT License as follows:
Copyright (c) 2011 Diogo Costa (costa.h4evr@gmail.com)
*/
function YAML() {
var errors = [],
reference_blocks = [],
processing_time = 0,
regex =
{
"regLevel" : new RegExp("^([\\s\\-]+)"),
"invalidLine" : new RegExp("^\\-\\-\\-|^\\.\\.\\.|^\\s*#.*|^\\s*$"),
"dashesString" : new RegExp("^\\s*\\\"([^\\\"]*)\\\"\\s*$"),
"quotesString" : new RegExp("^\\s*\\\'([^\\\']*)\\\'\\s*$"),
"float" : new RegExp("^[+-]?[0-9]+\\.[0-9]+(e[+-]?[0-9]+(\\.[0-9]+)?)?$"),
"integer" : new RegExp("^[+-]?[0-9]+$"),
"array" : new RegExp("\\[\\s*(.*)\\s*\\]"),
"map" : new RegExp("\\{\\s*(.*)\\s*\\}"),
"key_value" : new RegExp("([a-z0-9_-][ a-z0-9_-]*):( .+)", "i"),
"single_key_value" : new RegExp("^([a-z0-9_-][ a-z0-9_-]*):( .+?)$", "i"),
"key" : new RegExp("([a-z0-9_-][ a-z0-9_-]+):( .+)?", "i"),
"item" : new RegExp("^-\\s+"),
"trim" : new RegExp("^\\s+|\\s+$"),
"comment" : new RegExp("([^\\\'\\\"#]+([\\\'\\\"][^\\\'\\\"]*[\\\'\\\"])*)*(#.*)?")
};
/**
* @class A block of lines of a given level.
* @param {int} lvl The block's level.
* @private
*/
function Block(lvl) {
return {
/* The block's parent */
parent: null,
/* Number of children */
length: 0,
/* Block's level */
level: lvl,
/* Lines of code to process */
lines: [],
/* Blocks with greater level */
children : [],
/* Add a block to the children collection */
addChild : function(obj) {
this.children.push(obj);
obj.parent = this;
++this.length;
}
};
}
// function to create an XMLHttpClient in a cross-browser manner
function fromURL(src, ondone) {
var client = createXMLHTTPRequest();
client.onreadystatechange = function() {
if (this.readyState == 4 || this.status == 200) {
var txt = this.responseText;
ondone(YAML.eval0(txt));
}
};
client.open('GET', src);
client.send();
}
function parser(str) {
var regLevel = regex["regLevel"];
var invalidLine = regex["invalidLine"];
var lines = str.split("\n");
var m;
var level = 0, curLevel = 0;
var blocks = [];
var result = new Block(-1);
var currentBlock = new Block(0);
result.addChild(currentBlock);
var levels = [];
var line = "";
blocks.push(currentBlock);
levels.push(level);
for(var i = 0, len = lines.length; i < len; ++i) {
line = lines[i];
if(line.match(invalidLine)) {
continue;
}
if(m = regLevel.exec(line)) {
level = m[1].length;
} else
level = 0;
if(level > curLevel) {
var oldBlock = currentBlock;
currentBlock = new Block(level);
oldBlock.addChild(currentBlock);
blocks.push(currentBlock);
levels.push(level);
} else if(level < curLevel) {
var added = false;
var k = levels.length - 1;
for(; k >= 0; --k) {
if(levels[k] == level) {
currentBlock = new Block(level);
blocks.push(currentBlock);
levels.push(level);
if(blocks[k].parent!= null)
blocks[k].parent.addChild(currentBlock);
added = true;
break;
}
}
if(!added) {
errors.push("Error: Invalid indentation at line " + i + ": " + line);
return;
}
}
currentBlock.lines.push(line.replace(regex["trim"], ""));
curLevel = level;
}
return result;
}
function processValue(val) {
val = val.replace(regex["trim"], "");
var m = null;
if(val == 'true') {
return true;
} else if(val == 'false') {
return false;
} else if(val == '.NaN') {
return Number.NaN;
} else if(val == 'null') {
return null;
} else if(val == '.inf') {
return Number.POSITIVE_INFINITY;
} else if(val == '-.inf') {
return Number.NEGATIVE_INFINITY;
} else if(m = val.match(regex["dashesString"])) {
return m[1];
} else if(m = val.match(regex["quotesString"])) {
return m[1];
} else if(m = val.match(regex["float"])) {
return parseFloat(m[0]);
} else if(m = val.match(regex["integer"])) {
return parseInt(m[0]);
} else if( !isNaN(m = Date.parse(val))) {
return new Date(m);
} else if(m = val.match(regex["single_key_value"])) {
var res = {};
res[m[1]] = processValue(m[2]);
return res;
} else if(m = val.match(regex["array"])){
var count = 0, c = ' ';
var res = [];
var content = "";
var str = false;
for(var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
c = m[1][j];
if(c == '\'' || c == '"') {
if(str === false) {
str = c;
content += c;
continue;
} else if((c == '\'' && str == '\'') || (c == '"' && str == '"')) {
str = false;
content += c;
continue;
}
} else if(str === false && (c == '[' || c == '{')) {
++count;
} else if(str === false && (c == ']' || c == '}')) {
--count;
} else if(str === false && count == 0 && c == ',') {
res.push(processValue(content));
content = "";
continue;
}
content += c;
}
if(content.length > 0)
res.push(processValue(content));
return res;
} else if(m = val.match(regex["map"])){
var count = 0, c = ' ';
var res = [];
var content = "";
var str = false;
for(var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
c = m[1][j];
if(c == '\'' || c == '"') {
if(str === false) {
str = c;
content += c;
continue;
} else if((c == '\'' && str == '\'') || (c == '"' && str == '"')) {
str = false;
content += c;
continue;
}
} else if(str === false && (c == '[' || c == '{')) {
++count;
} else if(str === false && (c == ']' || c == '}')) {
--count;
} else if(str === false && count == 0 && c == ',') {
res.push(content);
content = "";
continue;
}
content += c;
}
if(content.length > 0)
res.push(content);
var newRes = {};
for(var j = 0, lenJ = res.length; j < lenJ; ++j) {
if(m = res[j].match(regex["key_value"])) {
newRes[m[1]] = processValue(m[2]);
}
}
return newRes;
} else
return val;
}
function processFoldedBlock(block) {
var lines = block.lines;
var children = block.children;
var str = lines.join(" ");
var chunks = [str];
for(var i = 0, len = children.length; i < len; ++i) {
chunks.push(processFoldedBlock(children[i]));
}
return chunks.join("\n");
}
function processLiteralBlock(block) {
var lines = block.lines;
var children = block.children;
var str = lines.join("\n");
for(var i = 0, len = children.length; i < len; ++i) {
str += processLiteralBlock(children[i]);
}
return str;
}
function processBlock(blocks) {
var m = null;
var res = {};
var lines = null;
var children = null;
var currentObj = null;
var level = -1;
var processedBlocks = [];
var isMap = true;
for(var j = 0, lenJ = blocks.length; j < lenJ; ++j) {
if(level != -1 && level != blocks[j].level)
continue;
processedBlocks.push(j);
level = blocks[j].level;
lines = blocks[j].lines;
children = blocks[j].children;
currentObj = null;
for(var i = 0, len = lines.length; i < len; ++i) {
var line = lines[i];
if(m = line.match(regex["key"])) {
var key = m[1];
if(key[0] == '-') {
key = key.replace(regex["item"], "");
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
if(currentObj != null) res.push(currentObj);
currentObj = {};
isMap = true;
}
if(typeof m[2] != "undefined") {
var value = m[2].replace(regex["trim"], "");
if(value[0] == '&') {
var nb = processBlock(children);
if(currentObj != null) currentObj[key] = nb;
else res[key] = nb;
reference_blocks[value.substr(1)] = nb;
} else if(value[0] == '|') {
if(currentObj != null) currentObj[key] = processLiteralBlock(children.shift());
else res[key] = processLiteralBlock(children.shift());
} else if(value[0] == '*') {
var v = value.substr(1);
var no = {};
if(typeof reference_blocks[v] == "undefined") {
errors.push("Reference '" + v + "' not found!");
} else {
for(var k in reference_blocks[v]) {
no[k] = reference_blocks[v][k];
}
if(currentObj != null) currentObj[key] = no;
else res[key] = no;
}
} else if(value[0] == '>') {
if(currentObj != null) currentObj[key] = processFoldedBlock(children.shift());
else res[key] = processFoldedBlock(children.shift());
} else {
if(currentObj != null) currentObj[key] = processValue(value);
else res[key] = processValue(value);
}
} else {
if(currentObj != null) currentObj[key] = processBlock(children);
else res[key] = processBlock(children);
}
} else if(line.match(/^-\s*$/)) {
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
if(currentObj != null) res.push(currentObj);
currentObj = {};
isMap = true;
continue;
} else if(m = line.match(/^-\s*(.*)/)) {
if(currentObj != null)
currentObj.push(processValue(m[1]));
else {
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
res.push(processValue(m[1]));
}
continue;
}
}
if(currentObj != null) {
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
res.push(currentObj);
}
}
for(var j = processedBlocks.length - 1; j >= 0; --j) {
blocks.splice.call(blocks, processedBlocks[j], 1);
}
return res;
}
function semanticAnalysis(blocks) {
var res = processBlock(blocks.children);
return res;
}
function preProcess(src) {
var m;
var lines = src.split("\n");
var r = regex["comment"];
for(var i in lines) {
if(m = lines[i].match(r)) {
/* var cmt = "";
if(typeof m[3] != "undefined")
lines[i] = m[1];
else if(typeof m[3] != "undefined")
lines[i] = m[3];
else
lines[i] = "";
*/
if(typeof m[3] !== "undefined") {
lines[i] = m[0].substr(0, m[0].length - m[3].length);
}
}
}
return lines.join("\n");
}
this.parse = function eval0(str) {
errors = [];
reference_blocks = [];
processing_time = (new Date()).getTime();
var pre = preProcess(str)
var doc = parser(pre);
var res = semanticAnalysis(doc);
processing_time = (new Date()).getTime() - processing_time;
return res;
}
};
/***********************************************************************************************/ /***********************************************************************************************/
function Tools() { function Tools() {
const filter = (src, ...regex) => { const filter = (src, ...regex) => {