1、对象

项目属性要添加

QT       +=  script
自定义的对象头文件如下,实现正常就好,记得脚本里要调用的方法一定要定义在public slots:下,要不然调用时提示该对象没有*方法
 
 #ifndef CMU_H
#define CMU_H
#include "Communication/Communication.h"
#include "stt_basic_moudle.h"
#include <iostream>
#include <map>
using namespace std; struct CMU_INFO
{
///
/// \brief CMU_Table
/// name
///
std::map<std::string, CCommunication*> name_commu;
///
/// \brief anonymous_commu
///
CCommunication* anonymous_commu;
}; ///
/// \brief CMU_Table
///
extern std::map<int,CMU_INFO> CMU_Table; class CMU:public QObject
{
Q_OBJECT public slots: #define D_CONNECT ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 打开并连接通讯 目前支持 telnet、console、系统命令行 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 连接模式[telnet;console,cmd] ----------必选参数\r\n\
# arg2: 是否使用配置登陆,0默认登陆,1不登陆 [;]---可选\r\n\
# arg3: 匿名通讯会自动关闭,给当前通讯命名[任意名字] \r\n\
# arg4: 无 \r\n\
# arg5: 无 \r\n\
# arg6: 无 \r\n\
# 示例: \r\n\
# connect = telnet , , cpe_telnet \r\n\
# \r\n\
#########################################################")
bool connect (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_CLOSE ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 关闭通讯 目前支持 telnet、console、系统命令行 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 连接模式[telnet;console,cmd] ----------必选参数\r\n\
# arg2: 匿名通讯会自动关闭,关闭通讯命名[任意名字] ---可选\r\n\
# 示例: \r\n\
# connect = telnet , cpe_telnet \r\n\
# \r\n\
#########################################################")
bool close (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_SEND ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 发送命令到通讯 目前支持 telnet、console、系统命令行 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 发送的命令 ----------必选参数\r\n\
# arg2: 发送目标通讯,无为匿名通讯 通讯命名[任意名字] ---可选\r\n\
# 示例: \r\n\
# send = dir , cpe_telnet \r\n\
# \r\n\
#########################################################")
bool send (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_RECEIVE ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 发送命令到通讯 目前支持 telnet、console、系统命令行 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 延时时间 ----------必选参数\r\n\
# arg2: 为正则表达式 ----------必选参数\r\n\
# arg3: 需要查找的值在正则表达式的第几组内 ----------必选参数\r\n\
# arg4: 获取的结果保存到变量,默认RECEIVE ----------可选参数\r\n\
# arg5: 发送目标通讯,无为匿名通讯 通讯命名[任意名字] ---可选\r\n\
# 示例: \r\n\
# receive = ,Mac.Address.{}(.*).,,para \r\n\
# \r\n\
#########################################################")
bool receive(int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_PING ("\
#########################################################\r\n\
# 函数说明:\r\n\
# ping \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 目标IP ----------必选参数\r\n\
# arg2: 源IP [使用默认路由设置] ----------可选参数\r\n\
# arg3: PING包的次数 默认4 ----------可选参数\r\n\
# arg4: PING通的连续成功次数,默认1 ----------可选参数\r\n\
# arg5: PING包的大小 默认64 ---可选\r\n\
# 示例: \r\n\
# ping = %ip%,,,, \r\n\
# \r\n\
#########################################################")
bool ping (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_SLEEP ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 示设置延时的时间 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 延时时间,时间单位为毫秒 ----------必选参数\r\n\
# 示例: \r\n\
# sleep = \r\n\
# \r\n\
#########################################################")
bool sleep (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_FIND ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 查找通讯返回信息相应的值 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 延时时间,时间单位为毫秒 ----------必选参数\r\n\
# arg2: 要查找得值 ----------必选参数\r\n\
# arg3: 发送目标通讯,无为匿名通讯 通讯命名[任意名字] ---可选\r\n\
# 示例: \r\n\
# find = ,succee \r\n\
# \r\n\
#########################################################")
bool find (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_LOOPCHK ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 在一定的时间内下一串指令然后通过正则表达式查找是否有返回所需要的值 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 发送的指令 ----------必选参数\r\n\
# arg2: 总时间 ----------必选参数\r\n\
# arg3: 正则表达式 ----------必选参数\r\n\
# arg4: 需要查找的值在正则表达式的第几组内 ----------必选参数\r\n\
# arg5: 发送完指令后等待时间 默认0----------可选参数\r\n\
# arg6: 获取的结果保存到变量,默认RECEIVE ----------可选参数\r\n\
# arg7: 目标通讯,无为匿名通讯 通讯命名[任意名字] ---可选\r\n\
# 示例: \r\n\
# loopchk = adsl info,,Path.*\D\d.*\D(\d*)\DKbps.*Downstream,, \r\n\
# \r\n\
#########################################################")
bool loopchk(int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_CHECK ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 如果需要比较相同,则使用一个参数,如果需要比较范围,则需要使用两个参数,用来表示上下限 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 比较值1 为数值择是上线 ----------必选参数\r\n\
# arg2: 比较值2 不为空则是数值范围比较下线 ----------可选参数\r\n\
# arg3: 目标变量,默认RECEIVE ----------可选参数\r\n\
# 示例: \r\n\
# check = %up_rate%,%down_rate% \r\n\
# \r\n\
#########################################################")
bool check (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_SET ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 用来将receive指令通过正则表达匹配到的值保存一个变量里 \r\n\
# 如果有四个参数:set = 新变量名,变量名,分隔符类型(数字),分隔数量 \r\n\
# 分隔符类型有:->无,->:,->-,->.,->%3A,->空格,->空格 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 目标变量名 ----------必选参数\r\n\
# arg2: 源数据 ----------可选参数\r\n\
# arg3: 分隔符类型 ->无,->:,->-,->.,->%3A,->空格,->空格(除了空格,数据会变成十六进制)----------可选参数\r\n\
# arg4: 分隔数量 ----------可选参数\r\n\
# 示例: \r\n\
# set = newmac,%mac%,, \r\n\
# \r\n\
#########################################################")
bool set (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_STRINGADD ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 根据具体截取数值确定累积参数增加 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 目的截取后的数值字符串 ----------必选参数\r\n\
# arg2: stringAdd指令所用到参数的个数(包含本身) ----------必选参数\r\n\
# arg3: 前缀字符串 ----------必选参数\r\n\
# arg4: 括号内的第一个参数表示被截取的字符串,第二个参数表示起始位,第三个参数表示位数长度 ----------必选参数\r\n\
# arg..: 同[arg4] \r\n\
# 示例: \r\n\
# stringAdd = %StrNew%,,Str(WLAN_),Sub(&mac&;;) \r\n\
# \r\n\
#########################################################")
bool stringAdd (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_COMPARE ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 表示用于目的字符串的值与源字符串的值进行对比 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 目的字符串的值 ----------必选参数\r\n\
# arg2: 是源字符串的值 ----------必选参数\r\n\
# arg3: 第一个参数截取子字符串的索引号 ----------可选参数\r\n\
# arg4: 截取子字符串的长度 ----------可选参数\r\n\
# 示例: \r\n\
# compare = %StrNew%,%ssid%,, \r\n\
# \r\n\
#########################################################")
bool compare (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_ADD ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 将源字符串的内容加/减一个数,然后按指定格式保存到目的字符串的变 \r\n\
# 量里 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 目的字符串的值 ----------必选参数\r\n\
# arg2: 是源字符串的值 ----------必选参数\r\n\
# arg3: 被加/减数[整数]:表示要减或加的参数 ----------必选参数\r\n\
# arg4: 目的字符串格式[整数]:参数表示指定的间隔符(:无,: \":\",2: \"-\",3: \".\",4: \"%3A\",5:\" \")----------必选参数\r\n\
# arg5: 目的串截取段[整数]:间隔符之间的字符数 ----------必选参数\r\n\
# arg6: 加/减[/]:1为递增,0为递减。 ----------必选参数\r\n\
# 示例: \r\n\
# add = %mac1%,%mac%,,,, \r\n\
# \r\n\
#########################################################")
bool add (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_LOOPFIND ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 在一定的时间内下一串指令然后通过正则表达式查找是否有返回所需要的值 \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 发送的指令 ----------必选参数\r\n\
# arg2: 总时间 ----------必选参数\r\n\
# arg3: 单步循环时间 ----------必选参数\r\n\
# arg4: 需要查找的值 ----------必选参数\r\n\
# arg5: 目标通讯,无为匿名通讯 通讯命名[任意名字] ---可选\r\n\
# 示例: \r\n\
# loopfind = NULL, ,,rstBtn_pressed \r\n\
# \r\n\
#########################################################")
bool loopfind (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); #define D_CHANGE ("\
#########################################################\r\n\
# 函数说明:\r\n\
# 从[源字符串名称]获取的数据,用[正则式]匹配出来的子字符串,根据[改变的方式]对子字符串进行格式上的转换并保存到[目标字符名称] \r\n\
# \r\n\
# 参数说明:\r\n\
# arg1: 目标字符串名 ----------必选参数\r\n\
# arg2: 源字符名称 ----------必选参数\r\n\
# arg3: 正则式 ----------必选参数\r\n\
# arg4: 表达式所在组 ----------必选参数\r\n\
# arg5: 改变的方式 :无改变;:变为小写,,变为大写---必选参数\r\n\
# 示例: \r\n\
# loopfind = NULL, ,,rstBtn_pressed \r\n\
# \r\n\
#########################################################")
bool change (int test_id,QString arg1,QString arg2,QString arg3,QString arg4, QString arg5,QString arg6,QString arg7,QString arg8,QString arg9); };
#endif // CMU_H
2、注册对象到JavaScript解释器

注意要是在不同的函数调用需要使用new 创建注册的对象以免函数执行完毕被销毁
    CMU * cmu = new CMU();
QScriptValue qcmu = eng->newQObject(cmu);
eng->globalObject().setProperty(this->get_moudle_name().c_str(), qcmu);

 /******************************************************************************************************
* Copyright (C) 2014, All right reserved. * file
* version 1.0
* author NingJian (freegodly@gmail.com)
* brief * detail * TODO
* history 2014-9-17 created by NingJian
*
* note
******************************************************************************************************/ #include "stt_basic_moudle.h"
#include "cmu.h" std::map<int,TEST_INFO> *STT_Basic_Moudle::STT_G_Test_Info; std::map<std::string,TEST_FUN_INFO> *STT_Basic_Moudle::STT_G_Test_Fun_Info; RUN_FUN STT_Basic_Moudle::STT_G_Test_Run_Fun; std::map<std::string,std::string> *STT_Basic_Moudle::STT_G_Moudles_Config; STT_Basic_Moudle::STT_Basic_Moudle()
{ } bool STT_Basic_Moudle::init(std::map<int, TEST_INFO> &test_info, std::map<string, TEST_FUN_INFO> &test_fun_info, std::map<string, string> &moudles_config, RUN_FUN run_fun) const
{ STT_Basic_Moudle::STT_G_Test_Info = &test_info;
STT_Basic_Moudle::STT_G_Test_Fun_Info = &test_fun_info;
STT_Basic_Moudle::STT_G_Test_Run_Fun = run_fun;
STT_Basic_Moudle::STT_G_Moudles_Config = &moudles_config;
return true;
} bool STT_Basic_Moudle::release() const
{
return true;
} bool STT_Basic_Moudle::initiation(int test_id) const
{
return true;
} bool STT_Basic_Moudle::finish(int test_id) const
{
std::string error_str;
CMU_INFO ci = CMU_Table[test_id];
if( ci.anonymous_commu != NULL )
{
ci.anonymous_commu->fnClose(error_str);
}
std::map<std::string, CCommunication*>::iterator it = ci.name_commu.begin();
while(it != ci.name_commu.end())
{
it->second->fnClose(error_str);
it++;
}
ci.name_commu.clear();
return true;
} std::string STT_Basic_Moudle::get_moudle_version() const
{
return std::string("Version: V1.0.0 \r\n" ) + STT_BUILD_TIME ;
} std::string STT_Basic_Moudle::get_moudle_describe() const
{
return "基本功能模块";
} void STT_Basic_Moudle::reg_ui_fun(REG_UI_FUN reg_ui_f) const
{ } void STT_Basic_Moudle::reg_fun(int test_id,QScriptEngine *eng) const
{
CMU * cmu = new CMU();
QScriptValue qcmu = eng->newQObject(cmu);
eng->globalObject().setProperty(this->get_moudle_name().c_str(), qcmu); add_fun(this->get_moudle_name().c_str(), "connect", D_CONNECT );
add_fun(this->get_moudle_name().c_str(), "close", D_CLOSE );
add_fun( this->get_moudle_name().c_str(), "send", D_SEND );
add_fun(this->get_moudle_name().c_str(), "receive", D_RECEIVE );
add_fun(this->get_moudle_name().c_str(), "ping", D_PING );
add_fun(this->get_moudle_name().c_str(), "sleep", D_SLEEP );
add_fun( this->get_moudle_name().c_str(), "find", D_FIND );
add_fun(this->get_moudle_name().c_str(), "loopchk", D_LOOPCHK );
add_fun( this->get_moudle_name().c_str(), "check", D_CHECK );
add_fun( this->get_moudle_name().c_str(), "set", D_SET );
add_fun(this->get_moudle_name().c_str(), "stringAdd", D_STRINGADD );
add_fun( this->get_moudle_name().c_str(), "compare", D_COMPARE );
add_fun( this->get_moudle_name().c_str(), "add", D_ADD );
add_fun(this->get_moudle_name().c_str(), "loopfind", D_LOOPFIND );
add_fun( this->get_moudle_name().c_str(), "change", D_CHANGE );
} string STT_Basic_Moudle::get_moudle_name() const
{
return "STT_Basic_Moudle";
} string get_stt_variable(int test_id, string key)
{
return (*STT_Basic_Moudle::STT_G_Test_Info)[test_id].variable_map[key];
} void set_stt_variable(int test_id, string key, string value)
{
(*STT_Basic_Moudle::STT_G_Test_Info)[test_id].variable_map.insert(std::pair<std::string,std::string>(key,value));
} void add_fun(const char *moudle_name, const char *fun_name, const char *fun_describe)
{ if((*STT_Basic_Moudle::STT_G_Test_Fun_Info).find(fun_name)==(*STT_Basic_Moudle::STT_G_Test_Fun_Info).end())
{
TEST_FUN_INFO tfi={moudle_name,fun_name,fun_describe};
(*STT_Basic_Moudle::STT_G_Test_Fun_Info).insert(std::pair<std::string,TEST_FUN_INFO>(fun_name,tfi));
}
}

3、使用
我的注册时在插件里实现的,调用在主程序里,这样可以n个插件向同一个javascript解释器里注册不同的对象
执行完一次可以判断是否有异常,打印异常信息等
 ///
/// \brief G_STT_Interpreter [STT解释器]
///
std::map<int,QScriptEngine *> G_STT_Interpreter; /* ############################################################################################################# */ bool G_STT_Run_Fun(QString fun_name, int test_id, QString v1, QString v2, QString v3, QString v4, QString v5, QString v6, QString v7, QString v8, QString v9)
{
bool result = false;
TEST_FUN_INFO tfi = G_Test_Fun_Info[fun_name.toStdString()]; if(tfi.fun_name == fun_name.toStdString())
{
QString script=QString("%1.%2").arg(tfi.modle_name.c_str(),fun_name); QScriptValueList args;
QScriptEngine * eng = G_STT_Interpreter[test_id];
args << test_id << v1<<v2<<v3<< v4<<v5<<v6<< v7<<v8<<v9;
QScriptValue cpp_fun = eng->evaluate(script);
qDebug()<<cpp_fun.toString();
QScriptValue value = cpp_fun.call(QScriptValue(), args); if (G_STT_Interpreter[test_id]->hasUncaughtException()){
emit STT_Global::mw->signal_add_Log(test_id, G_STT_Interpreter[test_id]->uncaughtException().toString());
emit STT_Global::mw->signal_add_Log(test_id,G_STT_Interpreter[test_id]->uncaughtExceptionBacktrace().join("/n"));
qDebug()<<G_STT_Interpreter[test_id]->uncaughtException().toString();
qDebug()<<G_STT_Interpreter[test_id]->uncaughtExceptionBacktrace().join("/n");
return false;
}else{
result = value.toBool();
} } return result;
}

												

QT自定义对象导入JavaScript脚本使用的更多相关文章

  1. JS中的函数,Array对象,for-in语句,with语句,自定义对象,Prototype

    一)函数 A)JS中的函数的定义格式: function add(a,b) { var sum = a+b; document.write("两个数的和是:" + sum); // ...

  2. JavaScript 类的定义和引用 JavaScript高级培训 自定义对象

    在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等.     一,概述 在Java语言中 ...

  3. JavaScript学习笔记(12)——JavaScript自定义对象

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. javascript创建自定义对象和prototype

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. javascript . 04 匿名函数、递归、回调函数、对象、基于对象的javascript、状态和行为、New、This、构造函数/自定义对象、属性绑定、进制转换

    匿名函数:   没有名字的函数,函数整体加小括号不报错, 函数调用 : a:直接调用 (function (){函数体}) ( ) ; b:事件绑定 document.onlick = functio ...

  6. JavaScript自定义对象

    一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在Javascrip ...

  7. javascript的自定义对象/取消事件/事件兼容性/取消冒泡

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. JavaScript 自定义对象

    在Js中,除了Array.Date.Number等内置对象外,开发者可以通过Js代码创建自己的对象. 目录 1. 对象特性:描述对象的特性 2. 创建对象方式:对象直接量.new 构造函数.Objec ...

  9. JavaScript 创建和浅析自定义对象

    在Js中,除了Array.Date.Number等内置对象外,开发者可以通过Js代码创建自己的对象. 目录 1. 对象特性:描述对象的特性 2. 创建对象方式:对象直接量.new 构造函数.Objec ...

随机推荐

  1. js正则验证"汉字"

    var nickname = value; var regex = new RegExp("^([\u4E00-\uFA29]|[\uE7C7-\uE7F3]|[a-zA-Z0-9_]){1 ...

  2. 取得phpcms网站下所有栏目的内容链接

    今天做了一个小功能,就是取得公司网站的所有文章的内容地址,公司网站是用phpcms 做的,感觉还蛮简单的,记录下: <?php $conf['DB_USER'] = 'user'; $conf[ ...

  3. MyEclipse13中修改Servlet.java源代码

    Servlet.java源代码想要修改的步骤,与低版本的不同废话少说,直接来步骤: 1,在myEclipse的安装目录中搜索com.genuitec.eclipse.wizards文件,如图:选择co ...

  4. docker基础入门之一

    一.概述 1.传统虚拟化技术: 纯软件的虚拟化是通过对于硬件层的模拟从而实现允许运行多个操作系统: 硬件辅助虚拟化需要硬件层面对于虚拟化的支持,类似Intel-VT技术等,具有更高的运行效率: 解决方 ...

  5. objective-C学习笔记(八) 集合类型 Collection Types

    OBJC的集合类型: 1.数组 Array 2.Set 3.键值对 Dictionary 数组:OC中的数组被定义为class,引用类型.索引从0开始,访问越界会抛出运行时异常. NSArray的元素 ...

  6. python生成器之斐波切纳数列

    面试的时候遇到过这样的一个题目: 斐波切纳数列1,2,3,5,8,13,21.........根据这样的规律,编程求出400万以内最大的斐波切纳数,并求出是第几个斐波切纳数. 方法一: 方法二:这个方 ...

  7. Android 开发笔记 “android调试遇到ADB server didn't ACK以及顽固的sjk_daemon进程 ”

    资源来源:http://blog.csdn.net/wangdong20/article/details/20839533 做Android调试的时候经常会遇到,程序写好了,准备接上手机调试,可不一会 ...

  8. access数据库 top语句失效解决方法

    使用查询语句  select   top 1  *  from  News  order  by  [PublicTime] desc   就不一定管用了,如果News表里面的PublicTime字段 ...

  9. RFID电子标签的二次注塑封装

    生活当中,RFID电子标签具有明显的优势,随着RFID电子标签成本的降低.读写距离的提高.标签存储容量增大及处理时间缩短的发展趋势,R F I D电子标签的应用将会越来越广泛. RFID电子标签的应用 ...

  10. elk 分布式数据同步

    zjtest7-redis:/elk/elasticsearch/data/es_cluster/nodes/0/indices/library# strings ./1/index/_3.cfs | ...